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' => [
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 ) {
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' );
176 [
'class' =>
'mw-datatable sortable mw-tags-table' ],
182 function doTagRow( $tag, $hitcount, $showManageActions, $showDeleteActions, $showEditLinks ) {
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();
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 ) {
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 );
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();
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'] = [
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'] = [
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" ],
463 } elseif (
$status->isOK() && $form->tagAction ===
'delete' ) {
465 $out->addWikiTextAsInterface( $this->
msg(
'tags-delete-warnings-after-delete', $tag,
466 count(
$status->getWarningsArray() ) )->text() .
"\n" .
471 $out->wrapWikiTextAsInterface(
'error',
$status->getWikitext() );