jenkins-bot has submitted this change and it was merged.
Change subject: Put parser cache js config fallback in
MakeGlobalVariablesScript hook handler
......................................................................
Put parser cache js config fallback in MakeGlobalVariablesScript hook handler
If we need to do fallback, then we need OutputPage::getRevisionId which
returns null when called in OutputPageBeforeHTML (which occurs during
OutputPage::addParserOutput).
addParserOutput is called in Article, just before OutputPage::setRevisionId
gets called by Article.
When MakeGlobalVariablesScript is called, output page has revision id set.
Change-Id: Ideb2a4dbf8228f3163d3432157894fabd4760c20
(cherry picked from commit d9ae8e66ba1fe54d537441b0ee7079851d194751)
---
M repo/Wikibase.hooks.php
M repo/Wikibase.php
A repo/includes/Hook/MakeGlobalVariablesScriptHandler.php
M repo/includes/Hook/OutputPageJsConfigHookHandler.php
A repo/tests/phpunit/includes/Hook/MakeGlobalVariablesScriptHandlerTest.php
M repo/tests/phpunit/includes/Hook/OutputPageJsConfigHookHandlerTest.php
6 files changed, 318 insertions(+), 187 deletions(-)
Approvals:
Aude: Looks good to me, approved
WikidataJenkins: Verified
jenkins-bot: Verified
diff --git a/repo/Wikibase.hooks.php b/repo/Wikibase.hooks.php
index e9617cd..ed3c188 100644
--- a/repo/Wikibase.hooks.php
+++ b/repo/Wikibase.hooks.php
@@ -28,6 +28,7 @@
use SplFileInfo;
use Title;
use User;
+use Wikibase\Hook\MakeGlobalVariablesScriptHandler;
use Wikibase\Hook\OutputPageJsConfigHookHandler;
use Wikibase\Repo\WikibaseRepo;
use WikiPage;
@@ -1150,6 +1151,33 @@
return true;
}
+ $settings = WikibaseRepo::getDefaultInstance()->getSettings();
+ $hookHandler = new OutputPageJsConfigHookHandler( $settings );
+
+ $isExperimental = defined( 'WB_EXPERIMENTAL_FEATURES' ) &&
WB_EXPERIMENTAL_FEATURES;
+
+ $hookHandler->handle( $out, $isExperimental );
+
+ return true;
+ }
+
+ /**
+ * Provides fallback for output page js config vars that are stored in
parser cache.
+ *
+ * In some cases, e.g. stale parser cache contents, variables including
wbEntity might be
+ * missing, so we add them here as a fallback. This hook is called
after
+ * OutputPage::setRevisionId is called. Revision id is needed to
retrieve the correct entity.
+ *
+ * @param array $vars
+ * @param OutputPage $out
+ *
+ * @return boolean
+ */
+ public static function onMakeGlobalVariablesScript( $vars, $out ) {
+ if ( !self::isTitleInEntityNamespace( $out->getTitle() ) ) {
+ return true;
+ }
+
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
$langCode = $out->getContext()->getLanguage()->getCode();
@@ -1158,16 +1186,13 @@
$langCodes = Utils::getLanguageCodes() + array( $langCode =>
$fallbackChain );
- $hookHandler = new OutputPageJsConfigHookHandler(
+ $hookHandler = new MakeGlobalVariablesScriptHandler(
$wikibaseRepo->getEntityContentFactory(),
$wikibaseRepo->getParserOutputJsConfigBuilder(
$langCode ),
- $wikibaseRepo->getSettings(),
$langCodes
);
- $isExperimental = defined( 'WB_EXPERIMENTAL_FEATURES' ) &&
WB_EXPERIMENTAL_FEATURES;
-
- $hookHandler->handle( $out, $isExperimental );
+ $hookHandler->handle( $out );
return true;
}
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index 53cf7e5..a7de07b 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -177,6 +177,7 @@
$wgHooks['ContentModelCanBeUsedOn'][] =
'Wikibase\RepoHooks::onContentModelCanBeUsedOn';
$wgHooks['OutputPageBeforeHTML'][] =
'Wikibase\RepoHooks::onOutputPageBeforeHTML';
$wgHooks['OutputPageBeforeHTML'][] =
'Wikibase\RepoHooks::onOutputPageBeforeHtmlRegisterConfig';
+ $wgHooks['MakeGlobalVariablesScript'][] =
'Wikibase\RepoHooks::onMakeGlobalVariablesScript';
// Resource Loader Modules:
$wgResourceModules = array_merge( $wgResourceModules, include( __DIR__
. "/resources/Resources.php" ) );
diff --git a/repo/includes/Hook/MakeGlobalVariablesScriptHandler.php
b/repo/includes/Hook/MakeGlobalVariablesScriptHandler.php
new file mode 100644
index 0000000..763f17f
--- /dev/null
+++ b/repo/includes/Hook/MakeGlobalVariablesScriptHandler.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Wikibase\Hook;
+
+use OutputPage;
+use Title;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\EntityIdParsingException;
+use Wikibase\EntityContent;
+use Wikibase\EntityContentFactory;
+use Wikibase\LanguageFallbackChainFactory;
+use Wikibase\Lib\Serializers\SerializationOptions;
+use Wikibase\NamespaceUtils;
+use Wikibase\OutputPageJsConfigBuilder;
+use Wikibase\ParserOutputJsConfigBuilder;
+use Wikibase\Settings;
+
+/**
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < [email protected] >
+ */
+class MakeGlobalVariablesScriptHandler {
+
+ /**
+ * @var EntityContentFactory
+ */
+ protected $entityContentFactory;
+
+ /**
+ * @var ParserOutputJsConfigBuilder
+ */
+ protected $parserOutputConfigBuilder;
+
+ /**
+ * @param EntityContentFactory $entityContentFactory
+ * @param ParserOutputJsConfigBuilder $configBuilder
+ * @param array $langCodes
+ */
+ public function __construct(
+ EntityContentFactory $entityContentFactory,
+ ParserOutputJsConfigBuilder $parserOutputConfigBuilder,
+ array $langCodes
+ ) {
+ $this->entityContentFactory = $entityContentFactory;
+ $this->parserOutputConfigBuilder = $parserOutputConfigBuilder;
+ $this->langCodes = $langCodes;
+ }
+
+ /**
+ * @param OutputPage $out
+ */
+ public function handle( OutputPage $out ) {
+ $configVars = $out->getJsConfigVars();
+
+ // backwards compatibility, in case config is not in parser
cache and output page
+ if ( !$this->hasParserConfigVars( $configVars ) ) {
+ $this->addConfigVars( $out );
+ }
+ }
+
+ /**
+ * Regenerates and adds parser config variables (e.g. wbEntity), in case
+ * they are missing in OutputPage (e.g. not in parser cache)
+ *
+ * @param OutputPage $out
+ */
+ private function addConfigVars( OutputPage $out ) {
+ $revisionId = $out->getRevisionId();
+
+ // this will not be set for deleted pages
+ if ( !$revisionId ) {
+ return;
+ }
+
+ $parserConfigVars = $this->getParserConfigVars( $revisionId );
+ $out->addJsConfigVars( $parserConfigVars );
+ }
+
+ /**
+ * @param mixed
+ *
+ * @return boolean
+ */
+ private function hasParserConfigVars( $configVars ) {
+ return is_array( $configVars ) && array_key_exists(
'wbEntityId', $configVars );
+ }
+
+ /**
+ * @param int $revisionId
+ *
+ * @return array
+ */
+ private function getParserConfigVars( $revisionId ) {
+ $entityContent = $this->entityContentFactory->getFromRevision(
$revisionId );
+
+ if ( $entityContent === null || ! $entityContent instanceof
\Wikibase\EntityContent ) {
+ // entity or revision deleted, or non-entity content in
entity namespace
+ wfDebugLog( __CLASS__, "No entity content found for
revision $revisionId" );
+ return array();
+ }
+
+ return $this->buildParserConfigVars( $entityContent );
+ }
+
+ /**
+ * @param EntityContent $entityContent
+ *
+ * @return array
+ */
+ private function buildParserConfigVars( EntityContent $entityContent ) {
+ $options = $this->makeSerializationOptions();
+
+ $entity = $entityContent->getEntity();
+
+ $parserConfigVars = $this->parserOutputConfigBuilder->build(
+ $entity,
+ $options
+ );
+
+ return $parserConfigVars;
+ }
+
+ /**
+ * @return SerializationOptions
+ */
+ private function makeSerializationOptions() {
+ $options = new SerializationOptions();
+ $options->setLanguages( $this->langCodes );
+
+ return $options;
+ }
+
+}
diff --git a/repo/includes/Hook/OutputPageJsConfigHookHandler.php
b/repo/includes/Hook/OutputPageJsConfigHookHandler.php
index 52d6d9b..2eed4c4 100644
--- a/repo/includes/Hook/OutputPageJsConfigHookHandler.php
+++ b/repo/includes/Hook/OutputPageJsConfigHookHandler.php
@@ -24,16 +24,6 @@
class OutputPageJsConfigHookHandler {
/**
- * @var EntityContentFactory
- */
- protected $entityContentFactory;
-
- /**
- * @var ParserOutputJsConfigBuilder
- */
- protected $parserOutputConfigBuilder;
-
- /**
* @var Settings
*/
protected $settings;
@@ -44,47 +34,21 @@
protected $outputPageConfigBuilder;
/**
- * @param EntityContentFactory $entityContentFactory
* @param Settings $settings
- * @param ParserOutputJsConfigBuilder $configBuilder
- * @param array $langCodes
*/
- public function __construct(
- EntityContentFactory $entityContentFactory,
- ParserOutputJsConfigBuilder $parserOutputConfigBuilder,
- Settings $settings,
- array $langCodes
- ) {
- $this->entityContentFactory = $entityContentFactory;
- $this->parserOutputConfigBuilder = $parserOutputConfigBuilder;
+ public function __construct( Settings $settings ) {
$this->settings = $settings;
- $this->langCodes = $langCodes;
-
$this->outputPageConfigBuilder = new
OutputPageJsConfigBuilder();
}
/**
* @param OutputPage &$out
* @param boolean $isExperimental
- *
- * @return OutputPage
*/
public function handle( OutputPage $out, $isExperimental ) {
- $configVars = $out->getJsConfigVars();
-
- // backwards compatibility, in case config is not in parser
cache and output page
- if ( !$this->hasParserConfigVars( $configVars ) ) {
- // gets from parser cache, with fallback to generate it
if not cached
- $revisionId = $out->getRevisionId();
- $parserConfigVars = $this->getParserConfigVars(
$revisionId );
- $out->addJsConfigVars( $parserConfigVars );
- }
-
$outputConfigVars = $this->buildConfigVars( $out,
$isExperimental );
$out->addJsConfigVars( $outputConfigVars );
-
- return true;
}
/**
@@ -105,60 +69,6 @@
);
return $configVars;
- }
-
- /**
- * @param mixed
- *
- * @return boolean
- */
- private function hasParserConfigVars( $configVars ) {
- return is_array( $configVars ) && array_key_exists(
'wbEntityId', $configVars );
- }
-
- /**
- * @param int $revisionId
- *
- * @return array
- */
- private function getParserConfigVars( $revisionId ) {
- $entityContent = $this->entityContentFactory->getFromRevision(
$revisionId );
-
- if ( $entityContent === null || ! $entityContent instanceof
\Wikibase\EntityContent ) {
- // entity or revision deleted, or non-entity content in
entity namespace
- wfDebugLog( __CLASS__, "No entity content found for
revision $revisionId" );
- return array();
- }
-
- return $this->buildParserConfigVars( $entityContent );
- }
-
- /**
- * @param EntityContent $entityContent
- *
- * @return array
- */
- private function buildParserConfigVars( EntityContent $entityContent ) {
- $options = $this->makeSerializationOptions();
-
- $entity = $entityContent->getEntity();
-
- $parserConfigVars = $this->parserOutputConfigBuilder->build(
- $entity,
- $options
- );
-
- return $parserConfigVars;
- }
-
- /**
- * @return SerializationOptions
- */
- private function makeSerializationOptions() {
- $options = new SerializationOptions();
- $options->setLanguages( $this->langCodes );
-
- return $options;
}
}
diff --git
a/repo/tests/phpunit/includes/Hook/MakeGlobalVariablesScriptHandlerTest.php
b/repo/tests/phpunit/includes/Hook/MakeGlobalVariablesScriptHandlerTest.php
new file mode 100644
index 0000000..cf014a2
--- /dev/null
+++ b/repo/tests/phpunit/includes/Hook/MakeGlobalVariablesScriptHandlerTest.php
@@ -0,0 +1,144 @@
+<?php
+
+namespace Wikibase\Test;
+
+use DataValues\StringValue;
+use RequestContext;
+use Title;
+use Wikibase\DataModel\Claim\Claim;
+use Wikibase\DataModel\Entity\BasicEntityIdParser;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\Hook\MakeGlobalVariablesScriptHandler;
+use Wikibase\ItemContent;
+use Wikibase\LanguageFallbackChainFactory;
+use Wikibase\ParserOutputJsConfigBuilder;
+
+/**
+ * @covers Wikibase\Hook\MakeGlobalVariablesScriptHandler
+ *
+ * @since 0.5
+ *
+ * @group WikibaseRepo
+ * @group Wikibase
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < [email protected] >
+ */
+class MakeGlobalVariablesScriptHandlerTest extends \PHPUnit_Framework_TestCase
{
+
+ /**
+ * @dataProvider handleProvider
+ */
+ public function testHandle( array $expected, Title $title, array
$parserConfigVars, $message ) {
+ $hookHandler = new MakeGlobalVariablesScriptHandler(
+ $this->getEntityContentFactory(),
+ $this->getParserOutputJsConfigBuilder(
$parserConfigVars ),
+ array( 'de', 'en', 'es', 'fr' )
+ );
+
+ $context = new RequestContext();
+ $context->setTitle( $title );
+
+ $output = $context->getOutput();
+ $output->setRevisionId( 9320 );
+
+ $hookHandler->handle( $output );
+
+ $configVars = $output->getJsConfigVars();
+
+ $this->assertEquals( $expected, array_keys( $configVars ),
$message );
+ }
+
+ public function handleProvider() {
+ $entityId = new ItemId( 'Q4' );
+ $title = $this->getTitleForId( $entityId );
+
+ $expected = array(
+ 'wbEntityId'
+ );
+
+ $parserConfigVars = array(
+ 'wbEntityId' => 'Q4'
+ );
+
+ return array(
+ array( $expected, $title, $parserConfigVars, 'config
vars without parser cache' )
+ );
+ }
+
+ /**
+ * @param EntityId $entityId
+ *
+ * @return Title
+ */
+ public function getTitleForId( EntityId $entityId ) {
+ $name = $entityId->getEntityType() . ':' .
$entityId->getPrefixedId();
+ return Title::makeTitle( NS_MAIN, $name );
+ }
+
+ /**
+ * @return ParserOutputJsConfigBuilder
+ */
+ private function getParserOutputJsConfigBuilder( $configVars ) {
+ $configBuilder = $this->getMockBuilder(
'Wikibase\ParserOutputJsConfigBuilder' )
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $configBuilder->expects( $this->any() )
+ ->method( 'build' )
+ ->will( $this->returnCallback(
+ function() use( $configVars ) {
+ return $configVars;
+ }
+ )
+ );
+
+ return $configBuilder;
+ }
+
+ /**
+ * @return EntityContentFactory
+ */
+ private function getEntityContentFactory() {
+ $entityContentFactory = $this->getMockBuilder(
'Wikibase\EntityContentFactory' )
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $entityContentFactory->expects( $this->any() )
+ ->method( 'getFromRevision' )
+ ->will( $this->returnCallback( array( $this,
'getEntityContent' ) ) );
+
+ $entityContentFactory->expects( $this->any() )
+ ->method( 'getTitleForId' )
+ ->will( $this->returnCallback( array( $this,
'getTitleForId' ) ) );
+
+ return $entityContentFactory;
+ }
+
+ /**
+ * @return EntityContent
+ */
+ public function getEntityContent() {
+ $item = Item::newFromArray( array() );
+
+ $itemId = new ItemId( 'Q5881' );
+ $item->setId( $itemId );
+ $item->setLabel( 'en', 'Cake' );
+
+ $snak = new PropertyValueSnak( new PropertyId( 'P794' ), new
StringValue( 'a' ) );
+
+ $claim = new Claim( $snak );
+ $claim->setGuid( 'P794$muahahaha' );
+
+ $item->addClaim( $claim );
+
+ $entityContent = new ItemContent( $item );
+
+ return $entityContent;
+ }
+
+}
diff --git
a/repo/tests/phpunit/includes/Hook/OutputPageJsConfigHookHandlerTest.php
b/repo/tests/phpunit/includes/Hook/OutputPageJsConfigHookHandlerTest.php
index 33f089b..546facb 100644
--- a/repo/tests/phpunit/includes/Hook/OutputPageJsConfigHookHandlerTest.php
+++ b/repo/tests/phpunit/includes/Hook/OutputPageJsConfigHookHandlerTest.php
@@ -2,20 +2,11 @@
namespace Wikibase\Test;
-use DataValues\StringValue;
use RequestContext;
use Title;
-use Wikibase\DataModel\Claim\Claim;
-use Wikibase\DataModel\Entity\BasicEntityIdParser;
use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\DataModel\Entity\Item;
use Wikibase\DataModel\Entity\ItemId;
-use Wikibase\DataModel\Snak\PropertyValueSnak;
-use Wikibase\DataModel\Entity\PropertyId;
use Wikibase\Hook\OutputPageJsConfigHookHandler;
-use Wikibase\ItemContent;
-use Wikibase\LanguageFallbackChainFactory;
-use Wikibase\ParserOutputJsConfigBuilder;
use Wikibase\Settings;
/**
@@ -34,23 +25,15 @@
/**
* @dataProvider handleProvider
*/
- public function testHandle( array $expected, EntityId $entityId, array
$cachedConfig,
- array $parserConfig, Settings $settings, $experimental, $message
+ public function testHandle( array $expected, Title $title, Settings
$settings, $experimental,
+ $message
) {
- $hookHandler = new OutputPageJsConfigHookHandler(
- $this->getEntityContentFactory(),
- $this->getParserOutputJsConfigBuilder( $parserConfig ),
- $settings,
- array( 'de', 'en', 'es', 'fr' )
- );
-
- $title = $this->getTitleForId( $entityId );
+ $hookHandler = new OutputPageJsConfigHookHandler( $settings );
$context = new RequestContext();
$context->setTitle( $title );
$output = $context->getOutput();
- $output->addJsConfigVars( $cachedConfig );
$hookHandler->handle( $output, $experimental );
@@ -62,25 +45,19 @@
public function handleProvider() {
$settings = $this->getSettings();
- $entityId = new ItemId( 'Q4' );
-
- $parserConfig = array(
- 'wbEntityId' => $entityId->getSerialization()
- );
$expected = array(
- 'wbEntityId',
'wbUserIsBlocked',
'wbUserCanEdit',
'wbCopyright',
'wbExperimentalFeatures'
);
+ $entityId = new ItemId( 'Q4' );
+ $title = $this->getTitleForId( $entityId );
+
return array(
- array( $expected, $entityId, $parserConfig,
$parserConfig,
- $settings, true, 'config vars with parser
cache' ),
- array( $expected, $entityId, array(), $parserConfig,
- $settings, true, 'config vars without parser
cache' )
+ array( $expected, $title, $settings, true, 'config vars
added to OutputPage' )
);
}
@@ -103,67 +80,6 @@
public function getTitleForId( EntityId $entityId ) {
$name = $entityId->getEntityType() . ':' .
$entityId->getPrefixedId();
return Title::makeTitle( NS_MAIN, $name );
- }
-
- /**
- * @return ParserOutputJsConfigBuilder
- */
- private function getParserOutputJsConfigBuilder( $configVars ) {
- $configBuilder = $this->getMockBuilder(
'Wikibase\ParserOutputJsConfigBuilder' )
- ->disableOriginalConstructor()
- ->getMock();
-
- $configBuilder->expects( $this->any() )
- ->method( 'build' )
- ->will( $this->returnCallback(
- function() use( $configVars ) {
- return $configVars;
- }
- )
- );
-
- return $configBuilder;
- }
-
- /**
- * @return EntityContentFactory
- */
- private function getEntityContentFactory() {
- $entityContentFactory = $this->getMockBuilder(
'Wikibase\EntityContentFactory' )
- ->disableOriginalConstructor()
- ->getMock();
-
- $entityContentFactory->expects( $this->any() )
- ->method( 'getFromRevision' )
- ->will( $this->returnCallback( array( $this,
'getEntityContent' ) ) );
-
- $entityContentFactory->expects( $this->any() )
- ->method( 'getTitleForId' )
- ->will( $this->returnCallback( array( $this,
'getTitleForId' ) ) );
-
- return $entityContentFactory;
- }
-
- /**
- * @return EntityContent
- */
- public function getEntityContent() {
- $item = Item::newFromArray( array() );
-
- $itemId = new ItemId( 'Q5881' );
- $item->setId( $itemId );
- $item->setLabel( 'en', 'Cake' );
-
- $snak = new PropertyValueSnak( new PropertyId( 'P794' ), new
StringValue( 'a' ) );
-
- $claim = new Claim( $snak );
- $claim->setGuid( 'P794$muahahaha' );
-
- $item->addClaim( $claim );
-
- $entityContent = new ItemContent( $item );
-
- return $entityContent;
}
}
--
To view, visit https://gerrit.wikimedia.org/r/120831
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ideb2a4dbf8228f3163d3432157894fabd4760c20
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: mw1.23-wmf19
Gerrit-Owner: Aude <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: WikidataJenkins <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits