* @ingroup Change tagging
*/
+use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\Database;
+
class ChangeTags {
/**
* Can't delete tags with more than this many uses. Similar in intent to
}
// to be applied, a tag has to be explicitly defined
- // @todo Allow extensions to define tags that can be applied by users...
$allowedTags = self::listExplicitlyDefinedTags();
+ Hooks::run( 'ChangeTagsAllowedAdd', [ &$allowedTags, $tags, $user ] );
$disallowedTags = array_diff( $tags, $allowedTags );
if ( $disallowedTags ) {
return self::restrictedTagError( 'tags-apply-not-allowed-one',
$tables[] = 'change_tag';
$join_conds['change_tag'] = [ 'INNER JOIN', $join_cond ];
- $conds['ct_tag'] = $filter_tag;
+ $conds['ct_tag'] = explode( '|', $filter_tag );
}
}
return Status::newGood( $logId );
}
+ /**
+ * Is the tag name valid?
+ *
+ * @param string $tag Tag that you are interested in creating
+ * @return Status
+ * @since 1.30
+ */
+ public static function isTagNameValid( $tag ) {
+ // no empty tags
+ if ( $tag === '' ) {
+ return Status::newFatal( 'tags-create-no-name' );
+ }
+
+ // tags cannot contain commas (used as a delimiter in tag_summary table),
+ // pipe (used as a delimiter between multiple tags in
+ // modifyDisplayQuery), or slashes (would break tag description messages in
+ // MediaWiki namespace)
+ if ( strpos( $tag, ',' ) !== false || strpos( $tag, '|' ) !== false
+ || strpos( $tag, '/' ) !== false ) {
+ return Status::newFatal( 'tags-create-invalid-chars' );
+ }
+
+ // could the MediaWiki namespace description messages be created?
+ $title = Title::makeTitleSafe( NS_MEDIAWIKI, "Tag-$tag-description" );
+ if ( is_null( $title ) ) {
+ return Status::newFatal( 'tags-create-invalid-title-chars' );
+ }
+
+ return Status::newGood();
+ }
+
/**
* Is it OK to allow the user to create this tag?
*
}
}
- // no empty tags
- if ( $tag === '' ) {
- return Status::newFatal( 'tags-create-no-name' );
- }
-
- // tags cannot contain commas (used as a delimiter in tag_summary table) or
- // slashes (would break tag description messages in MediaWiki namespace)
- if ( strpos( $tag, ',' ) !== false || strpos( $tag, '/' ) !== false ) {
- return Status::newFatal( 'tags-create-invalid-chars' );
- }
-
- // could the MediaWiki namespace description messages be created?
- $title = Title::makeTitleSafe( NS_MEDIAWIKI, "Tag-$tag-description" );
- if ( is_null( $title ) ) {
- return Status::newFatal( 'tags-create-invalid-title-chars' );
+ $status = self::isTagNameValid( $tag );
+ if ( !$status->isGood() ) {
+ return $status;
}
// does the tag already exist?
if ( !Hooks::isRegistered( 'ChangeTagsListActive' ) ) {
return $tags;
}
- return ObjectCache::getMainWANInstance()->getWithSetCallback(
- wfMemcKey( 'active-tags' ),
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ return $cache->getWithSetCallback(
+ $cache->makeKey( 'active-tags' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
return $tags;
},
[
- 'checkKeys' => [ wfMemcKey( 'active-tags' ) ],
+ 'checkKeys' => [ $cache->makeKey( 'active-tags' ) ],
'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
'pcTTL' => WANObjectCache::TTL_PROC_LONG
]
public static function listExplicitlyDefinedTags() {
$fname = __METHOD__;
- return ObjectCache::getMainWANInstance()->getWithSetCallback(
- wfMemcKey( 'valid-tags-db' ),
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ return $cache->getWithSetCallback(
+ $cache->makeKey( 'valid-tags-db' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
$dbr = wfGetDB( DB_REPLICA );
return array_filter( array_unique( $tags ) );
},
[
- 'checkKeys' => [ wfMemcKey( 'valid-tags-db' ) ],
+ 'checkKeys' => [ $cache->makeKey( 'valid-tags-db' ) ],
'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
'pcTTL' => WANObjectCache::TTL_PROC_LONG
]
if ( !Hooks::isRegistered( 'ListDefinedTags' ) ) {
return $tags;
}
- return ObjectCache::getMainWANInstance()->getWithSetCallback(
- wfMemcKey( 'valid-tags-hook' ),
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ return $cache->getWithSetCallback(
+ $cache->makeKey( 'valid-tags-hook' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
return array_filter( array_unique( $tags ) );
},
[
- 'checkKeys' => [ wfMemcKey( 'valid-tags-hook' ) ],
+ 'checkKeys' => [ $cache->makeKey( 'valid-tags-hook' ) ],
'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
'pcTTL' => WANObjectCache::TTL_PROC_LONG
]
* @since 1.25
*/
public static function purgeTagCacheAll() {
- $cache = ObjectCache::getMainWANInstance();
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
- $cache->touchCheckKey( wfMemcKey( 'active-tags' ) );
- $cache->touchCheckKey( wfMemcKey( 'valid-tags-db' ) );
- $cache->touchCheckKey( wfMemcKey( 'valid-tags-hook' ) );
+ $cache->touchCheckKey( $cache->makeKey( 'active-tags' ) );
+ $cache->touchCheckKey( $cache->makeKey( 'valid-tags-db' ) );
+ $cache->touchCheckKey( $cache->makeKey( 'valid-tags-hook' ) );
self::purgeTagUsageCache();
}
* @since 1.25
*/
public static function purgeTagUsageCache() {
- $cache = ObjectCache::getMainWANInstance();
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
- $cache->touchCheckKey( wfMemcKey( 'change-tag-statistics' ) );
+ $cache->touchCheckKey( $cache->makeKey( 'change-tag-statistics' ) );
}
/**
*/
public static function tagUsageStatistics() {
$fname = __METHOD__;
- return ObjectCache::getMainWANInstance()->getWithSetCallback(
- wfMemcKey( 'change-tag-statistics' ),
+ $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+ return $cache->getWithSetCallback(
+ $cache->makeKey( 'change-tag-statistics' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
$dbr = wfGetDB( DB_REPLICA, 'vslow' );
return $out;
},
[
- 'checkKeys' => [ wfMemcKey( 'change-tag-statistics' ) ],
+ 'checkKeys' => [ $cache->makeKey( 'change-tag-statistics' ) ],
'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
'pcTTL' => WANObjectCache::TTL_PROC_LONG
]