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