Bene has uploaded a new change for review.
https://gerrit.wikimedia.org/r/277906
Change subject: [WIP] Introduce EditEntityHandlers for wbeditentity
......................................................................
[WIP] Introduce EditEntityHandlers for wbeditentity
This patch removes the last and only real purpose of EntityFactory which
is in the wbeditentity api module (EditEntity). The interface currently
contains two methods to create new entities based on a data array or an
existing entity (as a replacement for clear).
We might want to factor out even more of the code that lives within
EditEntity at the moment and add more methods to the interface but for now
this is sufficient to allow some basic new entity types like mediainfo.
Change-Id: Icd0ad807aca6b4fe037f38631369e662b243e5af
---
M lib/includes/EntityTypeDefinitions.php
M repo/WikibaseRepo.entitytypes.php
M repo/includes/Api/EditEntity.php
A repo/includes/Api/EditEntityHandler.php
A repo/includes/Api/EditEntityHandlerFactory.php
A repo/includes/Api/ItemEditEntityHandler.php
M repo/includes/Api/ModifyEntity.php
A repo/includes/Api/PropertyEditEntityHandler.php
M repo/includes/WikibaseRepo.php
9 files changed, 212 insertions(+), 40 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/06/277906/1
diff --git a/lib/includes/EntityTypeDefinitions.php
b/lib/includes/EntityTypeDefinitions.php
index c2c44cf..8730824 100644
--- a/lib/includes/EntityTypeDefinitions.php
+++ b/lib/includes/EntityTypeDefinitions.php
@@ -109,4 +109,11 @@
return $this->getMapForDefinitionField(
'content-handler-factory-callback' );
}
+ /**
+ * @return callable[]
+ */
+ public function getEditEntityHandlerFactoryCallbacks() {
+ return $this->getMapForDefinitionField(
'edit-entity-handler-factory-callback' );
+ }
+
}
diff --git a/repo/WikibaseRepo.entitytypes.php
b/repo/WikibaseRepo.entitytypes.php
index a309650..1e1f31a 100644
--- a/repo/WikibaseRepo.entitytypes.php
+++ b/repo/WikibaseRepo.entitytypes.php
@@ -16,6 +16,8 @@
* @author Bene* < [email protected] >
*/
+use Wikibase\Api\ItemEditEntityHandler;
+use Wikibase\Api\PropertyEditEntityHandler;
use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
use Wikibase\LanguageFallbackChain;
use Wikibase\Repo\WikibaseRepo;
@@ -41,6 +43,9 @@
'content-handler-factory-callback' => function() {
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
return $wikibaseRepo->newItemHandler();
+ },
+ 'edit-entity-handler-factory-callback' => function() {
+ return new ItemEditEntityHandler();
}
),
'property' => array(
@@ -62,6 +67,9 @@
'content-handler-factory-callback' => function() {
$wikibaseRepo = WikibaseRepo::getDefaultInstance();
return $wikibaseRepo->newPropertyHandler();
+ },
+ 'edit-entity-handler-factory-callback' => function() {
+ return new PropertyEditEntityHandler();
}
)
);
diff --git a/repo/includes/Api/EditEntity.php b/repo/includes/Api/EditEntity.php
index 2ece96e..b2b1d73 100644
--- a/repo/includes/Api/EditEntity.php
+++ b/repo/includes/Api/EditEntity.php
@@ -8,9 +8,11 @@
use InvalidArgumentException;
use LogicException;
use MWException;
+use OutOfBoundsException;
use SiteList;
use Title;
use UsageException;
+use Wikibase\Api\EditEntityHandlerFactory;
use Wikibase\ChangeOp\ChangeOp;
use Wikibase\ChangeOp\ChangeOps;
use Wikibase\ChangeOp\FingerprintChangeOpFactory;
@@ -20,13 +22,11 @@
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Entity\EntityIdParser;
use Wikibase\DataModel\Entity\Item;
-use Wikibase\DataModel\Entity\Property;
use Wikibase\DataModel\Statement\Statement;
use Wikibase\DataModel\Statement\StatementListProvider;
use Wikibase\DataModel\Term\AliasesProvider;
use Wikibase\DataModel\Term\DescriptionsProvider;
use Wikibase\DataModel\Term\LabelsProvider;
-use Wikibase\EntityFactory;
use Wikibase\Lib\ContentLanguages;
use Wikibase\Lib\Store\EntityRevisionLookup;
use Wikibase\Repo\WikibaseRepo;
@@ -88,9 +88,9 @@
private $statementDeserializer;
/**
- * @var EntityFactory
+ * @var EditEntityHandlerFactory
*/
- private $entityFactory;
+ private $editEntityHandlerFactory;
/**
* @var string[]
@@ -116,7 +116,7 @@
$this->revisionLookup = $wikibaseRepo->getEntityRevisionLookup(
'uncached' );
$this->idParser = $wikibaseRepo->getEntityIdParser();
$this->statementDeserializer =
$wikibaseRepo->getExternalFormatStatementDeserializer();
- $this->entityFactory = $wikibaseRepo->getEntityFactory();
+ $this->editEntityHandlerFactory =
$wikibaseRepo->getEditEntityHandlerFactory();
$this->enabledEntityTypes =
$wikibaseRepo->getEnabledEntityTypes();
$changeOpFactoryProvider =
$wikibaseRepo->getChangeOpFactoryProvider();
@@ -178,19 +178,22 @@
/**
* @see ModifyEntity::createEntity
*
- * @param string $entityType
+ * @param array $params
*
* @throws UsageException
* @throws LogicException
* @return EntityDocument
*/
- protected function createEntity( $entityType ) {
+ protected function createEntity( array $params ) {
$this->flags |= EDIT_NEW;
try {
- return $this->entityFactory->newEmpty( $entityType );
+ $handler =
$this->editEntityHandlerFactory->newEditEntityHandler( $params['new'] );
+ return $handler->createEntityFromData( $params['data']
);
+ } catch ( OutOfBoundsException $ex ) {
+ $this->errorReporter->dieError( "No such entity type:
'{$params['new']}'", 'no-such-entity-type' );
} catch ( InvalidArgumentException $ex ) {
- $this->errorReporter->dieError( "No such entity type:
'$entityType'", 'no-such-entity-type' );
+ $this->errorReporter->dieError( $ex->getMessage(),
'param-illegal' );
}
throw new LogicException( 'ApiErrorReporter::dieError did not
throw an exception' );
@@ -253,16 +256,8 @@
}
}
- $entity = $this->clearEntity( $entity );
- }
-
- // if we create a new property, make sure we set the datatype
- if ( !$exists && $entity instanceof Property ) {
- if ( !isset( $data['datatype'] ) ) {
- $this->errorReporter->dieError( 'No datatype
given', 'param-illegal' );
- } else {
- $entity->setDataTypeId( $data['datatype'] );
- }
+ $handler =
$this->editEntityHandlerFactory->newEditEntityHandler( $entity->getType() );
+ $entity = $handler->createEmptyEntity( $entity );
}
$changeOps = $this->getChangeOps( $data, $entity );
@@ -271,24 +266,6 @@
$this->buildResult( $entity );
return $this->getSummary( $params );
- }
-
- /**
- * @param EntityDocument $entity
- *
- * @return EntityDocument
- */
- private function clearEntity( EntityDocument $entity ) {
- $newEntity = $this->entityFactory->newEmpty( $entity->getType()
);
- $newEntity->setId( $entity->getId() );
-
- // FIXME how to avoid special case handling here?
- if ( $entity instanceof Property ) {
- /** @var Property $newEntity */
- $newEntity->setDataTypeId( $entity->getDataTypeId() );
- }
-
- return $newEntity;
}
/**
diff --git a/repo/includes/Api/EditEntityHandler.php
b/repo/includes/Api/EditEntityHandler.php
new file mode 100644
index 0000000..d8bc1cd
--- /dev/null
+++ b/repo/includes/Api/EditEntityHandler.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Wikibase\Api;
+
+use Wikibase\DataModel\Entity\EntityDocument;
+
+/**
+ * Interface to handle specific entity types for the wbeditentity api module.
+ *
+ * @license GPL-2.0+
+ * @author Bene* < [email protected] >
+ */
+interface EditEntityHandler {
+
+ /**
+ * Create a new empty entity based on the data provided in the array.
+ * Note that the returned entity must not have an id set.
+ *
+ * @param array $data
+ *
+ * @return EntityDocument
+ */
+ public function createEntityFromData( array $data );
+
+ /**
+ * Creates a new empty entity based on the provided, possible non-empty
entity.
+ * Note that the returned entity must have the same id as the provided
one.
+ *
+ * @param EntityDocument $entity
+ *
+ * @return EntityDocument
+ */
+ public function createEmptyEntity( EntityDocument $entity );
+
+}
diff --git a/repo/includes/Api/EditEntityHandlerFactory.php
b/repo/includes/Api/EditEntityHandlerFactory.php
new file mode 100644
index 0000000..3c9e0f9
--- /dev/null
+++ b/repo/includes/Api/EditEntityHandlerFactory.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Wikibase\Api;
+
+use OutOfBoundsException;
+use Wikimedia\Assert\Assert;
+
+/**
+ * Factory for entity type specific handlers for the wbeditentity api module
+ * which is based on callbacks from a definitions array.
+ *
+ * @license GPL-2.0+
+ * @author Bene* < [email protected] >
+ */
+class EditEntityHandlerFactory {
+
+ /**
+ * @var callable
+ */
+ private $factoryCallbacks;
+
+ /**
+ * @param callable[] $factoryCallbacks
+ */
+ public function __construct( array $factoryCallbacks ) {
+ Assert::parameterElementType( 'callable', $factoryCallbacks,
'$factoryCallbacks' );
+
+ $this->factoryCallbacks = $factoryCallbacks;
+ }
+
+ /**
+ * @param string $entityType
+ *
+ * @throws OutOfBoundsException
+ * @return EditEntityHandler
+ */
+ public function newEditEntityHandler( $entityType ) {
+ if ( !isset( $this->factoryCallbacks[$entityType] ) ) {
+ throw new OutOfBoundsException( "No EditEntityHandler
is registered for entity type '$entityType'" );
+ }
+
+ $editEntityHandler = call_user_func(
$this->factoryCallbacks[$entityType] );
+
+ Assert::postcondition(
+ $editEntityHandler instanceof EditEntityHandler,
+ 'Callback must return an instance of EditEntityHandler'
+ );
+
+ return $editEntityHandler;
+ }
+
+}
diff --git a/repo/includes/Api/ItemEditEntityHandler.php
b/repo/includes/Api/ItemEditEntityHandler.php
new file mode 100644
index 0000000..864ca69
--- /dev/null
+++ b/repo/includes/Api/ItemEditEntityHandler.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Wikibase\Api;
+
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\EntityDocument;
+use Wikibase\DataModel\Entity\Item;
+
+/**
+ * Class to handle items for the wbeditentites api module.
+ *
+ * @license GPL-2.0+
+ * @author Bene* < [email protected] >
+ */
+class ItemEditEntityHandler implements EditEntityHandler{
+
+ /**
+ * @param array $data
+ *
+ * @return EntityDocument
+ */
+ public function createEntityFromData( array $data ) {
+ return new Item();
+ }
+
+ /**
+ * @param EntityDocument $entity
+ *
+ * @throws InvalidArgumentException
+ * @return EntityDocument
+ */
+ public function createEmptyEntity( EntityDocument $entity ) {
+ if ( !( $entity instanceof Item ) ) {
+ throw new InvalidArgumentException( 'This handler can
only handle items.' );
+ }
+
+ return new Item( $entity->getId() );
+ }
+
+}
diff --git a/repo/includes/Api/ModifyEntity.php
b/repo/includes/Api/ModifyEntity.php
index 376fd40..67ed8c8 100644
--- a/repo/includes/Api/ModifyEntity.php
+++ b/repo/includes/Api/ModifyEntity.php
@@ -322,11 +322,11 @@
*
* @since 0.1
*
- * @param string $entityType
+ * @param array $params
*
* @return EntityDocument Newly created entity
*/
- protected function createEntity( $entityType ) {
+ protected function createEntity( array $params ) {
$this->errorReporter->dieError( 'Could not find an existing
entity', 'no-such-entity' );
}
@@ -417,7 +417,7 @@
// Try to find the entity or fail and create it, or die in the
process
$entityRev = $this->getEntityRevisionFromApiParams( $params );
if ( is_null( $entityRev ) ) {
- $entity = $this->createEntity( $params['new'] );
+ $entity = $this->createEntity( $params );
$entityRevId = 0;
// HACK: We need to assign an ID early, for things like
the ClaimIdGenerator.
diff --git a/repo/includes/Api/PropertyEditEntityHandler.php
b/repo/includes/Api/PropertyEditEntityHandler.php
new file mode 100644
index 0000000..caefd57
--- /dev/null
+++ b/repo/includes/Api/PropertyEditEntityHandler.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Wikibase\Api;
+
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\EntityDocument;
+use Wikibase\DataModel\Entity\Property;
+
+/**
+ * Class to handle properties for the wbeditentites api module.
+ *
+ * @license GPL-2.0+
+ * @author Bene* < [email protected] >
+ */
+class PropertyEditEntityHandler implements EditEntityHandler {
+
+ /**
+ * @param array $data
+ *
+ * @return EntityDocument
+ */
+ public function createEntityFromData( array $data ) {
+ if ( !isset( $data['datatype'] ) ) {
+ throw new InvalidArgumentException( 'No datatype given'
);
+ }
+
+ return Property::newFromType( $data['datatype'] );
+ }
+
+ /**
+ * @param EntityDocument $entity
+ *
+ * @throws InvalidArgumentException
+ * @return EntityDocument
+ */
+ public function createEmptyEntity( EntityDocument $entity ) {
+ if ( !( $entity instanceof Property ) ) {
+ throw new InvalidArgumentException( 'This handler can
only handle properties.' );
+ }
+
+ return new Property( $entity->getId(), null,
$entity->getDataTypeId() );
+ }
+}
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 25dcfb3..4219923 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -33,6 +33,7 @@
use User;
use ValueFormatters\FormatterOptions;
use ValueFormatters\ValueFormatter;
+use Wikibase\Api\EditEntityHandlerFactory;
use Wikibase\ChangeOp\ChangeOpFactoryProvider;
use Wikibase\DataModel\DeserializerFactory;
use Wikibase\DataModel\Entity\BasicEntityIdParser;
@@ -1191,6 +1192,15 @@
}
/**
+ * @return EditEntityHandlerFactory
+ */
+ public function getEditEntityHandlerFactory() {
+ return new EditEntityHandlerFactory(
+
$this->entityTypeDefinitions->getEditEntityHandlerFactoryCallbacks()
+ );
+ }
+
+ /**
* @return string[]
*/
public function getEnabledEntityTypes() {
--
To view, visit https://gerrit.wikimedia.org/r/277906
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icd0ad807aca6b4fe037f38631369e662b243e5af
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Bene <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits