Tobias Gritschacher has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/76725


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

Change-Id: I0521a20bf6f600a952831418ebd4ef02bcb3f52f
---
M repo/Wikibase.classes.php
M repo/includes/api/CreateClaim.php
A repo/includes/api/ModifyClaim.php
M repo/includes/api/SetClaimValue.php
4 files changed, 357 insertions(+), 428 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/25/76725/1

diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index 795b7c0..cd9e0b0 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -97,6 +97,7 @@
                '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',
 
                // includes/content
                'Wikibase\EntityContent' => 
'includes/content/EntityContent.php',
diff --git a/repo/includes/api/CreateClaim.php 
b/repo/includes/api/CreateClaim.php
index 884ddb9..ed6cdfb 100644
--- a/repo/includes/api/CreateClaim.php
+++ b/repo/includes/api/CreateClaim.php
@@ -3,24 +3,21 @@
 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\Claims;
+use Wikibase\ChangeOpClaim;
+use Wikibase\Property;
 use Wikibase\Summary;
 use Wikibase\Snak;
 use Wikibase\Validators\ValidatorErrorLocalizer;
+use DataValues\IllegalValueException;
+use InvalidArgumentException;
+use ValueParsers\ParseException;
 
 /**
  * API module for creating claims.
@@ -48,9 +45,9 @@
  * @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 {
 
        /**
         * @var SnakValidationHelper
@@ -86,105 +83,33 @@
                $params = $this->extractRequestParams();
                $this->validateParameters( $params );
 
-               $entityContent = $this->getEntityContent();
+               $entityId = EntityId::newFromPrefixedId( $params['entity'] );
+               $entityContent = $this->getEntityContent( $entityId );
+               $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.
+               $entityIdParser = 
WikibaseRepo::getDefaultInstance()->getEntityIdParser();
+
                try {
-                       $snak = $this->getSnakInstance();
-
-                       $this->snakValidation->validateSnak( $snak );
-
-                       $claim = $this->addClaim( $entityContent->getEntity(), 
$snak );
-                       $summary = $this->createSummary( $snak, 'create' );
-
-                       $this->saveChanges( $entityContent, $summary );
-
-                       $this->outputClaim( $claim );
-
+                       $propertyId = $entityIdParser->parse( 
$params['property'] );
+               } catch ( ParseException $parseException ) {
+                       wfProfileOut( __METHOD__ );
+                       $this->dieUsage( 'Invalid property ID: ParseException', 
'invalid-guid' );
                }
-               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' );
-               }
+
+               $snak = $this->getSnakInstance( $params, $propertyId );
+               $this->snakValidation->validateSnak( $snak );
+
+               $summary = $this->createSummary( $params );
+               $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->outputClaim( $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 +117,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 +133,79 @@
                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() ),
+               return array_merge(
+                       parent::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() ),
-                       array( 'code' => 'no-such-entity', 'info' => 
$this->msg( 'wikibase-api-no-such-entity' )->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 +215,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..dac9807
--- /dev/null
+++ b/repo/includes/api/ModifyClaim.php
@@ -0,0 +1,213 @@
+<?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, with common functionality
+ * for creating summaries.
+ *
+ * @todo decide if this is really needed or not
+ *
+ * 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
+        */
+       protected function saveChanges( EntityContent $content, Summary 
$summary ) {
+               $status = $this->attemptSaveEntity(
+                       $content,
+                       $summary->toString(),
+                       EDIT_UPDATE
+               );
+
+               $this->addRevisionIdFromStatusToResult( 'pageinfo', 
'lastrevid', $status );
+       }
+
+       /**
+        * @since 0.4
+        *
+        * @param Claim $claim
+        */
+       protected function outputClaim( Claim $claim ) {
+               $serializerFactory = new SerializerFactory();
+               $serializer = $serializerFactory->newSerializerForObject( 
$claim );
+               $serializer->getOptions()->setIndexTags( 
$this->getResult()->getIsRawMode() );
+
+               $this->getResult()->addValue(
+                       null,
+                       'claim',
+                       $serializer->getSerialized( $claim )
+               );
+       }
+
+       /**
+        * @since 0.4
+        *
+        * @param EntityId $entityId
+        *
+        * @return \Wikibase\EntityContent
+        */
+       protected function getEntityContent( EntityId $entityId ) {
+               $params = $this->extractRequestParams();
+               $baseRevisionId = isset( $params['baserevid'] ) ? intval( 
$params['baserevid'] ) : null;
+               $entityTitle = 
EntityContentFactory::singleton()->getTitleForId( $entityId );
+
+               if ( $entityTitle === null ) {
+                       $this->dieUsage( 'No such entity' , 'no-such-entity' );
+               }
+
+               return $this->loadEntityContent( $entityTitle, $baseRevisionId 
);
+       }
+
+       /**
+        * @since 0.4
+        *
+        * @param array $params
+        * @param EntityId $propertyId
+        *
+        * @return \Wikibase\Snak
+        *
+        * @throws ParseException
+        * @throws IllegalValueException
+        */
+       protected function getSnakInstance( $params, EntityId $propertyId ) {
+               $valueData = null;
+               if ( isset( $params['value'] ) ) {
+                       $valueData = \FormatJson::decode( $params['value'], 
true );
+                       if ( $valueData === null ) {
+                               $this->dieUsage( 'Could not decode snak value', 
'invalid-snak' );
+                       }
+               }
+
+               $factory = 
WikibaseRepo::getDefaultInstance()->getSnakConstructionService();
+
+               if ( $propertyId->getEntityType() !== Property::ENTITY_TYPE ) {
+                       $this->dieUsage( 'Property expected, got ' . 
$propertyId->getEntityType(), 'invalid-snak' );
+               }
+
+               try {
+                       $snak = $factory->newSnak( $propertyId, 
$params['snaktype'], $valueData );
+               }
+               catch ( IllegalValueException $ex ) {
+                       wfProfileOut( __METHOD__ );
+                       $this->dieUsage( 'Invalid snak: IllegalValueException', 
'invalid-snak' );
+               }
+               catch ( InvalidArgumentException $ex ) {
+                       // shouldn't happen, but might.
+                       wfProfileOut( __METHOD__ );
+                       $this->dieUsage( 'Invalid snak: 
InvalidArgumentException', 'invalid-snak' );
+               }
+
+               return $snak;
+       }
+
+       /**
+        * Create a new Summary instance suitable for representing the action 
performed by this module.
+        *
+        * @since 0.4
+        *
+        * @param array $params
+        *
+        * @return Summary
+        */
+       protected function createSummary( array $params ) {
+               $summary = new Summary( $this->getModuleName() );
+               if ( isset( $params['summary'] ) ) {
+                       $summary->setUserSummary( $params['summary'] );
+               }
+               return $summary;
+       }
+
+       /**
+        * @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::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' => 'invalid-snak', 'info' => 
$this->msg( 'wikibase-api-invalid-snak' )->text() ),
+                       )
+               );
+       }
+
+       /**
+        * @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..8d5a187 100644
--- a/repo/includes/api/SetClaimValue.php
+++ b/repo/includes/api/SetClaimValue.php
@@ -3,24 +3,20 @@
 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;
+use Wikibase\Validators\SnakValidator;
+use Wikibase\Summary;
+use DataValues\IllegalValueException;
 
 /**
  * API module for setting the DataValue contained by the main snak of a claim.
@@ -47,18 +43,14 @@
  *
  * @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
         */
        protected $snakValidation;
-
-       /**
-        * @var SnakConstructionService
-        */
-       protected $snakConstruction;
 
        /**
         * see ApiBase::__construct()
@@ -76,8 +68,6 @@
                        
WikibaseRepo::getDefaultInstance()->getDataTypeFactory(),
                        new ValidatorErrorLocalizer()
                );
-
-               $this->snakConstruction = 
WikibaseRepo::getDefaultInstance()->getSnakConstructionService();
        }
 
        /**
@@ -88,45 +78,39 @@
        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 = EntityId::newFromPrefixedId( 
Entity::getIdFromClaimGuid( $params['claim'] ) );
+               $entityContent = $this->getEntityContent( $entityId );
+               $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->getSnakInstance( $params, 
$claim->getMainSnak()->getPropertyId() );
+
+               $summary = $this->createSummary( $params );
+               $changeOp = new ChangeOpClaim( $claimGuid, $snak, 
WikibaseRepo::getDefaultInstance()->getIdFormatter() );
+               $changeOp->apply( $entity, $summary );
+
+               $this->saveChanges( $entityContent, $summary );
+
+               $this->outputClaim( $claim );
 
                wfProfileOut( __METHOD__ );
        }
 
        /**
-        * @since 0.3
-        *
-        * @return \Wikibase\EntityContent
+        * @since 0.4
+        * 
+        * @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,
+                       )
                );
        }
 
@@ -251,42 +158,33 @@
         */
        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() ),
                ) );
        }
 
        /**
         * @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 +194,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: newchange
Gerrit-Change-Id: I0521a20bf6f600a952831418ebd4ef02bcb3f52f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Tobias Gritschacher <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to