/** * @param PropertyId $propertyId * @param User $user User to attribute the changes made to. * @param string $dataTypeId * * @throws InvalidArgumentException * @throws StorageException */ public function changeDataType(PropertyId $propertyId, User $user, $dataTypeId) { $entityRevision = $this->entityRevisionLookup->getEntityRevision($propertyId, EntityRevisionLookup::LATEST_FROM_MASTER); if ($entityRevision === null) { throw new StorageException("Could not load property: " . $propertyId->getSerialization()); } /* @var $property Property */ $property = $entityRevision->getEntity(); $oldDataTypeId = $property->getDataTypeId(); $this->assertDataTypesCompatible($oldDataTypeId, $dataTypeId); $property->setDataTypeId($dataTypeId); $this->entityStore->saveEntity($property, 'Changed data type from ' . $oldDataTypeId . ' to ' . $dataTypeId, $user, EDIT_UPDATE, $entityRevision->getRevisionId()); }
/** * @param string[] $labels Associative array, mapping language codes to labels. * * @return bool true if the item was created, false otherwise */ private function createProperty(array $labels) { $property = Property::newFromType('wikibase-item'); $fingerprint = $property->getFingerprint(); foreach ($labels as $languageCode => $label) { $fingerprint->setLabel($languageCode, $label); } try { $this->store->saveEntity($property, 'imported', $this->user, EDIT_NEW); return true; } catch (Exception $ex) { $this->doPrint('ERROR: ' . str_replace("\n", ' ', $ex->getMessage())); } return false; }
private function saveEntity(Entity $entity, Summary $summary, $bot) { // Given we already check all constraints in ChangeOpsMerge, it's // fine to ignore them here. This is also needed to not run into // the constraints we're supposed to ignore (see ChangeOpsMerge::removeConflictsWithEntity // for reference) $flags = EDIT_UPDATE | EntityContent::EDIT_IGNORE_CONSTRAINTS; if ($bot && $this->user->isAllowed('bot')) { $flags |= EDIT_FORCE_BOT; } try { return $this->entityStore->saveEntity($entity, $this->summaryFormatter->formatSummary($summary), $this->user, $flags); } catch (StorageException $ex) { throw new ItemMergeException($ex->getMessage(), 'failed-save', $ex); } }
/** * Attempts to save the new entity content, chile first checking for permissions, edit conflicts, etc. * * @param string $summary The edit summary. * @param int $flags The EDIT_XXX flags as used by WikiPage::doEditContent(). * Additionally, the EntityContent::EDIT_XXX constants can be used. * @param string|bool $token Edit token to check, or false to disable the token check. * Null will fail the token text, as will the empty string. * @param bool|null $watch Whether the user wants to watch the entity. * Set to null to apply default according to getWatchDefault(). * * @throws ReadOnlyError * @return Status Indicates success and provides detailed warnings or error messages. See * getStatus() for more details. * @see WikiPage::doEditContent */ public function attemptSave($summary, $flags, $token, $watch = null) { if (wfReadOnly()) { throw new ReadOnlyError(); } if ($watch === null) { $watch = $this->getWatchDefault(); } $this->status = Status::newGood(); $this->errorType = 0; if ($token !== false && !$this->isTokenOK($token)) { //@todo: This is redundant to the error code set in isTokenOK(). // We should figure out which error codes the callers expect, // and only set the correct error code, in one place, probably here. $this->errorType |= self::TOKEN_ERROR; $this->status->fatal('sessionfailure'); $this->status->setResult(false, array('errorFlags' => $this->errorType)); return $this->status; } $this->checkEditPermissions(); $this->checkRateLimits(); // modifies $this->status if (!$this->status->isOK()) { $this->status->setResult(false, array('errorFlags' => $this->errorType)); return $this->status; } //NOTE: Make sure the latest revision is loaded and cached. // Would happen on demand anyway, but we want a well-defined point at which "latest" is frozen // to a specific revision, just before the first check for edit conflicts. $this->getLatestRevision(); $this->getLatestRevisionId(); $this->applyPreSaveChecks(); // modifies $this->status if (!$this->status->isOK()) { $this->errorType |= self::PRECONDITION_FAILED; } if (!$this->status->isOK()) { $this->status->setResult(false, array('errorFlags' => $this->errorType)); return $this->status; } $hookStatus = $this->editFilterHookRunner->run($this->newEntity, $this->user, $summary); if (!$hookStatus->isOK()) { $this->errorType |= self::FILTERED; } $this->status->merge($hookStatus); if (!$this->status->isOK()) { $this->status->setResult(false, array('errorFlags' => $this->errorType)); return $this->status; } try { $entityRevision = $this->entityStore->saveEntity($this->newEntity, $summary, $this->user, $flags | EDIT_AUTOSUMMARY, $this->doesCheckForEditConflicts() ? $this->getLatestRevisionId() : false); $editStatus = Status::newGood(array('revision' => $entityRevision)); } catch (StorageException $ex) { $editStatus = $ex->getStatus(); if ($editStatus === null) { // XXX: perhaps internalerror_info isn't the best, but we need some generic error message. $editStatus = Status::newFatal('internalerror_info', $ex->getMessage()); } $this->errorType |= self::SAVE_ERROR; } $this->status->setResult($editStatus->isOK(), $editStatus->getValue()); $this->status->merge($editStatus); if ($this->status->isOK()) { $this->updateWatchlist($watch); } else { $value = $this->status->getValue(); $value['errorFlags'] = $this->errorType; $this->status->setResult(false, $value); } return $this->status; }