Liangent has uploaded a new change for review.
https://gerrit.wikimedia.org/r/70871
Change subject: New Utils::getLanguageFallbackChain() function
......................................................................
New Utils::getLanguageFallbackChain() function
Change-Id: Ib95e3edda9c21adec5d7ed87bdf3cd6324b30fd1
---
M lib/includes/Utils.php
M lib/tests/phpunit/UtilsTest.php
2 files changed, 185 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/71/70871/1
diff --git a/lib/includes/Utils.php b/lib/includes/Utils.php
index c6ce523..269c674 100644
--- a/lib/includes/Utils.php
+++ b/lib/includes/Utils.php
@@ -34,6 +34,77 @@
*/
final class Utils {
+ const LANGUAGE_FALLBACK_ALL = -1;
+ const LANGUAGE_FALLBACK_SELF = 1;
+ const LANGUAGE_FALLBACK_VARIANTS = 2;
+ const LANGUAGE_FALLBACK_OTHERS = 4;
+
+ /**
+ * Returns the fallback chain for a single language.
+ *
+ * @param Language $language
+ * @param $mode bitfield of self::LANGUAGE_FALLBACK_*
+ * @param array $fetched private use only for internal recursive call
+ *
+ * @return array of LanguageWrapper objects
+ */
+ public static function getLanguageFallbackChain( Language $language,
+ $mode = self::LANGUAGE_FALLBACK_ALL, &$fetched = array()
+ ) {
+ $chain = array();
+
+ if ( $mode & self::LANGUAGE_FALLBACK_SELF ) {
+ if ( !isset( $fetched[$language->getCode()] ) ) {
+ $chain[] = LanguageWrapper::factory( $language
);
+ $fetched[$language->getCode()] = true;
+ }
+ }
+
+ if ( $mode & self::LANGUAGE_FALLBACK_VARIANTS ) {
+ $parentLanguage = $language->getParentLanguage();
+ if ( $parentLanguage ) {
+ // It's less likely to trigger conversion
mistakes by converting
+ // zh-tw to zh-hk first instead of converting
zh-cn to zh-tw.
+ $variantFallbacks =
$parentLanguage->getConverter()
+ ->getVariantFallbacks(
$language->getCode() );
+ if ( is_array( $variantFallbacks ) ) {
+ $variants = array_unique( array_merge(
+ $variantFallbacks,
$parentLanguage->getVariants()
+ ) );
+ } else {
+ $variants =
$parentLanguage->getVariants();
+ }
+
+ foreach ( $variants as $variant ) {
+ $variantLanguage = Language::factory(
$variant );
+ if ( isset(
$fetched[$variantLanguage->getCode()] ) ) {
+ continue;
+ }
+
+ $chain[] = LanguageWrapper::factory(
$language, $variantLanguage );
+ $fetched[$variantLanguage->getCode()] =
true;
+ }
+ }
+ }
+
+ if ( $mode & self::LANGUAGE_FALLBACK_OTHERS ) {
+ // Regarding $mode in recursive calls:
+ // * self is a must to have the fallback item itself
included;
+ // * respect the original caller about whether to
include variants or not;
+ // * others should be excluded as they'll be handled
here in loops.
+ $recursiveMode = $mode;
+ $recursiveMode &= self::LANGUAGE_FALLBACK_VARIANTS;
+ $recursiveMode |= self::LANGUAGE_FALLBACK_SELF;
+ foreach ( $language->getFallbackLanguages() as $other )
{
+ $chain = array_merge( $chain,
self::getLanguageFallbackChain(
+ Language::factory( $other ),
$recursiveMode, $fetched
+ ) );
+ }
+ }
+
+ return $chain;
+ }
+
/**
* Returns a list of language codes that Wikibase supports,
* ie the languages that a label or description can be in.
diff --git a/lib/tests/phpunit/UtilsTest.php b/lib/tests/phpunit/UtilsTest.php
index db166c7..41c6901 100644
--- a/lib/tests/phpunit/UtilsTest.php
+++ b/lib/tests/phpunit/UtilsTest.php
@@ -24,6 +24,120 @@
/**
* @group WikibaseUtils
+ * @dataProvider providerGetLanguageFallbackChain
+ */
+ public function testGetLanguageFallbackChain( $lang, $mode, $expected )
{
+ $chain = Utils::getLanguageFallbackChain( \Language::factory(
$lang ), $mode );
+
+ $this->assertEquals( count( $chain ), count( $expected ) );
+ for ( $i = 0; $i < count( $chain ); $i++ ) {
+ if ( is_array( $expected[$i] ) ) {
+ $this->assertEquals(
$chain[$i]->getLanguage()->getCode(), $expected[$i][0] );
+ $this->assertEquals(
$chain[$i]->getSourceLanguage()->getCode(), $expected[$i][1] );
+ } else {
+ $this->assertEquals(
$chain[$i]->getLanguage()->getCode(), $expected[$i] );
+ $this->assertNull(
$chain[$i]->getSourceLanguage() );
+ }
+ }
+ }
+
+ public static function providerGetLanguageFallbackChain() {
+ return array(
+ array( 'en', Utils::LANGUAGE_FALLBACK_ALL, array( 'en'
) ),
+ array( 'en', Utils::LANGUAGE_FALLBACK_VARIANTS, array()
),
+ array( 'en', Utils::LANGUAGE_FALLBACK_OTHERS, array() ),
+
+ array( 'zh', Utils::LANGUAGE_FALLBACK_ALL, array(
+ 'zh',
+ array( 'zh', 'zh-hans' ),
+ array( 'zh', 'zh-hant' ),
+ array( 'zh', 'zh-cn' ),
+ array( 'zh', 'zh-tw' ),
+ array( 'zh', 'zh-hk' ),
+ array( 'zh', 'zh-sg' ),
+ array( 'zh', 'zh-mo' ),
+ array( 'zh', 'zh-my' ),
+ 'en',
+ ) ),
+ array( 'zh', Utils::LANGUAGE_FALLBACK_SELF, array( 'zh'
) ),
+ array( 'zh', Utils::LANGUAGE_FALLBACK_VARIANTS, array(
+ array( 'zh', 'zh-hans' ),
+ array( 'zh', 'zh-hant' ),
+ array( 'zh', 'zh-cn' ),
+ array( 'zh', 'zh-tw' ),
+ array( 'zh', 'zh-hk' ),
+ array( 'zh', 'zh-sg' ),
+ array( 'zh', 'zh-mo' ),
+ array( 'zh', 'zh-my' ),
+ array( 'zh', 'zh' ),
+ ) ),
+ array( 'zh', Utils::LANGUAGE_FALLBACK_OTHERS, array(
'zh-hans', 'en' ) ),
+ array( 'zh', Utils::LANGUAGE_FALLBACK_SELF |
Utils::LANGUAGE_FALLBACK_OTHERS,
+ array( 'zh', 'zh-hans', 'en' )
+ ),
+
+ array( 'zh-cn', Utils::LANGUAGE_FALLBACK_ALL, array(
+ 'zh-cn',
+ array( 'zh-cn', 'zh-hans' ),
+ array( 'zh-cn', 'zh-sg' ),
+ array( 'zh-cn', 'zh-my' ),
+ array( 'zh-cn', 'zh' ),
+ array( 'zh-cn', 'zh-hant' ),
+ array( 'zh-cn', 'zh-hk' ),
+ array( 'zh-cn', 'zh-mo' ),
+ array( 'zh-cn', 'zh-tw' ),
+ 'en',
+ ) ),
+ array( 'zh-cn', ~Utils::LANGUAGE_FALLBACK_VARIANTS,
+ array( 'zh-cn', 'zh-hans', 'en' )
+ ),
+ array( 'zh-cn', ~Utils::LANGUAGE_FALLBACK_OTHERS, array(
+ 'zh-cn',
+ array( 'zh-cn', 'zh-hans' ),
+ array( 'zh-cn', 'zh-sg' ),
+ array( 'zh-cn', 'zh-my' ),
+ array( 'zh-cn', 'zh' ),
+ array( 'zh-cn', 'zh-hant' ),
+ array( 'zh-cn', 'zh-hk' ),
+ array( 'zh-cn', 'zh-mo' ),
+ array( 'zh-cn', 'zh-tw' ),
+ ) ),
+
+ array( 'ii', Utils::LANGUAGE_FALLBACK_ALL, array(
+ 'ii',
+ 'zh-cn',
+ array( 'zh-cn', 'zh-hans' ),
+ array( 'zh-cn', 'zh-sg' ),
+ array( 'zh-cn', 'zh-my' ),
+ array( 'zh-cn', 'zh' ),
+ array( 'zh-cn', 'zh-hant' ),
+ array( 'zh-cn', 'zh-hk' ),
+ array( 'zh-cn', 'zh-mo' ),
+ array( 'zh-cn', 'zh-tw' ),
+ 'en',
+ ) ),
+ array( 'ii', ~Utils::LANGUAGE_FALLBACK_VARIANTS,
+ array( 'ii', 'zh-cn', 'zh-hans', 'en' )
+ ),
+ array( 'ii', Utils::LANGUAGE_FALLBACK_VARIANTS, array()
),
+ array( 'ii', Utils::LANGUAGE_FALLBACK_VARIANTS |
Utils::LANGUAGE_FALLBACK_OTHERS, array(
+ 'zh-cn',
+ array( 'zh-cn', 'zh-hans' ),
+ array( 'zh-cn', 'zh-sg' ),
+ array( 'zh-cn', 'zh-my' ),
+ array( 'zh-cn', 'zh' ),
+ array( 'zh-cn', 'zh-hant' ),
+ array( 'zh-cn', 'zh-hk' ),
+ array( 'zh-cn', 'zh-mo' ),
+ array( 'zh-cn', 'zh-tw' ),
+ 'en',
+ ) ),
+ array( 'ii', Utils::LANGUAGE_FALLBACK_OTHERS, array(
'zh-cn', 'zh-hans', 'en' ) ),
+ );
+ }
+
+ /**
+ * @group WikibaseUtils
* @dataProvider providerGetLanguageCodes
*/
public function testGetLanguageCodes( $lang ) {
--
To view, visit https://gerrit.wikimedia.org/r/70871
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib95e3edda9c21adec5d7ed87bdf3cd6324b30fd1
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Liangent <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits