49 parent::__construct(
'Tags' );
78 $out->setPageTitle( $this->
msg(
'tags-title' ) );
79 $out->wrapWikiMsg(
"<div class='mw-tags-intro'>\n$1\n</div>",
'tags-intro' );
82 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
83 $userCanManage = $permissionManager->userHasRight( $user,
'managechangetags' );
84 $userCanDelete = $permissionManager->userHasRight( $user,
'deletechangetags' );
85 $userCanEditInterface = $permissionManager->userHasRight( $user,
'editinterface' );
88 if ( $userCanManage ) {
92 'label' => $this->
msg(
'tags-create-tag-name' )->plain(),
97 'label' => $this->
msg(
'tags-create-reason' )->plain(),
100 'IgnoreWarnings' => [
105 $form = HTMLForm::factory(
'ooui', $fields, $this->
getContext() );
106 $form->setAction( $this->
getPageTitle(
'create' )->getLocalURL() );
107 $form->setWrapperLegendMsg(
'tags-create-heading' );
108 $form->setHeaderText( $this->
msg(
'tags-create-explanation' )->parseAsBlock() );
109 $form->setSubmitCallback( [ $this,
'processCreateTagForm' ] );
110 $form->setSubmitTextMsg(
'tags-create-submit' );
120 if ( $out->getRedirect() !==
'' ) {
129 $this->explicitlyDefinedTags = array_fill_keys(
131 $this->softwareDefinedTags = array_fill_keys(
135 $definedTags = array_keys( $this->explicitlyDefinedTags + $this->softwareDefinedTags );
138 if ( !$tagStats && !$definedTags ) {
143 $thead = Xml::tags(
'tr',
null, Xml::tags(
'th',
null, $this->
msg(
'tags-tag' )->parse() ) .
144 Xml::tags(
'th',
null, $this->
msg(
'tags-display-header' )->parse() ) .
145 Xml::tags(
'th',
null, $this->
msg(
'tags-description-header' )->parse() ) .
146 Xml::tags(
'th',
null, $this->
msg(
'tags-source-header' )->parse() ) .
147 Xml::tags(
'th',
null, $this->
msg(
'tags-active-header' )->parse() ) .
148 Xml::tags(
'th',
null, $this->
msg(
'tags-hitcount-header' )->parse() ) .
149 ( ( $userCanManage || $userCanDelete ) ?
150 Xml::tags(
'th', [
'class' =>
'unsortable' ],
151 $this->
msg(
'tags-actions-header' )->parse() ) :
157 $this->softwareActivatedTags = array_fill_keys(
161 foreach ( $tagStats as $tag => $hitcount ) {
162 $tbody .= $this->
doTagRow( $tag, $hitcount, $userCanManage,
163 $userCanDelete, $userCanEditInterface );
166 foreach ( $definedTags as $tag ) {
167 if ( !isset( $tagStats[$tag] ) ) {
168 $tbody .= $this->
doTagRow( $tag, 0, $userCanManage, $userCanDelete, $userCanEditInterface );
172 $out->addModuleStyles(
'jquery.tablesorter.styles' );
173 $out->addModules(
'jquery.tablesorter' );
174 $out->addHTML( Xml::tags(
176 [
'class' =>
'mw-datatable sortable mw-tags-table' ],
177 Xml::tags(
'thead',
null, $thead ) .
178 Xml::tags(
'tbody',
null, $tbody )
182 function doTagRow( $tag, $hitcount, $showManageActions, $showDeleteActions, $showEditLinks ) {
184 $newRow .= Xml::tags(
'td',
null, Xml::element(
'code',
null, $tag ) );
188 if ( $showEditLinks ) {
191 $this->
msg(
"tag-$tag" )->inContentLanguage()->
getTitle(),
192 $this->
msg(
'tags-edit' )->text()
194 $disp .= $this->
msg(
'parentheses' )->rawParams( $editLink )->escaped();
196 $newRow .= Xml::tags(
'td',
null, $disp );
198 $msg = $this->
msg(
"tag-$tag-description" );
199 $desc = !$msg->exists() ?
'' : $msg->parse();
200 if ( $showEditLinks ) {
203 $this->
msg(
"tag-$tag-description" )->inContentLanguage()->
getTitle(),
204 $this->
msg(
'tags-edit' )->text()
206 $desc .= $this->
msg(
'parentheses' )->rawParams( $editDescLink )->escaped();
208 $newRow .= Xml::tags(
'td',
null, $desc );
211 $isSoftware = isset( $this->softwareDefinedTags[$tag] );
212 $isExplicit = isset( $this->explicitlyDefinedTags[$tag] );
215 $sourceMsgs[] = $this->
msg(
'tags-source-extension' )->escaped();
218 $sourceMsgs[] = $this->
msg(
'tags-source-manual' )->escaped();
220 if ( !$sourceMsgs ) {
221 $sourceMsgs[] = $this->
msg(
'tags-source-none' )->escaped();
223 $newRow .= Xml::tags(
'td',
null, implode( Xml::element(
'br' ), $sourceMsgs ) );
225 $isActive = $isExplicit || isset( $this->softwareActivatedTags[$tag] );
226 $activeMsg = ( $isActive ?
'tags-active-yes' :
'tags-active-no' );
227 $newRow .= Xml::tags(
'td',
null, $this->
msg( $activeMsg )->escaped() );
229 $hitcountLabelMsg = $this->
msg(
'tags-hitcount' )->numParams( $hitcount );
230 if ( $this->
getConfig()->
get(
'UseTagFilter' ) ) {
233 $hitcountLabelMsg->text(),
235 [
'tagfilter' => $tag ]
238 $hitcountLabel = $hitcountLabelMsg->escaped();
242 $newRow .= Xml::tags(
'td', [
'data-sort-value' => $hitcount ], $hitcountLabel );
249 $this->
msg(
'tags-delete' )->text(),
254 if ( $showManageActions ) {
258 $this->
msg(
'tags-activate' )->text(),
266 $this->
msg(
'tags-deactivate' )->text(),
272 if ( $showDeleteActions || $showManageActions ) {
273 $newRow .= Xml::tags(
'td',
null, $this->
getLanguage()->pipeList( $actionLinks ) );
276 return Xml::tags(
'tr',
null, $newRow ) .
"\n";
283 $tag = trim( strval( $data[
'Tag'] ) );
284 $ignoreWarnings = isset( $data[
'IgnoreWarnings'] ) && $data[
'IgnoreWarnings'] ===
'1';
286 $context->getUser(), $ignoreWarnings );
288 if ( $status->isGood() ) {
291 } elseif ( $status->isOK() ) {
296 'default' => $data[
'Tag'],
300 'default' => $data[
'Reason'],
302 'IgnoreWarnings' => [
310 $context->getRequest()->unsetVal(
'wpEditToken' );
312 $headerText = $this->
msg(
'tags-create-warnings-above', $tag,
313 count( $status->getWarningsArray() ) )->parseAsBlock() .
314 $out->parseAsInterface( $status->getWikiText() ) .
315 $this->
msg(
'tags-create-warnings-below' )->parseAsBlock();
317 $subform = HTMLForm::factory(
'ooui', $fields, $this->
getContext() );
318 $subform->setAction( $this->
getPageTitle(
'create' )->getLocalURL() );
319 $subform->setWrapperLegendMsg(
'tags-create-heading' );
320 $subform->setHeaderText( $headerText );
321 $subform->setSubmitCallback( [ $this,
'processCreateTagForm' ] );
322 $subform->setSubmitTextMsg(
'htmlform-yes' );
328 $out->wrapWikiTextAsInterface(
'error', $status->getWikiText() );
335 if ( !MediaWikiServices::getInstance()
337 ->userHasRight( $user,
'deletechangetags' ) ) {
342 $out->setPageTitle( $this->
msg(
'tags-delete-title' ) );
347 if ( !$canDeleteResult->isGood() ) {
348 $out->wrapWikiTextAsInterface(
'error', $canDeleteResult->getWikiText() );
349 if ( !$canDeleteResult->isOK() ) {
354 $preText = $this->
msg(
'tags-delete-explanation-initial', $tag )->parseAsBlock();
356 if ( isset( $tagUsage[$tag] ) && $tagUsage[$tag] > 0 ) {
357 $preText .= $this->
msg(
'tags-delete-explanation-in-use', $tag,
358 $tagUsage[$tag] )->parseAsBlock();
360 $preText .= $this->
msg(
'tags-delete-explanation-warning', $tag )->parseAsBlock();
363 $this->softwareActivatedTags = array_fill_keys(
365 if ( isset( $this->softwareActivatedTags[$tag] ) ) {
366 $preText .= $this->
msg(
'tags-delete-explanation-active', $tag )->parseAsBlock();
370 $fields[
'Reason'] = [
372 'label' => $this->
msg(
'tags-delete-reason' )->plain(),
375 $fields[
'HiddenTag'] = [
382 $form = HTMLForm::factory(
'ooui', $fields, $this->
getContext() );
383 $form->setAction( $this->
getPageTitle(
'delete' )->getLocalURL() );
385 $form->tagAction =
'delete';
386 $form->setSubmitCallback( [ $this,
'processTagForm' ] );
387 $form->setSubmitTextMsg(
'tags-delete-submit' );
388 $form->setSubmitDestructive();
389 $form->addPreText( $preText );
394 $actionStr = $activate ?
'activate' :
'deactivate';
397 if ( !MediaWikiServices::getInstance()
399 ->userHasRight( $user,
'managechangetags' ) ) {
405 $out->setPageTitle( $this->
msg(
"tags-$actionStr-title" ) );
409 $func = $activate ?
'canActivateTag' :
'canDeactivateTag';
410 $result = ChangeTags::$func( $tag, $user );
411 if ( !$result->isGood() ) {
412 $out->wrapWikiTextAsInterface(
'error', $result->getWikiText() );
413 if ( !$result->isOK() ) {
419 $preText = $this->
msg(
"tags-$actionStr-question", $tag )->parseAsBlock();
423 $fields[
'Reason'] = [
425 'label' => $this->
msg(
"tags-$actionStr-reason" )->plain(),
428 $fields[
'HiddenTag'] = [
435 $form = HTMLForm::factory(
'ooui', $fields, $this->
getContext() );
436 $form->setAction( $this->
getPageTitle( $actionStr )->getLocalURL() );
438 $form->tagAction = $actionStr;
439 $form->setSubmitCallback( [ $this,
'processTagForm' ] );
441 $form->setSubmitTextMsg(
"tags-$actionStr-submit" );
442 $form->addPreText( $preText );
456 $tag = $data[
'HiddenTag'];
457 $status = call_user_func( [ ChangeTags::class,
"{$form->tagAction}TagWithChecks" ],
458 $tag, $data[
'Reason'],
$context->getUser(),
true );
460 if ( $status->isGood() ) {
463 } elseif ( $status->isOK() && $form->tagAction ===
'delete' ) {
465 $out->addWikiTextAsInterface( $this->
msg(
'tags-delete-warnings-after-delete', $tag,
466 count( $status->getWarningsArray() ) )->text() .
"\n" .
467 $status->getWikitext() );
471 $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.
getUser()
Shortcut to get the User executing 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.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
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.
MediaWiki Linker LinkRenderer null $linkRenderer