47 parent::__construct(
'Tags' );
76 $out->setPageTitle( $this->
msg(
'tags-title' ) );
77 $out->wrapWikiMsg(
"<div class='mw-tags-intro'>\n$1\n</div>",
'tags-intro' );
80 $userCanManage = $authority->isAllowed(
'managechangetags' );
81 $userCanDelete = $authority->isAllowed(
'deletechangetags' );
82 $userCanEditInterface = $authority->isAllowed(
'editinterface' );
85 if ( $userCanManage ) {
89 'label' => $this->
msg(
'tags-create-tag-name' )->plain(),
94 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
95 'label' => $this->
msg(
'tags-create-reason' )->plain(),
103 HTMLForm::factory(
'ooui', $fields, $this->
getContext() )
104 ->setAction( $this->
getPageTitle(
'create' )->getLocalURL() )
105 ->setWrapperLegendMsg(
'tags-create-heading' )
106 ->setHeaderText( $this->
msg(
'tags-create-explanation' )->parseAsBlock() )
107 ->setSubmitCallback( [ $this,
'processCreateTagForm' ] )
108 ->setSubmitTextMsg(
'tags-create-submit' )
118 if ( $out->getRedirect() !==
'' ) {
127 $this->explicitlyDefinedTags = array_fill_keys(
129 $this->softwareDefinedTags = array_fill_keys(
133 $definedTags = array_keys( $this->explicitlyDefinedTags + $this->softwareDefinedTags );
136 if ( !$tagStats && !$definedTags ) {
141 $thead = Xml::tags(
'tr',
null, Xml::tags(
'th',
null, $this->
msg(
'tags-tag' )->parse() ) .
142 Xml::tags(
'th',
null, $this->
msg(
'tags-display-header' )->parse() ) .
143 Xml::tags(
'th',
null, $this->
msg(
'tags-description-header' )->parse() ) .
144 Xml::tags(
'th',
null, $this->
msg(
'tags-source-header' )->parse() ) .
145 Xml::tags(
'th',
null, $this->
msg(
'tags-active-header' )->parse() ) .
146 Xml::tags(
'th',
null, $this->
msg(
'tags-hitcount-header' )->parse() ) .
147 ( ( $userCanManage || $userCanDelete ) ?
148 Xml::tags(
'th', [
'class' =>
'unsortable' ],
149 $this->
msg(
'tags-actions-header' )->parse() ) :
155 $this->softwareActivatedTags = array_fill_keys(
159 foreach ( $tagStats as $tag => $hitcount ) {
160 $tbody .= $this->
doTagRow( $tag, $hitcount, $userCanManage,
161 $userCanDelete, $userCanEditInterface );
164 foreach ( $definedTags as $tag ) {
165 if ( !isset( $tagStats[$tag] ) ) {
166 $tbody .= $this->
doTagRow( $tag, 0, $userCanManage, $userCanDelete, $userCanEditInterface );
170 $out->addModuleStyles( [
171 'jquery.tablesorter.styles',
172 'mediawiki.pager.tablePager'
174 $out->addModules(
'jquery.tablesorter' );
175 $out->addHTML( Xml::tags(
177 [
'class' =>
'mw-datatable sortable mw-tags-table' ],
178 Xml::tags(
'thead',
null, $thead ) .
179 Xml::tags(
'tbody',
null, $tbody )
184 $tag, $hitcount, $showManageActions, $showDeleteActions, $showEditLinks
187 $newRow .= Xml::tags(
'td',
null, Xml::element(
'code',
null, $tag ) );
191 if ( $disp ===
false ) {
192 $disp = Xml::element(
'em',
null, $this->
msg(
'tags-hidden' )->text() );
194 if ( $showEditLinks ) {
197 $this->
msg(
"tag-$tag" )->inContentLanguage()->
getTitle(),
198 $this->
msg(
'tags-edit' )->text(),
200 [
'action' =>
'edit' ]
202 $disp .= $this->
msg(
'parentheses' )->rawParams( $editLink )->escaped();
204 $newRow .= Xml::tags(
'td',
null, $disp );
206 $msg = $this->
msg(
"tag-$tag-description" );
207 $desc = !$msg->exists() ?
'' : $msg->parse();
208 if ( $showEditLinks ) {
211 $this->
msg(
"tag-$tag-description" )->inContentLanguage()->
getTitle(),
212 $this->
msg(
'tags-edit' )->text(),
214 [
'action' =>
'edit' ]
216 $desc .= $this->
msg(
'parentheses' )->rawParams( $editDescLink )->escaped();
218 $newRow .= Xml::tags(
'td',
null, $desc );
221 $isSoftware = isset( $this->softwareDefinedTags[$tag] );
222 $isExplicit = isset( $this->explicitlyDefinedTags[$tag] );
225 $sourceMsgs[] = $this->
msg(
'tags-source-extension' )->escaped();
228 $sourceMsgs[] = $this->
msg(
'tags-source-manual' )->escaped();
230 if ( !$sourceMsgs ) {
231 $sourceMsgs[] = $this->
msg(
'tags-source-none' )->escaped();
233 $newRow .= Xml::tags(
'td',
null, implode( Xml::element(
'br' ), $sourceMsgs ) );
235 $isActive = $isExplicit || isset( $this->softwareActivatedTags[$tag] );
236 $activeMsg = ( $isActive ?
'tags-active-yes' :
'tags-active-no' );
237 $newRow .= Xml::tags(
'td',
null, $this->
msg( $activeMsg )->escaped() );
239 $hitcountLabelMsg = $this->
msg(
'tags-hitcount' )->numParams( $hitcount );
240 if ( $this->
getConfig()->
get(
'UseTagFilter' ) ) {
243 $hitcountLabelMsg->text(),
245 [
'tagfilter' => $tag ]
248 $hitcountLabel = $hitcountLabelMsg->escaped();
252 $newRow .= Xml::tags(
'td', [
'data-sort-value' => $hitcount ], $hitcountLabel );
259 $this->
msg(
'tags-delete' )->text(),
264 if ( $showManageActions ) {
268 $this->
msg(
'tags-activate' )->text(),
276 $this->
msg(
'tags-deactivate' )->text(),
282 if ( $showDeleteActions || $showManageActions ) {
283 $newRow .= Xml::tags(
'td',
null, $this->
getLanguage()->pipeList( $actionLinks ) );
286 return Xml::tags(
'tr',
null, $newRow ) .
"\n";
291 $out = $context->getOutput();
293 $tag = trim( strval( $data[
'Tag'] ) );
294 $ignoreWarnings = isset( $data[
'IgnoreWarnings'] ) && $data[
'IgnoreWarnings'] ===
'1';
296 $context->getUser(), $ignoreWarnings );
298 if ( $status->isGood() ) {
301 } elseif ( $status->isOK() ) {
306 'default' => $data[
'Tag'],
310 'default' => $data[
'Reason'],
312 'IgnoreWarnings' => [
320 $context->getRequest()->unsetVal(
'wpEditToken' );
322 $headerText = $this->
msg(
'tags-create-warnings-above', $tag,
323 count( $status->getWarningsArray() ) )->parseAsBlock() .
324 $out->parseAsInterface( $status->getWikiText() ) .
325 $this->
msg(
'tags-create-warnings-below' )->parseAsBlock();
327 HTMLForm::factory(
'ooui', $fields, $this->
getContext() )
328 ->setAction( $this->
getPageTitle(
'create' )->getLocalURL() )
329 ->setWrapperLegendMsg(
'tags-create-heading' )
330 ->setHeaderText( $headerText )
331 ->setSubmitCallback( [ $this,
'processCreateTagForm' ] )
332 ->setSubmitTextMsg(
'htmlform-yes' )
338 $out->wrapWikiTextAsInterface(
'error', $status->getWikiText() );
345 if ( !$authority->isAllowed(
'deletechangetags' ) ) {
350 $out->setPageTitle( $this->
msg(
'tags-delete-title' ) );
355 if ( !$canDeleteResult->isGood() ) {
356 $out->wrapWikiTextAsInterface(
'error', $canDeleteResult->getWikiText() );
357 if ( !$canDeleteResult->isOK() ) {
362 $preText = $this->
msg(
'tags-delete-explanation-initial', $tag )->parseAsBlock();
364 if ( isset( $tagUsage[$tag] ) && $tagUsage[$tag] > 0 ) {
365 $preText .= $this->
msg(
'tags-delete-explanation-in-use', $tag,
366 $tagUsage[$tag] )->parseAsBlock();
368 $preText .= $this->
msg(
'tags-delete-explanation-warning', $tag )->parseAsBlock();
371 $this->softwareActivatedTags = array_fill_keys(
373 if ( isset( $this->softwareActivatedTags[$tag] ) ) {
374 $preText .= $this->
msg(
'tags-delete-explanation-active', $tag )->parseAsBlock();
378 $fields[
'Reason'] = [
380 'label' => $this->
msg(
'tags-delete-reason' )->plain(),
383 $fields[
'HiddenTag'] = [
390 HTMLForm::factory(
'ooui', $fields, $this->
getContext() )
391 ->setAction( $this->
getPageTitle(
'delete' )->getLocalURL() )
392 ->setSubmitCallback(
function ( $data, $form ) {
395 ->setSubmitTextMsg(
'tags-delete-submit' )
396 ->setSubmitDestructive()
397 ->addPreText( $preText )
402 $actionStr = $activate ?
'activate' :
'deactivate';
405 if ( !$authority->isAllowed(
'managechangetags' ) ) {
411 $out->setPageTitle( $this->
msg(
"tags-$actionStr-title" ) );
420 if ( !$result->isGood() ) {
421 $out->wrapWikiTextAsInterface(
'error', $result->getWikiText() );
422 if ( !$result->isOK() ) {
428 $preText = $this->
msg(
"tags-$actionStr-question", $tag )->parseAsBlock();
432 $fields[
'Reason'] = [
434 'label' => $this->
msg(
"tags-$actionStr-reason" )->plain(),
437 $fields[
'HiddenTag'] = [
444 HTMLForm::factory(
'ooui', $fields, $this->
getContext() )
445 ->setAction( $this->
getPageTitle( $actionStr )->getLocalURL() )
446 ->setSubmitCallback(
function ( $data, $form ) use ( $actionStr ) {
450 ->setSubmitTextMsg(
"tags-$actionStr-submit" )
451 ->addPreText( $preText )
463 $out = $context->getOutput();
465 $tag = $data[
'HiddenTag'];
467 $status = call_user_func( [ ChangeTags::class,
"{$action}TagWithChecks" ],
468 $tag, $data[
'Reason'], $context->getUser(),
true );
470 if ( $status->isGood() ) {
473 } elseif ( $status->isOK() && $action ===
'delete' ) {
475 $out->addWikiTextAsInterface( $this->
msg(
'tags-delete-warnings-after-delete', $tag,
476 count( $status->getWarningsArray() ) )->text() .
"\n" .
477 $status->getWikitext() );
481 $out->wrapWikiTextAsInterface(
'error', $status->getWikitext() );
getContext()
Get the base IContextSource object.
Show an error when a user tries to do something they do not have the necessary permissions for.
Parent class for all special pages.
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.
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.
LinkRenderer null $linkRenderer
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
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.