Aude has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/171528

Change subject: Implement EntityParserOutputGeneratorFactory
......................................................................

Implement EntityParserOutputGeneratorFactory

allows removing a lot of cruft from EntityContent

attempts to address some of the issues in Ic06639c approach,
or perhaps can rebase on top of that.

Change-Id: I9453fd95eb7af8f34e7dbe18bd159b8bcb1927f7
---
M lib/includes/LanguageFallbackChainFactory.php
A repo/includes/View/EntityParserOutputGeneratorFactory.php
M repo/includes/WikibaseRepo.php
M repo/includes/content/EntityContent.php
M repo/includes/content/ItemContent.php
M repo/includes/content/PropertyContent.php
6 files changed, 298 insertions(+), 209 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/28/171528/2

diff --git a/lib/includes/LanguageFallbackChainFactory.php 
b/lib/includes/LanguageFallbackChainFactory.php
index b653da7..eee471f 100644
--- a/lib/includes/LanguageFallbackChainFactory.php
+++ b/lib/includes/LanguageFallbackChainFactory.php
@@ -349,20 +349,31 @@
         * @return LanguageFallbackChain
         */
        public function newFromContextForPageView( IContextSource $context ) {
+               return $this->newFromUserAndLanguageCodeForPageView(
+                       $context->getUser(),
+                       $context->getLanguage()->getCode()
+               );
+       }
+
+       /**
+        * @param User $user
+        * @param string $languageCode
+        *
+        * @return LanguageFallbackChain
+        */
+       public function newFromUserAndLanguageCodeForPageView( User $user, 
$languageCode ) {
                if ( $this->isExperimentalMode ) {
                        // The generated chain should yield a cacheable result
-                       if ( $this->anonymousPageViewCached && 
$context->getUser()->isAnon() ) {
+                       if ( $this->anonymousPageViewCached && $user->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() );
+                               // That means we can't do anything except for 
what completely depends
+                               // by URL such as &uselang=.
+                               return $this->newFromLanguageCode( 
$languageCode );
                        }
 
-                       return $this->newFromContext( $context );
+                       return $this->newFromUserAndLanguageCode( $user, 
$languageCode );
                } else {
-                       return $this->newFromLanguage(
-                               $context->getLanguage(),
-                               self::FALLBACK_SELF
-                       );
+                       return $this->newFromLanguageCode( $languageCode, 
self::FALLBACK_SELF );
                }
        }
 
diff --git a/repo/includes/View/EntityParserOutputGeneratorFactory.php 
b/repo/includes/View/EntityParserOutputGeneratorFactory.php
new file mode 100644
index 0000000..455d435
--- /dev/null
+++ b/repo/includes/View/EntityParserOutputGeneratorFactory.php
@@ -0,0 +1,242 @@
+<?php
+
+namespace Wikibase;
+
+use IContextSource;
+use Language;
+use ParserOptions;
+use ParserOutput;
+use RequestContext;
+use User;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\ValueFormatter;
+use Wikibase\DataModel\Entity\Entity;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\PropertyDataTypeLookup;
+use Wikibase\LanguageFallbackChainFactory;
+use Wikibase\Lib\OutputFormatSnakFormatterFactory;
+use Wikibase\Lib\Serializers\SerializationOptions;
+use Wikibase\Lib\SnakFormatter;
+use Wikibase\Lib\Store\EntityInfoBuilderFactory;
+use Wikibase\Lib\Store\EntityTitleLookup;
+use Wikibase\Repo\View\ClaimsView;
+use Wikibase\Repo\View\FingerprintView;
+use Wikibase\Repo\View\SectionEditLinkGenerator;
+use Wikibase\Repo\View\SnakHtmlGenerator;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.w...@gmail.com >
+ */
+class EntityParserOutputGeneratorFactory {
+
+       /**
+        * @var OutputFormatSnakFormatterFactory
+        */
+       private $snakFormatterFactory;
+
+       /**
+        * @var EntityInfoBuilderFactory
+        */
+       private $entityInfoBuilderFactory;
+
+       /**
+        * @var EntityTitleLookup
+        */
+       private $entityTitleLookup;
+
+       /**
+        * @var EntityIdParser
+        */
+       private $entityIdParser;
+
+       /**
+        * @var PropertyDataTypeLookup
+        */
+       private $propertyDataTypeLookup;
+
+       /**
+        * @var LanguageFallbackChainFactory
+        */
+       private $languageFallbackChainFactory;
+
+       /**
+        * @var ReferencedEntitiesFinder
+        */
+       private $referencedEntitiesFinder;
+
+       /**
+        * @var SectionEditLinkGenerator
+        */
+       private $sectionEditLinkGenerator;
+
+       public function __construct(
+               OutputFormatSnakFormatterFactory $snakFormatterFactory,
+               EntityInfoBuilderFactory $entityInfoBuilderFactory,
+               EntityTitleLookup $entityTitleLookup,
+               EntityIdParser $entityIdParser,
+               PropertyDataTypeLookup $propertyDataTypeLookup,
+               LanguageFallbackChainFactory $languageFallbackChainFactory,
+               ReferencedEntitiesFinder $referencedEntitiesFinder
+       ) {
+               $this->snakFormatterFactory = $snakFormatterFactory;
+               $this->entityInfoBuilderFactory = $entityInfoBuilderFactory;
+               $this->entityTitleLookup = $entityTitleLookup;
+               $this->entityIdParser = $entityIdParser;
+               $this->propertyDataTypeLookup = $propertyDataTypeLookup;
+               $this->languageFallbackChainFactory = 
$languageFallbackChainFactory;
+               $this->referencedEntitiesFinder = $referencedEntitiesFinder;
+               $this->sectionEditLinkGenerator = new 
SectionEditLinkGenerator();
+       }
+
+       /**
+        * Creates an EntityParserOutputGenerator to create the ParserOutput 
for the entity
+        *
+        * @param EntityRevision $entityRevision
+        * @param LanguageFallbackChain $languageFallbackChain
+        * @param ParserOptions|null $options
+        *
+        * @return EntityParserOutputGenerator
+        */
+       public function getEntityParserOutputGenerator(
+               EntityRevision $entityRevision,
+               ParserOptions $options = null
+       ) {
+               $languageCode = $this->getLanguageCode( $options );
+
+               return $this->newEntityParserOutputGenerator( $entityRevision, 
$languageCode );
+       }
+
+       private function getSnakFormatter( $languageCode ) {
+               $formatterOptions = new FormatterOptions();
+               $formatterOptions->setOption( ValueFormatter::OPT_LANG, 
$languageCode );
+
+               // @fixme don't get fallback chain twice and it's also probably 
not needed here.
+               $languageFallbackChain = $this->getLanguageFallbackChain( 
$languageCode );
+               $formatterOptions->setOption( 'languages', 
$languageFallbackChain );
+
+               return $this->snakFormatterFactory->getSnakFormatter(
+                       SnakFormatter::FORMAT_HTML_WIDGET,
+                       $formatterOptions
+               );
+       }
+
+       private function newParserOutputJsConfigBuilder( $languageCode ) {
+               return new ParserOutputJsConfigBuilder(
+                       $this->entityInfoBuilderFactory,
+                       $this->entityIdParser,
+                       $this->entityTitleLookup,
+                       $this->referencedEntitiesFinder,
+                       $languageCode
+               );
+       }
+
+       private function newEntityParserOutputGenerator(
+               EntityRevision $entityRevision,
+               $languageCode
+       ) {
+               return new EntityParserOutputGenerator(
+                       $this->newEntityView( $entityRevision, $languageCode ),
+                       $this->newParserOutputJsConfigBuilder( $languageCode ),
+                       $this->makeSerializationOptions( $languageCode ),
+                       $this->entityTitleLookup,
+                       $this->propertyDataTypeLookup
+               );
+       }
+
+       private function getLanguageCode( ParserOptions $options = null ) {
+               $context = RequestContext::getMain();
+
+               // NOTE: Parser Options language overrides context language!
+               if ( $options !== null ) {
+                       $languageCode = $options->getUserLang();
+               } else {
+                       $languageCode = $context->getLanguage()->getCode();
+               }
+
+               return $languageCode;
+       }
+
+       private function newClaimsView( $languageCode ) {
+               $snakHtmlGenerator = new SnakHtmlGenerator(
+                       $this->getSnakFormatter( $languageCode ),
+                       $this->entityTitleLookup
+               );
+
+               $claimHtmlGenerator = new ClaimHtmlGenerator(
+                       $snakHtmlGenerator,
+                       $this->entityTitleLookup
+               );
+
+               return new ClaimsView(
+                       $this->entityInfoBuilderFactory,
+                       $this->entityTitleLookup,
+                       $this->sectionEditLinkGenerator,
+                       $claimHtmlGenerator,
+                       $languageCode
+               );
+       }
+
+       private function newFingerprintView( $languageCode ) {
+               return new FingerprintView(
+                       $this->sectionEditLinkGenerator,
+                       $languageCode
+               );
+       }
+
+       /**
+        * Creates an EntityView suitable for rendering the entity.
+        *
+        * @param EntityRevision $entityRevision
+        * @param string $languageCode
+        *
+        * @return EntityView
+        */
+       private function newEntityView( EntityRevision $entityRevision, 
$languageCode ) {
+               $fingerprintView = $this->newFingerprintView( $languageCode );
+               $claimsView = $this->newClaimsView( $languageCode );
+               $entityType = $entityRevision->getEntity()->getType();
+
+               // @fixme all that seems needed in EntityView is language code 
and dir.
+               $language = Language::factory( $languageCode );
+
+               // @fixme support more entity types
+               if ( $entityType === 'item' ) {
+                       return new ItemView( $fingerprintView, $claimsView, 
$language );
+               } elseif ( $entityType === 'property' ) {
+                       return new PropertyView( $fingerprintView, $claimsView, 
$language );
+               }
+
+               throw new InvalidArgumentException( 'No EntityView for entity 
type: ' . $entityType );
+       }
+
+       private function getLanguageFallbackChain( $languageCode ) {
+               // @fixme inject User
+               $context = RequestContext::getMain();
+
+               return 
$this->languageFallbackChainFactory->newFromUserAndLanguageCodeForPageView(
+                       $context->getUser(),
+                       $languageCode
+               );
+       }
+
+       /**
+        * @param string $languageCode
+        *
+        * @return SerializationOptions
+        */
+       private function makeSerializationOptions( $languageCode ) {
+               $fallbackChain = $this->getLanguageFallbackChain( $languageCode 
);
+               $languageCodes = Utils::getLanguageCodes() + array( 
$languageCode => $fallbackChain );
+
+               $options = new SerializationOptions();
+               $options->setLanguages( $languageCodes );
+
+               return $options;
+       }
+
+}
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 0933a16..654eee5 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -23,6 +23,7 @@
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\Property;
 use Wikibase\EntityFactory;
+use Wikibase\EntityParserOutputGeneratorFactory;
 use Wikibase\InternalSerialization\DeserializerFactory;
 use Wikibase\InternalSerialization\SerializerFactory;
 use Wikibase\LabelDescriptionDuplicateDetector;
@@ -944,4 +945,19 @@
                return $this->entityNamespaceLookup;
        }
 
+       /**
+        * @return EntityParserOutputGeneratorFactory
+        */
+       public function getEntityParserOutputGeneratorFactory() {
+               return new EntityParserOutputGeneratorFactory(
+                       $this->getSnakFormatterFactory(),
+                       $this->getStore()->getEntityInfoBuilderFactory(),
+                       $this->getEntityContentFactory(),
+                       $this->getEntityIdParser(),
+                       $this->getPropertyDataTypeLookup(),
+                       $this->getLanguageFallbackChainFactory(),
+                       new ReferencedEntitiesFinder()
+               );
+       }
+
 }
diff --git a/repo/includes/content/EntityContent.php 
b/repo/includes/content/EntityContent.php
index 2d6073e..80e7741 100644
--- a/repo/includes/content/EntityContent.php
+++ b/repo/includes/content/EntityContent.php
@@ -268,17 +268,23 @@
        protected function getParserOutputFromEntityView( Title $title, $revId 
= null,
                ParserOptions $options = null, $generateHtml = true
        ) {
-               $editable = !$options? true : $options->getEditSection();
+               $wikibaseRepo = WikibaseRepo::getDefaultInstance();
+               $entityParserOutputGeneratorFactory = 
$wikibaseRepo->getEntityParserOutputGeneratorFactory();
 
-               if ( $revId === null || $revId === 0 ) {
-                       $revId = $title->getLatestRevID();
-               }
+               $entityRevision = $this->getEntityRevision( $title, $revId );
 
-               $revision = new EntityRevision( $this->getEntity(), $revId );
+               $outputGenerator = 
$entityParserOutputGeneratorFactory->getEntityParserOutputGenerator(
+                       $entityRevision,
+                       $options
+               );
 
-               // generate parser output
-               $outputGenerator = $this->getEntityParserOutputGenerator( null, 
$options, null );
-               $output = $outputGenerator->getParserOutput( $revision, 
$editable, $generateHtml );
+               $editable = !$options ? true : $options->getEditSection();
+
+               $output = $outputGenerator->getParserOutput(
+                       $entityRevision,
+                       $editable,
+                       $generateHtml
+               );
 
                // Since the output depends on the user language, we must make 
sure
                // ParserCache::getKey() includes it in the cache key.
@@ -291,155 +297,18 @@
        }
 
        /**
-        * Creates an EntityParserOutputGenerator to create the ParserOutput 
for the entity
+        * @param Title $title
+        * @param int|null $revId
         *
-        * @param IContextSource|null $context
-        * @param ParserOptions|null $options
-        * @param LanguageFallbackChain|null $uiLanguageFallbackChain
-        *
-        * @note: this uses global state to access the services needed for
-        * displaying the entity.
-        *
-        * @return EntityParserOutputGenerator
+        * @return EntityRevision
         */
-       private function getEntityParserOutputGenerator(
-               IContextSource $context = null,
-               ParserOptions $options = null,
-               LanguageFallbackChain $uiLanguageFallbackChain = null
-       ) {
-               if ( $context === null ) {
-                       $context = RequestContext::getMain();
+       private function getEntityRevision( Title $title, $revId = null ) {
+               if ( $revId === null || $revId === 0 ) {
+                       $revId = $title->getLatestRevID();
                }
 
-               $languageCode = $context->getLanguage()->getCode();
-
-               if ( $options !== null ) {
-                       // NOTE: Parser Options language overrides context 
language!
-                       $languageCode = $options->getUserLang();
-               }
-
-               $formatterOptions = new FormatterOptions();
-               $formatterOptions->setOption( ValueFormatter::OPT_LANG, 
$languageCode );
-
-               // Force the context's language to be the one specified by the 
parser options.
-               if ( $context && $context->getLanguage()->getCode() !== 
$languageCode ) {
-                       $context = clone $context;
-                       $context->setLanguage( $languageCode );
-               }
-
-               $wikibaseRepo = WikibaseRepo::getDefaultInstance();
-
-               if ( !$uiLanguageFallbackChain ) {
-                       $factory = 
$wikibaseRepo->getLanguageFallbackChainFactory();
-                       $uiLanguageFallbackChain = 
$factory->newFromContextForPageView( $context );
-               }
-
-               $formatterOptions->setOption( 'languages', 
$uiLanguageFallbackChain );
-
-               // get all the necessary services ----
-               $snakFormatter = $wikibaseRepo->getSnakFormatterFactory()
-                       ->getSnakFormatter( SnakFormatter::FORMAT_HTML_WIDGET, 
$formatterOptions );
-
-               $entityInfoBuilderFactory = 
$wikibaseRepo->getStore()->getEntityInfoBuilderFactory();
-               $entityContentFactory = 
$wikibaseRepo->getEntityContentFactory();
-
-               $serializationOptions = $this->makeSerializationOptions( 
$languageCode, $uiLanguageFallbackChain );
-
-               $entityView = $this->getEntityView(
-                       $snakFormatter,
-                       $entityContentFactory,
-                       $entityInfoBuilderFactory,
-                       $context->getLanguage()
-               );
-
-               // 
---------------------------------------------------------------------
-
-               $configBuilder = new ParserOutputJsConfigBuilder(
-                       $entityInfoBuilderFactory,
-                       $wikibaseRepo->getEntityIdParser(),
-                       $entityContentFactory,
-                       new ReferencedEntitiesFinder(),
-                       $context->getLanguage()->getCode()
-               );
-
-               $dataTypeLookup = $wikibaseRepo->getPropertyDataTypeLookup();
-
-               return new EntityParserOutputGenerator(
-                       $entityView,
-                       $configBuilder,
-                       $serializationOptions,
-                       $entityContentFactory,
-                       $dataTypeLookup
-               );
+               return new EntityRevision( $this->getEntity(), $revId );
        }
-
-       /**
-        * Creates an EntityView suitable for rendering the entity.
-        *
-        * @since 0.5
-        *
-        * @param SnakFormatter $snakFormatter
-        * @param EntityTitleLookup $entityTitleLookup
-        * @param EntityInfoBuilderFactory $entityInfoBuilderFactory
-        * @param Language $language
-        *
-        * @return EntityView
-        */
-       private function getEntityView(
-               SnakFormatter $snakFormatter,
-               EntityTitleLookup $entityTitleLookup,
-               EntityInfoBuilderFactory $entityInfoBuilderFactory,
-               Language $language
-       ) {
-               //TODO: cache last used entity view
-               $sectionEditLinkGenerator = new SectionEditLinkGenerator();
-
-               $snakHtmlGenerator = new SnakHtmlGenerator(
-                       $snakFormatter,
-                       $entityTitleLookup
-               );
-
-               $claimHtmlGenerator = new ClaimHtmlGenerator(
-                       $snakHtmlGenerator,
-                       $entityTitleLookup
-               );
-
-               $claimsView =  new ClaimsView(
-                       $entityInfoBuilderFactory,
-                       $entityTitleLookup,
-                       $sectionEditLinkGenerator,
-                       $claimHtmlGenerator,
-                       $language->getCode()
-               );
-
-               $fingerprintView = new FingerprintView(
-                       $sectionEditLinkGenerator,
-                       $language->getCode()
-               );
-
-               return $this->newEntityView(
-                       $fingerprintView,
-                       $claimsView,
-                       $language
-               );
-       }
-
-       /**
-        * Instantiates an EntityView.
-        *
-        * @see getEntityView()
-        *
-        * @param FingerprintView $fingerprintView
-        * @param ClaimsView $claimsView
-        * @param Language $language
-        *
-        * @return EntityView
-        */
-       protected abstract function newEntityView(
-               FingerprintView $fingerprintView,
-               ClaimsView $claimsView,
-               Language $language
-       );
 
        /**
         * @return String a string representing the content in a way useful for 
building a full text
@@ -849,21 +718,6 @@
                $handler = $this->getContentHandler();
                $status = 
$handler->getValidationErrorLocalizer()->getResultStatus( $result );
                return $status;
-       }
-
-       /**
-        * @param string $languageCode
-        * @param LanguageFallbackChain $fallbackChain
-        *
-        * @return SerializationOptions
-        */
-       private function makeSerializationOptions( $languageCode, 
LanguageFallbackChain $fallbackChain ) {
-               $languageCodes = Utils::getLanguageCodes() + array( 
$languageCode => $fallbackChain );
-
-               $options = new SerializationOptions();
-               $options->setLanguages( $languageCodes );
-
-               return $options;
        }
 
        /**
diff --git a/repo/includes/content/ItemContent.php 
b/repo/includes/content/ItemContent.php
index 11359d0..46cd222 100644
--- a/repo/includes/content/ItemContent.php
+++ b/repo/includes/content/ItemContent.php
@@ -198,23 +198,6 @@
        }
 
        /**
-        * @see getEntityView()
-        *
-        * @param FingerprintView $fingerprintView
-        * @param ClaimsView $claimsView
-        * @param Language $language
-        *
-        * @return ItemView
-        */
-       protected function newEntityView(
-               FingerprintView $fingerprintView,
-               ClaimsView $claimsView,
-               Language $language
-       ) {
-               return new ItemView( $fingerprintView, $claimsView, $language );
-       }
-
-       /**
         * @see EntityContent::getEntityPageProperties
         *
         * Records the number of sitelinks in the 'wb-sitelinks' key.
diff --git a/repo/includes/content/PropertyContent.php 
b/repo/includes/content/PropertyContent.php
index 7a35fcc..78b094c 100644
--- a/repo/includes/content/PropertyContent.php
+++ b/repo/includes/content/PropertyContent.php
@@ -104,21 +104,4 @@
                return true;
        }
 
-       /**
-        * @see getEntityView()
-        *
-        * @param FingerprintView $fingerprintView
-        * @param ClaimsView $claimsView
-        * @param Language $language
-        *
-        * @return PropertyView
-        */
-       protected function newEntityView(
-               FingerprintView $fingerprintView,
-               ClaimsView $claimsView,
-               Language $language
-       ) {
-               return new PropertyView( $fingerprintView, $claimsView, 
$language );
-       }
-
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9453fd95eb7af8f34e7dbe18bd159b8bcb1927f7
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to