private function propertyMatchesFilter(EntityId $propertyId)
 {
     if (isset($this->requestParams['property'])) {
         try {
             $parsedProperty = $this->idParser->parse($this->requestParams['property']);
         } catch (EntityIdParsingException $e) {
             $this->errorReporter->dieException($e, 'param-invalid');
         }
         /** @var EntityId $parsedProperty */
         return $propertyId->equals($parsedProperty);
     }
     return true;
 }
Example #2
0
 /**
  * Checks if the required parameters are set and the ones that make no sense given the
  * snaktype value are not set.
  *
  * @params array $params
  */
 private function validateParameters(array $params)
 {
     if ($params['snaktype'] === 'value' xor isset($params['value'])) {
         if ($params['snaktype'] === 'value') {
             $this->errorReporter->dieError('A value needs to be provided when creating a claim with PropertyValueSnak snak', 'param-missing');
         } else {
             $this->errorReporter->dieError('You cannot provide a value when creating a claim with no PropertyValueSnak as main snak', 'param-illegal');
         }
     }
     if (!isset($params['property'])) {
         $this->errorReporter->dieError('A property ID needs to be provided when creating a claim with a Snak', 'param-missing');
     }
     if (isset($params['value']) && json_decode($params['value'], true) === null) {
         $this->errorReporter->dieError('Could not decode snak value', 'invalid-snak');
     }
 }
 /**
  * @see ModifyEntity::modifyEntity
  */
 protected function modifyEntity(EntityDocument &$entity, array $params, $baseRevId)
 {
     if (!$entity instanceof FingerprintProvider) {
         $this->errorReporter->dieError('The given entity does not contain aliases', 'no-aliases');
     }
     $summary = $this->createSummary($params);
     $language = $params['language'];
     /** @var ChangeOp[] $aliasesChangeOps */
     $aliasesChangeOps = $this->getChangeOps($params);
     if (count($aliasesChangeOps) == 1) {
         $this->applyChangeOp($aliasesChangeOps[0], $entity, $summary);
     } else {
         $changeOps = new ChangeOps();
         $changeOps->add($aliasesChangeOps);
         $this->applyChangeOp($changeOps, $entity);
         // Set the action to 'set' in case we add and remove aliases in a single edit
         $summary->setAction('set');
         $summary->setLanguage($language);
         // Get the full list of current aliases
         $fingerprint = $entity->getFingerprint();
         $aliases = $fingerprint->hasAliasGroup($language) ? $fingerprint->getAliasGroup($language)->getAliases() : array();
         $summary->addAutoSummaryArgs($aliases);
     }
     $fingerprint = $entity->getFingerprint();
     if ($fingerprint->hasAliasGroup($language)) {
         $aliasGroupList = $fingerprint->getAliasGroups()->getWithLanguages(array($language));
         $this->getResultBuilder()->addAliasGroupList($aliasGroupList, 'entity');
     }
     return $summary;
 }
 private function getEntityIdFromStatementGuid($guid)
 {
     if ($this->guidValidator->validateFormat($guid) === false) {
         $this->errorReporter->dieError('Invalid claim guid', 'invalid-guid');
     }
     return $this->guidParser->parse($guid)->getEntityId()->getSerialization();
 }
Example #5
0
 /**
  * @param string $arrayParam
  *
  * @return array
  */
 private function getArrayFromParam($arrayParam)
 {
     $rawArray = json_decode($arrayParam, true);
     if (!is_array($rawArray) || !count($rawArray)) {
         $this->errorReporter->dieError('No array or invalid JSON given', 'invalid-json');
     }
     return $rawArray;
 }
 /**
  * Load the entity content of the given revision.
  *
  * Will fail by calling dieException() $this->errorReporter if the revision
  * cannot be found or cannot be loaded.
  *
  * @since 0.5
  *
  * @param EntityId $entityId EntityId of the page to load the revision for
  * @param int|string $revId revision to load. If not given, the current revision will be loaded.
  *
  * @throws UsageException
  * @throws LogicException
  *
  * @return EntityRevision
  */
 public function loadEntityRevision(EntityId $entityId, $revId = EntityRevisionLookup::LATEST_FROM_MASTER)
 {
     try {
         $revision = $this->entityRevisionLookup->getEntityRevision($entityId, $revId);
         if (!$revision) {
             $this->errorReporter->dieError('Entity ' . $entityId->getSerialization() . ' not found', 'cant-load-entity-content');
         }
         return $revision;
     } catch (RevisionedUnresolvedRedirectException $ex) {
         $this->errorReporter->dieException($ex, 'unresolved-redirect');
     } catch (BadRevisionException $ex) {
         $this->errorReporter->dieException($ex, 'nosuchrevid');
     } catch (StorageException $ex) {
         $this->errorReporter->dieException($ex, 'cant-load-entity-content');
     }
     throw new LogicException('ApiErrorReporter::dieException did not throw a UsageException');
 }
 /**
  * @param ItemMergeException|RedirectCreationException $ex
  *
  * @throws UsageException always
  */
 private function handleException(Exception $ex)
 {
     $cause = $ex->getPrevious();
     if ($cause) {
         $this->errorReporter->dieException($cause, $ex->getErrorCode());
     } else {
         $this->errorReporter->dieError($ex->getMessage(), $ex->getErrorCode());
     }
 }
 /**
  * @see ModifyEntity::validateParameters
  */
 protected function validateParameters(array $params)
 {
     if ($params['fromsite'] === $params['tosite']) {
         $this->errorReporter->dieError('The from site cannot match the to site', 'param-illegal');
     }
     if ($params['fromtitle'] === '' || $params['totitle'] === '') {
         $this->errorReporter->dieError('The from title and to title must have a value', 'param-illegal');
     }
 }
 /**
  * @see ModifyEntity::modifyEntity
  */
 protected function modifyEntity(EntityDocument &$entity, array $params, $baseRevId)
 {
     if (!$entity instanceof FingerprintProvider) {
         $this->errorReporter->dieError('The given entity does not contain descriptions', 'no-descriptions');
     }
     $summary = $this->createSummary($params);
     $language = $params['language'];
     $changeOp = $this->getChangeOp($params);
     $this->applyChangeOp($changeOp, $entity, $summary);
     $resultBuilder = $this->getResultBuilder();
     if ($entity->getFingerprint()->hasDescription($language)) {
         $termList = $entity->getFingerprint()->getDescriptions()->getWithLanguages(array($language));
         $resultBuilder->addDescriptions($termList, 'entity');
     } else {
         $resultBuilder->addRemovedDescription($language, 'entity');
     }
     return $summary;
 }
 /**
  * Include messages from a Status object in the API call's output.
  *
  * An ApiErrorHandler is used to report the status, if necessary.
  * If $status->isOK() is false, this method will terminate with a UsageException.
  *
  * @param Status $status The status to report
  * @param string  $errorCode The API error code to use in case $status->isOK() returns false
  * @param array   $extradata Additional data to include the the error report,
  *                if $status->isOK() returns false
  * @param int     $httpRespCode the HTTP response code to use in case
  *                $status->isOK() returns false.+
  *
  * @throws UsageException If $status->isOK() returns false.
  */
 private function handleStatus(Status $status, $errorCode, array $extradata = array(), $httpRespCode = 0)
 {
     if ($status->isGood()) {
         return;
     } elseif ($status->isOK()) {
         $this->errorReporter->reportStatusWarnings($status);
     } else {
         $this->errorReporter->reportStatusWarnings($status);
         $this->errorReporter->dieStatus($status, $errorCode, $httpRespCode, $extradata);
     }
 }
 /**
  * @param array $params
  * @param Statement $statement
  *
  * @return string[]
  */
 private function getQualifierHashesFromParams(array $params, Statement $statement)
 {
     $qualifiers = $statement->getQualifiers();
     $hashes = array();
     foreach (array_unique($params['qualifiers']) as $qualifierHash) {
         if (!$qualifiers->hasSnakHash($qualifierHash)) {
             $this->errorReporter->dieError('Invalid snak hash', 'no-such-qualifier');
         }
         $hashes[] = $qualifierHash;
     }
     return $hashes;
 }
 /**
  * @param array $params
  * @param Statement $statement
  *
  * @return string[]
  */
 private function getReferenceHashesFromParams(array $params, Statement $statement)
 {
     $references = $statement->getReferences();
     $hashes = array();
     foreach (array_unique($params['references']) as $referenceHash) {
         if (!$references->hasReferenceHash($referenceHash)) {
             $this->errorReporter->dieError('Invalid reference hash', 'no-such-reference');
         }
         $hashes[] = $referenceHash;
     }
     return $hashes;
 }
 /**
  * @return ChangeOpQualifier
  */
 private function getChangeOp()
 {
     $params = $this->extractRequestParams();
     $guid = $params['claim'];
     $propertyId = $this->modificationHelper->getEntityIdFromString($params['property']);
     if (!$propertyId instanceof PropertyId) {
         $this->errorReporter->dieError($propertyId->getSerialization() . ' does not appear to be a property ID', 'param-illegal');
     }
     $newQualifier = $this->modificationHelper->getSnakInstance($params, $propertyId);
     $snakHash = isset($params['snakhash']) ? $params['snakhash'] : '';
     $changeOp = $this->statementChangeOpFactory->newSetQualifierOp($guid, $newQualifier, $snakHash);
     return $changeOp;
 }
 /**
  * @param array $params
  * @return EntityId[]
  */
 private function getEntityIdsFromIdParam($params)
 {
     $ids = array();
     if (isset($params['ids'])) {
         foreach ($params['ids'] as $id) {
             try {
                 $ids[] = $this->idParser->parse($id);
             } catch (EntityIdParsingException $e) {
                 $this->errorReporter->dieError("Invalid id: {$id}", 'no-such-entity', 0, array('id' => $id));
             }
         }
     }
     return $ids;
 }
 /**
  * @param string $json A JSON-encoded DataValue
  *
  * @throws UsageException
  * @throws LogicException
  * @return DataValue
  */
 private function decodeDataValue($json)
 {
     $data = json_decode($json, true);
     if (!is_array($data)) {
         $this->errorReporter->dieError('Failed to decode datavalue', 'baddatavalue');
     }
     try {
         $value = $this->dataValueFactory->newFromArray($data);
         return $value;
     } catch (IllegalValueException $ex) {
         $this->errorReporter->dieException($ex, 'baddatavalue');
     }
     throw new LogicException('ApiErrorReporter::dieException did not throw a UsageException');
 }
Example #16
0
 /**
  * @param StatementList $statements
  * @param string[] $requiredGuids
  */
 private function assertStatementListContainsGuids(StatementList $statements, array $requiredGuids)
 {
     $existingGuids = array();
     /** @var Statement $statement */
     foreach ($statements as $statement) {
         $guid = $statement->getGuid();
         // This array is used as a HashSet where only the keys are used.
         $existingGuids[$guid] = null;
     }
     // Not using array_diff but array_diff_key does have a huge performance impact.
     $missingGuids = array_diff_key(array_flip($requiredGuids), $existingGuids);
     if (!empty($missingGuids)) {
         $this->errorReporter->dieError('Statement(s) with GUID(s) ' . implode(', ', array_keys($missingGuids)) . ' not found', 'invalid-guid');
     }
 }
 /**
  * @param string|null $optionsParam
  *
  * @return ParserOptions
  */
 private function getOptionsObject($optionsParam)
 {
     $parserOptions = new ParserOptions();
     $parserOptions->setOption(ValueParser::OPT_LANG, $this->getLanguage()->getCode());
     if (is_string($optionsParam) && $optionsParam !== '') {
         $options = json_decode($optionsParam, true);
         if (!is_array($options)) {
             $this->errorReporter->dieError('Malformed options parameter', 'malformed-options');
         }
         foreach ($options as $name => $value) {
             $parserOptions->setOption($name, $value);
         }
     }
     return $parserOptions;
 }
Example #18
0
 /**
  * @param array $params
  *
  * @throws IllegalValueException
  * @throws UsageException
  * @throws LogicException
  * @return Statement
  */
 private function getClaimFromParams(array $params)
 {
     try {
         $serializedStatement = json_decode($params['claim'], true);
         if (!is_array($serializedStatement)) {
             throw new IllegalValueException('Failed to get statement from Serialization');
         }
         $claim = $this->statementDeserializer->deserialize($serializedStatement);
         if (!$claim instanceof Statement) {
             throw new IllegalValueException('Failed to get statement from Serialization');
         }
         return $claim;
     } catch (InvalidArgumentException $invalidArgumentException) {
         $this->errorReporter->dieError('Failed to get claim from claim Serialization ' . $invalidArgumentException->getMessage(), 'invalid-claim');
     } catch (OutOfBoundsException $outOfBoundsException) {
         $this->errorReporter->dieError('Failed to get claim from claim Serialization ' . $outOfBoundsException->getMessage(), 'invalid-claim');
     }
     // Note: since dieUsage() never returns, this should be unreachable!
     throw new LogicException('ApiErrorReporter::dieError did not throw an exception');
 }
Example #19
0
 /**
  * @see ApiBase::execute()
  *
  * @since 0.1
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $user = $this->getUser();
     $this->flags = 0;
     $this->validateParameters($params);
     // 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']);
         $entityRevId = 0;
         // HACK: We need to assign an ID early, for things like the ClaimIdGenerator.
         if ($entity->getId() === null) {
             $this->getEntityStore()->assignFreshId($entity);
         }
     } else {
         $entity = $entityRev->getEntity();
         $entityRevId = $entityRev->getRevisionId();
     }
     if ($entity->getId() === null) {
         throw new LogicException('The Entity should have an ID at this point!');
     }
     // At this point only change/edit rights should be checked
     $status = $this->checkPermissions($entity, $user);
     if (!$status->isOK()) {
         $this->errorReporter->dieError('You do not have sufficient permissions', 'permissiondenied');
     }
     $summary = $this->modifyEntity($entity, $params, $entityRevId);
     if (!$summary) {
         //XXX: This could rather be used for "silent" failure, i.e. in cases where
         //     there was simply nothing to do.
         $this->errorReporter->dieError('Attempted modification of the item failed', 'failed-modify');
     }
     $this->addFlags($entity->getId() === null);
     //NOTE: EDIT_NEW will not be set automatically. If the entity doesn't exist, and EDIT_NEW was
     //      not added to $this->flags explicitly, the save will fail.
     $status = $this->attemptSaveEntity($entity, $summary, $this->flags);
     $this->addToOutput($entity, $status, $entityRevId);
 }
 /**
  * @param array $params
  *
  * @return ChangeOpSiteLink
  */
 private function getChangeOp(array $params)
 {
     if ($this->shouldRemove($params)) {
         $linksite = $this->stringNormalizer->trimToNFC($params['linksite']);
         return $this->siteLinkChangeOpFactory->newRemoveSiteLinkOp($linksite);
     } else {
         $linksite = $this->stringNormalizer->trimToNFC($params['linksite']);
         $sites = $this->siteLinkTargetProvider->getSiteList($this->siteLinkGroups);
         $site = $sites->getSite($linksite);
         if ($site === false) {
             $this->errorReporter->dieError('The supplied site identifier was not recognized', 'not-recognized-siteid');
         }
         if (isset($params['linktitle'])) {
             $page = $site->normalizePageName($this->stringNormalizer->trimWhitespace($params['linktitle']));
             if ($page === false) {
                 $this->errorReporter->dieMessage('no-external-page', $linksite, $params['linktitle']);
             }
         } else {
             $page = null;
         }
         $badges = isset($params['badges']) ? $this->parseSiteLinkBadges($params['badges']) : null;
         return $this->siteLinkChangeOpFactory->newSetSiteLinkOp($linksite, $page, $badges);
     }
 }
Example #21
0
 /**
  * @param array $params
  */
 private function validateParameters(array $params)
 {
     if (!$this->modificationHelper->validateStatementGuid($params['claim'])) {
         $this->errorReporter->dieError('Invalid claim guid', 'invalid-guid');
     }
 }
Example #22
0
 /**
  * @see ModifyEntity::createEntity
  */
 protected function createEntity($entityType)
 {
     $this->errorReporter->dieError('Could not find an existing entity', 'no-such-entity');
 }
 /**
  * @param string $type
  * @param mixed $value
  * @param string $message
  */
 private function assertType($type, $value, $message)
 {
     if (gettype($value) !== $type) {
         $this->errorReporter->dieError($message, 'not-recognized-' . $type);
     }
 }
 /**
  * @dataProvider warningProvider
  */
 public function testReportStatusWarnings(Status $status, array $expectedDataFields)
 {
     $api = new ApiMain();
     $localizer = $this->getExceptionLocalizer();
     $reporter = new ApiErrorReporter($api, $localizer, Language::factory('de'));
     $reporter->reportStatusWarnings($status);
     $result = $api->getResult()->getResultData();
     foreach ($expectedDataFields as $path => $value) {
         $path = explode('/', $path);
         $this->assertValueAtPath($value, $path, $result);
     }
 }