Merge "Use MediaWiki\SuppressWarnings around trigger_error('') instead @"
[lhc/web/wiklou.git] / includes / CommentStore.php
index 9969b78..cba7a15 100644 (file)
@@ -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
@@ -174,9 +169,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";
                        }
                }
@@ -213,12 +212,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 +287,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 +351,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 +533,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 +549,8 @@ class CommentStore {
                                                $func
                                        );
                                };
-                       } else {
+                       }
+                       if ( $tempTableStage >= MIGRATION_WRITE_BOTH ) {
                                $fields["{$key}_id"] = $comment->id;
                        }
                }
@@ -575,7 +586,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 +630,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 );