X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fchangetags%2FChangeTags.php;h=e7d08fdb6f5bf77b001a98c178fdffacf2ac151f;hb=bb07b4a368f59fabfdcd7d08610c9f1cb6c00ba7;hp=dd29c100e8ac5214676186940183bbe155082f05;hpb=73380233aab4e2009acdbaa8d6ac928c499408af;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index dd29c100e8..e7d08fdb6f 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -22,6 +22,7 @@ */ use MediaWiki\MediaWikiServices; +use MediaWiki\Storage\NameTableAccessException; use Wikimedia\Rdbms\Database; class ChangeTags { @@ -87,6 +88,7 @@ class ChangeTags { * @return array Array with two items: (html, classes) * - html: String: HTML for displaying the tags (empty string when param $tags is empty) * - classes: Array of strings: CSS classes used in the generated html, one class for each tag + * @return-taint onlysafefor_htmlnoent */ public static function formatSummaryRow( $tags, $page, IContextSource $context = null ) { if ( !$tags ) { @@ -342,11 +344,10 @@ class ChangeTags { } // insert a row into change_tag for each new tag + $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore(); if ( count( $tagsToAdd ) ) { $changeTagMapping = []; if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { - $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore(); - foreach ( $tagsToAdd as $tag ) { $changeTagMapping[$tag] = $changeTagDefStore->acquireId( $tag ); } @@ -361,13 +362,18 @@ class ChangeTags { $tagsRows = []; foreach ( $tagsToAdd as $tag ) { + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tagName = null; + } else { + $tagName = $tag; + } // Filter so we don't insert NULLs as zero accidentally. // Keep in mind that $rc_id === null means "I don't care/know about the // rc_id, just delete $tag on this revision/log entry". It doesn't // mean "only delete tags on this revision/log WHERE rc_id IS NULL". $tagsRows[] = array_filter( [ - 'ct_tag' => $tag, + 'ct_tag' => $tagName, 'ct_rc_id' => $rc_id, 'ct_log_id' => $log_id, 'ct_rev_id' => $rev_id, @@ -384,12 +390,20 @@ class ChangeTags { // delete from change_tag if ( count( $tagsToRemove ) ) { foreach ( $tagsToRemove as $tag ) { + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tagName = null; + $tagId = $changeTagDefStore->getId( $tag ); + } else { + $tagName = $tag; + $tagId = null; + } $conds = array_filter( [ - 'ct_tag' => $tag, + 'ct_tag' => $tagName, 'ct_rc_id' => $rc_id, 'ct_log_id' => $log_id, - 'ct_rev_id' => $rev_id + 'ct_rev_id' => $rev_id, + 'ct_tag_id' => $tagId, ] ); $dbw->delete( 'change_tag', $conds, __METHOD__ ); @@ -769,7 +783,7 @@ class ChangeTags { public static function modifyDisplayQuery( &$tables, &$fields, &$conds, &$join_conds, &$options, $filter_tag = '' ) { - global $wgUseTagFilter; + global $wgUseTagFilter, $wgChangeTagsSchemaMigrationStage; // Normalize to arrays $tables = (array)$tables; @@ -790,8 +804,18 @@ class ChangeTags { throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' ); } + $tagTables[] = 'change_tag'; + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tagTables[] = 'change_tag_def'; + $join_cond_ts_tags = [ $join_cond, 'ct_tag_id=ctd_id' ]; + $field = 'ctd_name'; + } else { + $field = 'ct_tag'; + $join_cond_ts_tags = $join_cond; + } + $fields['ts_tags'] = wfGetDB( DB_REPLICA )->buildGroupConcatField( - ',', 'change_tag', 'ct_tag', $join_cond + ',', $tagTables, $field, $join_cond_ts_tags ); if ( $wgUseTagFilter && $filter_tag ) { @@ -800,7 +824,26 @@ class ChangeTags { $tables[] = 'change_tag'; $join_conds['change_tag'] = [ 'INNER JOIN', $join_cond ]; - $conds['ct_tag'] = $filter_tag; + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $filterTagIds = []; + $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore(); + foreach ( (array)$filter_tag as $filterTagName ) { + try { + $filterTagIds[] = $changeTagDefStore->getId( $filterTagName ); + } catch ( NameTableAccessException $exception ) { + // Return nothing. + $conds[] = '0'; + break; + }; + } + + if ( $filterTagIds !== [] ) { + $conds['ct_tag_id'] = $filterTagIds; + } + } else { + $conds['ct_tag'] = $filter_tag; + } + if ( is_array( $filter_tag ) && count( $filter_tag ) > 1 && !in_array( 'DISTINCT', $options ) @@ -888,13 +931,14 @@ class ChangeTags { ); } - $dbw->replace( - 'valid_tag', - [ 'vt_tag' ], - [ 'vt_tag' => $tag ], - __METHOD__ - ); - + if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) { + $dbw->replace( + 'valid_tag', + [ 'vt_tag' ], + [ 'vt_tag' => $tag ], + __METHOD__ + ); + } // clear the memcache of defined tags self::purgeTagCacheAll(); } @@ -927,7 +971,9 @@ class ChangeTags { ); } - $dbw->delete( 'valid_tag', [ 'vt_tag' => $tag ], __METHOD__ ); + if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) { + $dbw->delete( 'valid_tag', [ 'vt_tag' => $tag ], __METHOD__ ); + } // clear the memcache of defined tags self::purgeTagCacheAll(); @@ -1236,10 +1282,17 @@ class ChangeTags { // delete from valid_tag and/or set ctd_user_defined = 0 self::undefineTag( $tag ); + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag ); + $conditions = [ 'ct_tag_id' => $tagId ]; + } else { + $conditions = [ 'ct_tag' => $tag ]; + } + // find out which revisions use this tag, so we can delete from tag_summary $result = $dbw->select( 'change_tag', - [ 'ct_rc_id', 'ct_log_id', 'ct_rev_id', 'ct_tag' ], - [ 'ct_tag' => $tag ], + [ 'ct_rc_id', 'ct_log_id', 'ct_rev_id' ], + $conditions, __METHOD__ ); foreach ( $result as $row ) { // remove the tag from the relevant row of tag_summary @@ -1250,7 +1303,12 @@ class ChangeTags { } // delete from change_tag - $dbw->delete( 'change_tag', [ 'ct_tag' => $tag ], __METHOD__ ); + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag ); + $dbw->delete( 'change_tag', [ 'ct_tag_id' => $tagId ], __METHOD__ ); + } else { + $dbw->delete( 'change_tag', [ 'ct_tag' => $tag ], __METHOD__ ); + } if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) { $dbw->delete( 'change_tag_def', [ 'ctd_name' => $tag ], __METHOD__ ); @@ -1406,7 +1464,7 @@ class ChangeTags { /** * Lists tags explicitly defined in the `valid_tag` table of the database. * Tags in table 'change_tag' which are not in table 'valid_tag' are not - * included. + * included. In case of new backend loads the data from `change_tag_def` table. * * Tries memcached first. * @@ -1421,11 +1479,16 @@ class ChangeTags { $cache->makeKey( 'valid-tags-db' ), WANObjectCache::TTL_MINUTE * 5, function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) { + global $wgChangeTagsSchemaMigrationStage; $dbr = wfGetDB( DB_REPLICA ); $setOpts += Database::getCacheSetOptions( $dbr ); - $tags = $dbr->selectFieldValues( 'valid_tag', 'vt_tag', [], $fname ); + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { + $tags = self::listExplicitlyDefinedTagsNewBackend(); + } else { + $tags = $dbr->selectFieldValues( 'valid_tag', 'vt_tag', [], $fname ); + } return array_filter( array_unique( $tags ) ); }, @@ -1437,6 +1500,22 @@ class ChangeTags { ); } + /** + * Lists tags explicitly user defined tags. When ctd_user_defined is true. + * + * @return string[] Array of strings: tags + * @since 1.25 + */ + private static function listExplicitlyDefinedTagsNewBackend() { + $dbr = wfGetDB( DB_REPLICA ); + return $dbr->selectFieldValues( + 'change_tag_def', + 'ctd_name', + [ 'ctd_user_defined' => 1 ], + __METHOD__ + ); + } + /** * Lists tags defined by core or extensions using the ListDefinedTags hook. * Extensions need only define those tags they deem to be in active use. @@ -1506,10 +1585,8 @@ class ChangeTags { * @return array Array of string => int */ public static function tagUsageStatistics() { - global $wgChangeTagsSchemaMigrationStage, $wgTagStatisticsNewTable; - if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH || - ( $wgTagStatisticsNewTable && $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) - ) { + global $wgChangeTagsSchemaMigrationStage; + if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) { return self::newTagUsageStatistics(); }