39 private $submitClicked;
57 private $permissionManager;
65 parent::__construct(
'EditTags',
'changetags' );
67 $this->permissionManager = $permissionManager;
85 $output->addModules( [
'mediawiki.special.edittags' ] );
86 $output->addModuleStyles( [
87 'mediawiki.interface.helpers.styles',
91 $this->submitClicked = $request->wasPosted() && $request->getBool(
'wpSubmit' );
94 $ids = $request->getVal(
'ids' );
95 if ( $ids !==
null ) {
97 $this->ids = explode(
',', $ids );
100 $this->ids = array_keys( $request->getArray(
'ids', [] ) );
102 $this->ids = array_unique( array_filter( $this->ids ) );
105 if ( count( $this->ids ) == 0 ) {
106 throw new ErrorPageError(
'tags-edit-nooldid-title',
'tags-edit-nooldid-text' );
109 $this->typeName = $request->getVal(
'type' );
110 $this->targetObj = Title::newFromText( $request->getText(
'target' ) );
112 switch ( $this->typeName ) {
115 $this->typeName =
'logentry';
118 $this->typeName =
'revision';
126 $this->typeName ===
'revision' ?
'revision' :
'logging',
131 $this->reason = $request->getVal(
'wpReason',
'' );
133 if ( $this->targetObj ===
null ) {
134 $output->addWikiMsg(
'undelete-header' );
139 $checkReplica = !$this->submitClicked;
141 $this->permissionManager->isBlockedFrom(
151 $this->getLanguage(),
160 if ( $this->submitClicked ) {
167 $tagLogPage =
new LogPage(
'tag' );
168 $output->addHTML(
"<h2>" . $tagLogPage->getName()->escaped() .
"</h2>\n" );
174 [
'lim' => 25,
'conds' => [],
'useMaster' => $this->wasSaved ]
183 if ( $this->targetObj ) {
185 $this->
getSkin()->setRelevantTitle( $this->targetObj );
189 $links[] = $linkRenderer->makeKnownLink(
191 $this->
msg(
'viewpagelogs' )->text(),
194 'page' => $this->targetObj->getPrefixedText(),
195 'wpfilters' => [
'tag' ],
198 if ( !$this->targetObj->isSpecialPage() ) {
200 $links[] = $linkRenderer->makeKnownLink(
202 $this->
msg(
'pagehist' )->text(),
204 [
'action' =>
'history' ]
208 $links[] = $linkRenderer->makeKnownLink(
210 $this->
msg(
'tags-edit-manage-link' )->text()
222 if ( $this->revList ===
null ) {
224 $this->targetObj, $this->ids );
227 return $this->revList;
237 $out->wrapWikiMsg(
"<strong>$1</strong>", [
238 "tags-edit-{$this->typeName}-selected",
239 $this->
getLanguage()->formatNum( count( $this->ids ) ),
240 $this->targetObj->getPrefixedText()
244 $out->addHTML(
"<ul>" );
249 for ( $list->reset(); $list->current(); $list->next() ) {
250 $item = $list->current();
251 if ( !$item->canView() ) {
252 throw new ErrorPageError(
'permissionserrors',
'tags-update-no-permission' );
255 $out->addHTML( $item->getHTML() );
258 if ( !$numRevisions ) {
259 throw new ErrorPageError(
'tags-edit-nooldid-title',
'tags-edit-nooldid-text' );
262 $out->addHTML(
"</ul>" );
264 $out->wrapWikiMsg(
'<p>$1</p>',
"tags-edit-{$this->typeName}-explanation" );
268 'action' => $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] ),
269 'id' =>
'mw-revdel-form-revisions' ] ) .
271 count( $this->ids ) )->text() ) .
275 '<td class="mw-label">' .
276 Xml::label( $this->
msg(
'tags-edit-reason' )->text(),
'wpReason' ) .
278 '<td class="mw-input">' .
284 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
289 '<td class="mw-submit">' .
291 $numRevisions )->text(), [
'name' =>
'wpSubmit' ] ) .
295 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() ) .
296 Html::hidden(
'target', $this->targetObj->getPrefixedText() ) .
297 Html::hidden(
'type', $this->typeName ) .
298 Html::hidden(
'ids', implode(
',', $this->ids ) ) .
302 $out->addHTML( $form );
312 if ( $list->length() == 1 ) {
314 $tags = $list->current()->getTags();
316 $tags = explode(
',', $tags );
321 $html =
'<table id="mw-edittags-tags-selector">';
322 $html .=
'<tr><td>' . $this->
msg(
'tags-edit-existing-tags' )->escaped() .
325 $html .= $this->
getLanguage()->commaList( array_map(
'htmlspecialchars', $tags ) );
327 $html .= $this->
msg(
'tags-edit-existing-tags-none' )->parse();
329 $html .=
'</td></tr>';
330 $tagSelect = $this->
getTagSelect( $tags, $this->
msg(
'tags-edit-new-tags' )->plain() );
331 $html .=
'<tr><td>' . $tagSelect[0] .
'</td><td>' . $tagSelect[1];
336 for ( $list->reset(); $list->current(); $list->next() ) {
337 $currentTags = $list->current()->getTags();
338 if ( $currentTags ) {
339 $tags = array_merge( $tags, explode(
',', $currentTags ) );
342 $tags = array_unique( $tags );
344 $html =
'<table id="mw-edittags-tags-selector-multi"><tr><td>';
345 $tagSelect = $this->
getTagSelect( [], $this->
msg(
'tags-edit-add' )->plain() );
346 $html .=
'<p>' . $tagSelect[0] .
'</p>' . $tagSelect[1] .
'</td><td>';
347 $html .=
Xml::element(
'p',
null, $this->
msg(
'tags-edit-remove' )->plain() );
349 'wpRemoveAllTags',
'mw-edittags-remove-all' );
351 foreach ( $tags as $tag ) {
353 'wpTagsToRemove[]',
'mw-edittags-remove-' . $i++,
false, [
355 'class' =>
'mw-edittags-remove-checkbox',
362 $html .= Html::hidden(
'wpExistingTags', implode(
',', $tags ) );
363 $html .=
'</td></tr></table>';
382 $result[0] =
Xml::label( $label,
'mw-edittags-tag-list' );
384 $select =
new XmlSelect(
'wpTagList[]',
'mw-edittags-tag-list', $selectedTags );
385 $select->setAttribute(
'multiple',
'multiple' );
386 $select->setAttribute(
'size',
'8' );
389 $tags = array_unique( array_merge( $tags, $selectedTags ) );
392 $select->addOptions( array_combine( $tags, $tags ) );
394 $result[1] = $select->getHTML();
405 $token = $request->getVal(
'wpEditToken' );
406 if ( $this->submitClicked && !$this->
getUser()->matchEditToken( $token ) ) {
407 $this->
getOutput()->addWikiMsg(
'sessionfailure' );
412 $tagList = $request->getArray(
'wpTagList' ) ?? [];
413 $existingTags = $request->getVal(
'wpExistingTags' );
414 if ( $existingTags ===
null || $existingTags ===
'' ) {
417 $existingTags = explode(
',', $existingTags );
420 if ( count( $this->ids ) > 1 ) {
422 $tagsToAdd = $tagList;
423 if ( $request->getBool(
'wpRemoveAllTags' ) ) {
424 $tagsToRemove = $existingTags;
426 $tagsToRemove = $request->getArray(
'wpTagsToRemove', [] );
432 $tagsToAdd = array_diff( $tagList, $existingTags );
433 $tagsToRemove = array_diff( $existingTags, $tagList );
436 if ( !$tagsToAdd && !$tagsToRemove ) {
439 $status = $this->
getList()->updateChangeTagsOnAll( $tagsToAdd,
440 $tagsToRemove,
null, $this->reason, $this->
getAuthority() );
443 if ( $status->isGood() ) {
457 $out->setPageTitle( $this->
msg(
'actioncomplete' ) );
459 Html::successBox( $out->msg(
'tags-edit-success' )->parse() )
461 $this->wasSaved =
true;
462 $this->revList->reloadFromPrimary();
473 $out->setPageTitle( $this->
msg(
'actionfailed' ) );
476 $out->parseAsContent(
477 $status->getWikiText(
'tags-edit-failure',
false, $this->getLanguage() )
485 return $this->
msg(
'tags-edit-title' )->text();
An error page which can definitely be safely rendered using the OutputPage.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Class to simplify the use of log pages.
static suggestTarget( $typeName, $target, array $ids)
Suggest a target for the revision deletion.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
getSkin()
Shortcut to get the skin being used for this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
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.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getPageTitle( $subpage=false)
Get a self-referential title object.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Shortcut to construct a special page which is unlisted by default.
Show an error when the user tries to do something whilst blocked.
Class for generating HTML <select> or <datalist> elements.
static closeElement( $element)
Shortcut to close an XML element.
static label( $label, $id, $attribs=[])
Convenience function to build an HTML form label.
static openElement( $element, $attribs=null)
This opens an XML element.
static input( $name, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field.
static submitButton( $value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
static checkLabel( $label, $name, $id, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox with a label.
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
static fieldset( $legend=false, $content=false, $attribs=[])
Shortcut for creating fieldsets.