X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/pie.php?a=blobdiff_plain;f=includes%2FCommentStore.php;h=994a064f2cf4a5eab02eb5758a6fcf18f526a59a;hb=e50f14a47fdc98c024bbcaca341453a5091f11bb;hp=9969b787821ea9bc45c8b1df717a1b5e1fa68dd7;hpb=c0fa6997ae8e544ca25bbe0796e99de6df5144bd;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/CommentStore.php b/includes/CommentStore.php index 9969b78782..994a064f2c 100644 --- a/includes/CommentStore.php +++ b/includes/CommentStore.php @@ -52,34 +52,29 @@ class CommentStore { /** * Define fields that use temporary tables for transitional purposes - * @var array Keys are '$key', values are arrays with four fields: + * @var array Keys are '$key', values are arrays with these possible fields: * - table: Temporary table name * - pk: Temporary table column referring to the main table's primary key * - field: Temporary table column referring comment.comment_id * - joinPK: Main table's primary key + * - stage: Migration stage + * - deprecatedIn: Version when using insertWithTempTable() was deprecated */ - protected static $tempTables = [ + protected $tempTables = [ 'rev_comment' => [ 'table' => 'revision_comment_temp', 'pk' => 'revcomment_rev', 'field' => 'revcomment_comment_id', 'joinPK' => 'rev_id', + 'stage' => MIGRATION_OLD, + 'deprecatedIn' => null, ], 'img_description' => [ - 'table' => 'image_comment_temp', - 'pk' => 'imgcomment_name', - 'field' => 'imgcomment_description_id', - 'joinPK' => 'img_name', + 'stage' => MIGRATION_NEW, + 'deprecatedIn' => '1.32', ], ]; - /** - * Fields that formerly used $tempTables - * @var array Key is '$key', value is the MediaWiki version in which it was - * removed from $tempTables. - */ - protected static $formerTempTables = []; - /** * @since 1.30 * @deprecated in 1.31 @@ -87,7 +82,11 @@ class CommentStore { */ protected $key = null; - /** @var int One of the MIGRATION_* constants */ + /** + * @var int One of the MIGRATION_* constants + * @todo Deprecate and remove once extensions seem unlikely to need to use + * it for migration anymore. + */ protected $stage; /** @var array[] Cache for `self::getJoin()` */ @@ -99,7 +98,8 @@ class CommentStore { /** * @param Language $lang Language to use for comment truncation. Defaults * to content language. - * @param int $migrationStage One of the MIGRATION_* constants + * @param int $migrationStage One of the MIGRATION_* constants. Always + * MIGRATION_NEW for MediaWiki core since 1.33. */ public function __construct( Language $lang, $migrationStage ) { $this->stage = $migrationStage; @@ -114,10 +114,10 @@ class CommentStore { * @return CommentStore */ public static function newKey( $key ) { - global $wgCommentTableSchemaMigrationStage; wfDeprecated( __METHOD__, '1.31' ); - $store = new CommentStore( MediaWikiServices::getInstance()->getContentLanguage(), - $wgCommentTableSchemaMigrationStage ); + $store = new CommentStore( + MediaWikiServices::getInstance()->getContentLanguage(), MIGRATION_NEW + ); $store->key = $key; return $store; } @@ -174,9 +174,13 @@ class CommentStore { if ( $this->stage < MIGRATION_NEW ) { $fields["{$key}_old"] = $key; } - if ( isset( self::$tempTables[$key] ) ) { - $fields["{$key}_pk"] = self::$tempTables[$key]['joinPK']; - } else { + + $tempTableStage = isset( $this->tempTables[$key] ) + ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; + if ( $tempTableStage < MIGRATION_NEW ) { + $fields["{$key}_pk"] = $this->tempTables[$key]['joinPK']; + } + if ( $tempTableStage > MIGRATION_OLD ) { $fields["{$key}_id"] = "{$key}_id"; } } @@ -193,11 +197,12 @@ class CommentStore { * @since 1.31 Method signature changed, $key parameter added (with deprecated back compat) * @param string|null $key A key such as "rev_comment" identifying the comment * field being fetched. - * @return array With three keys: + * @return array[] With three keys: * - tables: (string[]) to include in the `$table` to `IDatabase->select()` * - fields: (string[]) to include in the `$vars` to `IDatabase->select()` * - joins: (array) to include in the `$join_conds` to `IDatabase->select()` * All tables, fields, and joins are aliased, so `+` is safe to use. + * @phan-return array{tables:string[],fields:string[],joins:array} */ public function getJoin( $key = null ) { $key = $this->getKey( $key ); @@ -213,12 +218,25 @@ class CommentStore { } else { $join = $this->stage === MIGRATION_NEW ? 'JOIN' : 'LEFT JOIN'; - if ( isset( self::$tempTables[$key] ) ) { - $t = self::$tempTables[$key]; + $tempTableStage = isset( $this->tempTables[$key] ) + ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; + if ( $tempTableStage < MIGRATION_NEW ) { + $t = $this->tempTables[$key]; $alias = "temp_$key"; $tables[$alias] = $t['table']; $joins[$alias] = [ $join, "{$alias}.{$t['pk']} = {$t['joinPK']}" ]; - $joinField = "{$alias}.{$t['field']}"; + if ( $tempTableStage === MIGRATION_OLD ) { + $joinField = "{$alias}.{$t['field']}"; + } else { + // Nothing hits this code path for now, but will in the future when we set + // $this->tempTables['rev_comment']['stage'] to MIGRATION_WRITE_NEW while + // merging revision_comment_temp into revision. + // @codeCoverageIgnoreStart + $joins[$alias][0] = 'LEFT JOIN'; + $joinField = "(CASE WHEN {$key}_id != 0 THEN {$key}_id ELSE {$alias}.{$t['field']} END)"; + throw new LogicException( 'Nothing should reach this code path at this time' ); + // @codeCoverageIgnoreEnd + } } else { $joinField = "{$key}_id"; } @@ -275,51 +293,48 @@ class CommentStore { } $data = null; } else { - if ( isset( self::$tempTables[$key] ) ) { - if ( array_key_exists( "{$key}_pk", $row ) ) { - if ( !$db ) { - throw new InvalidArgumentException( - "\$row does not contain fields needed for comment $key and getComment(), but " - . "does have fields for getCommentLegacy()" - ); - } - $t = self::$tempTables[$key]; - $id = $row["{$key}_pk"]; - $row2 = $db->selectRow( - [ $t['table'], 'comment' ], - [ 'comment_id', 'comment_text', 'comment_data' ], - [ $t['pk'] => $id ], - __METHOD__, - [], - [ 'comment' => [ 'JOIN', [ "comment_id = {$t['field']}" ] ] ] + $tempTableStage = isset( $this->tempTables[$key] ) + ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; + $row2 = null; + if ( $tempTableStage > MIGRATION_OLD && array_key_exists( "{$key}_id", $row ) ) { + if ( !$db ) { + throw new InvalidArgumentException( + "\$row does not contain fields needed for comment $key and getComment(), but " + . "does have fields for getCommentLegacy()" ); - } elseif ( $fallback && isset( $row[$key] ) ) { - wfLogWarning( "Using deprecated fallback handling for comment $key" ); - $row2 = (object)[ 'comment_text' => $row[$key], 'comment_data' => null ]; - } else { - throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key" ); } - } else { - if ( array_key_exists( "{$key}_id", $row ) ) { - if ( !$db ) { - throw new InvalidArgumentException( - "\$row does not contain fields needed for comment $key and getComment(), but " - . "does have fields for getCommentLegacy()" - ); - } - $id = $row["{$key}_id"]; - $row2 = $db->selectRow( - 'comment', - [ 'comment_id', 'comment_text', 'comment_data' ], - [ 'comment_id' => $id ], - __METHOD__ + $id = $row["{$key}_id"]; + $row2 = $db->selectRow( + 'comment', + [ 'comment_id', 'comment_text', 'comment_data' ], + [ 'comment_id' => $id ], + __METHOD__ + ); + } + if ( !$row2 && $tempTableStage < MIGRATION_NEW && array_key_exists( "{$key}_pk", $row ) ) { + if ( !$db ) { + throw new InvalidArgumentException( + "\$row does not contain fields needed for comment $key and getComment(), but " + . "does have fields for getCommentLegacy()" ); - } elseif ( $fallback && isset( $row[$key] ) ) { - wfLogWarning( "Using deprecated fallback handling for comment $key" ); - $row2 = (object)[ 'comment_text' => $row[$key], 'comment_data' => null ]; - } else { - throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key" ); } + $t = $this->tempTables[$key]; + $id = $row["{$key}_pk"]; + $row2 = $db->selectRow( + [ $t['table'], 'comment' ], + [ 'comment_id', 'comment_text', 'comment_data' ], + [ $t['pk'] => $id ], + __METHOD__, + [], + [ 'comment' => [ 'JOIN', [ "comment_id = {$t['field']}" ] ] ] + ); + } + if ( $row2 === null && $fallback && isset( $row[$key] ) ) { + wfLogWarning( "Using deprecated fallback handling for comment $key" ); + $row2 = (object)[ 'comment_text' => $row[$key], 'comment_data' => null ]; + } + if ( $row2 === null ) { + throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key" ); } if ( $row2 ) { @@ -342,14 +357,13 @@ class CommentStore { $msg = null; if ( $data !== null ) { - $data = FormatJson::decode( $data ); - if ( !is_object( $data ) ) { + $data = FormatJson::decode( $data, true ); + if ( !is_array( $data ) ) { // @codeCoverageIgnoreStart wfLogWarning( "Invalid JSON object in comment: $data" ); $data = null; // @codeCoverageIgnoreEnd } else { - $data = (array)$data; if ( isset( $data['_message'] ) ) { $msg = self::decodeMessage( $data['_message'] ) ->setInterfaceMessageFlag( true ); @@ -525,8 +539,10 @@ class CommentStore { } if ( $this->stage >= MIGRATION_WRITE_BOTH ) { - if ( isset( self::$tempTables[$key] ) ) { - $t = self::$tempTables[$key]; + $tempTableStage = isset( $this->tempTables[$key] ) + ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; + if ( $tempTableStage <= MIGRATION_WRITE_BOTH ) { + $t = $this->tempTables[$key]; $func = __METHOD__; $commentId = $comment->id; $callback = function ( $id ) use ( $dbw, $commentId, $t, $func ) { @@ -539,7 +555,8 @@ class CommentStore { $func ); }; - } else { + } + if ( $tempTableStage >= MIGRATION_WRITE_BOTH ) { $fields["{$key}_id"] = $comment->id; } } @@ -575,7 +592,9 @@ class CommentStore { // @codeCoverageIgnoreEnd } - if ( isset( self::$tempTables[$key] ) ) { + $tempTableStage = isset( $this->tempTables[$key] ) + ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; + if ( $tempTableStage < MIGRATION_WRITE_NEW ) { throw new InvalidArgumentException( "Must use insertWithTempTable() for $key" ); } @@ -617,10 +636,10 @@ class CommentStore { // @codeCoverageIgnoreEnd } - if ( isset( self::$formerTempTables[$key] ) ) { - wfDeprecated( __METHOD__ . " for $key", self::$formerTempTables[$key] ); - } elseif ( !isset( self::$tempTables[$key] ) ) { + if ( !isset( $this->tempTables[$key] ) ) { throw new InvalidArgumentException( "Must use insert() for $key" ); + } elseif ( isset( $this->tempTables[$key]['deprecatedIn'] ) ) { + wfDeprecated( __METHOD__ . " for $key", $this->tempTables[$key]['deprecatedIn'] ); } list( $fields, $callback ) = $this->insertInternal( $dbw, $key, $comment, $data );