jenkins-bot has submitted this change and it was merged.
Change subject: Implement EntityParserOutputGeneratorFactory
......................................................................
Implement EntityParserOutputGeneratorFactory
allows removing a lot of cruft from EntityContent
Change-Id: I9453fd95eb7af8f34e7dbe18bd159b8bcb1927f7
---
M lib/includes/LanguageFallbackChainFactory.php
A repo/includes/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
A repo/tests/phpunit/includes/EntityParserOutputGeneratorFactoryTest.php
7 files changed, 384 insertions(+), 209 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 b653da7..b5d9678 100644
--- a/lib/includes/LanguageFallbackChainFactory.php
+++ b/lib/includes/LanguageFallbackChainFactory.php
@@ -345,24 +345,36 @@
* Caching mechanisms used are taken into consideration.
*
* @param IContextSource $context
+ * @deprecated 0.5 use newFromUserAndLanguageCodeForPageView or other
method.
*
* @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/EntityParserOutputGeneratorFactory.php
b/repo/includes/EntityParserOutputGeneratorFactory.php
new file mode 100644
index 0000000..e865e60
--- /dev/null
+++ b/repo/includes/EntityParserOutputGeneratorFactory.php
@@ -0,0 +1,263 @@
+<?php
+
+namespace Wikibase;
+
+use InvalidArgumentException;
+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 < [email protected] >
+ */
+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 ParserOptions|null $options
+ *
+ * @return EntityParserOutputGenerator
+ */
+ public function getEntityParserOutputGenerator( $entityType,
ParserOptions $options = null ) {
+ $languageCode = $this->getLanguageCode( $options );
+
+ return new EntityParserOutputGenerator(
+ $this->newEntityView( $entityType, $languageCode ),
+ $this->newParserOutputJsConfigBuilder( $languageCode ),
+ $this->makeSerializationOptions( $languageCode ),
+ $this->entityTitleLookup,
+ $this->propertyDataTypeLookup,
+ $this->entityInfoBuilderFactory,
+ $languageCode
+ );
+ }
+
+ /**
+ * @param string $languageCode
+ *
+ * @return SnakFormatter
+ */
+ 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
+ );
+ }
+
+ /**
+ * @param string $languageCode
+ *
+ * @return ParserOutputJsConfigBuilder
+ */
+ private function newParserOutputJsConfigBuilder( $languageCode ) {
+ return new ParserOutputJsConfigBuilder(
+ $this->entityIdParser,
+ $this->entityTitleLookup,
+ $languageCode
+ );
+ }
+
+ /**
+ * @param ParserOptions|null $options
+ *
+ * @return string
+ */
+ private function getLanguageCode( ParserOptions $options = null ) {
+ // NOTE: Parser Options language overrides context language!
+ if ( $options !== null ) {
+ $languageCode = $options->getUserLang();
+ } else {
+ // @todo do we still need to fallback to context here?
+ // if needed, then maybe inject some 'default' in the
constructor.
+ $context = RequestContext::getMain();
+ $languageCode = $context->getLanguage()->getCode();
+ }
+
+ return $languageCode;
+ }
+
+ /**
+ * @param string $languageCode
+ *
+ * @return ClaimsView
+ */
+ private function newClaimsView( $languageCode ) {
+ // @fixme SnakFormatterFactory needs to be injected into
ClaimsView,
+ // and also the entity info records via a TermLookup or such.
+ $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
+ );
+ }
+
+ /**
+ * @param string $languageCode
+ *
+ * @return FingerprintView
+ */
+ 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( $entityType, $languageCode ) {
+ $fingerprintView = $this->newFingerprintView( $languageCode );
+ $claimsView = $this->newClaimsView( $languageCode );
+
+ // @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 );
+ }
+
+ /**
+ * @param string $languageCode
+ *
+ * @return LanguageFallbackChain
+ */
+ 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 cab85c0..02c82dd 100644
--- a/repo/includes/content/EntityContent.php
+++ b/repo/includes/content/EntityContent.php
@@ -268,17 +268,24 @@
protected function getParserOutputFromEntityView( Title $title, $revId
= null,
ParserOptions $options = null, $generateHtml = true
) {
- $editable = !$options? true : $options->getEditSection();
+ // @todo: move this to the ContentHandler
+ $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->getEntity()->getType(),
+ $options
+ );
- // generate parser output
- $outputGenerator = $this->getEntityParserOutputGenerator( null,
$options, null );
- $output = $outputGenerator->getParserOutput( $revision,
$editable, $generateHtml );
+ $editable = $options ? $options->getEditSection() : true;
+
+ $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 +298,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(
- $wikibaseRepo->getEntityIdParser(),
- $entityContentFactory,
- $context->getLanguage()->getCode()
- );
-
- $dataTypeLookup = $wikibaseRepo->getPropertyDataTypeLookup();
-
- return new EntityParserOutputGenerator(
- $entityView,
- $configBuilder,
- $serializationOptions,
- $entityContentFactory,
- $dataTypeLookup,
- $entityInfoBuilderFactory,
- $context->getLanguage()->getCode()
- );
+ 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 +719,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 );
- }
-
}
diff --git
a/repo/tests/phpunit/includes/EntityParserOutputGeneratorFactoryTest.php
b/repo/tests/phpunit/includes/EntityParserOutputGeneratorFactoryTest.php
new file mode 100644
index 0000000..13fa66a
--- /dev/null
+++ b/repo/tests/phpunit/includes/EntityParserOutputGeneratorFactoryTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Wikibase;
+
+use Language;
+use ParserOptions;
+use TestUser;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < [email protected] >
+ */
+class EntityParserOutputGeneratorFactoryTest extends \MediaWikiTestCase {
+
+ /**
+ * @dataProvider getEntityParserOutputGeneratorProvider
+ */
+ public function testGetEntityParserOutputGenerator( $entityType ) {
+ $wikibaseRepo = WikibaseRepo::getDefaultInstance();
+ $parserOutputGeneratorFactory =
$wikibaseRepo->getEntityParserOutputGeneratorFactory();
+
+ $parserOutputGenerator =
$parserOutputGeneratorFactory->getEntityParserOutputGenerator(
+ $entityType,
+ $this->getParserOptions()
+ );
+
+ $this->assertInstanceOf(
+ 'Wikibase\EntityParserOutputGenerator',
+ $parserOutputGenerator
+ );
+ }
+
+ public function getEntityParserOutputGeneratorProvider() {
+ return array(
+ array( 'item' ),
+ array( 'property' )
+ );
+ }
+
+ public function testGetEntityParserOutputGenerator_invalidType() {
+ $wikibaseRepo = WikibaseRepo::getDefaultInstance();
+ $parserOutputGeneratorFactory =
$wikibaseRepo->getEntityParserOutputGeneratorFactory();
+
+ $this->setExpectedException( 'InvalidArgumentException' );
+
+ $parserOutputGeneratorFactory->getEntityParserOutputGenerator(
+ 'kittens',
+ $this->getParserOptions()
+ );
+ }
+
+ private function getParserOptions() {
+ $testUser = new TestUser( 'Wikibase User' );
+ $language = Language::factory( 'en' );
+
+ return new ParserOptions( $testUser->getUser(), $language );
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/171528
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I9453fd95eb7af8f34e7dbe18bd159b8bcb1927f7
Gerrit-PatchSet: 13
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Aude <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits