jenkins-bot has submitted this change and it was merged.
Change subject: Use ChangeOps for wbsetclaimvalue and wbcreateclaim
......................................................................
Use ChangeOps for wbsetclaimvalue and wbcreateclaim
- wbsetclaimvalue & wbcreateclaim are now using ChangeOpClaim
- autocomment functionality added to wbsetclaimvalue
- these modules now also allow custom edit summaries
Bug: 41490
Bug: 50307
Change-Id: I0521a20bf6f600a952831418ebd4ef02bcb3f52f
---
M repo/Wikibase.classes.php
M repo/Wikibase.i18n.php
A repo/includes/api/ClaimModificationHelper.php
M repo/includes/api/CreateClaim.php
A repo/includes/api/ModifyClaim.php
M repo/includes/api/SetClaimValue.php
6 files changed, 495 insertions(+), 447 deletions(-)
Approvals:
Daniel Kinzler: Looks good to me, but someone else must approve
Addshore: Looks good to me, approved
jenkins-bot: Verified
diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index 795b7c0..3bc9689 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -97,6 +97,8 @@
'Wikibase\Api\RemoveQualifiers' =>
'includes/api/RemoveQualifiers.php',
'Wikibase\Api\SetQualifier' => 'includes/api/SetQualifier.php',
'Wikibase\Api\SnakValidationHelper' =>
'includes/api/SnakValidationHelper.php',
+ 'Wikibase\Api\ModifyClaim' => 'includes/api/ModifyClaim.php',
+ 'Wikibase\Api\ClaimModificationHelper' =>
'includes/api/ClaimModificationHelper.php',
// includes/content
'Wikibase\EntityContent' =>
'includes/content/EntityContent.php',
diff --git a/repo/Wikibase.i18n.php b/repo/Wikibase.i18n.php
index a826a0f..475a2cc 100644
--- a/repo/Wikibase.i18n.php
+++ b/repo/Wikibase.i18n.php
@@ -249,6 +249,7 @@
'wikibase-api-invalid-snak' => 'Invalid snak', # Do not translate
'wikibase-api-invalid-list' => 'Invalid list', # Do not translate
'wikibase-api-invalid-property-id' => 'Invalid propertyid', # Do not
translate
+ 'wikibase-api-invalid-entity-id' => 'Invalid entityid', # Do not
translate
'wikibase-api-invalid-snak' => 'Invalid snak', # Do not translate
'wikibase-api-no-common-iten' => 'There is no common item', # Do not
translate
'wikibase-api-no-data' => 'No data to operate on', # Do not translate
@@ -920,6 +921,7 @@
'wikibase-api-invalid-snak' => '!!DO NOT TRANSLATE!! Invalid snak has
been provided, This is similar to invalid-json',
'wikibase-api-invalid-list' => '!!DO NOT TRANSLATE!! Invalid list or
data has been provided. This can occour when a list conflicts with itself (the
list contains something to modify, but also to remove this item)',
'wikibase-api-invalid-property-id' => '!!DO NOT TRANSLATE!! Invalid
propertyid has been supplied',
+ 'wikibase-api-invalid-entity-id' => '!!DO NOT TRANSLATE!! Invalid
entityid has been supplied',
'wikibase-api-no-common-iten' => '!!DO NOT TRANSLATE!! There is no
common item between to passed parameters when there should be',
'wikibase-api-no-data' => '!!DO NOT TRANSLATE!! This is an error
message for a situation where the "data" argument to the API is lacking
content. Usually this should never be shown to the user, unless there are some
exceptional error condition. This message should probably not exist in the
final version.',
'wikibase-api-no-external-page' => '!!DO NOT TRANSLATE!! This is an
error message where the external client did reply, but either because of a
faulty reply or because the page title could not be unwound, it was not
possible to identify an external page.',
diff --git a/repo/includes/api/ClaimModificationHelper.php
b/repo/includes/api/ClaimModificationHelper.php
new file mode 100644
index 0000000..8f6d30a
--- /dev/null
+++ b/repo/includes/api/ClaimModificationHelper.php
@@ -0,0 +1,217 @@
+<?php
+
+namespace Wikibase\Api;
+
+use Wikibase\Lib\EntityIdParser;
+
+use Wikibase\Lib\SnakConstructionService;
+
+use ApiBase, MWException;
+use Wikibase\EntityContent;
+use Wikibase\Claim;
+use Wikibase\Summary;
+use Wikibase\Lib\Serializers\SerializerFactory;
+use Wikibase\Entity;
+use Wikibase\EntityId;
+use Wikibase\Property;
+use Wikibase\EntityContentFactory;
+
+/**
+ * Helper class for modifying claims
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.4
+ *
+ * @ingroup WikibaseRepo
+ * @ingroup API
+ *
+ * @licence GNU GPL v2+
+ * @author Tobias Gritschacher < [email protected] >
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class ClaimModificationHelper {
+
+ /**
+ * @since 0.4
+ *
+ * @var \ApiMain
+ */
+ protected $apiMain;
+
+ /**
+ * @since 0.4
+ *
+ * @var EntityContentFactory
+ */
+ protected $entityContentFactory;
+
+ /**
+ * @since 0.4
+ *
+ * @var SnakConstructionService
+ */
+ protected $snakConstructionService;
+
+ /**
+ * @since 0.4
+ *
+ * @var EntityIdParser
+ */
+ protected $entityIdParser;
+
+ /**
+ * @since 0.4
+ *
+ * @param \ApiMain $apiMain
+ * @param EntityContentFactory $entityContentFactory
+ * @param SnakConstructionService $snakConstructionService
+ * @param EntityIdParser $entityIdParser
+ */
+ public function __construct(
+ \ApiMain $apiMain,
+ EntityContentFactory $entityContentFactory,
+ SnakConstructionService $snakConstructionService,
+ EntityIdParser $entityIdParser
+ ) {
+ $this->apiMain = $apiMain;
+ $this->entityContentFactory = $entityContentFactory;
+ $this->snakConstructionService = $snakConstructionService;
+ $this->entityIdParser = $entityIdParser;
+ }
+
+ /**
+ * @since 0.4
+ *
+ * @param Claim $claim
+ */
+ public function addClaimToApiResult( Claim $claim ) {
+ $serializerFactory = new SerializerFactory();
+ $serializer = $serializerFactory->newSerializerForObject(
$claim );
+ $serializer->getOptions()->setIndexTags(
$this->apiMain->getResult()->getIsRawMode() );
+
+ $this->apiMain->getResult()->addValue(
+ null,
+ 'claim',
+ $serializer->getSerialized( $claim )
+ );
+ }
+
+ /**
+ * @since 0.4
+ *
+ * @param EntityId $entityId
+ *
+ * @return \Title
+ * TODO: this could go into a ApiWikibaseHelper as it is useful for
almost all API modules
+ */
+ public function getEntityTitle( EntityId $entityId ) {
+ $entityTitle =
EntityContentFactory::singleton()->getTitleForId( $entityId );
+
+ if ( $entityTitle === null ) {
+ $this->apiMain->dieUsage( 'No such entity' ,
'no-such-entity' );
+ }
+
+ return $entityTitle;
+ }
+
+ /**
+ * @since 0.4
+ *
+ * @param array $params
+ * @param EntityId $propertyId
+ *
+ * @return \Wikibase\Snak
+ *
+ * @throws ParseException
+ * @throws IllegalValueException
+ */
+ public function getSnakInstance( $params, EntityId $propertyId ) {
+ $valueData = null;
+ if ( isset( $params['value'] ) ) {
+ $valueData = \FormatJson::decode( $params['value'],
true );
+ if ( $valueData === null ) {
+ $this->apiMain->dieUsage( 'Could not decode
snak value', 'invalid-snak' );
+ }
+ }
+
+ if ( $propertyId->getEntityType() !== Property::ENTITY_TYPE ) {
+ $this->apiMain->dieUsage( 'Property expected, got ' .
$propertyId->getEntityType(), 'invalid-snak' );
+ }
+
+ try {
+ $snak = $this->snakConstructionService->newSnak(
$propertyId, $params['snaktype'], $valueData );
+ }
+ catch ( IllegalValueException $ex ) {
+ $this->apiMain->dieUsage( 'Invalid snak:
IllegalValueException', 'invalid-snak' );
+ }
+ catch ( InvalidArgumentException $ex ) {
+ // shouldn't happen, but might.
+ $this->apiMain->dieUsage( 'Invalid snak:
InvalidArgumentException', 'invalid-snak' );
+ }
+
+ return $snak;
+ }
+
+ /**
+ * Parses an entity id string coming from the user
+ *
+ * @since 0.4
+ *
+ * @param string $entityIdParam
+ *
+ * TODO: this could go into an EntityModificationHelper or even in a
ApiWikibaseHelper
+ * as it is useful for almost all API modules
+ */
+ public function getEntityIdFromString( $entityIdParam ) {
+ try {
+ $entityId = $this->entityIdParser->parse(
$entityIdParam );
+ } catch ( ParseException $parseException ) {
+ $this->dieUsage( 'Invalid entity ID: ParseException',
'invalid-entity-id' );
+ }
+
+ return $entityId;
+ }
+
+ /**
+ * Creates a new Summary instance suitable for representing the action
performed by this module.
+ *
+ * @since 0.4
+ *
+ * @param array $params
+ *
+ * @return Summary
+ */
+ public function createSummary( array $params, \ApiBase $module ) {
+ $summary = new Summary( $module->getModuleName() );
+ if ( isset( $params['summary'] ) ) {
+ $summary->setUserSummary( $params['summary'] );
+ }
+ return $summary;
+ }
+
+ /**
+ * @see ApiBase::getPossibleErrors()
+ */
+ public function getPossibleErrors() {
+ return array(
+ array( 'code' => 'invalid-guid', 'info' =>
$this->apiMain->msg( 'wikibase-api-invalid-guid' )->text() ),
+ array( 'code' => 'no-such-entity', 'info' =>
$this->apiMain->msg( 'wikibase-api-no-such-entity' )->text() ),
+ array( 'code' => 'invalid-snak', 'info' =>
$this->apiMain->msg( 'wikibase-api-invalid-snak' )->text() ),
+ array( 'code' => 'invalid-entity-id', 'info' =>
$this->apiMain->msg( 'wikibase-api-invalid-entity-id' )->text() ),
+ );
+ }
+}
diff --git a/repo/includes/api/CreateClaim.php
b/repo/includes/api/CreateClaim.php
index 884ddb9..faf926e 100644
--- a/repo/includes/api/CreateClaim.php
+++ b/repo/includes/api/CreateClaim.php
@@ -3,24 +3,13 @@
namespace Wikibase\Api;
use ApiBase, MWException;
-
use ApiMain;
-use DataValues\IllegalValueException;
-use InvalidArgumentException;
-use ValueParsers\ParseException;
use Wikibase\EntityId;
-use Wikibase\Entity;
-use Wikibase\EntityContent;
-use Wikibase\EntityContentFactory;
-use Wikibase\Lib\PropertyNotFoundException;
-use Wikibase\Property;
use Wikibase\Repo\WikibaseRepo;
-use Wikibase\LibRegistry;
-use Wikibase\Claim;
-use Wikibase\Autocomment;
-use Wikibase\Summary;
-use Wikibase\Snak;
+use Wikibase\Claims;
+use Wikibase\ChangeOpClaim;
use Wikibase\Validators\ValidatorErrorLocalizer;
+use ValueParsers\ParseException;
/**
* API module for creating claims.
@@ -48,14 +37,23 @@
* @licence GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
* @author Daniel Kinzler
+ * @author Tobias Gritschacher < [email protected] >
*/
-class CreateClaim extends ApiWikibase {
-
+class CreateClaim extends ModifyClaim {
/**
+ * @since 0.4
+ *
* @var SnakValidationHelper
*/
protected $snakValidation;
+
+ /**
+ * @since 0.4
+ *
+ * @var ClaimModificationHelper
+ */
+ protected $claimModificationHelper;
/**
* see ApiBase::__construct()
@@ -73,6 +71,13 @@
WikibaseRepo::getDefaultInstance()->getDataTypeFactory(),
new ValidatorErrorLocalizer()
);
+
+ $this->claimModificationHelper = new ClaimModificationHelper(
+ $mainModule,
+
WikibaseRepo::getDefaultInstance()->getEntityContentFactory(),
+
WikibaseRepo::getDefaultInstance()->getSnakConstructionService(),
+ WikibaseRepo::getDefaultInstance()->getEntityIdParser()
+ );
}
/**
@@ -86,105 +91,29 @@
$params = $this->extractRequestParams();
$this->validateParameters( $params );
- $entityContent = $this->getEntityContent();
+ $entityId =
$this->claimModificationHelper->getEntityIdFromString( $params['entity'] );
+ $baseRevisionId = isset( $params['baserevid'] ) ? intval(
$params['baserevid'] ) : null;
+ $entityTitle = $this->claimModificationHelper->getEntityTitle(
$entityId );
+ // TODO: put loadEntityContent into a separate helper class for
great reuse!
+ $entityContent = $this->loadEntityContent( $entityTitle,
$baseRevisionId );
+ $entity = $entityContent->getEntity();
- // It is possible we get an exception from this method because
of specifying
- // a non existing-property, specifying an entity id for an
entity with wrong
- // entity type or providing an invalid DataValue.
- try {
- $snak = $this->getSnakInstance();
+ $propertyId =
$this->claimModificationHelper->getEntityIdFromString( $params['property'] );
- $this->snakValidation->validateSnak( $snak );
+ $snak = $this->claimModificationHelper->getSnakInstance(
$params, $propertyId );
+ $this->snakValidation->validateSnak( $snak );
- $claim = $this->addClaim( $entityContent->getEntity(),
$snak );
- $summary = $this->createSummary( $snak, 'create' );
+ $summary = $this->claimModificationHelper->createSummary(
$params, $this );
+ $changeOp = new ChangeOpClaim( '', $snak,
WikibaseRepo::getDefaultInstance()->getIdFormatter() );
+ $changeOp->apply( $entity, $summary );
+ $claims = new Claims( $entity->getClaims() );
+ $claim = $claims->getClaimWithGuid( $changeOp->getClaimGuid() );
- $this->saveChanges( $entityContent, $summary );
+ $this->saveChanges( $entityContent, $summary );
- $this->outputClaim( $claim );
-
- }
- catch ( IllegalValueException $ex ) {
- $this->dieUsage( 'Invalid snak: IllegalValueException',
'invalid-snak' );
- }
- catch ( PropertyNotFoundException $ex ) {
- $this->dieUsage( 'Invalid snak:
PropertyNotFoundException', 'invalid-snak' );
- }
- catch ( ParseException $parseException ) {
- $this->dieUsage( 'Invalid guid: ParseException',
'invalid-guid' );
- }
+ $this->claimModificationHelper->addClaimToApiResult( $claim );
wfProfileOut( __METHOD__ );
- }
-
- /**
- * Constructs a new Claim based on the arguments provided to the API,
- * adds it to the Entity and saves it.
- *
- * On success, the added Claim is returned as part of the Status object.
- *
- * @since 0.2
- *
- * @param \Wikibase\Entity $entity
- * @param \Wikibase\Snak $snak
- *
- * @return Claim
- */
- protected function addClaim( Entity $entity, Snak $snak ) {
- wfProfileIn( __METHOD__ );
- $claim = $entity->newClaim( $snak );
-
- $entity->addClaim( $claim );
-
- wfProfileOut( __METHOD__ );
- return $claim;
- }
-
- /**
- * @since 0.3
- *
- * @param \Wikibase\EntityContent $content
- * @param \Wikibase\Summary $summary
- */
- protected function saveChanges( EntityContent $content, Summary
$summary ) {
- $status = $this->attemptSaveEntity(
- $content,
- $summary->toString(),
- EDIT_UPDATE
- );
-
- $this->addRevisionIdFromStatusToResult( 'pageinfo',
'lastrevid', $status );
- }
-
- /**
- * Create a summary
- *
- * @since 0.4
- *
- * @param Snak $snak
- * @param string $action
- *
- * @return Summary
- * @throws \MWException
- */
- protected function createSummary( Snak $snak, $action ) {
- if ( !is_string( $action ) ) {
- throw new \MWException( 'action is invalid or unknown
type.' );
- }
-
- $summary = new Summary( $this->getModuleName() );
- $summary->setAction( $action );
- $summary->addAutoSummaryArgs( $snak->getPropertyId(),
$snak->getDataValue() );
-
- return $summary;
- }
-
- /**
- * @see ApiBase::isWriteMode
- * @return bool true
- */
- public function isWriteMode() {
- return true;
}
/**
@@ -192,6 +121,8 @@
* snaktype value are not set.
*
* @since 0.2
+ *
+ * @params array $params
*/
protected function validateParameters( array $params ) {
if ( $params['snaktype'] == 'value' XOR isset( $params['value']
) ) {
@@ -206,152 +137,82 @@
if ( !isset( $params['property'] ) ) {
$this->dieUsage( 'A property ID needs to be provided
when creating a claim with a Snak', 'param-missing' );
}
- }
- /**
- * @since 0.2
- *
- * @return EntityContent
- */
- protected function getEntityContent() {
- $params = $this->extractRequestParams();
-
- $baseRevisionId = isset( $params['baserevid'] ) ? intval(
$params['baserevid'] ) : null;
-
- $entityId = EntityId::newFromPrefixedId( $params['entity'] );
- $entityTitle = $entityId ?
EntityContentFactory::singleton()->getTitleForId( $entityId ) : null;
- $entityContent = $entityTitle === null ? null :
$this->loadEntityContent( $entityTitle, $baseRevisionId );
-
- if ( $entityContent === null ) {
- $this->dieUsage( 'Entity not found, snak not created',
'no-such-entity' );
+ if ( isset( $params['value'] ) && \FormatJson::decode(
$params['value'], true ) == null ) {
+ $this->dieUsage( 'Could not decode snak value',
'invalid-snak' );
}
-
- return $entityContent;
- }
-
- /**
- * @since 0.2
- *
- * @return Snak
- * @throws ParseException
- * @throws IllegalValueException
- */
- protected function getSnakInstance() {
- $params = $this->extractRequestParams();
-
- $snakType = $params['snaktype'];
- $valueData = isset( $params['value'] ) ? \FormatJson::decode(
$params['value'], true ) : null;
-
- //TODO: Inject all this, or at least initialize it in a central
location.
- $factory =
WikibaseRepo::getDefaultInstance()->getSnakConstructionService();
- $entityIdParser =
WikibaseRepo::getDefaultInstance()->getEntityIdParser();
-
- $entityId = $entityIdParser->parse( $params['property'] );
-
- if ( $entityId->getEntityType() !== Property::ENTITY_TYPE ) {
- $this->dieUsage( 'Property expected, got ' .
$entityId->getEntityType(), 'invalid-snak' );
- }
-
- return $factory->newSnak(
- $entityId,
- $snakType,
- $valueData
- );
- }
-
- /**
- * @since 0.3
- *
- * @param Claim $claim
- */
- protected function outputClaim( Claim $claim ) {
- $serializerFactory = new
\Wikibase\Lib\Serializers\SerializerFactory();
-
- $serializer = $serializerFactory->newSerializerForObject(
$claim );
- $serializer->getOptions()->setIndexTags(
$this->getResult()->getIsRawMode() );
-
- $this->getResult()->addValue(
- null,
- 'claim',
- $serializer->getSerialized( $claim )
- );
}
/**
* @see \ApiBase::getPossibleErrors()
*/
public function getPossibleErrors() {
- return array_merge( parent::getPossibleErrors(), array(
- array( 'code' => 'invalid-snak', 'info' => $this->msg(
'wikibase-api-invalid-snak' )->text() ),
- array( 'code' => 'invalid-guid', 'info' => $this->msg(
'wikibase-api-invalid-guid' )->text() ),
- array( 'code' => 'param-missing', 'info' => $this->msg(
'wikibase-api-param-missing' )->text() ),
- array( 'code' => 'param-illegal', 'info' => $this->msg(
'wikibase-api-param-illegal' )->text() ),
- array( 'code' => 'no-such-entity', 'info' =>
$this->msg( 'wikibase-api-no-such-entity' )->text() ),
- ) );
+ return array_merge(
+ parent::getPossibleErrors(),
+ $this->claimModificationHelper->getPossibleErrors(),
+ array(
+ array( 'code' => 'param-missing', 'info' =>
$this->msg( 'wikibase-api-param-missing' )->text() ),
+ array( 'code' => 'param-illegal', 'info' =>
$this->msg( 'wikibase-api-param-illegal' )->text() ),
+ )
+ );
}
/**
* @see \ApiBase::getAllowedParams
- *
- * @since 0.2
- *
- * @return array
*/
public function getAllowedParams() {
- return array(
- 'entity' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true,
- ),
- 'snaktype' => array(
- ApiBase::PARAM_TYPE => array( 'value',
'novalue', 'somevalue' ),
- ApiBase::PARAM_REQUIRED => true,
- ),
- 'property' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => false,
- ),
- 'value' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => false,
- ),
- 'token' => null,
- 'baserevid' => array(
- ApiBase::PARAM_TYPE => 'integer',
- ),
- 'bot' => false,
+ return array_merge(
+ parent::getAllowedParams(),
+ array(
+ 'entity' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'snaktype' => array(
+ ApiBase::PARAM_TYPE => array( 'value',
'novalue', 'somevalue' ),
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'property' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ 'value' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ 'token' => null,
+ 'baserevid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
+ 'bot' => false,
+ )
);
}
/**
* @see \ApiBase::getParamDescription
- *
- * @since 0.2
- *
- * @return array
*/
public function getParamDescription() {
- return array(
- 'entity' => 'Id of the entity you are adding the claim
to',
- 'property' => 'Id of the snaks property',
- 'value' => 'Value of the snak when creating a claim
with a snak that has a value',
- 'snaktype' => 'The type of the snak',
- 'token' => 'An "edittoken" token previously obtained
through the token module (prop=info).',
- 'baserevid' => array( 'The numeric identifier for the
revision to base the modification on.',
- "This is used for detecting conflicts during
save."
- ),
- 'bot' => array( 'Mark this edit as bot',
- 'This URL flag will only be respected if the
user belongs to the group "bot".'
- ),
+ return array_merge(
+ parent::getParamDescription(),
+ array(
+ 'entity' => 'Id of the entity you are adding
the claim to',
+ 'property' => 'Id of the snaks property',
+ 'value' => 'Value of the snak when creating a
claim with a snak that has a value',
+ 'snaktype' => 'The type of the snak',
+ 'token' => 'An "edittoken" token previously
obtained through the token module (prop=info).',
+ 'baserevid' => array( 'The numeric identifier
for the revision to base the modification on.',
+ "This is used for detecting conflicts
during save."
+ ),
+ 'bot' => array( 'Mark this edit as bot',
+ 'This URL flag will only be respected
if the user belongs to the group "bot".'
+ ),
+ )
);
}
/**
* @see \ApiBase::getDescription
- *
- * @since 0.2
- *
- * @return string
*/
public function getDescription() {
return array(
@@ -361,15 +222,12 @@
/**
* @see \ApiBase::getExamples
- *
- * @since 0.2
- *
- * @return array
*/
protected function getExamples() {
return array(
-
'api.php?action=wbcreateclaim&entity=q42&property=p9001&snaktype=novalue&token=foobar&baserevid=7201010',
-
'api.php?action=wbcreateclaim&entity=q42&property=p9001&snaktype=value&value={"entity-type":"item","numeric-id":1}&token=foobar&baserevid=7201010'
=> 'Creates a claim for q42 of p101 with a value of q1',
+
'api.php?action=wbcreateclaim&entity=q42&property=p9001&snaktype=novalue' =>
'Creates a claim for item q42 of property p9001 with a novalue snak.',
+
'api.php?action=wbcreateclaim&entity=q42&property=p9002&snaktype=value&value="itsastring"'
=> ' Creates a claim for item q42 of property p9002 with string value
"itsastring"',
+
'api.php?action=wbcreateclaim&entity=q42&property=p9003&snaktype=value&value={"entity-type":"item","numeric-id":1}'
=> 'Creates a claim for item q42 of property p9003 with a value of item q1',
);
}
}
diff --git a/repo/includes/api/ModifyClaim.php
b/repo/includes/api/ModifyClaim.php
new file mode 100644
index 0000000..9d2f71d
--- /dev/null
+++ b/repo/includes/api/ModifyClaim.php
@@ -0,0 +1,101 @@
+<?php
+namespace Wikibase\Api;
+
+use ApiBase, MWException;
+use Wikibase\EntityContent;
+use Wikibase\Claim;
+use Wikibase\Summary;
+use Wikibase\Lib\Serializers\SerializerFactory;
+use Wikibase\Repo\WikibaseRepo;
+use Wikibase\Entity;
+use Wikibase\EntityId;
+use Wikibase\Property;
+use Wikibase\EntityContentFactory;
+
+/**
+ * Base class for modifying claims.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.4
+ *
+ * @ingroup WikibaseRepo
+ * @ingroup API
+ *
+ * @licence GNU GPL v2+
+ * @author Tobias Gritschacher < [email protected] >
+ * @author Jeroen De Dauw < [email protected] >
+ */
+abstract class ModifyClaim extends ApiWikibase {
+
+ /**
+ * @since 0.4
+ *
+ * @param \Wikibase\EntityContent $content
+ * @param \Wikibase\Summary $summary
+ */
+ public function saveChanges( EntityContent $content, Summary $summary )
{
+ $status = $this->attemptSaveEntity(
+ $content,
+ $summary->toString(),
+ EDIT_UPDATE
+ );
+
+ $this->addRevisionIdFromStatusToResult( 'pageinfo',
'lastrevid', $status );
+ }
+
+ /**
+ * @see ApiBase::isWriteMode
+ * @return bool true
+ */
+ public function isWriteMode() {
+ return true;
+ }
+
+ /**
+ * @see \Api::getRequiredPermissions()
+ */
+ protected function getRequiredPermissions( Entity $entity, array
$params ) {
+ $permissions = parent::getRequiredPermissions( $entity, $params
);
+
+ $permissions[] = 'edit';
+ return $permissions;
+ }
+
+ /**
+ * @see \ApiBase::getAllowedParams
+ */
+ public function getAllowedParams() {
+ return array_merge(
+ parent::getAllowedParams(),
+ array( 'summary' => array( ApiBase::PARAM_TYPE =>
'string' ) )
+ );
+ }
+
+ /**
+ * @see ApiBase::getParamDescription()
+ */
+ public function getParamDescription() {
+ return array_merge(
+ parent::getParamDescription(),
+ array( 'summary' => array( 'Summary for the edit.',
+ "Will be prepended by an automatically
generated comment. The length limit of the
+ autocomment together with the summary is 260
characters. Be aware that everything above that
+ limit will be cut off." )
+ )
+ );
+ }
+}
diff --git a/repo/includes/api/SetClaimValue.php
b/repo/includes/api/SetClaimValue.php
index 495d8cd..57f7524 100644
--- a/repo/includes/api/SetClaimValue.php
+++ b/repo/includes/api/SetClaimValue.php
@@ -3,24 +3,13 @@
namespace Wikibase\Api;
use ApiBase, MWException;
-
-use DataValues\IllegalValueException;
use ApiMain;
-use ValueParsers\ParseException;
-use Wikibase\Autocomment;
use Wikibase\EntityId;
use Wikibase\Entity;
-use Wikibase\EntityContent;
-use Wikibase\EntityContentFactory;
-use Wikibase\Lib\PropertyNotFoundException;
-use Wikibase\Lib\SnakConstructionService;
-use Wikibase\SnakObject;
-use Wikibase\Claim;
use Wikibase\Claims;
+use Wikibase\ChangeOpClaim;
use Wikibase\Lib\ClaimGuidValidator;
use Wikibase\Repo\WikibaseRepo;
-use Wikibase\Validators\ValidatorErrorLocalizer;
-use Wikibase\validators\SnakValidator;
/**
* API module for setting the DataValue contained by the main snak of a claim.
@@ -47,18 +36,16 @@
*
* @licence GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
+ * @author Tobias Gritschacher < [email protected] >
*/
-class SetClaimValue extends ApiWikibase implements IAutocomment{
+class SetClaimValue extends ModifyClaim {
/**
- * @var SnakValidationHelper
+ * @since 0.4
+ *
+ * @var ClaimModificationHelper
*/
- protected $snakValidation;
-
- /**
- * @var SnakConstructionService
- */
- protected $snakConstruction;
+ protected $claimModificationHelper;
/**
* see ApiBase::__construct()
@@ -70,14 +57,12 @@
public function __construct( ApiMain $mainModule, $moduleName,
$modulePrefix = '' ) {
parent::__construct( $mainModule, $moduleName, $modulePrefix );
- $this->snakValidation = new SnakValidationHelper(
- $this,
-
WikibaseRepo::getDefaultInstance()->getPropertyDataTypeLookup(),
-
WikibaseRepo::getDefaultInstance()->getDataTypeFactory(),
- new ValidatorErrorLocalizer()
+ $this->claimModificationHelper = new ClaimModificationHelper(
+ $mainModule,
+
WikibaseRepo::getDefaultInstance()->getEntityContentFactory(),
+
WikibaseRepo::getDefaultInstance()->getSnakConstructionService(),
+ WikibaseRepo::getDefaultInstance()->getEntityIdParser()
);
-
- $this->snakConstruction =
WikibaseRepo::getDefaultInstance()->getSnakConstructionService();
}
/**
@@ -88,45 +73,44 @@
public function execute() {
wfProfileIn( __METHOD__ );
- $content = $this->getEntityContent();
-
$params = $this->extractRequestParams();
+ $this->validateParameters( $params );
- try {
- $claim = $this->updateClaim(
- $content->getEntity(),
- $params['claim'],
- $params['snaktype'],
- isset( $params['value'] ) ?
\FormatJson::decode( $params['value'], true ) : null
- );
+ $entityId =
$this->claimModificationHelper->getEntityIdFromString(
+ Entity::getIdFromClaimGuid( $params['claim'] )
+ );
+ $baseRevisionId = isset( $params['baserevid'] ) ? intval(
$params['baserevid'] ) : null;
+ $entityTitle = $this->claimModificationHelper->getEntityTitle(
$entityId );
+ // TODO: put loadEntityContent into a separate helper class for
great reuse!
+ $entityContent = $this->loadEntityContent( $entityTitle,
$baseRevisionId );
+ $entity = $entityContent->getEntity();
+ $claims = new Claims( $entity->getClaims() );
+ $claimGuid = $params['claim'];
+ $claim = $claims->getClaimWithGuid( $claimGuid );
- $this->saveChanges( $content );
- $this->outputClaim( $claim );
+ if ( $claim === null ) {
+ $this->dieUsage( "No claim for GUID: $claimGuid" ,
'no-such-claim' );
}
- catch ( IllegalValueException $ex ) {
- wfProfileOut( __METHOD__ );
- $this->dieUsage( 'Invalid snak: IllegalValueException',
'invalid-snak' );
- }
- catch ( PropertyNotFoundException $ex ) {
- wfProfileOut( __METHOD__ );
- $this->dieUsage( 'Invalid snak:
PropertyNotFoundException', 'invalid-snak' );
- }
- catch ( ParseException $parseException ) {
- wfProfileOut( __METHOD__ );
- $this->dieUsage( 'Invalid guid: ParseException',
'invalid-guid' );
- }
+
+ $snak = $this->claimModificationHelper->getSnakInstance(
$params, $claim->getMainSnak()->getPropertyId() );
+
+ $summary = $this->claimModificationHelper->createSummary(
$params, $this );
+ $changeOp = new ChangeOpClaim( $claimGuid, $snak,
WikibaseRepo::getDefaultInstance()->getIdFormatter() );
+ $changeOp->apply( $entity, $summary );
+
+ $this->saveChanges( $entityContent, $summary );
+
+ $this->claimModificationHelper->addClaimToApiResult( $claim );
wfProfileOut( __METHOD__ );
}
/**
- * @since 0.3
+ * @since 0.4
*
- * @return \Wikibase\EntityContent
+ * @param array $params
*/
- protected function getEntityContent() {
- $params = $this->extractRequestParams();
-
+ protected function validateParameters( array $params ) {
// @todo generalize handling of settings in api modules
$settings = WikibaseRepo::getDefaultInstance()->getSettings();
$entityPrefixes = $settings->getSetting( 'entityPrefixes' );
@@ -135,86 +119,6 @@
if ( !( $claimGuidValidator->validate( $params['claim'] ) ) ) {
$this->dieUsage( 'Invalid claim guid' , 'invalid-guid'
);
}
-
- $entityId = EntityId::newFromPrefixedId(
Entity::getIdFromClaimGuid( $params['claim'] ) );
- $entityTitle =
EntityContentFactory::singleton()->getTitleForId( $entityId );
-
- if ( $entityTitle === null ) {
- $this->dieUsage( 'No such entity' , 'no-such-entity' );
- }
-
- $baseRevisionId = isset( $params['baserevid'] ) ? intval(
$params['baserevid'] ) : null;
-
- return $this->loadEntityContent( $entityTitle, $baseRevisionId
);
- }
-
- /**
- * Updates the claim with specified GUID to have a main snak with
provided value.
- * The claim is modified in the passed along entity and is returned as
well.
- *
- * @since 0.3
- *
- * @param \Wikibase\Entity $entity
- * @param string $guid
- * @param string $snakType
- * @param mixed $value
- *
- * @return \Wikibase\Claim
- */
- protected function updateClaim( Entity $entity, $guid, $snakType,
$value = null ) {
- $claims = new Claims( $entity->getClaims() );
-
- if ( !$claims->hasClaimWithGuid( $guid ) ) {
- $this->dieUsage( 'No such claim' , 'no-such-claim' );
- }
-
- $claim = $claims->getClaimWithGuid( $guid );
- $oldSnak = $claim->getMainSnak();
-
- try {
- $snak = $this->snakConstruction->newSnak(
$oldSnak->getPropertyId(), $snakType, $value );
- $this->snakValidation->validateSnak( $snak );
-
- $claim->setMainSnak( $snak );
- $entity->setClaims( $claims );
-
- return $claim;
- } catch ( IllegalValueException $ex ) {
- $this->dieUsage( $ex->getMessage(), 'invalid-snak' );
- }
- }
-
- /**
- * @since 0.3
- *
- * @param \Wikibase\EntityContent $content
- */
- protected function saveChanges( EntityContent $content ) {
- $status = $this->attemptSaveEntity(
- $content,
- '', // TODO: automcomment
- EDIT_UPDATE
- );
-
- $this->addRevisionIdFromStatusToResult( 'pageinfo',
'lastrevid', $status );
- }
-
- /**
- * @since 0.3
- *
- * @param \Wikibase\Claim $claim
- */
- protected function outputClaim( Claim $claim ) {
- $serializerFactory = new
\Wikibase\Lib\Serializers\SerializerFactory();
- $serializer = $serializerFactory->newSerializerForObject(
$claim );
-
- $serializer->getOptions()->setIndexTags(
$this->getResult()->getIsRawMode() );
-
- $this->getResult()->addValue(
- null,
- 'claim',
- $serializer->getSerialized( $claim )
- );
}
/**
@@ -225,24 +129,27 @@
* @return array
*/
public function getAllowedParams() {
- return array(
- 'claim' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true,
- ),
- 'value' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => false,
- ),
- 'snaktype' => array(
- ApiBase::PARAM_TYPE => array( 'value',
'novalue', 'somevalue' ),
- ApiBase::PARAM_REQUIRED => true,
- ),
- 'token' => null,
- 'baserevid' => array(
- ApiBase::PARAM_TYPE => 'integer',
- ),
- 'bot' => false,
+ return array_merge(
+ parent::getAllowedParams(),
+ array(
+ 'claim' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'value' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => false,
+ ),
+ 'snaktype' => array(
+ ApiBase::PARAM_TYPE => array( 'value',
'novalue', 'somevalue' ),
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'token' => null,
+ 'baserevid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
+ 'bot' => false,
+ )
);
}
@@ -250,43 +157,38 @@
* @see ApiBase::getPossibleErrors()
*/
public function getPossibleErrors() {
- return array_merge( parent::getPossibleErrors(), array(
- array( 'code' => 'invalid-guid', 'info' => $this->msg(
'wikibase-api-invalid-guid' )->text() ),
- array( 'code' => 'no-such-entity', 'info' =>
$this->msg( 'wikibase-api-no-such-entity' )->text() ),
- array( 'code' => 'no-such-claim', 'info' => $this->msg(
'wikibase-api-no-such-claim' )->text() ),
- array( 'code' => 'invalid-snak', 'info' => $this->msg(
'wikibase-api-invalid-snak' )->text() ),
- ) );
+ return array_merge(
+ parent::getPossibleErrors(),
+ $this->claimModificationHelper->getPossibleErrors(),
+ array(
+ array( 'code' => 'no-such-claim', 'info' =>
$this->msg( 'wikibase-api-no-such-claim' )->text() ),
+ )
+ );
}
/**
* @see \ApiBase::getParamDescription
- *
- * @since 0.3
- *
- * @return array
*/
public function getParamDescription() {
- return array(
- 'claim' => 'A GUID identifying the claim',
- 'snaktype' => 'The type of the snak',
- 'value' => 'The value to set the datavalue of the the
main snak of the claim to',
- 'token' => 'An "edittoken" token previously obtained
through the token module (prop=info).',
- 'baserevid' => array( 'The numeric identifier for the
revision to base the modification on.',
- "This is used for detecting conflicts during
save."
- ),
- 'bot' => array( 'Mark this edit as bot',
- 'This URL flag will only be respected if the
user belongs to the group "bot".'
- ),
-
+ return array_merge(
+ parent::getParamDescription(),
+ array(
+ 'claim' => 'A GUID identifying the claim',
+ 'snaktype' => 'The type of the snak',
+ 'value' => 'The value to set the datavalue of
the the main snak of the claim to',
+ 'token' => 'An "edittoken" token previously
obtained through the token module (prop=info).',
+ 'baserevid' => array( 'The numeric identifier
for the revision to base the modification on.',
+ "This is used for detecting conflicts
during save."
+ ),
+ 'bot' => array( 'Mark this edit as bot',
+ 'This URL flag will only be respected
if the user belongs to the group "bot".'
+ ),
+ )
);
}
/**
* @see \ApiBase::getDescription
- *
- * @since 0.3
- *
- * @return string
*/
public function getDescription() {
return array(
@@ -296,44 +198,10 @@
/**
* @see \ApiBase::getExamples
- *
- * @since 0.3
- *
- * @return array
*/
protected function getExamples() {
return array(
'api.php?action=wbsetclaimvalue&claim=q42$D8404CDA-25E4-4334-AF13-A3290BCD9C0F&snaktype=value&value={"entity-type":"item","numeric-id":1}&token=foobar&baserevid=7201010'
=> 'Sets the claim with the GUID of q42$D8404CDA-25E4-4334-AF13-A3290BCD9C0F
to a value of q1',
);
}
-
- /**
- * @see \Wikibase\Api\IAutocomment::getTextForComment()
- */
- public function getTextForComment( array $params, $plural = 1 ) {
- return Autocomment::formatAutoComment(
- $this->getModuleName(),
- array(
- /*plural */ (int)isset( $params['claim'] )
- )
- );
- }
-
- /**
- * @see \Wikibase\Api\IAutocomment::getTextForSummary()
- */
- public function getTextForSummary( array $params ) {
- return Autocomment::formatAutoSummary(
- Autocomment::pickValuesFromParams( $params, 'claim' )
- );
- }
-
- /**
- * @see ApiBase::isWriteMode
- * @return bool true
- */
- public function isWriteMode() {
- return true;
- }
-
}
--
To view, visit https://gerrit.wikimedia.org/r/76725
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I0521a20bf6f600a952831418ebd4ef02bcb3f52f
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits