X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fchangetags%2FChangeTags.php;h=5b6088d59f6f6591eb51cd3979a72ed59553d165;hb=23b7f3bbd553183a21d785bae175249efad5ee5d;hp=b30b82df1d93783505203a0c4ab87bf4d9749cea;hpb=4b2f95bed5a9ae0a917264abed2ba1fd9fb78f3c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index b30b82df1d..d019f41cea 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -32,6 +32,9 @@ class ChangeTags { */ const MAX_DELETE_USES = 5000; + /** + * A list of tags defined and used by MediaWiki itself. + */ private static $definedSoftwareTags = [ 'mw-contentmodelchange', 'mw-new-redirect', @@ -258,6 +261,8 @@ class ChangeTags { &$rev_id = null, &$log_id = null, $params = null, RecentChange $rc = null, User $user = null ) { + global $wgChangeTagsSchemaMigrationStage; + $tagsToAdd = array_filter( (array)$tagsToAdd ); // Make sure we're submitting all tags... $tagsToRemove = array_filter( (array)$tagsToRemove ); @@ -339,6 +344,35 @@ class ChangeTags { // insert a row into change_tag for each new tag if ( count( $tagsToAdd ) ) { + $changeTagMapping = []; + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { + $tagDefRows = []; + foreach ( $tagsToAdd as $tag ) { + $tagDefRows[] = [ + 'ctd_name' => $tag, + 'ctd_user_defined' => 0, + 'ctd_count' => 1 + ]; + } + + $dbw->upsert( + 'change_tag_def', + $tagDefRows, + [ 'ctd_name' ], + [ 'ctd_count = ctd_count + 1' ], + __METHOD__ + ); + + $res = $dbw->select( + 'change_tag_def', + [ 'ctd_name', 'ctd_id' ], + [ 'ctd_name' => $tagsToAdd ] + ); + foreach ( $res as $row ) { + $changeTagMapping[$row->ctd_name] = $row->ctd_id; + } + } + $tagsRows = []; foreach ( $tagsToAdd as $tag ) { // Filter so we don't insert NULLs as zero accidentally. @@ -351,9 +385,11 @@ class ChangeTags { 'ct_rc_id' => $rc_id, 'ct_log_id' => $log_id, 'ct_rev_id' => $rev_id, - 'ct_params' => $params + 'ct_params' => $params, + 'ct_tag_id' => $changeTagMapping[$tag] ?? null, ] ); + } $dbw->insert( 'change_tag', $tagsRows, __METHOD__, [ 'IGNORE' ] ); @@ -371,6 +407,20 @@ class ChangeTags { ] ); $dbw->delete( 'change_tag', $conds, __METHOD__ ); + if ( $dbw->affectedRows() && $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { + $dbw->update( + 'change_tag_def', + [ 'ctd_count = ctd_count - 1' ], + [ 'ctd_name' => $tag ], + __METHOD__ + ); + + $dbw->delete( + 'change_tag_def', + [ 'ctd_name' => $tag, 'ctd_count' => 0, 'ctd_user_defined' => 0 ], + __METHOD__ + ); + } } } @@ -416,7 +466,7 @@ class ChangeTags { // $prevTags can be out of date on replica DBs, especially when addTags is called consecutively, // causing loss of tags added recently in tag_summary table. $prevTags = $dbw->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ ); - $prevTags = $prevTags ? $prevTags : ''; + $prevTags = $prevTags ?: ''; $prevTags = array_filter( explode( ',', $prevTags ) ); // add tags @@ -474,9 +524,12 @@ class ChangeTags { * Is it OK to allow the user to apply all the specified tags at the same time * as they edit/make the change? * + * Extensions should not use this function, unless directly handling a user + * request to add a tag to a revision or log entry that the user is making. + * * @param array $tags Tags that you are interested in applying - * @param User|null $user User whose permission you wish to check, or null if - * you don't care (e.g. maintenance scripts) + * @param User|null $user User whose permission you wish to check, or null to + * check for a generic non-blocked user with the relevant rights * @return Status * @since 1.25 */ @@ -541,10 +594,13 @@ class ChangeTags { * Is it OK to allow the user to adds and remove the given tags tags to/from a * change? * + * Extensions should not use this function, unless directly handling a user + * request to add or remove tags from an existing revision or log entry. + * * @param array $tagsToAdd Tags that you are interested in adding * @param array $tagsToRemove Tags that you are interested in removing - * @param User|null $user User whose permission you wish to check, or null if - * you don't care (e.g. maintenance scripts) + * @param User|null $user User whose permission you wish to check, or null to + * check for a generic non-blocked user with the relevant rights * @return Status * @since 1.25 */ @@ -589,11 +645,15 @@ class ChangeTags { * Adds and/or removes tags to/from a given change, checking whether it is * allowed first, and adding a log entry afterwards. * - * Includes a call to ChangeTag::canUpdateTags(), so your code doesn't need + * Includes a call to ChangeTags::canUpdateTags(), so your code doesn't need * to do that. However, it doesn't check whether the *_id parameters are a * valid combination. That is up to you to enforce. See ApiTag::execute() for * an example. * + * Extensions should generally avoid this function. Call + * ChangeTags::updateTags() instead, unless directly handling a user request + * to add or remove tags from an existing revision or log entry. + * * @param array|null $tagsToAdd If none, pass array() or null * @param array|null $tagsToRemove If none, pass array() or null * @param int|null $rc_id The rc_id of the change to add the tags to @@ -721,7 +781,8 @@ class ChangeTags { * @throws MWException When unable to determine appropriate JOIN condition for tagging */ public static function modifyDisplayQuery( &$tables, &$fields, &$conds, - &$join_conds, &$options, $filter_tag = '' ) { + &$join_conds, &$options, $filter_tag = '' + ) { global $wgUseTagFilter; // Normalize to arrays @@ -814,8 +875,8 @@ class ChangeTags { } /** - * Defines a tag in the valid_tag table, without checking that the tag name - * is valid. + * Defines a tag in the valid_tag table and/or update ctd_user_defined field in change_tag_def, + * without checking that the tag name is valid. * Extensions should NOT use this function; they can use the ListDefinedTags * hook instead. * @@ -823,26 +884,63 @@ class ChangeTags { * @since 1.25 */ public static function defineTag( $tag ) { + global $wgChangeTagsSchemaMigrationStage; + $dbw = wfGetDB( DB_MASTER ); - $dbw->replace( 'valid_tag', + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { + $tagDef = [ + 'ctd_name' => $tag, + 'ctd_user_defined' => 1, + 'ctd_count' => 0 + ]; + $dbw->upsert( + 'change_tag_def', + $tagDef, + [ 'ctd_name' ], + [ 'ctd_user_defined' => 1 ], + __METHOD__ + ); + } + + $dbw->replace( + 'valid_tag', [ 'vt_tag' ], [ 'vt_tag' => $tag ], - __METHOD__ ); + __METHOD__ + ); // clear the memcache of defined tags self::purgeTagCacheAll(); } /** - * Removes a tag from the valid_tag table. The tag may remain in use by - * extensions, and may still show up as 'defined' if an extension is setting - * it from the ListDefinedTags hook. + * Removes a tag from the valid_tag table and/or update ctd_user_defined field in change_tag_def. + * The tag may remain in use by extensions, and may still show up as 'defined' + * if an extension is setting it from the ListDefinedTags hook. * * @param string $tag Tag to remove * @since 1.25 */ public static function undefineTag( $tag ) { + global $wgChangeTagsSchemaMigrationStage; + $dbw = wfGetDB( DB_MASTER ); + + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { + $dbw->update( + 'change_tag_def', + [ 'ctd_name' => $tag ], + [ 'ctd_user_defined' => 0 ], + __METHOD__ + ); + + $dbw->delete( + 'change_tag_def', + [ 'ctd_name' => $tag, 'ctd_count' => 0 ], + __METHOD__ + ); + } + $dbw->delete( 'valid_tag', [ 'vt_tag' => $tag ], __METHOD__ ); // clear the memcache of defined tags @@ -1057,6 +1155,9 @@ class ChangeTags { /** * Is it OK to allow the user to create this tag? * + * Extensions should NOT use this function. In most cases, a tag can be + * defined using the ListDefinedTags hook without any checking. + * * @param string $tag Tag that you are interested in creating * @param User|null $user User whose permission you wish to check, or null if * you don't care (e.g. maintenance scripts) @@ -1091,6 +1192,10 @@ class ChangeTags { /** * Creates a tag by adding a row to the `valid_tag` table. + * and/or add it to `change_tag_def` table. + * + * Extensions should NOT use this function; they can use the ListDefinedTags + * hook instead. * * Includes a call to ChangeTag::canDeleteTag(), so your code doesn't need to * do that. @@ -1138,10 +1243,11 @@ class ChangeTags { * @since 1.25 */ public static function deleteTagEverywhere( $tag ) { + global $wgChangeTagsSchemaMigrationStage; $dbw = wfGetDB( DB_MASTER ); $dbw->startAtomic( __METHOD__ ); - // delete from valid_tag + // delete from valid_tag and/or set ctd_user_defined = 0 self::undefineTag( $tag ); // find out which revisions use this tag, so we can delete from tag_summary @@ -1160,6 +1266,10 @@ class ChangeTags { // delete from change_tag $dbw->delete( 'change_tag', [ 'ct_tag' => $tag ], __METHOD__ ); + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { + $dbw->delete( 'change_tag_def', [ 'ctd_name' => $tag ], __METHOD__ ); + } + $dbw->endAtomic( __METHOD__ ); // give extensions a chance @@ -1248,7 +1358,7 @@ class ChangeTags { // store the tag usage statistics $tagUsage = self::tagUsageStatistics(); - $hitcount = isset( $tagUsage[$tag] ) ? $tagUsage[$tag] : 0; + $hitcount = $tagUsage[$tag] ?? 0; // do it! $deleteResult = self::deleteTagEverywhere( $tag ); @@ -1295,20 +1405,9 @@ class ChangeTags { ); } - /** - * @see listSoftwareActivatedTags - * @deprecated since 1.28 call listSoftwareActivatedTags directly - * @return array - */ - public static function listExtensionActivatedTags() { - wfDeprecated( __METHOD__, '1.28' ); - return self::listSoftwareActivatedTags(); - } - /** * Basically lists defined tags which count even if they aren't applied to anything. - * It returns a union of the results of listExplicitlyDefinedTags() and - * listExtensionDefinedTags(). + * It returns a union of the results of listExplicitlyDefinedTags() * * @return string[] Array of strings: tags */ @@ -1385,18 +1484,6 @@ class ChangeTags { ); } - /** - * Call listSoftwareDefinedTags directly - * - * @see listSoftwareDefinedTags - * @deprecated since 1.28 - * @return array - */ - public static function listExtensionDefinedTags() { - wfDeprecated( __METHOD__, '1.28' ); - return self::listSoftwareDefinedTags(); - } - /** * Invalidates the short-term cache of defined tags used by the * list*DefinedTags functions, as well as the tag statistics cache.