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

Reply via email to