44 private $contentHandlerFactory;
47 private $pageEditStash;
50 private $revisionLookup;
53 private $statsdDataFactory;
56 private $wikiPageFactory;
76 parent::__construct( $main, $action );
78 $this->contentHandlerFactory = $contentHandlerFactory;
79 $this->pageEditStash = $pageEditStash;
80 $this->revisionLookup = $revisionLookup;
81 $this->statsdDataFactory = $statsdDataFactory;
82 $this->wikiPageFactory = $wikiPageFactory;
89 if ( $user->isBot() ) {
94 $title = $page->getTitle();
97 if ( !$this->contentHandlerFactory
98 ->getContentHandler( $params[
'contentmodel'] )
99 ->isSupportedFormat( $params[
'contentformat'] )
102 [
'apierror-badformat-generic', $params[
'contentformat'], $params[
'contentmodel'] ],
111 if ( $params[
'stashedtexthash'] !==
null ) {
113 $textHash = $params[
'stashedtexthash'];
114 if ( !preg_match(
'/^[0-9a-f]{40}$/', $textHash ) ) {
115 $this->
dieWithError(
'apierror-stashedit-missingtext',
'missingtext' );
117 $text = $this->pageEditStash->fetchInputText( $textHash );
118 if ( !is_string( $text ) ) {
119 $this->
dieWithError(
'apierror-stashedit-missingtext',
'missingtext' );
124 $text = rtrim( str_replace(
"\r\n",
"\n", $params[
'text'] ) );
125 $textHash = sha1( $text );
128 $textContent = $this->contentHandlerFactory
129 ->getContentHandler( $params[
'contentmodel'] )
130 ->unserializeContent( $text, $params[
'contentformat'] );
132 $page = $this->wikiPageFactory->newFromTitle(
$title );
133 if ( $page->exists() ) {
135 $baseRev = $this->revisionLookup->getRevisionByPageId(
140 $this->
dieWithError( [
'apierror-nosuchrevid', $params[
'baserevid'] ] );
142 $currentRev = $page->getRevisionRecord();
143 if ( !$currentRev ) {
144 $this->
dieWithError( [
'apierror-missingrev-pageid', $page->getId() ],
'missingrev' );
147 $editContent = $page->replaceSectionAtRev(
150 $params[
'sectiontitle'],
153 if ( !$editContent ) {
154 $this->
dieWithError(
'apierror-sectionreplacefailed',
'replacefailed' );
156 if ( $currentRev->getId() == $baseRev->getId() ) {
161 $baseContent = $baseRev->getContent( SlotRecord::MAIN );
162 $currentContent = $currentRev->getContent( SlotRecord::MAIN );
163 if ( !$baseContent || !$currentContent ) {
164 $this->
dieWithError( [
'apierror-missingcontent-pageid', $page->getId() ],
'missingrev' );
167 $baseModel = $baseContent->getModel();
168 $currentModel = $currentContent->getModel();
173 $content = $this->contentHandlerFactory
174 ->getContentHandler( $baseModel )
175 ->merge3( $baseContent, $editContent, $currentContent );
176 }
catch ( Exception $e ) {
178 'wrap' => ApiMessage::create(
179 [
'apierror-contentmodel-mismatch', $currentModel, $baseModel ]
196 if ( $user->pingLimiter(
'stashedit' ) ) {
197 $status =
'ratelimited';
199 $updater = $page->newPageUpdater( $user );
200 $status = $this->pageEditStash->parseAndCache( $updater,
$content, $user, $params[
'summary'] );
201 $this->pageEditStash->stashInputText( $text, $textHash );
204 $this->statsdDataFactory->increment(
"editstash.cache_stores.$status" );
206 $ret = [
'status' => $status ];
208 if ( $status !==
'ratelimited' || $params[
'stashedtexthash'] !==
null ) {
209 $ret[
'texthash'] = $textHash;
218 ParamValidator::PARAM_TYPE =>
'string',
219 ParamValidator::PARAM_REQUIRED =>
true
222 ParamValidator::PARAM_TYPE =>
'string',
225 ParamValidator::PARAM_TYPE =>
'string'
228 ParamValidator::PARAM_TYPE =>
'text',
229 ParamValidator::PARAM_DEFAULT => null
231 'stashedtexthash' => [
232 ParamValidator::PARAM_TYPE =>
'string',
233 ParamValidator::PARAM_DEFAULT => null
236 ParamValidator::PARAM_TYPE =>
'string',
237 ParamValidator::PARAM_DEFAULT =>
''
240 ParamValidator::PARAM_TYPE => $this->contentHandlerFactory->getContentModels(),
241 ParamValidator::PARAM_REQUIRED =>
true
244 ParamValidator::PARAM_TYPE => $this->contentHandlerFactory->getAllContentFormats(),
245 ParamValidator::PARAM_REQUIRED =>
true
248 ParamValidator::PARAM_TYPE =>
'integer',
249 ParamValidator::PARAM_REQUIRED =>
true
This abstract class implements many basic API functions, and is the base of all API classes.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
requireOnlyOneParameter( $params,... $required)
Die if none or more than one of a certain set of parameters is set and not false.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
getModuleName()
Get the name of the module being executed by this instance.
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
dieWithException(Throwable $exception, array $options=[])
Abort execution with an error derived from a throwable.
This is the main API class, used for both external and internal processing.
Prepare an edit in shared cache so that it can be reused on edit.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
isInternal()
Indicates whether this module is "internal" Internal API modules are not (yet) intended for 3rd party...
needsToken()
Returns the token type this module requires in order to execute.
isWriteMode()
Indicates whether this module requires write mode.
__construct(ApiMain $main, $action, IContentHandlerFactory $contentHandlerFactory, PageEditStash $pageEditStash, RevisionLookup $revisionLookup, IBufferingStatsdDataFactory $statsdDataFactory, WikiPageFactory $wikiPageFactory)
mustBePosted()
Indicates whether this module must be called with a POST request.
Service for creating WikiPage objects.
Manage the pre-emptive page parsing for edits to wiki pages.
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.