/** * @param EntityRedirect $redirect * @param Summary $summary * @param bool $bot Whether the edit should be marked as bot * * @throws RedirectCreationException */ private function saveRedirect(EntityRedirect $redirect, Summary $summary, $bot) { $summary = $this->summaryFormatter->formatSummary($summary); $flags = EDIT_UPDATE; if ($bot) { $flags = $flags | EDIT_FORCE_BOT; } $hookStatus = $this->editFilterHookRunner->run($redirect, $this->user, $summary); if (!$hookStatus->isOK()) { throw new RedirectCreationException('EditFilterHook stopped redirect creation', 'cant-redirect'); } try { $this->entityStore->saveRedirect($redirect, $summary, $this->user, $flags); } catch (StorageException $ex) { throw new RedirectCreationException($ex->getMessage(), 'cant-redirect', $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; }