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

Reply via email to