47 'mw-contentmodelchange',
49 'mw-removed-redirect',
50 'mw-changed-redirect-target',
81 wfWarn(
'wgSoftwareTags should be associative array of enabled tags.
82 Please refer to documentation for the list of tags you can enable' );
86 $availableSoftwareTags = !$all ?
90 $softwareTags = array_intersect(
91 $availableSoftwareTags,
92 self::$definedSoftwareTags
112 if ( $tags ===
'' || $tags ===
null ) {
116 $localizer = RequestContext::getMain();
121 $tags = explode(
',', $tags );
123 foreach ( $tags as $tag ) {
127 $classes[] = Sanitizer::escapeClass(
"mw-tag-$tag" );
129 if ( $description ===
false ) {
132 $displayTags[] = Xml::tags(
134 [
'class' =>
'mw-tag-marker ' .
135 Sanitizer::escapeClass(
"mw-tag-marker-$tag" ) ],
140 if ( !$displayTags ) {
141 return [
'', $classes ];
144 $markers = $localizer->msg(
'tag-list-wrapper' )
145 ->numParams( count( $displayTags ) )
146 ->rawParams( implode(
' ', $displayTags ) )
148 $markers = Xml::tags(
'span', [
'class' =>
'mw-tag-markers' ], $markers );
150 return [ $markers, $classes ];
167 $msg = $context->
msg(
"tag-$tag" );
168 if ( !$msg->exists() ) {
175 ->inLanguage( $msg->getLanguage() );
178 if ( $msg->isDisabled() ) {
202 return $msg ? $msg->parse() :
false;
218 $msg = $context->
msg(
"tag-$tag-description" );
219 if ( !$msg->exists() ) {
222 if ( $msg->isDisabled() ) {
247 if ( !$originalDesc ) {
251 $taglessDesc = Sanitizer::stripAllTags( $originalDesc->parse() );
253 return $context->
getLanguage()->truncateForVisual( $taglessDesc, $length );
270 public static function addTags( $tags, $rc_id =
null, $rev_id =
null,
273 $result =
self::updateTags( $tags,
null, $rc_id, $rev_id, $log_id, $params, $rc );
274 return (
bool)$result[0];
307 public static function updateTags( $tagsToAdd, $tagsToRemove, &$rc_id =
null,
308 &$rev_id =
null, &$log_id =
null, $params =
null,
RecentChange $rc =
null,
311 $tagsToAdd = array_filter(
313 static function ( $value ) {
314 return ( $value ??
'' ) !==
'';
317 $tagsToRemove = array_filter(
318 (array)$tagsToRemove,
319 static function ( $value ) {
320 return ( $value ??
'' ) !==
'';
324 if ( !$rc_id && !$rev_id && !$log_id ) {
325 throw new MWException(
'At least one of: RCID, revision ID, and log ID MUST be ' .
326 'specified when adding or removing a tag from a change!' );
337 $rc_id = $dbw->selectField(
338 [
'logging',
'recentchanges' ],
342 'rc_timestamp = log_timestamp',
347 } elseif ( $rev_id ) {
348 $rc_id = $dbw->selectField(
349 [
'revision',
'recentchanges' ],
353 'rc_this_oldid = rev_id'
358 } elseif ( !$log_id && !$rev_id ) {
360 $log_id = $dbw->selectField(
363 [
'rc_id' => $rc_id ],
366 $rev_id = $dbw->selectField(
369 [
'rc_id' => $rc_id ],
374 if ( $log_id && !$rev_id ) {
375 $rev_id = $dbw->selectField(
378 [
'ls_field' =>
'associated_rev_id',
'ls_log_id' => $log_id ],
381 } elseif ( !$log_id && $rev_id ) {
382 $log_id = $dbw->selectField(
385 [
'ls_field' =>
'associated_rev_id',
'ls_value' => (
string)$rev_id ],
393 $tagsToAdd = array_values( array_diff( $tagsToAdd, $prevTags ) );
394 $newTags = array_unique( array_merge( $prevTags, $tagsToAdd ) );
397 $tagsToRemove = array_values( array_intersect( $tagsToRemove, $newTags ) );
398 $newTags = array_values( array_diff( $newTags, $tagsToRemove ) );
402 if ( $prevTags == $newTags ) {
403 return [ [], [], $prevTags ];
407 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
408 if ( count( $tagsToAdd ) ) {
409 $changeTagMapping = [];
410 foreach ( $tagsToAdd as $tag ) {
411 $changeTagMapping[$tag] = $changeTagDefStore->acquireId( $tag );
415 $dbw->onTransactionPreCommitOrIdle(
function () use ( $dbw, $tagsToAdd, $fname ) {
418 [
'ctd_count = ctd_count + 1' ],
419 [
'ctd_name' => $tagsToAdd ],
425 foreach ( $tagsToAdd as $tag ) {
430 $tagsRows[] = array_filter(
432 'ct_rc_id' => $rc_id,
433 'ct_log_id' => $log_id,
434 'ct_rev_id' => $rev_id,
435 'ct_params' => $params,
436 'ct_tag_id' => $changeTagMapping[$tag] ??
null,
442 $dbw->insert(
'change_tag', $tagsRows, __METHOD__, [
'IGNORE' ] );
446 if ( count( $tagsToRemove ) ) {
448 foreach ( $tagsToRemove as $tag ) {
449 $conds = array_filter(
451 'ct_rc_id' => $rc_id,
452 'ct_log_id' => $log_id,
453 'ct_rev_id' => $rev_id,
454 'ct_tag_id' => $changeTagDefStore->getId( $tag ),
457 $dbw->delete(
'change_tag', $conds, __METHOD__ );
458 if ( $dbw->affectedRows() ) {
460 $dbw->onTransactionPreCommitOrIdle(
function () use ( $dbw, $tag, $fname ) {
463 [
'ctd_count = ctd_count - 1' ],
464 [
'ctd_name' => $tag ],
470 [
'ctd_name' => $tag,
'ctd_count' => 0,
'ctd_user_defined' => 0 ],
478 Hooks::runner()->onChangeTagsAfterUpdateTags( $tagsToAdd, $tagsToRemove, $prevTags,
479 $rc_id, $rev_id, $log_id, $params, $rc, $user );
481 return [ $tagsToAdd, $tagsToRemove, $prevTags ];
494 public static function getTags(
IDatabase $db, $rc_id =
null, $rev_id =
null, $log_id =
null ) {
495 $conds = array_filter(
497 'ct_rc_id' => $rc_id,
498 'ct_rev_id' => $rev_id,
499 'ct_log_id' => $log_id,
511 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
512 foreach ( $tagIds as $tagId ) {
513 $tags[] = $changeTagDefStore->getName( (
int)$tagId );
530 $lang = RequestContext::getMain()->getLanguage();
531 $tags = array_values( $tags );
532 $count = count( $tags );
533 $status = Status::newFatal( ( $count > 1 ) ? $msgMulti : $msgOne,
534 $lang->commaList( $tags ), $count );
535 $status->value = $tags;
553 if ( $user !==
null ) {
555 ->userHasRight( $user,
'applychangetags' )
557 return Status::newFatal(
'tags-apply-no-permission' );
558 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
559 return Status::newFatal(
'tags-apply-blocked', $user->getName() );
565 Hooks::runner()->onChangeTagsAllowedAdd( $allowedTags, $tags, $user );
566 $disallowedTags = array_diff( $tags, $allowedTags );
567 if ( $disallowedTags ) {
569 'tags-apply-not-allowed-multi', $disallowedTags );
572 return Status::newGood();
596 array $tags, $rc_id, $rev_id, $log_id, $params,
User $user
600 if ( !$result->isOK() ) {
601 $result->value =
null;
608 return Status::newGood(
true );
625 public static function canUpdateTags( array $tagsToAdd, array $tagsToRemove,
628 if ( $user !==
null ) {
630 ->userHasRight( $user,
'changetags' )
632 return Status::newFatal(
'tags-update-no-permission' );
633 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
634 return Status::newFatal(
'tags-update-blocked', $user->getName() );
642 $diff = array_diff( $tagsToAdd, $explicitlyDefinedTags );
645 'tags-update-add-not-allowed-multi', $diff );
649 if ( $tagsToRemove ) {
654 $intersect = array_intersect( $tagsToRemove, $softwareDefinedTags );
657 'tags-update-remove-not-allowed-multi', $intersect );
661 return Status::newGood();
695 $rc_id, $rev_id, $log_id, $params, $reason,
User $user
697 if ( $tagsToAdd ===
null ) {
700 if ( $tagsToRemove ===
null ) {
703 if ( !$tagsToAdd && !$tagsToRemove ) {
705 return Status::newGood( (
object)[
714 if ( !$result->isOK() ) {
715 $result->value =
null;
721 return Status::newFatal(
'actionthrottledtext' );
725 list( $tagsAdded, $tagsRemoved, $initialTags ) =
self::updateTags( $tagsToAdd,
726 $tagsToRemove, $rc_id, $rev_id, $log_id, $params,
null, $user );
727 if ( !$tagsAdded && !$tagsRemoved ) {
729 return Status::newGood( (
object)[
738 $logEntry->setPerformer( $user );
739 $logEntry->setComment( $reason );
743 $revisionRecord = MediaWikiServices::getInstance()
744 ->getRevisionLookup()
745 ->getRevisionById( $rev_id );
746 if ( $revisionRecord ) {
747 $logEntry->setTarget( $revisionRecord->getPageAsLinkTarget() );
749 } elseif ( $log_id ) {
756 if ( !$logEntry->getTarget() ) {
762 '4::revid' => $rev_id,
763 '5::logid' => $log_id,
764 '6:list:tagsAdded' => $tagsAdded,
765 '7:number:tagsAddedCount' => count( $tagsAdded ),
766 '8:list:tagsRemoved' => $tagsRemoved,
767 '9:number:tagsRemovedCount' => count( $tagsRemoved ),
768 'initialTags' => $initialTags,
770 $logEntry->setParameters( $logParams );
771 $logEntry->setRelations( [
'Tag' => array_merge( $tagsAdded, $tagsRemoved ) ] );
774 $logId = $logEntry->insert( $dbw );
776 $logEntry->publish( $logId,
'udp' );
778 return Status::newGood( (
object)[
780 'addedTags' => $tagsAdded,
781 'removedTags' => $tagsRemoved,
806 &$join_conds, &$options, $filter_tag =
''
811 $tables = (array)$tables;
812 $fields = (array)$fields;
813 $conds = (array)$conds;
814 $options = (array)$options;
819 if ( in_array(
'recentchanges', $tables ) ) {
820 $join_cond =
'ct_rc_id=rc_id';
821 } elseif ( in_array(
'logging', $tables ) ) {
822 $join_cond =
'ct_log_id=log_id';
823 } elseif ( in_array(
'revision', $tables ) ) {
824 $join_cond =
'ct_rev_id=rev_id';
825 } elseif ( in_array(
'archive', $tables ) ) {
826 $join_cond =
'ct_rev_id=ar_rev_id';
828 throw new MWException(
'Unable to determine appropriate JOIN condition for tagging.' );
835 if ( !is_array( $filter_tag ) ) {
837 $filter_tag = (string)$filter_tag;
840 if ( $filter_tag !== [] && $filter_tag !==
'' ) {
844 $tagTable =
'change_tag';
845 if ( self::$avoidReopeningTablesForTesting && defined(
'MW_PHPUNIT_TEST' ) ) {
848 if ( $db->getType() ===
'mysql' ) {
857 $tagTable =
'change_tag_for_display_query';
859 'CREATE TEMPORARY TABLE IF NOT EXISTS ' . $db->tableName( $tagTable )
860 .
' LIKE ' . $db->tableName(
'change_tag' )
863 'INSERT IGNORE INTO ' . $db->tableName( $tagTable )
864 .
' SELECT * FROM ' . $db->tableName(
'change_tag' )
869 $tables[] = $tagTable;
870 $join_conds[$tagTable] = [
'JOIN', $join_cond ];
872 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
873 foreach ( (array)$filter_tag as $filterTagName ) {
875 $filterTagIds[] = $changeTagDefStore->getId( $filterTagName );
883 if ( $filterTagIds !== [] ) {
884 $conds[
'ct_tag_id'] = $filterTagIds;
888 is_array( $filter_tag ) && count( $filter_tag ) > 1 &&
889 !in_array(
'DISTINCT', $options )
891 $options[] =
'DISTINCT';
906 $tables = (array)$tables;
909 if ( in_array(
'recentchanges', $tables ) ) {
910 $join_cond =
'ct_rc_id=rc_id';
911 } elseif ( in_array(
'logging', $tables ) ) {
912 $join_cond =
'ct_log_id=log_id';
913 } elseif ( in_array(
'revision', $tables ) ) {
914 $join_cond =
'ct_rev_id=rev_id';
915 } elseif ( in_array(
'archive', $tables ) ) {
916 $join_cond =
'ct_rev_id=ar_rev_id';
918 throw new MWException(
'Unable to determine appropriate JOIN condition for tagging.' );
921 $tagTables = [
'change_tag',
'change_tag_def' ];
922 $join_cond_ts_tags = [
'change_tag_def' => [
'JOIN',
'ct_tag_id=ctd_id' ] ];
926 ',', $tagTables, $field, $join_cond, $join_cond_ts_tags
945 $context = RequestContext::getMain();
948 $config = $context->getConfig();
949 if ( !$config->get(
'UseTagFilter' ) || !count( self::listDefinedTags() ) ) {
956 [
'for' =>
'tagfilter' ],
957 $context->msg(
'tag-filter' )->parse()
962 $data[] =
new OOUI\TextInputWidget( [
964 'name' =>
'tagfilter',
965 'value' => $selected,
966 'classes' =>
'mw-tagfilter-input',
969 $data[] = Xml::input(
973 [
'class' =>
'mw-tagfilter-input mw-ui-input mw-ui-input-inline',
'id' =>
'tagfilter' ]
992 'ctd_user_defined' => 1,
999 [
'ctd_user_defined' => 1 ],
1020 [
'ctd_user_defined' => 0 ],
1021 [
'ctd_name' => $tag ],
1027 [
'ctd_name' => $tag,
'ctd_count' => 0 ],
1050 User $user, $tagCount =
null, array $logEntryTags = []
1055 $logEntry->setPerformer( $user );
1058 $logEntry->setTarget( Title::newFromText(
'Special:Tags' ) );
1059 $logEntry->setComment( $reason );
1061 $params = [
'4::tag' => $tag ];
1062 if ( $tagCount !==
null ) {
1063 $params[
'5:number:count'] = $tagCount;
1065 $logEntry->setParameters( $params );
1066 $logEntry->setRelations( [
'Tag' => $tag ] );
1067 $logEntry->addTags( $logEntryTags );
1069 $logId = $logEntry->insert( $dbw );
1070 $logEntry->publish( $logId );
1084 if ( $user !==
null ) {
1086 ->userHasRight( $user,
'managechangetags' )
1088 return Status::newFatal(
'tags-manage-no-permission' );
1089 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
1090 return Status::newFatal(
'tags-manage-blocked', $user->getName() );
1098 if ( in_array( $tag, $definedTags ) ) {
1099 return Status::newFatal(
'tags-activate-not-allowed', $tag );
1104 if ( !isset( $tagUsage[$tag] ) ) {
1105 return Status::newFatal(
'tags-activate-not-found', $tag );
1108 return Status::newGood();
1129 $ignoreWarnings =
false, array $logEntryTags = []
1133 if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
1134 $result->value =
null;
1143 null, $logEntryTags );
1145 return Status::newGood( $logId );
1158 if ( $user !==
null ) {
1160 ->userHasRight( $user,
'managechangetags' )
1162 return Status::newFatal(
'tags-manage-no-permission' );
1163 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
1164 return Status::newFatal(
'tags-manage-blocked', $user->getName() );
1170 if ( !in_array( $tag, $explicitlyDefinedTags ) ) {
1171 return Status::newFatal(
'tags-deactivate-not-allowed', $tag );
1173 return Status::newGood();
1194 $ignoreWarnings =
false, array $logEntryTags = []
1198 if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
1199 $result->value =
null;
1208 null, $logEntryTags );
1210 return Status::newGood( $logId );
1222 if ( $tag ===
'' ) {
1223 return Status::newFatal(
'tags-create-no-name' );
1230 if ( strpos( $tag,
',' ) !==
false || strpos( $tag,
'|' ) !==
false
1231 || strpos( $tag,
'/' ) !==
false ) {
1232 return Status::newFatal(
'tags-create-invalid-chars' );
1238 return Status::newFatal(
'tags-create-invalid-title-chars' );
1241 return Status::newGood();
1257 if ( $user !==
null ) {
1259 ->userHasRight( $user,
'managechangetags' )
1261 return Status::newFatal(
'tags-manage-no-permission' );
1262 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
1263 return Status::newFatal(
'tags-manage-blocked', $user->getName() );
1268 if ( !$status->isGood() ) {
1274 if ( isset( $tagUsage[$tag] ) || in_array( $tag, self::listDefinedTags() ) ) {
1275 return Status::newFatal(
'tags-create-already-exists', $tag );
1279 $canCreateResult = Status::newGood();
1280 Hooks::runner()->onChangeTagCanCreate( $tag, $user, $canCreateResult );
1281 return $canCreateResult;
1304 $ignoreWarnings =
false, array $logEntryTags = []
1308 if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
1309 $result->value =
null;
1318 null, $logEntryTags );
1320 return Status::newGood( $logId );
1337 $dbw->startAtomic( __METHOD__ );
1340 $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag );
1346 $dbw->delete(
'change_tag', [
'ct_tag_id' => $tagId ], __METHOD__ );
1347 $dbw->delete(
'change_tag_def', [
'ctd_name' => $tag ], __METHOD__ );
1348 $dbw->endAtomic( __METHOD__ );
1351 $status = Status::newGood();
1352 Hooks::runner()->onChangeTagAfterDelete( $tag, $status );
1354 if ( !$status->isOK() ) {
1355 wfDebug(
'ChangeTagAfterDelete error condition downgraded to warning' );
1356 $status->setOK(
true );
1380 if ( $user !==
null ) {
1382 ->userHasRight( $user,
'deletechangetags' )
1384 return Status::newFatal(
'tags-delete-no-permission' );
1385 } elseif ( $user->getBlock() && $user->getBlock()->isSitewide() ) {
1386 return Status::newFatal(
'tags-manage-blocked', $user->getName() );
1390 if ( !isset( $tagUsage[$tag] ) && !in_array( $tag, self::listDefinedTags() ) ) {
1391 return Status::newFatal(
'tags-delete-not-found', $tag );
1394 if ( $flags !== self::BYPASS_MAX_USAGE_CHECK &&
1395 isset( $tagUsage[$tag] ) &&
1396 $tagUsage[$tag] > self::MAX_DELETE_USES
1398 return Status::newFatal(
'tags-delete-too-many-uses', $tag, self::MAX_DELETE_USES );
1402 if ( in_array( $tag, $softwareDefined ) ) {
1405 $status = Status::newFatal(
'tags-delete-not-allowed' );
1408 $status = Status::newGood();
1411 Hooks::runner()->onChangeTagCanDelete( $tag, $user, $status );
1433 $ignoreWarnings =
false, array $logEntryTags = []
1437 if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
1438 $result->value =
null;
1444 $hitcount = $tagUsage[$tag] ?? 0;
1448 if ( !$deleteResult->isOK() ) {
1449 return $deleteResult;
1454 $hitcount, $logEntryTags );
1456 $deleteResult->value = $logId;
1457 return $deleteResult;
1469 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1470 if ( !$hookContainer->isRegistered(
'ChangeTagsListActive' ) ) {
1473 $hookRunner =
new HookRunner( $hookContainer );
1474 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1475 return $cache->getWithSetCallback(
1476 $cache->makeKey(
'active-tags' ),
1477 WANObjectCache::TTL_MINUTE * 5,
1478 function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags, $hookRunner ) {
1482 $hookRunner->onChangeTagsListActive( $tags );
1486 'checkKeys' => [
$cache->makeKey(
'active-tags' ) ],
1487 'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
1488 'pcTTL' => WANObjectCache::TTL_PROC_LONG
1502 return array_values( array_unique( array_merge( $tags1, $tags2 ) ) );
1514 $fname = __METHOD__;
1516 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1517 return $cache->getWithSetCallback(
1518 $cache->makeKey(
'valid-tags-db' ),
1519 WANObjectCache::TTL_MINUTE * 5,
1520 function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
1523 $setOpts += Database::getCacheSetOptions(
$dbr );
1525 $tags =
$dbr->selectFieldValues(
1528 [
'ctd_user_defined' => 1 ],
1532 return array_unique( $tags );
1535 'checkKeys' => [
$cache->makeKey(
'valid-tags-db' ) ],
1536 'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
1537 'pcTTL' => WANObjectCache::TTL_PROC_LONG
1554 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1555 if ( !$hookContainer->isRegistered(
'ListDefinedTags' ) ) {
1558 $hookRunner =
new HookRunner( $hookContainer );
1559 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1560 return $cache->getWithSetCallback(
1561 $cache->makeKey(
'valid-tags-hook' ),
1562 WANObjectCache::TTL_MINUTE * 5,
1563 function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags, $hookRunner ) {
1566 $hookRunner->onListDefinedTags( $tags );
1567 return array_unique( $tags );
1570 'checkKeys' => [
$cache->makeKey(
'valid-tags-hook' ) ],
1571 'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
1572 'pcTTL' => WANObjectCache::TTL_PROC_LONG
1583 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1585 $cache->touchCheckKey(
$cache->makeKey(
'active-tags' ) );
1586 $cache->touchCheckKey(
$cache->makeKey(
'valid-tags-db' ) );
1587 $cache->touchCheckKey(
$cache->makeKey(
'valid-tags-hook' ) );
1588 $cache->touchCheckKey(
$cache->makeKey(
'tags-usage-statistics' ) );
1590 MediaWikiServices::getInstance()->getChangeTagDefStore()->reloadMap();
1600 $fname = __METHOD__;
1602 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1603 return $cache->getWithSetCallback(
1604 $cache->makeKey(
'tags-usage-statistics' ),
1605 WANObjectCache::TTL_MINUTE * 5,
1606 function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
1610 [
'ctd_name',
'ctd_count' ],
1613 [
'ORDER BY' =>
'ctd_count DESC' ]
1617 foreach (
$res as $row ) {
1618 $out[$row->ctd_name] = $row->ctd_count;
1624 'checkKeys' => [
$cache->makeKey(
'tags-usage-statistics' ) ],
1625 'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
1626 'pcTTL' => WANObjectCache::TTL_PROC_LONG
1646 return MediaWikiServices::getInstance()->getPermissionManager()
1647 ->userHasRight( $user,
'changetags' ) &&
1648 (bool)self::listExplicitlyDefinedTags();
$wgUseTagFilter
Allow filtering by change tag in recentchanges, history, etc Has no effect if no tags are defined in ...
array $wgSoftwareTags
List of core tags to enable.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Class for creating new log entries and inserting them into the database.
static plaintextParam( $plaintext)
Variant of the Message class.
Utility class for creating new RC entries.
static suggestTarget( $target, array $ids)
Suggest a target for the revision deletion Optionally override this function.
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,...
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
pingLimiter( $action='edit', $incrBy=1)
Primitive rate limits: enforce maximum actions per time period to put a brake on flooding.
Interface for objects which can provide a MediaWiki context on request.
Interface for localizing messages in MediaWiki.
msg( $key,... $params)
This is the method for getting translated interface messages.
if(!isset( $args[0])) $lang