jenkins-bot has submitted this change and it was merged.

Change subject: LanguageFallbackChainFactory: Avoid creating Language objects
......................................................................


LanguageFallbackChainFactory: Avoid creating Language objects

Change-Id: Ief3adf61cfa24ee58f6d2a6eb99d5ba6fe56a098
---
M lib/includes/LanguageFallbackChainFactory.php
M lib/tests/phpunit/LanguageFallbackChainFactoryTest.php
2 files changed, 118 insertions(+), 15 deletions(-)

Approvals:
  Daniel Kinzler: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/includes/LanguageFallbackChainFactory.php 
b/lib/includes/LanguageFallbackChainFactory.php
index 5bcfda1..475db4e 100644
--- a/lib/includes/LanguageFallbackChainFactory.php
+++ b/lib/includes/LanguageFallbackChainFactory.php
@@ -1,7 +1,7 @@
 <?php
 
 namespace Wikibase;
-use Language, IContextSource;
+use Language, IContextSource, MWException;
 
 /**
  * Object creating LanguageFallbackChain objects in Wikibase.
@@ -84,32 +84,65 @@
        }
 
        /**
-        * Build fallback chain array for a given language.
+        * Get the fallback chain based a single language code, and specified 
fallback level.
         *
-        * @param Language $language
+        * @param string $language
+        * @param $mode bitfield of self::FALLBACK_*
+        *
+        * @return LanguageFallbackChain
+        */
+       public function newFromLanguageCode( $languageCode, $mode = 
self::FALLBACK_ALL ) {
+
+               $languageCode = LanguageWithConversion::validateLanguageCode( 
$languageCode );
+
+               if ( isset( $this->languageCache[$languageCode][$mode] ) ) {
+                       return $this->languageCache[$languageCode][$mode];
+               }
+
+               $chain = $this->buildFromLanguage( $languageCode, $mode );
+               $languageFallbackChain = new LanguageFallbackChain( $chain );
+
+               $this->languageCache[$languageCode][$mode] = 
$languageFallbackChain;
+
+               return $languageFallbackChain;
+       }
+
+       /**
+        * Build fallback chain array for a given language or validated 
language code.
+        *
+        * @param $language Language object or language code as string
         * @param $mode bitfield of self::FALLBACK_*
         * @param LanguageFallbackChain[] $chain for recursive calls
         * @param array $fetched for recursive calls
         *
         * @return LanguageWithConversion[]
         */
-       public function buildFromLanguage( Language $language, $mode, &$chain = 
array(), &$fetched = array() ) {
+       public function buildFromLanguage( $language, $mode, &$chain = array(), 
&$fetched = array() ) {
                wfProfileIn( __METHOD__ );
 
+               if ( is_string( $language ) ) {
+                       $languageCode = $language;
+               } else {
+                       $languageCode = $language->getCode();
+               }
+
                if ( $mode & self::FALLBACK_SELF ) {
-                       if ( !isset( $fetched[$language->getCode()] ) ) {
+                       if ( !isset( $fetched[$languageCode] ) ) {
                                $chain[] = LanguageWithConversion::factory( 
$language );
-                               $fetched[$language->getCode()] = true;
+                               $fetched[$languageCode] = true;
                        }
                }
 
                if ( $mode & self::FALLBACK_VARIANTS ) {
+                       if ( is_string( $language ) ) {
+                               $language = Language::factory( $language );
+                       }
                        $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() );
+                                       ->getVariantFallbacks( $languageCode );
                                if ( is_array( $variantFallbacks ) ) {
                                        $variants = array_unique( array_merge(
                                                $variantFallbacks, 
$parentLanguage->getVariants()
@@ -119,13 +152,12 @@
                                }
 
                                foreach ( $variants as $variant ) {
-                                       $variantLanguage = Language::factory( 
$variant );
-                                       if ( isset( 
$fetched[$variantLanguage->getCode()] ) ) {
+                                       if ( isset( $fetched[$variant] ) ) {
                                                continue;
                                        }
 
-                                       $chain[] = 
LanguageWithConversion::factory( $language, $variantLanguage );
-                                       $fetched[$variantLanguage->getCode()] = 
true;
+                                       $chain[] = 
LanguageWithConversion::factory( $language, $variant );
+                                       $fetched[$variant] = true;
                                }
                        }
                }
@@ -138,8 +170,8 @@
                        $recursiveMode = $mode;
                        $recursiveMode &= self::FALLBACK_VARIANTS;
                        $recursiveMode |= self::FALLBACK_SELF;
-                       foreach ( $language->getFallbackLanguages() as $other ) 
{
-                               $this->buildFromLanguage( Language::factory( 
$other ), $recursiveMode, $chain, $fetched );
+                       foreach ( Language::getFallbacksFor( $languageCode ) as 
$other ) {
+                               $this->buildFromLanguage( $other, 
$recursiveMode, $chain, $fetched );
                        }
                }
 
@@ -217,7 +249,12 @@
                foreach ( $babel as $languageCodes ) { // Already sorted when 
added
                        foreach ( array( self::FALLBACK_SELF, 
self::FALLBACK_VARIANTS ) as $mode ) {
                                foreach ( $languageCodes as $languageCode ) {
-                                       $this->buildFromLanguage( 
Language::factory( $languageCode ), $mode, $chain, $fetched );
+                                       try {
+                                               $languageCode = 
LanguageWithConversion::validateLanguageCode( $languageCode );
+                                       } catch ( MWException $e ) {
+                                               continue;
+                                       }
+                                       $this->buildFromLanguage( 
$languageCode, $mode, $chain, $fetched );
                                }
                        }
                }
@@ -225,7 +262,12 @@
                // Second pass to get other languages from system fallback chain
                foreach ( $babel as $languageCodes ) {
                        foreach ( $languageCodes as $languageCode ) {
-                               $this->buildFromLanguage( Language::factory( 
$languageCode ),
+                               try {
+                                       $languageCode = 
LanguageWithConversion::validateLanguageCode( $languageCode );
+                               } catch ( MWException $e ) {
+                                       continue;
+                               }
+                               $this->buildFromLanguage( $languageCode,
                                        self::FALLBACK_OTHERS | 
self::FALLBACK_VARIANTS, $chain, $fetched
                                );
                        }
diff --git a/lib/tests/phpunit/LanguageFallbackChainFactoryTest.php 
b/lib/tests/phpunit/LanguageFallbackChainFactoryTest.php
index 73109bf..ca40695 100644
--- a/lib/tests/phpunit/LanguageFallbackChainFactoryTest.php
+++ b/lib/tests/phpunit/LanguageFallbackChainFactoryTest.php
@@ -44,11 +44,23 @@
                $this->assertChainEquals( $expected, $chain );
        }
 
+       /**
+        * @group WikibaseLib
+        * @dataProvider providerNewFromLanguage
+        */
+       public function testNewFromLanguageCode( $lang, $mode, $expected ) {
+               $factory = new LanguageFallbackChainFactory();
+               $chain = $factory->newFromLanguageCode( $lang, $mode 
)->getFallbackChain();
+               $this->assertChainEquals( $expected, $chain );
+       }
+
        public static function providerNewFromLanguage() {
                return array(
                        array( 'en', 
LanguageFallbackChainFactory::FALLBACK_ALL, array( 'en' ) ),
                        array( 'en', 
LanguageFallbackChainFactory::FALLBACK_VARIANTS, array() ),
                        array( 'en', 
LanguageFallbackChainFactory::FALLBACK_OTHERS, array() ),
+
+                       array( 'zh-classical', 
LanguageFallbackChainFactory::FALLBACK_SELF, array( 'lzh' ) ),
 
                        array( 'de-formal', 
LanguageFallbackChainFactory::FALLBACK_ALL, array( 'de-formal', 'de', 'en' ) ),
                        // Repeated to test caching
@@ -152,6 +164,22 @@
        }
 
        /**
+        * @dataProvider provideNewFromLanguageCodeException
+        * @expectedException MWException
+        */
+       public function testNewFromLanguageCodeException( $langCode ) {
+               $factory = new LanguageFallbackChainFactory();
+               $factory->newFromLanguageCode( $langCode );
+       }
+
+       public function provideNewFromLanguageCodeException() {
+               return array(
+                       array( ':' ),
+                       array( '/' ),
+               );
+       }
+
+       /**
         * @group WikibaseLib
         */
        public function testNewFromContext() {
@@ -184,6 +212,39 @@
                        ),
                        array(
                                array(
+                                       'N' => array( '/' ),
+                               ),
+                               array(
+                               ),
+                       ),
+                       array(
+                               array(
+                                       'N' => array( ':', 'en' ),
+                               ),
+                               array(
+                                       'en',
+                               ),
+                       ),
+                       array(
+                               array(
+                                       'N' => array( 'unknown' ),
+                               ),
+                               array(
+                                       'unknown',
+                                       'en',
+                               ),
+                       ),
+                       array(
+                               array(
+                                       'N' => array( 'zh-classical' ),
+                               ),
+                               array(
+                                       'lzh',
+                                       'en',
+                               ),
+                       ),
+                       array(
+                               array(
                                        'N' => array( 'en', 'de-formal' ),
                                ),
                                array(

-- 
To view, visit https://gerrit.wikimedia.org/r/72352
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ief3adf61cfa24ee58f6d2a6eb99d5ba6fe56a098
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Liangent <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Denny Vrandecic <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to