MediaWiki 1.40.4
SpecialChangeContentModel.php
Go to the documentation of this file.
1<?php
2
13
15
17 private $contentHandlerFactory;
18
20 private $contentModelChangeFactory;
21
23 private $spamChecker;
24
26 private $revisionLookup;
27
29 private $wikiPageFactory;
30
32 private $searchEngineFactory;
33
42 public function __construct(
43 IContentHandlerFactory $contentHandlerFactory,
44 ContentModelChangeFactory $contentModelChangeFactory,
45 SpamChecker $spamChecker,
46 RevisionLookup $revisionLookup,
47 WikiPageFactory $wikiPageFactory,
48 SearchEngineFactory $searchEngineFactory
49 ) {
50 parent::__construct( 'ChangeContentModel', 'editcontentmodel' );
51
52 $this->contentHandlerFactory = $contentHandlerFactory;
53 $this->contentModelChangeFactory = $contentModelChangeFactory;
54 $this->spamChecker = $spamChecker;
55 $this->revisionLookup = $revisionLookup;
56 $this->wikiPageFactory = $wikiPageFactory;
57 $this->searchEngineFactory = $searchEngineFactory;
58 }
59
60 public function doesWrites() {
61 return true;
62 }
63
67 private $title;
68
74 private $oldRevision;
75
76 protected function setParameter( $par ) {
77 $par = $this->getRequest()->getVal( 'pagetitle', $par );
78 $title = Title::newFromText( $par );
79 if ( $title ) {
80 $this->title = $title;
81 $this->par = $title->getPrefixedText();
82 } else {
83 $this->par = '';
84 }
85 }
86
87 protected function postHtml() {
88 $text = '';
89 if ( $this->title ) {
90 $contentModelLogPage = new LogPage( 'contentmodel' );
91 $text = Xml::element( 'h2', null, $contentModelLogPage->getName()->text() );
92 $out = '';
93 LogEventsList::showLogExtract( $out, 'contentmodel', $this->title );
94 $text .= $out;
95 }
96 return $text;
97 }
98
99 protected function getDisplayFormat() {
100 return 'ooui';
101 }
102
103 protected function alterForm( HTMLForm $form ) {
104 $this->addHelpLink( 'Help:ChangeContentModel' );
105
106 if ( $this->title ) {
107 $form->setFormIdentifier( 'modelform' );
108 } else {
109 $form->setFormIdentifier( 'titleform' );
110 }
111
112 // T120576
113 $form->setSubmitTextMsg( 'changecontentmodel-submit' );
114
115 if ( $this->title ) {
116 $this->getOutput()->addBacklinkSubtitle( $this->title );
117 }
118 }
119
120 public function validateTitle( $title ) {
121 // Already validated by HTMLForm, but if not, throw
122 // an exception instead of a fatal
123 $titleObj = Title::newFromTextThrow( $title );
124
125 $this->oldRevision = $this->revisionLookup->getRevisionByTitle( $titleObj ) ?: false;
126
127 if ( $this->oldRevision ) {
128 $oldContent = $this->oldRevision->getContent( SlotRecord::MAIN );
129 if ( !$oldContent->getContentHandler()->supportsDirectEditing() ) {
130 return $this->msg( 'changecontentmodel-nodirectediting' )
131 ->params( ContentHandler::getLocalizedName( $oldContent->getModel() ) )
132 ->escaped();
133 }
134 }
135
136 return true;
137 }
138
139 protected function getFormFields() {
140 $fields = [
141 'pagetitle' => [
142 'type' => 'title',
143 'creatable' => true,
144 'name' => 'pagetitle',
145 'default' => $this->par,
146 'label-message' => 'changecontentmodel-title-label',
147 'validation-callback' => [ $this, 'validateTitle' ],
148 ],
149 ];
150 if ( $this->title ) {
151 $options = $this->getOptionsForTitle( $this->title );
152 if ( empty( $options ) ) {
153 throw new ErrorPageError(
154 'changecontentmodel-emptymodels-title',
155 'changecontentmodel-emptymodels-text',
156 [ $this->title->getPrefixedText() ]
157 );
158 }
159 $fields['pagetitle']['readonly'] = true;
160 $fields += [
161 'currentmodel' => [
162 'type' => 'text',
163 'name' => 'currentcontentmodel',
164 'default' => $this->title->getContentModel(),
165 'label-message' => 'changecontentmodel-current-label',
166 'readonly' => true
167 ],
168 'model' => [
169 'type' => 'select',
170 'name' => 'model',
171 'options' => $options,
172 'label-message' => 'changecontentmodel-model-label'
173 ],
174 'reason' => [
175 'type' => 'text',
176 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
177 'name' => 'reason',
178 'validation-callback' => function ( $reason ) {
179 if ( $reason === null || $reason === '' ) {
180 // Null on form display, or no reason given
181 return true;
182 }
183
184 $match = $this->spamChecker->checkSummary( $reason );
185
186 if ( $match ) {
187 return $this->msg( 'spamprotectionmatch', $match )->parse();
188 }
189
190 return true;
191 },
192 'label-message' => 'changecontentmodel-reason-label',
193 ],
194 ];
195 }
196
197 return $fields;
198 }
199
200 private function getOptionsForTitle( Title $title = null ) {
201 $models = $this->contentHandlerFactory->getContentModels();
202 $options = [];
203 foreach ( $models as $model ) {
204 $handler = $this->contentHandlerFactory->getContentHandler( $model );
205 if ( !$handler->supportsDirectEditing() ) {
206 continue;
207 }
208 if ( $title ) {
209 if ( $title->getContentModel() === $model ) {
210 continue;
211 }
212 if ( !$handler->canBeUsedOn( $title ) ) {
213 continue;
214 }
215 }
216 $options[ContentHandler::getLocalizedName( $model )] = $model;
217 }
218
219 return $options;
220 }
221
222 public function onSubmit( array $data ) {
223 $this->title = Title::newFromText( $data['pagetitle'] );
224 $page = $this->wikiPageFactory->newFromTitle( $this->title );
225
226 $changer = $this->contentModelChangeFactory->newContentModelChange(
227 $this->getContext()->getAuthority(),
228 $page,
229 $data['model']
230 );
231
232 $permissionStatus = $changer->authorizeChange();
233 if ( !$permissionStatus->isGood() ) {
234 $out = $this->getOutput();
235 $wikitext = $out->formatPermissionStatus( $permissionStatus );
236 // Hack to get our wikitext parsed
237 return Status::newFatal( new RawMessage( '$1', [ $wikitext ] ) );
238 }
239
240 // Can also throw a ThrottledError, don't catch it
241 $status = $changer->doContentModelChange(
242 $this->getContext(),
243 $data['reason'],
244 true
245 );
246
247 return $status;
248 }
249
250 public function onSuccess() {
251 $out = $this->getOutput();
252 $out->setPageTitle( $this->msg( 'changecontentmodel-success-title' ) );
253 $out->addWikiMsg( 'changecontentmodel-success-text', $this->title );
254 }
255
264 public function prefixSearchSubpages( $search, $limit, $offset ) {
265 return $this->prefixSearchString( $search, $limit, $offset, $this->searchEngineFactory );
266 }
267
268 protected function getGroupName() {
269 return 'pagetools';
270 }
271}
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
An error page which can definitely be safely rendered using the OutputPage.
Special page which uses an HTMLForm to handle processing.
string null $par
The sub-page of the special page.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:153
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setFormIdentifier( $ident)
Set an internal identifier for this form.
Class to simplify the use of log pages.
Definition LogPage.php:41
Handle database storage of comments such as edit summaries and log reasons.
Service to check if text (either content or a summary) qualifies as spam.
Variant of the Message class.
Service for creating WikiPage objects.
Page revision base class.
Value object representing a content slot associated with a page revision.
Represents a title within MediaWiki.
Definition Title.php:82
getContentModel( $flags=0)
Get the page's content model id, see the CONTENT_MODEL_XXX constants.
Definition Title.php:1121
getPrefixedText()
Get the prefixed title with spaces.
Definition Title.php:1923
Factory class for SearchEngine.
setParameter( $par)
Maybe do something interesting with the subpage parameter.
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getFormFields()
Get an HTMLForm descriptor array.
getDisplayFormat()
Get display format for the form.
doesWrites()
Indicates whether this special page may perform database writes.
onSubmit(array $data)
Process the form on submission.
postHtml()
Add post-HTML to the form.
__construct(IContentHandlerFactory $contentHandlerFactory, ContentModelChangeFactory $contentModelChangeFactory, SpamChecker $spamChecker, RevisionLookup $revisionLookup, WikiPageFactory $wikiPageFactory, SearchEngineFactory $searchEngineFactory)
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
getOutput()
Get the OutputPage being used for this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getRequest()
Get the WebRequest being used for this instance.
prefixSearchString( $search, $limit, $offset, SearchEngineFactory $searchEngineFactory=null)
Perform a regular substring search for prefixSearchSubpages.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Service for changing the content model of wiki pages.
Service for looking up page revisions.
return true
Definition router.php:92