68 parent::__construct( $main, $action );
70 $this->contentHandlerFactory = $contentHandlerFactory;
71 $this->pageEditStash = $pageEditStash;
72 $this->revisionLookup = $revisionLookup;
73 $this->stats = $statsFactory;
74 $this->wikiPageFactory = $wikiPageFactory;
75 $this->tempUserCreator = $tempUserCreator;
76 $this->userFactory = $userFactory;
83 if ( $user->isBot() ) {
88 $title = $page->getTitle();
91 if ( !$this->contentHandlerFactory
92 ->getContentHandler( $params[
'contentmodel'] )
93 ->isSupportedFormat( $params[
'contentformat'] )
96 [
'apierror-badformat-generic', $params[
'contentformat'], $params[
'contentmodel'] ],
103 if ( $params[
'stashedtexthash'] !==
null ) {
105 $textHash = $params[
'stashedtexthash'];
106 if ( !preg_match(
'/^[0-9a-f]{40}$/', $textHash ) ) {
107 $this->
dieWithError(
'apierror-stashedit-missingtext',
'missingtext' );
109 $text = $this->pageEditStash->fetchInputText( $textHash );
110 if ( !is_string( $text ) ) {
111 $this->
dieWithError(
'apierror-stashedit-missingtext',
'missingtext' );
116 $text = rtrim( str_replace(
"\r\n",
"\n", $params[
'text'] ) );
117 $textHash = sha1( $text );
120 $textContent = $this->contentHandlerFactory
121 ->getContentHandler( $params[
'contentmodel'] )
122 ->unserializeContent( $text, $params[
'contentformat'] );
124 $page = $this->wikiPageFactory->newFromTitle( $title );
125 if ( $page->exists() ) {
127 $baseRev = $this->revisionLookup->getRevisionByPageId(
132 $this->
dieWithError( [
'apierror-nosuchrevid', $params[
'baserevid'] ] );
134 $currentRev = $page->getRevisionRecord();
135 if ( !$currentRev ) {
136 $this->
dieWithError( [
'apierror-missingrev-pageid', $page->getId() ],
'missingrev' );
139 $editContent = $page->replaceSectionAtRev(
142 $params[
'sectiontitle'],
145 if ( !$editContent ) {
146 $this->
dieWithError(
'apierror-sectionreplacefailed',
'replacefailed' );
148 if ( $currentRev->getId() == $baseRev->getId() ) {
150 $content = $editContent;
153 $baseContent = $baseRev->getContent( SlotRecord::MAIN );
154 $currentContent = $currentRev->getContent( SlotRecord::MAIN );
155 if ( !$baseContent || !$currentContent ) {
156 $this->
dieWithError( [
'apierror-missingcontent-pageid', $page->getId() ],
'missingrev' );
159 $baseModel = $baseContent->getModel();
160 $currentModel = $currentContent->getModel();
165 $content = $this->contentHandlerFactory
166 ->getContentHandler( $baseModel )
167 ->merge3( $baseContent, $editContent, $currentContent );
168 }
catch ( Exception $e ) {
171 [
'apierror-contentmodel-mismatch', $currentModel, $baseModel ]
179 $content = $textContent;
188 if ( !$user->authorizeWrite(
'stashedit', $title ) ) {
189 $status =
'ratelimited';
191 $user = $this->getUserForPreview();
192 $updater = $page->newPageUpdater( $user );
193 $status = $this->pageEditStash->parseAndCache( $updater, $content, $user, $params[
'summary'] );
194 $this->pageEditStash->stashInputText( $text, $textHash );
197 $this->stats->getCounter(
'editstash_cache_stores_total' )
198 ->setLabel(
'status', $status )
199 ->copyToStatsdAt(
"editstash.cache_stores.$status" )
202 $ret = [
'status' => $status ];
204 if ( $status !==
'ratelimited' || $params[
'stashedtexthash'] !==
null ) {
205 $ret[
'texthash'] = $textHash;
211 private function getUserForPreview() {
213 if ( $this->tempUserCreator->shouldAutoCreate( $user,
'edit' ) ) {
214 return $this->userFactory->newUnsavedTempUser(
215 $this->tempUserCreator->getStashedName( $this->getRequest()->getSession() )
224 ParamValidator::PARAM_TYPE =>
'string',
225 ParamValidator::PARAM_REQUIRED => true
228 ParamValidator::PARAM_TYPE =>
'string',
231 ParamValidator::PARAM_TYPE =>
'string'
234 ParamValidator::PARAM_TYPE =>
'text',
235 ParamValidator::PARAM_DEFAULT => null
237 'stashedtexthash' => [
238 ParamValidator::PARAM_TYPE =>
'string',
239 ParamValidator::PARAM_DEFAULT => null
242 ParamValidator::PARAM_TYPE =>
'string',
243 ParamValidator::PARAM_DEFAULT =>
''
246 ParamValidator::PARAM_TYPE => $this->contentHandlerFactory->getContentModels(),
247 ParamValidator::PARAM_REQUIRED => true
250 ParamValidator::PARAM_TYPE => $this->contentHandlerFactory->getAllContentFormats(),
251 ParamValidator::PARAM_REQUIRED => true
254 ParamValidator::PARAM_TYPE =>
'integer',
255 ParamValidator::PARAM_REQUIRED => true
277 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Stashedit';
282class_alias( ApiStashEdit::class,
'ApiStashEdit' );
This is the main API class, used for both external and internal processing.
Service for creating WikiPage objects.
Manage the pre-emptive page parsing for edits to wiki pages.