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

Change subject: Remove Utils::lookup[User]MultilangText() and related functions
......................................................................


Remove Utils::lookup[User]MultilangText() and related functions

Replaced by language fallback chain.

Utils::languageChain(), which has no usage in Wikibase, is removed too.

Other removed functions include those lookup* functions' dependency,
Utils::filterMultilangText() and Utils::reorderArray().

Change-Id: I40ad9647ba489a7950773f21a2ec04273ef1fe9e
---
M lib/includes/LanguageFallbackChain.php
M lib/includes/Utils.php
M lib/tests/phpunit/LanguageFallbackChainTest.php
M repo/Wikibase.hooks.php
M repo/includes/actions/EditEntityAction.php
M repo/includes/actions/ViewEntityAction.php
6 files changed, 164 insertions(+), 250 deletions(-)

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



diff --git a/lib/includes/LanguageFallbackChain.php 
b/lib/includes/LanguageFallbackChain.php
index ee91987..5802287 100644
--- a/lib/includes/LanguageFallbackChain.php
+++ b/lib/includes/LanguageFallbackChain.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Wikibase;
+use \Language;
 
 /**
  * Object representing a language fallback chain used in Wikibase.
@@ -61,7 +62,7 @@
         *      'value' => finally fetched and translated value
         *      'language' => language code of the language which final value 
is in
         *      'source' => language code of the language where the value is 
fetched
-        * ), or null when no data can be found.
+        * ), or null when no "acceptable" data can be found.
         */
        public function extractPreferredValue( $data ) {
 
@@ -80,4 +81,36 @@
 
                return null;
        }
+
+       /**
+        * Try to fetch the best value in a multilingual data array first.
+        * If no "acceptable" value exists, return any value known.
+        *
+        * @param string[] $data Multilingual data with language codes as keys
+        *
+        * @return null|array of three items: array(
+        *      'value' => finally fetched and translated value
+        *      'language' => language code of the language which final value 
is in
+        *      'source' => language code of the language where the value is 
fetched
+        * ), or null when no data with a valid language code can be found.
+        */
+       public function extractPreferredValueOrAny( $data ) {
+
+               $preferred = $this->extractPreferredValue( $data );
+               if ( $preferred ) {
+                       return $preferred;
+               }
+
+               foreach ( $data as $code => $value ) {
+                       if ( Language::isValidCode( $code ) ) {
+                               return array(
+                                       'value' => $value,
+                                       'language' => $code,
+                                       'source' => $code,
+                               );
+                       }
+               }
+
+               return null;
+       }
 }
diff --git a/lib/includes/Utils.php b/lib/includes/Utils.php
index c6ce523..e12dc70 100644
--- a/lib/includes/Utils.php
+++ b/lib/includes/Utils.php
@@ -232,200 +232,6 @@
        }
 
        /**
-        * Reorder an array with keys with the order given by a second array.
-        *
-        * Note that this function will do an intersection and then organize
-        * the resulting array in the order given by the array in the second
-        * argument. The sorting is not by the keys, but by the order the
-        * entries are inserted into the resulting array. Another way to
-        * describe this is to change the insertion order of the first array
-        * according to the sequence of values in the second array.
-        *
-        * @since 0.1
-        *
-        * @param array $array
-        * @param array $sequence
-        *
-        * @return array
-        */
-       static public function reorderArray( array $array, array $sequence ) {
-
-               // First create an intersection with our wanted entries as keys
-               $common = array_intersect_key( array_flip( $sequence ), $array 
);
-
-               // Then do a merge with our previous array, and with a new 
intersection
-               return array_merge( $common, array_intersect_key( $array, 
$common ) );
-       }
-
-       /**
-        * Find the multilingual texts that has keys in the the sequence.
-        *
-        * The final result will be in the order given by the sequence.
-        *
-        * @since 0.1
-        *
-        * @param array $texts the key-value pairs to check for existence
-        * @param array $sequence the list of keys that should exist
-        *
-        * @return array
-        */
-       static public function filterMultilangText( array $texts = null, array 
$sequence = null ) {
-
-               // Prerequisites for further processing
-               if ( is_null( $texts ) || is_null( $sequence ) ) {
-                       return array(); // makes the simplest use case
-               }
-
-               // Do a reordering to get the language strings in correct order
-               $texts = \Wikibase\Utils::reorderArray(
-                       $texts,
-                       $sequence
-               );
-
-               // Extract the valid codes
-               $validCodes = array_filter(
-                       array_keys( $texts ),
-                       function( $langCode ) { return is_string( $langCode ) 
&& Language::isValidCode( $langCode ); }
-               );
-
-               // If the valid codes are empty we don't need to process it 
further
-               if ( empty( $validCodes ) ) {
-                       return array();
-               }
-
-               // Filter out everything that matches with a key before we 
return the result
-               return array_intersect_key( $texts, array_flip( $validCodes ) );
-       }
-
-       /**
-        * Find the first multilingual string that can be used for constructing 
a language object. The
-        * global chain is always used.
-        *
-        * Note that a multilingual string from the global chain will always be 
globally cachable.
-        *
-        * @since 0.1
-        *
-        * @param array $texts the key-value pairs to check for existence
-        * @param array $sequence the list of keys that should exist
-        * @param array $fallback an array of values that are used as a 
replacement if nothing is found
-        *              The fallback is in the form array( code, text, language 
)
-        * @return array|null triplet with the initial language code, the text, 
and the language object
-        */
-       static public function lookupMultilangText( array $texts = null, array 
$sequence = null, array $fallback = null ) {
-
-               // Prerequisites for further processing
-               if ( is_null( $texts ) || is_null( $sequence ) ) {
-                       return $fallback; // makes the simplest use case
-               }
-
-               // Filter down the result
-               $texts = \Wikibase\Utils::filterMultilangText( $texts, 
$sequence );
-               if ( is_null( $texts ) || empty( $texts ) ) {
-                       return $fallback;
-               }
-
-               // Find the first language code we can turn into a language 
object
-               // Note that the factory call do a pretty dumb cleaning up that 
can make this vejjy slow
-               foreach ( $texts as $code => $text ) {
-                       $lang = Language::factory( $code );
-                       if ( !is_null( $lang ) ) {
-                               return array( $code, $text, $lang );
-                       }
-               }
-
-               // Use the fallback if the previous fails
-               return $fallback;
-       }
-
-       /**
-        * Find the first multilingual string that can be used for constructing 
a language object
-        * for the current user. If a preferred language can't be identified 
the global chain is
-        * used.
-        *
-        * Note that a user specific multilingual string is not globally 
cachable.
-        *
-        * FIXME: duplication with @see lookupMultilangText, needs refactor
-        *
-        * @since 0.1
-        *
-        * @param array $texts the key-value pairs to check for existence
-        * @param array $sequence the list of keys that should exist
-        * @param array $fallback an array of values that are used as a 
replacement if nothing is found
-        *              The fallback is in the form array( code, text, language 
)
-        * @return array|null triplet with the initial language code, the text, 
and the language object
-        */
-       static public function lookupUserMultilangText( array $texts = null, 
array $sequence = null, array $fallback = null ) {
-               // FIXME: deprecated globals!
-               global $wgUser, $wgLang;
-
-               // Prerequisites for further processing
-               if ( is_null( $texts ) || is_null( $sequence ) ) {
-                       return $fallback; // makes the simplest use case
-               }
-
-               // Filter down the result
-               $texts = \Wikibase\Utils::filterMultilangText( $texts, 
$sequence );
-               if ( is_null( $texts ) || empty( $texts ) ) {
-                       return $fallback;
-               }
-
-               // Check if we can use the ordinary language
-               // This should always be used if possible because this will 
match
-               // with the user set language
-               reset($texts);
-               list( $code, $text ) = each( $texts );
-               if ( $wgLang->getCode() === $code ) {
-                       $lang = Language::factory( $code );
-                       if ( !is_null( $lang ) ) {
-                               return array( $code, $text, $lang );
-                       }
-               }
-
-               // Find the first preferred language code we can turn into a 
language object
-               // Note that the factory call do a pretty dumb cleaning up that 
can make this vejjy slow
-               foreach ( $texts as $code => $text ) {
-                       if ( $wgUser->getOption( "sttl-languages-$code" ) ) {
-                               $lang = Language::factory( $code );
-                               if ( !is_null( $lang ) ) {
-                                       return array( $code, $text, $lang );
-                               }
-                       }
-               }
-
-               // Find the first ordinary language code we can turn into a 
language object
-               // Note that the factory call do a pretty dumb cleaning up that 
can make this vejjy slow
-               foreach ( $texts as $code => $text ) {
-                       $lang = Language::factory( $code );
-                       if ( !is_null( $lang ) ) {
-                               return array( $code, $text, $lang );
-                       }
-               }
-
-               // Use the fallback if the previous fails
-               return $fallback;
-       }
-
-       /**
-        * Get the fallback languages prepended with the source language itself.
-        *
-        * A language chain in this respect is the language itself and all 
fallback
-        * languagese. Because English is prepended to all languages it is not 
a real
-        * language group, its only a language group for the purpose of 
figuring out
-        * the best guess if language attributes are missing.
-        *
-        * Note that a language chain is globally unique, there will not be any
-        * language with two different chains.
-        *
-        * @since 0.1
-        *
-        * @param string $langCode the language code for the source language 
itself
-        * @return array of language codes
-        */
-       static public function languageChain( $langCode ) {
-               return array_merge( array( $langCode ), 
Language::getFallbacksFor( $langCode ) );
-       }
-
-       /**
         * Check the given PID to see if it is alive
         *
         * @since 0.3
diff --git a/lib/tests/phpunit/LanguageFallbackChainTest.php 
b/lib/tests/phpunit/LanguageFallbackChainTest.php
index 455c981..839dba8 100644
--- a/lib/tests/phpunit/LanguageFallbackChainTest.php
+++ b/lib/tests/phpunit/LanguageFallbackChainTest.php
@@ -105,4 +105,61 @@
                );
        }
 
+       /**
+        * @group WikibaseLib
+        * @dataProvider provideExtractPreferredValueOrAny
+        */
+       public function testExtractPreferredValueOrAny( $lang, $mode, $data, 
$expected ) {
+               $factory = new LanguageFallbackChainFactory();
+               $chain = $factory->newFromLanguage( \Language::factory( $lang 
), $mode );
+
+               $resolved = $chain->extractPreferredValueOrAny( $data );
+
+               $this->assertEquals( $expected, $resolved );
+       }
+
+       public function provideExtractPreferredValueOrAny() {
+               $data = array(
+                       'en' => 'foo',
+                       'nl' => 'bar',
+                       'zh-cn' => '测试',
+               );
+
+               return array(
+                       array( 'en', 
LanguageFallbackChainFactory::FALLBACK_ALL, $data, array(
+                               'value' => 'foo',
+                               'language' => 'en',
+                               'source' => 'en',
+                       ) ),
+                       array( 'nl', 
LanguageFallbackChainFactory::FALLBACK_ALL, $data, array(
+                               'value' => 'bar',
+                               'language' => 'nl',
+                               'source' => 'nl',
+                       ) ),
+                       array( 'de', 
LanguageFallbackChainFactory::FALLBACK_SELF, $data, array(
+                               'value' => 'foo',
+                               'language' => 'en',
+                               'source' => 'en',
+                       ) ),
+                       array( 'fr', 
LanguageFallbackChainFactory::FALLBACK_SELF, array(
+                               'kk' => 'baz',
+                       ), array(
+                               'value' => 'baz',
+                               'language' => 'kk',
+                               'source' => 'kk',
+                       ) ),
+                       array( 'it', 
LanguageFallbackChainFactory::FALLBACK_SELF, array(
+                               ':' => 'qux',
+                               'kk' => 'baz',
+                       ), array(
+                               'value' => 'baz',
+                               'language' => 'kk',
+                               'source' => 'kk',
+                       ) ),
+                       array( 'sr', 
LanguageFallbackChainFactory::FALLBACK_SELF, array(
+                               ':' => 'qux',
+                       ), null ),
+                       array( 'ar', 
LanguageFallbackChainFactory::FALLBACK_SELF, array(), null ),
+               );
+       }
 }
diff --git a/repo/Wikibase.hooks.php b/repo/Wikibase.hooks.php
index 86a9131..212e740 100644
--- a/repo/Wikibase.hooks.php
+++ b/repo/Wikibase.hooks.php
@@ -1,8 +1,8 @@
 <?php
 
 namespace Wikibase;
-use Title, Language, User, Revision, WikiPage, EditPage, ContentHandler, Html, 
MWException;
-
+use Title, Language, User, Revision, WikiPage, EditPage, ContentHandler, Html, 
MWException, RequestContext;
+use Wikibase\Repo\WikibaseRepo;
 
 /**
  * File defining the hook handlers for the Wikibase extension.
@@ -782,8 +782,6 @@
                        return true;
                }
 
-               global $wgLang, $wgOut;
-
                // The following three vars should all exist, unless there is a 
failurre
                // somewhere, and then it will fail hard. Better test it now!
                $page = new WikiPage( $target );
@@ -820,39 +818,36 @@
                        return true;
                }
 
-               // If this fails we will not find labels and descriptions later,
-               // but we will try to get a list of alternate languages. The 
following
-               // uses the user language as a starting point for the fallback 
chain.
-               // It could be argued that the fallbacks should be limited to 
the user
-               // selected languages.
-               $lang = $wgLang->getCode();
-               static $langStore = array();
-               if ( !isset( $langStore[$lang] ) ) {
-                       $langStore[$lang] = array_merge( array( $lang ), 
Language::getFallbacksFor( $lang ) );
+               // Try to find the most preferred available language to display 
data in current context.
+               $languageFallbackChainFactory = 
WikibaseRepo::getDefaultInstance()->getLanguageFallbackChainFactory();
+               $context = RequestContext::getMain();
+               $languageFallbackChain = 
$languageFallbackChainFactory->newFromContext( $context );
+
+               $labelData = 
$languageFallbackChain->extractPreferredValueOrAny( $entity->getLabels() );
+               $descriptionData = 
$languageFallbackChain->extractPreferredValueOrAny( $entity->getDescriptions() 
);
+
+               if ( $labelData ) {
+                       $labelText = $labelData['value'];
+                       $labelLang = Language::factory( $labelData['language'] 
);
+               } else {
+                       $labelText = '';
+                       $labelLang = $context->getLanguage();
                }
 
-               // Get the label and description for the first languages on the 
chain
-               // that doesn't fail, use a fallback if everything fails. This 
could
-               // use the user supplied list of acceptable languages as a 
filter.
-               list( , $labelText, $labelLang) = $labelTriplet =
-                       Utils::lookupMultilangText(
-                               $entity->getLabels( $langStore[$lang] ),
-                               $langStore[$lang],
-                               array( $wgLang->getCode(), null, $wgLang )
-                       );
-               list( , $descriptionText, $descriptionLang) = 
$descriptionTriplet =
-                       Utils::lookupMultilangText(
-                               $entity->getDescriptions( $langStore[$lang] ),
-                               $langStore[$lang],
-                               array( $wgLang->getCode(), null, $wgLang )
-                       );
+               if ( $descriptionData ) {
+                       $descriptionText = $descriptionData['value'];
+                       $descriptionLang = Language::factory( 
$descriptionData['language'] );
+               } else {
+                       $descriptionText = '';
+                       $descriptionLang = $context->getLanguage();
+               }
 
                // Go on and construct the link
                $idHtml = Html::openElement( 'span', array( 'class' => 
'wb-itemlink-id' ) )
                        . wfMessage( 'wikibase-itemlink-id-wrapper', 
$target->getText() )->inContentLanguage()->escaped()
                        . Html::closeElement( 'span' );
 
-               $labelHtml = Html::openElement( 'span', array( 'class' => 
'wb-itemlink-label', 'lang' => $labelLang->getCode(), 'dir' => 
$labelLang->getDir() ) )
+               $labelHtml = Html::openElement( 'span', array( 'class' => 
'wb-itemlink-label', 'lang' => $labelLang->getHtmlCode(), 'dir' => 
$labelLang->getDir() ) )
                        . htmlspecialchars( $labelText )
                        . Html::closeElement( 'span' );
 
@@ -861,19 +856,19 @@
                        . Html::closeElement( 'span' );
 
                // Set title attribute for constructed link, and make tricks 
with the directionality to get it right
-               $titleText = ( $labelText !== null )
-                       ? $labelLang->getDirMark() . $labelText . 
$wgLang->getDirMark()
+               $titleText = ( $labelText !== '' )
+                       ? $labelLang->getDirMark() . $labelText . 
$context->getLanguage()->getDirMark()
                        : $target->getPrefixedText();
-               $customAttribs[ 'title' ] = ( $descriptionText !== null ) ?
+               $customAttribs[ 'title' ] = ( $descriptionText !== '' ) ?
                        wfMessage(
                                'wikibase-itemlink-title',
                                $titleText,
-                               $descriptionLang->getDirMark() . 
$descriptionText . $wgLang->getDirMark()
+                               $descriptionLang->getDirMark() . 
$descriptionText . $context->getLanguage()->getDirMark()
                        )->inContentLanguage()->text() :
                        $titleText; // no description, just display the title 
then
 
                // add wikibase styles in all cases, so we can format the link 
properly:
-               $wgOut->addModuleStyles( array( 'wikibase.common' ) );
+               $context->getOutput()->addModuleStyles( array( 
'wikibase.common' ) );
 
                wfProfileOut( __METHOD__ );
                return true;
diff --git a/repo/includes/actions/EditEntityAction.php 
b/repo/includes/actions/EditEntityAction.php
index 21b4832..2db7579 100644
--- a/repo/includes/actions/EditEntityAction.php
+++ b/repo/includes/actions/EditEntityAction.php
@@ -288,15 +288,14 @@
         */
        public function getLabelText( EntityContent $content ) {
 
-               $langCode = $this->getContext()->getLanguage()->getCode();
-               list( , $labelText, ) =
-                       Utils::lookupUserMultilangText(
-                               $content->getEntity()->getLabels(),
-                               Utils::languageChain( $langCode ),
-                               array( $langCode, $this->getPageTitle(), 
$this->getContext()->getLanguage() )
-                       );
+               $languageFallbackChain = $this->getLanguageFallbackChain();
+               $labelData = 
$languageFallbackChain->extractPreferredValueOrAny( 
$content->getEntity()->getLabels() );
 
-               return $labelText;
+               if ( $labelData ) {
+                       return $labelData['value'];
+               } else {
+                       return $this->getPageTitle();
+               }
        }
 
        /**
diff --git a/repo/includes/actions/ViewEntityAction.php 
b/repo/includes/actions/ViewEntityAction.php
index 7482534..e50e765 100644
--- a/repo/includes/actions/ViewEntityAction.php
+++ b/repo/includes/actions/ViewEntityAction.php
@@ -20,6 +20,38 @@
 abstract class ViewEntityAction extends \ViewAction {
 
        /**
+        * @var LanguageFallbackChain
+        */
+       protected $languageFallbackChain;
+
+       /**
+        * Get the language fallback chain for current context.
+        *
+        * @since 0.4
+        *
+        * @return LanguageFallbackChain
+        */
+       public function getLanguageFallbackChain() {
+               if ( $this->languageFallbackChain === null ) {
+                       $this->languageFallbackChain = 
WikibaseRepo::getDefaultInstance()->getLanguageFallbackChainFactory()
+                               ->newFromContext( $this->getContext() );
+               }
+
+               return $this->languageFallbackChain;
+       }
+
+       /**
+        * Set language fallback chain.
+        *
+        * @since 0.4
+        *
+        * @param LanguageFallbackChain $chain
+        */
+       public function setLanguageFallbackChain( LanguageFallbackChain $chain 
) {
+               $this->languageFallbackChain = $chain;
+       }
+
+       /**
         * @see Action::getName()
         *
         * @since 0.1
@@ -194,20 +226,12 @@
                $this->getArticle()->view();
 
                // Figure out which label to use for title.
-               $langCode = $this->getContext()->getLanguage()->getCode();
-               // FIXME: Removed as a quickfix
-               /*
-               list( $labelCode, $labelText, $labelLang) =
-                       Utils::lookupUserMultilangText(
-                               $content->getEntity()->getLabels(),
-                               Utils::languageChain( $langCode ),
-                               array( $langCode, $this->getPageTitle(), 
$this->getContext()->getLanguage() )
-                       );
-*/
-               // FIXME: this replaces the stuff above
-               $labelText = $content->getEntity()->getLabel( $langCode );
+               $languageFallbackChain = $this->getLanguageFallbackChain();
+               $labelData = 
$languageFallbackChain->extractPreferredValueOrAny( 
$content->getEntity()->getLabels() );
 
-               if ( $labelText === false ) {
+               if ( $labelData ) {
+                       $labelText = $labelData['value'];
+               } else {
                        $idPrefixer = 
WikibaseRepo::getDefaultInstance()->getIdFormatter();
                        $labelText = strtoupper( $idPrefixer->format( 
$content->getEntity()->getId() ) );
                }

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

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

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

Reply via email to