Daniel Kinzler has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/335270 )
Change subject: Register ContentHandlers in $wgContentHandlers.
......................................................................
Register ContentHandlers in $wgContentHandlers.
Previously, Wikibase provided content handlers dynamically,
instead of registering them in the $wgContentHandlers global.
This caused these handlers to be unknown to ContentHandler::getContentModels().
Bug: T155139
Change-Id: I73ab3f156427abe206ded671c4a9145924a2c479
---
M repo/Wikibase.hooks.php
M repo/Wikibase.php
M repo/includes/Content/EntityContentFactory.php
M repo/includes/Content/EntityHandler.php
M repo/includes/WikibaseRepo.php
M repo/tests/phpunit/includes/Content/EntityContentFactoryTest.php
M repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
M repo/tests/phpunit/includes/WikibaseRepoTest.php
8 files changed, 80 insertions(+), 89 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/70/335270/1
diff --git a/repo/Wikibase.hooks.php b/repo/Wikibase.hooks.php
index fa9afde..9de9bda 100644
--- a/repo/Wikibase.hooks.php
+++ b/repo/Wikibase.hooks.php
@@ -67,34 +67,44 @@
}
/**
- * Handler for the SetupAfterCache hook, completing setup of
- * content and namespace setup.
- *
- * @note: $wgExtraNamespaces and $wgNamespaceAliases have already been
processed at this point
- * and should no longer be touched.
+ * Handler for the SetupAfterCache hook, completing the content and
namespace setup.
+ * This updates the $wgContentHandlers and $wgNamespaceContentModels
registries
+ * according to information provided by entity type definitions and the
entityNamespaces
+ * setting.
*
* @throws MWException
* @return bool
*/
public static function onSetupAfterCache() {
global $wgNamespaceContentModels;
+ global $wgContentHandlers;
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
$entityNamespaceLookup =
$wikibaseRepo->getEntityNamespaceLookup();
$namespaces = $entityNamespaceLookup->getEntityNamespaces();
- if ( empty( $namespaces ) ) {
- throw new MWException( 'Wikibase: Incomplete
configuration: '
- . '$wgWBRepoSettings[\'entityNamespaces\'] has
to be set to an '
- . 'array mapping entity types to namespace IDs.
'
- . 'See Wikibase.example.php for details and
examples.' );
- }
-
+ // Register entity namespaces.
+ // Note that $wgExtraNamespaces and $wgNamespaceAliases have
already been processed at this
+ // point and should no longer be touched.
$contentModelIds = $wikibaseRepo->getContentModelMappings();
foreach ( $namespaces as $entityType => $namespace ) {
if ( !isset( $wgNamespaceContentModels[$namespace] ) ) {
$wgNamespaceContentModels[$namespace] =
$contentModelIds[$entityType];
+ }
+ }
+
+ // Register callbacks for instantiating ContentHandlers for
EntityContent.
+ $contentHandlerInstantiators =
$wikibaseRepo->getContentHandlerInstantiators();
+
+ foreach ( $contentHandlerInstantiators as $entityType =>
$instantiator ) {
+ if ( isset( $contentModelIds[$entityType] ) ) {
+ $model = $contentModelIds[$entityType];
+
+ // Construct a closure, because instantiators
expect the entity type as a parameter.
+ $wgContentHandlers[$model] = function () use (
$instantiator, $entityType ) {
+ return $instantiator($entityType);
+ };
}
}
@@ -850,27 +860,6 @@
}
return true;
- }
-
- /**
- * Handler for the ContentHandlerForModelID hook, implemented to create
EntityHandler
- * instances that have knowledge of the necessary services.
- *
- * @param string $modelId
- * @param ContentHandler|null $handler
- *
- * @return bool|null False on success to stop other
ContentHandlerForModelID hooks from running,
- * null on error.
- */
- public static function onContentHandlerForModelID( $modelId, &$handler
) {
- $wikibaseRepo = WikibaseRepo::getDefaultInstance();
-
- try {
- $handler =
$wikibaseRepo->getEntityContentFactory()->getEntityHandlerForContentModel(
$modelId );
- return false;
- } catch ( OutOfBoundsException $ex ) {
- // no entity content model id
- }
}
/**
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index ec6618c..e3ed838 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -493,7 +493,6 @@
$wgHooks['SkinTemplateBuildNavUrlsNav_urlsAfterPermalink'][] =
'Wikibase\RepoHooks::onSkinTemplateBuildNavUrlsNavUrlsAfterPermalink';
$wgHooks['SkinMinervaDefaultModules'][] =
'Wikibase\RepoHooks::onSkinMinervaDefaultModules';
$wgHooks['ResourceLoaderRegisterModules'][] =
'Wikibase\RepoHooks::onResourceLoaderRegisterModules';
- $wgHooks['ContentHandlerForModelID'][] =
'Wikibase\RepoHooks::onContentHandlerForModelID';
$wgHooks['BeforeDisplayNoArticleText'][] =
'Wikibase\ViewEntityAction::onBeforeDisplayNoArticleText';
$wgHooks['InfoAction'][] = '\Wikibase\RepoHooks::onInfoAction';
diff --git a/repo/includes/Content/EntityContentFactory.php
b/repo/includes/Content/EntityContentFactory.php
index 64ad556..6cffb94 100644
--- a/repo/includes/Content/EntityContentFactory.php
+++ b/repo/includes/Content/EntityContentFactory.php
@@ -2,6 +2,7 @@
namespace Wikibase\Repo\Content;
+use ContentHandler;
use InvalidArgumentException;
use MWException;
use OutOfBoundsException;
@@ -36,26 +37,18 @@
private $entityContentModels;
/**
- * @var callable[] Entity type ID to callback mapping for creating
ContentHandler objects.
- */
- private $entityHandlerFactoryCallbacks;
-
- /**
* @var EntityHandler[] Entity type ID to entity handler mapping.
*/
private $entityHandlers = array();
/**
* @param string[] $entityContentModels Entity type ID to content model
ID mapping.
- * @param callable[] $entityHandlerFactoryCallbacks Entity type ID to
callback mapping for
* creating ContentHandler objects.
*/
- public function __construct( array $entityContentModels, array
$entityHandlerFactoryCallbacks ) {
+ public function __construct( array $entityContentModels ) {
Assert::parameterElementType( 'string', $entityContentModels,
'$entityContentModels' );
- Assert::parameterElementType( 'callable',
$entityHandlerFactoryCallbacks, '$entityHandlerFactoryCallbacks' );
$this->entityContentModels = $entityContentModels;
- $this->entityHandlerFactoryCallbacks =
$entityHandlerFactoryCallbacks;
}
/**
@@ -185,22 +178,8 @@
* @return EntityHandler
*/
public function getContentHandlerForType( $entityType ) {
- if ( !isset( $this->entityHandlerFactoryCallbacks[$entityType]
) ) {
- throw new OutOfBoundsException( 'No content handler
defined for entity type ' . $entityType );
- }
-
- if ( !isset( $this->entityHandlers[$entityType] ) ) {
- $entityHandler = call_user_func(
$this->entityHandlerFactoryCallbacks[$entityType] );
-
- Assert::postcondition(
- $entityHandler instanceof EntityHandler,
- 'Callback must return an instance of
EntityHandler'
- );
-
- $this->entityHandlers[$entityType] = $entityHandler;
- }
-
- return $this->entityHandlers[$entityType];
+ $model = $this->getContentModelForType( $entityType );
+ return ContentHandler::getForModelID( $model );
}
/**
diff --git a/repo/includes/Content/EntityHandler.php
b/repo/includes/Content/EntityHandler.php
index b9fa380..521e490 100644
--- a/repo/includes/Content/EntityHandler.php
+++ b/repo/includes/Content/EntityHandler.php
@@ -480,7 +480,13 @@
final public function getEntityNamespace() {
$entityNamespaceLookup =
WikibaseRepo::getDefaultInstance()->getEntityNamespaceLookup();
- return $entityNamespaceLookup->getEntityNamespace(
$this->getEntityType() );
+ $ns = $entityNamespaceLookup->getEntityNamespace(
$this->getEntityType() );
+
+ if ( $ns === null ) {
+ throw new MWException( 'No namespace configured for
entity type ' . $this->getEntityType() );
+ }
+
+ return $ns;
}
/**
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index b00f0ad..9dcf73c 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -573,8 +573,7 @@
*/
public function getEntityContentFactory() {
return new EntityContentFactory(
- $this->getContentModelMappings(),
-
$this->entityTypeDefinitions->getContentHandlerFactoryCallbacks()
+ $this->getContentModelMappings()
);
}
@@ -1224,6 +1223,20 @@
}
/**
+ * Get a mapping of entity types => content handler instantiator
callback.
+ *
+ * @note This is for use by bootstrap code only. Application logic
should have
+ * no need to call this method.
+ */
+ public function getContentHandlerInstantiators() {
+ $map =
$this->entityTypeDefinitions->getContentHandlerFactoryCallbacks();
+
+ // XXX: do we need Hooks::run(
'WikibaseContentHandlerInstantiators', array( &$map ) );
+
+ return $map;
+ }
+
+ /**
* @return EntityFactory
*/
public function getEntityFactory() {
@@ -1584,6 +1597,14 @@
);
Hooks::run( 'WikibaseEntityNamespaces', array( &$namespaces ) );
+
+ if ( empty( $namespaces ) ) {
+ throw new MWException( 'Wikibase: Incomplete
configuration: '
+ . '$wgWBRepoSettings[\'entityNamespaces\'] has
to be set to an '
+ . 'array mapping entity types to namespace IDs.
'
+ . 'See Wikibase.example.php for details and
examples.' );
+ }
+
return $namespaces;
}
diff --git a/repo/tests/phpunit/includes/Content/EntityContentFactoryTest.php
b/repo/tests/phpunit/includes/Content/EntityContentFactoryTest.php
index 7f80661..4d82fda 100644
--- a/repo/tests/phpunit/includes/Content/EntityContentFactoryTest.php
+++ b/repo/tests/phpunit/includes/Content/EntityContentFactoryTest.php
@@ -36,8 +36,7 @@
*/
public function testGetEntityContentModels( array $contentModelIds,
array $callbacks ) {
$factory = new EntityContentFactory(
- $contentModelIds,
- $callbacks
+ $contentModelIds
);
$this->assertEquals(
@@ -58,20 +57,18 @@
public function provideInvalidConstructorArguments() {
return array(
- array( array( null ), array() ),
- array( array(), array( null ) ),
- array( array( 1 ), array() ),
- array( array(), array( 'foo' ) )
+ array( array( null ) ),
+ array( array( 1 ) ),
);
}
/**
* @dataProvider provideInvalidConstructorArguments
*/
- public function testInvalidConstructorArguments( array
$contentModelIds, array $callbacks ) {
+ public function testInvalidConstructorArguments( array $contentModelIds
) {
$this->setExpectedException( InvalidArgumentException::class );
- new EntityContentFactory( $contentModelIds, $callbacks );
+ new EntityContentFactory( $contentModelIds );
}
public function testIsEntityContentModel() {
@@ -91,14 +88,6 @@
array(
'item' => CONTENT_MODEL_WIKIBASE_ITEM,
'property' => CONTENT_MODEL_WIKIBASE_PROPERTY
- ),
- array(
- 'item' => function() use ( $wikibaseRepo ) {
- return $wikibaseRepo->newItemHandler();
- },
- 'property' => function() use ( $wikibaseRepo ) {
- return
$wikibaseRepo->newPropertyHandler();
- }
)
);
}
diff --git a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
index 01d9c81..8f164fc 100644
--- a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
+++ b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityStoreTest.php
@@ -52,6 +52,19 @@
return $handler;
}
+ public function setUp() {
+ parent::setUp();
+
+ $this->mergeMwGlobalArrayValue(
+ 'wgContentHandlers',
+ [
+ 'wikibase-custom-type' => function() {
+ return $this->newCustomEntityHandler();
+ }
+ ]
+ );
+ }
+
/**
* @param string $idString
*
@@ -95,17 +108,6 @@
'item' => CONTENT_MODEL_WIKIBASE_ITEM,
'property' =>
CONTENT_MODEL_WIKIBASE_PROPERTY,
'custom-type' => 'wikibase-custom-type',
- ),
- array(
- 'item' => function() use (
$wikibaseRepo ) {
- return
$wikibaseRepo->newItemHandler();
- },
- 'property' => function() use (
$wikibaseRepo ) {
- return
$wikibaseRepo->newPropertyHandler();
- },
- 'custom-type' => function() use (
$wikibaseRepo ) {
- return
$this->newCustomEntityHandler();
- },
)
),
new SqlIdGenerator( wfGetLB() )
diff --git a/repo/tests/phpunit/includes/WikibaseRepoTest.php
b/repo/tests/phpunit/includes/WikibaseRepoTest.php
index d291609..5505d78 100644
--- a/repo/tests/phpunit/includes/WikibaseRepoTest.php
+++ b/repo/tests/phpunit/includes/WikibaseRepoTest.php
@@ -294,6 +294,12 @@
$this->assertContainsOnly( 'string', $array );
}
+ public function testGetContentHandlerInstantiators() {
+ $array =
$this->getWikibaseRepo()->getContentHandlerInstantiators();
+ $this->assertInternalType( 'array', $array );
+ $this->assertContainsOnly( 'callable', $array );
+ }
+
public function testGetEntityFactory() {
$entityFactory = $this->getWikibaseRepo()->getEntityFactory();
$this->assertInstanceOf( EntityFactory::class, $entityFactory );
--
To view, visit https://gerrit.wikimedia.org/r/335270
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I73ab3f156427abe206ded671c4a9145924a2c479
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits