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

Change subject: Include preferred labels / descriptions for entities in JS on 
EntityView
......................................................................


Include preferred labels / descriptions for entities in JS on EntityView

EntityView now initializes a fallback chain for current context, and in
experimental mode, wbUsedEntities and wbEntity include data with fallback
using this chain, to have data to be viewed by final user included.

Change-Id: Ic8ad24f49ba7fafe11e3dceb5d36e18d5b9ef19f
---
M lib/includes/LanguageFallbackChainFactory.php
M repo/includes/EntityView.php
M repo/includes/WikibaseRepo.php
M repo/includes/serializers/FetchedEntityContentSerializer.php
M repo/tests/phpunit/includes/EntityViewTest.php
M repo/tests/phpunit/includes/serializers/FetchedEntityContentSerializerTest.php
6 files changed, 158 insertions(+), 11 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 b2106f6..6860e08 100644
--- a/lib/includes/LanguageFallbackChainFactory.php
+++ b/lib/includes/LanguageFallbackChainFactory.php
@@ -62,6 +62,21 @@
        public $userLanguageCache;
 
        /**
+        * @var bool
+        */
+       public $anonymousPageViewCached;
+
+       /**
+        * Constructor.
+        *
+        * @param $anonymousPageViewCached bool
+        *          Whether full page outputs are cached for anons, so some 
fine-grained fallbacks shouldn't be used for them.
+        */
+       public function __construct( $anonymousPageViewCached = false ) {
+               $this->anonymousPageViewCached = $anonymousPageViewCached;
+       }
+
+       /**
         * Get the fallback chain based a single language, and specified 
fallback level.
         *
         * @param Language $language
@@ -329,4 +344,22 @@
                return $chain;
        }
 
+       /**
+        * Construct the fallback chain based on a context for direct page 
views.
+        * Caching mechanisms used are taken into consideration.
+        *
+        * @param IContextSource $context
+        *
+        * @return LanguageFallbackChain
+        */
+       public function newFromContextForPageView( IContextSource $context ) {
+               if ( $this->anonymousPageViewCached && 
$context->getUser()->isAnon() ) {
+                       // Anonymous users share the same Squid cache, which is 
splitted by URL.
+                       // That means we can't do anything except for what 
completely depends by URL such as &uselang=.
+                       return $this->newFromLanguage( $context->getLanguage() 
);
+               } else {
+                       return $this->newFromContext( $context );
+               }
+       }
+
 }
diff --git a/repo/includes/EntityView.php b/repo/includes/EntityView.php
index 1a6a693..a5b816e 100644
--- a/repo/includes/EntityView.php
+++ b/repo/includes/EntityView.php
@@ -88,6 +88,11 @@
        protected $dataTypeLookup;
 
        /**
+        * @var LanguageFallbackChain
+        */
+       protected $languageFallbackChain;
+
+       /**
         * Maps entity types to the corresponding entity view.
         * FIXME: remove this stuff, big OCP violation
         *
@@ -112,6 +117,7 @@
         * @param EntityLookup               $entityLookup
         * @param EntityTitleLookup          $entityTitleLookup
         * @param Lib\EntityIdFormatter      $idFormatter
+        * @param LanguageFallbackChain      $languageFallbackChain
         */
        public function __construct(
                IContextSource $context,
@@ -119,7 +125,8 @@
                PropertyDataTypeLookup $dataTypeLookup,
                EntityLookup $entityLookup,
                EntityTitleLookup $entityTitleLookup,
-               EntityIdFormatter $idFormatter
+               EntityIdFormatter $idFormatter,
+               LanguageFallbackChain $languageFallbackChain
        ) {
                $this->setContext( $context );
                $this->valueFormatters = $valueFormatters;
@@ -127,6 +134,7 @@
                $this->entityLookup = $entityLookup;
                $this->entityTitleLookup = $entityTitleLookup;
                $this->idFormatter = $idFormatter;
+               $this->languageFallbackChain = $languageFallbackChain;
        }
 
        /**
@@ -858,6 +866,7 @@
 
                // TODO: use injected id formatter
                $serializationOptions = new EntitySerializationOptions( 
WikibaseRepo::getDefaultInstance()->getIdFormatter() );
+               $serializationOptions->setLanguages( Utils::getLanguageCodes() 
+ array( $langCode => $this->languageFallbackChain ) );
 
                $serializerFactory = new SerializerFactory();
                $serializer = $serializerFactory->newSerializerForObject( 
$entity, $serializationOptions );
@@ -897,13 +906,17 @@
                $entities = $this->entityLookup->getEntities( $entityIds );
                $entityInfo = array();
 
-               $serializer = 
FetchedEntityContentSerializer::newForFrontendStore( $langCode );
+               $serializer = 
FetchedEntityContentSerializer::newForFrontendStore( $langCode, 
$this->languageFallbackChain );
 
                foreach( $entities as $prefixedId => $entity ) {
                        if( $entity === null ) {
                                continue;
                        }
                        $entityContent = $entityContentFactory->getFromId( 
$entity->getId() );
+                       if ( !$entityContent ) {
+                               // It's missing in the database, but we've 
already got an $entity (possibly from a MockRepository).
+                               $entityContent = 
$entityContentFactory->newFromEntity( $entity );
+                       }
                        $entityInfo[ $prefixedId ] = 
$serializer->getSerialized( $entityContent );
                }
 
@@ -921,6 +934,7 @@
         * @param Lib\PropertyDataTypeLookup $dataTypeLookup
         * @param EntityLookup               $entityLookup
         * @param IContextSource|null        $context
+        * @param LanguageFallbackChain|null $languageFallbackChain Overrides 
any language fallback chain created inside, for testing
         *
         * @throws \MWException
         * @return EntityView
@@ -930,7 +944,8 @@
                ValueFormatterFactory $valueFormatters,
                PropertyDataTypeLookup $dataTypeLookup,
                EntityLookup $entityLookup,
-               IContextSource $context = null
+               IContextSource $context = null,
+               LanguageFallbackChain $languageFallbackChain = null
        ) {
                $type = $entity->getEntity()->getType();
 
@@ -945,7 +960,19 @@
                $idFormatter = 
WikibaseRepo::getDefaultInstance()->getIdFormatter();
                $entityTitleLookup = EntityContentFactory::singleton();
 
-               $instance = new self::$typeMap[ $type ]( $context, 
$valueFormatters, $dataTypeLookup, $entityLookup, $entityTitleLookup, 
$idFormatter );
+               if ( !$languageFallbackChain ) {
+                       $factory = 
WikibaseRepo::getDefaultInstance()->getLanguageFallbackChainFactory();
+                       if ( defined( 'WB_EXPERIMENTAL_FEATURES' ) && 
WB_EXPERIMENTAL_FEATURES ) {
+                               $languageFallbackChain = 
$factory->newFromContextForPageView( $context );
+                       } else {
+                               # Effectively disables fallback.
+                               $languageFallbackChain = 
$factory->newFromLanguage(
+                                       $context->getLanguage(), 
LanguageFallbackChainFactory::FALLBACK_SELF
+                               );
+                       }
+               }
+
+               $instance = new self::$typeMap[ $type ]( $context, 
$valueFormatters, $dataTypeLookup, $entityLookup, $entityTitleLookup, 
$idFormatter, $languageFallbackChain );
                return $instance;
        }
 }
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 40065e1..8a29e87 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -305,7 +305,12 @@
         */
        public function getLanguageFallbackChainFactory() {
                if ( $this->languageFallbackChainFactory === null ) {
-                       $this->languageFallbackChainFactory = new 
LanguageFallbackChainFactory();
+                       global $wgUseSquid;
+                       // The argument is about whether full page output 
(OutputPage, specifically JS vars in it currently)
+                       // is cached for anons, where the only caching 
mechanism in use now is Squid.
+                       $this->languageFallbackChainFactory = new 
LanguageFallbackChainFactory(
+                               /* $anonymousPageViewCached = */ $wgUseSquid
+                       );
                }
 
                return $this->languageFallbackChainFactory;
diff --git a/repo/includes/serializers/FetchedEntityContentSerializer.php 
b/repo/includes/serializers/FetchedEntityContentSerializer.php
index 36dcb9e..45804d0 100644
--- a/repo/includes/serializers/FetchedEntityContentSerializer.php
+++ b/repo/includes/serializers/FetchedEntityContentSerializer.php
@@ -9,6 +9,8 @@
 use Wikibase\Entity;
 use Wikibase\Repo\WikibaseRepo;
 use Wikibase\EntityContent;
+use Wikibase\LanguageFallbackChain;
+use Wikibase\LanguageFallbackChainFactory;
 use Wikibase\Lib\Serializers\SerializerObject;
 use Wikibase\Lib\Serializers\EntitySerializationOptions;
 use Wikibase\Lib\Serializers\SerializerFactory;
@@ -89,13 +91,20 @@
         * @since 0.5
         *
         * @param string $primaryLanguage
+        * @param LanguageFallbackChain|null $languageFallbackChain
         * @return FetchedEntityContentSerializer
         */
-       public static function newForFrontendStore( $primaryLanguage ) {
+       public static function newForFrontendStore( $primaryLanguage, 
LanguageFallbackChain $languageFallbackChain ) {
                $entitySerializationOptions =
                        new EntitySerializationOptions( 
WikibaseRepo::getDefaultInstance()->getIdFormatter() );
                $entitySerializationOptions->setProps( array( 'labels', 
'descriptions', 'datatype' ) );
-               $entitySerializationOptions->setLanguages( array( 
$primaryLanguage ) );
+               if ( !$languageFallbackChain ) {
+                       $languageFallbackChainFactory = 
WikibaseRepo::getDefaultInstance()->getLanguageFallbackChain();
+                       $languageFallbackChain = 
$languageFallbackChainFactory->newFromLanguageCode(
+                               $primaryLanguage, 
LanguageFallbackChainFactory::FALLBACK_SELF
+                       );
+               }
+               $entitySerializationOptions->setLanguages( array( 
$primaryLanguage => $languageFallbackChain ) );
 
                $fetchedEntityContentSerializationOptions =
                        new FetchedEntityContentSerializationOptions( 
$entitySerializationOptions );
diff --git a/repo/tests/phpunit/includes/EntityViewTest.php 
b/repo/tests/phpunit/includes/EntityViewTest.php
index 24fe2e8..239e9bf 100644
--- a/repo/tests/phpunit/includes/EntityViewTest.php
+++ b/repo/tests/phpunit/includes/EntityViewTest.php
@@ -11,9 +11,12 @@
 use Wikibase\DataModel\Entity\PropertyId;
 use Wikibase\EntityContent;
 use Wikibase\EntityContentFactory;
+use Wikibase\EntityLookup;
 use Wikibase\EntityView;
 use Wikibase\Item;
 use Wikibase\ItemContent;
+use Wikibase\LanguageFallbackChain;
+use Wikibase\LanguageFallbackChainFactory;
 use Wikibase\Lib\InMemoryDataTypeLookup;
 use Wikibase\Property;
 use Wikibase\PropertyContent;
@@ -40,9 +43,13 @@
  */
 class EntityViewTest extends \PHPUnit_Framework_TestCase {
 
-       protected function newEntityView( EntityContent $entityContent ) {
+       protected function newEntityView( EntityContent $entityContent, 
EntityLookup $entityLoader = null,
+               \IContextSource $context = null, LanguageFallbackChain 
$languageFallbackChain = null
+       ) {
                $valueFormatters = new ValueFormatterFactory( array() );
-               $entityLoader = new MockRepository();
+               if ( !$entityLoader ) {
+                       $entityLoader = new MockRepository();
+               }
 
                $p11 = new PropertyId( 'p11' );
                $p23 = new PropertyId( 'p23' );
@@ -60,7 +67,9 @@
                        $entityContent,
                        $valueFormatters,
                        $dataTypeLookup,
-                       $entityLoader
+                       $entityLoader,
+                       $context,
+                       $languageFallbackChain
                );
 
                return $entityView;
@@ -269,4 +278,64 @@
                        array( PropertyContent::newEmpty() )
                );
        }
+
+       /**
+        * @dataProvider provideRegisterJsConfigVars
+        */
+       public function testRegisterJsConfigVars( EntityContent $entityContent, 
EntityLookup $entityLoader,
+               $context, LanguageFallbackChain $languageFallbackChain, 
$langCode, $editableView, $expected
+       ) {
+               $entityView = $this->newEntityView( $entityContent, 
$entityLoader, $context, $languageFallbackChain );
+               $out = new \OutputPage( new \RequestContext() );
+               $entityView->registerJsConfigVars( $out, $entityContent, 
$langCode, $editableView );
+               $actual = array_intersect_key( $out->mJsConfigVars, $expected );
+               ksort( $expected );
+               ksort( $actual );
+               $this->assertEquals( $expected, $actual );
+       }
+
+       public function provideRegisterJsConfigVars() {
+               $entityContentFactory = EntityContentFactory::singleton();
+               $languageFallbackChainFactory = new 
LanguageFallbackChainFactory();
+
+               $argLists = array();
+
+               $entity = Item::newEmpty();
+               $entity->setLabel( 'de', 'foo' );
+               $entity->setId( 49 );
+               $content = $entityContentFactory->newFromEntity( $entity );
+               $q98 = new ItemId( 'Q98' );
+               $entityQ98 = Item::newEmpty();
+               $entityQ98->setLabel( 'de', 'bar' );
+               $entityQ98->setId( $q98 );
+               $entityLoader = new MockRepository();
+               $entityLoader->putEntity( $entityQ98 );
+               $p11 = new PropertyId( 'p11' );
+               $entity->addClaim( new Claim( new PropertyValueSnak( $p11, new 
EntityIdValue( $q98 ) ) ) );
+               $languageFallbackChain = 
$languageFallbackChainFactory->newFromLanguageCode(
+                       'de-formal', LanguageFallbackChainFactory::FALLBACK_ALL
+               ); // with fallback to German
+               $argLists[] = array( $content, $entityLoader, null, 
$languageFallbackChain, 'fr', true, array(
+                       'wbEntityType' => 'item',
+                       'wbDataLangName' => 'français',
+                       'wbEntityId' => 'Q49',
+                       'wbEntity' => 
'{"id":"Q49","type":"item","labels":{"de":{"language":"de","value":"foo"},"fr":{"language":"de","value":"foo"}},"claims":{"P11":[{"id":null,"mainsnak":{"snaktype":"value","property":"P11","datavalue":{"value":{"entity-type":"item","numeric-id":98},"type":"wikibase-entityid"}},"type":"claim"}]}}',
+                       'wbUsedEntities' => 
'{"Q98":{"content":{"id":"Q98","type":"item","labels":{"fr":{"language":"de","value":"bar"}}},"title":"Item:Q98","revision":""}}',
+               ) );
+
+               $languageFallbackChain = 
$languageFallbackChainFactory->newFromLanguageCode(
+                       'de-formal', LanguageFallbackChainFactory::FALLBACK_SELF
+               ); // with no fallback
+               $argLists[] = array( $content, $entityLoader, null, 
$languageFallbackChain, 'nl', true, array(
+                       'wbEntityType' => 'item',
+                       'wbDataLangName' => 'Nederlands',
+                       'wbEntityId' => 'Q49',
+                       'wbEntity' => 
'{"id":"Q49","type":"item","labels":{"de":{"language":"de","value":"foo"}},"claims":{"P11":[{"id":null,"mainsnak":{"snaktype":"value","property":"P11","datavalue":{"value":{"entity-type":"item","numeric-id":98},"type":"wikibase-entityid"}},"type":"claim"}]}}',
+                       'wbUsedEntities' => 
'{"Q98":{"content":{"id":"Q98","type":"item"},"title":"Item:Q98","revision":""}}',
+               ) );
+
+               // TODO: add more tests for other JS vars
+
+               return $argLists;
+       }
 }
diff --git 
a/repo/tests/phpunit/includes/serializers/FetchedEntityContentSerializerTest.php
 
b/repo/tests/phpunit/includes/serializers/FetchedEntityContentSerializerTest.php
index 2c32dcb..880fa62 100644
--- 
a/repo/tests/phpunit/includes/serializers/FetchedEntityContentSerializerTest.php
+++ 
b/repo/tests/phpunit/includes/serializers/FetchedEntityContentSerializerTest.php
@@ -10,6 +10,7 @@
 use Wikibase\PropertyContent;
 use Wikibase\PropertyHandler;
 use Wikibase\Repo\WikibaseRepo;
+use Wikibase\LanguageFallbackChainFactory;
 use Title;
 
 /**
@@ -78,7 +79,10 @@
         * @since 0.5
         */
        public function testNewForFrontendStore() {
-               $serializer = 
FetchedEntityContentSerializer::newForFrontendStore( 'en' );
+               $serializer = 
FetchedEntityContentSerializer::newForFrontendStore( 'en',
+                       
WikibaseRepo::getDefaultInstance()->getLanguageFallbackChainFactory()
+                               ->newFromLanguageCode( 'en', 
LanguageFallbackChainFactory::FALLBACK_SELF )
+               );
                $this->assertInstanceOf( $this->getClass(), $serializer );
        }
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic8ad24f49ba7fafe11e3dceb5d36e18d5b9ef19f
Gerrit-PatchSet: 52
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: Hashar <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[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