65 'table' =>
'revision_comment_temp',
66 'pk' =>
'revcomment_rev',
67 'field' =>
'revcomment_comment_id',
70 'deprecatedIn' =>
null,
72 'img_description' => [
74 'deprecatedIn' =>
'1.32',
100 $this->stage = $migrationStage;
114 $store =
new CommentStore( MediaWikiServices::getInstance()->getContentLanguage(),
126 return MediaWikiServices::getInstance()->getCommentStore();
135 private function getKey( $methodKey =
null ) {
136 $key = $this->
key ?? $methodKey;
137 if (
$key ===
null ) {
139 throw new InvalidArgumentException(
'$key should not be null' );
165 $fields[
"{$key}_text"] =
$key;
166 $fields[
"{$key}_data"] =
'NULL';
167 $fields[
"{$key}_cid"] =
'NULL';
170 $fields[
"{$key}_old"] =
$key;
173 $tempTableStage = isset( $this->tempTables[
$key] )
176 $fields[
"{$key}_pk"] = $this->tempTables[
$key][
'joinPK'];
179 $fields[
"{$key}_id"] =
"{$key}_id";
203 if ( !array_key_exists(
$key, $this->joinCache ) ) {
209 $fields[
"{$key}_text"] =
$key;
210 $fields[
"{$key}_data"] =
'NULL';
211 $fields[
"{$key}_cid"] =
'NULL';
213 $join = $this->stage ===
MIGRATION_NEW ?
'JOIN' :
'LEFT JOIN';
215 $tempTableStage = isset( $this->tempTables[
$key] )
218 $t = $this->tempTables[
$key];
219 $alias =
"temp_$key";
221 $joins[$alias] = [ $join,
"{$alias}.{$t['pk']} = {$t['joinPK']}" ];
223 $joinField =
"{$alias}.{$t['field']}";
229 $joins[$alias][0] =
'LEFT JOIN';
230 $joinField =
"(CASE WHEN {$key}_id != 0 THEN {$key}_id ELSE {$alias}.{$t['field']} END)";
231 throw new LogicException(
'Nothing should reach this code path at this time' );
235 $joinField =
"{$key}_id";
238 $alias =
"comment_$key";
240 $joins[$alias] = [ $join,
"{$alias}.comment_id = {$joinField}" ];
243 $fields[
"{$key}_text"] =
"{$alias}.comment_text";
245 $fields[
"{$key}_text"] =
"COALESCE( {$alias}.comment_text, $key )";
247 $fields[
"{$key}_data"] =
"{$alias}.comment_data";
248 $fields[
"{$key}_cid"] =
"{$alias}.comment_id";
251 $this->joinCache[
$key] = [
258 return $this->joinCache[
$key];
275 if ( array_key_exists(
"{$key}_text", $row ) && array_key_exists(
"{$key}_data", $row ) ) {
276 $cid = $row[
"{$key}_cid"] ??
null;
277 $text = $row[
"{$key}_text"];
278 $data = $row[
"{$key}_data"];
282 wfLogWarning(
"Using deprecated fallback handling for comment $key" );
285 wfLogWarning(
"Missing {$key}_text and {$key}_data fields in row with MIGRATION_OLD" );
290 $tempTableStage = isset( $this->tempTables[
$key] )
293 if ( $tempTableStage >
MIGRATION_OLD && array_key_exists(
"{$key}_id", $row ) ) {
295 throw new InvalidArgumentException(
296 "\$row does not contain fields needed for comment $key and getComment(), but "
297 .
"does have fields for getCommentLegacy()"
300 $id = $row[
"{$key}_id"];
301 $row2 = $db->selectRow(
303 [
'comment_id',
'comment_text',
'comment_data' ],
304 [
'comment_id' => $id ],
308 if ( !$row2 && $tempTableStage <
MIGRATION_NEW && array_key_exists(
"{$key}_pk", $row ) ) {
310 throw new InvalidArgumentException(
311 "\$row does not contain fields needed for comment $key and getComment(), but "
312 .
"does have fields for getCommentLegacy()"
315 $t = $this->tempTables[
$key];
316 $id = $row[
"{$key}_pk"];
317 $row2 = $db->selectRow(
318 [
$t[
'table'],
'comment' ],
319 [
'comment_id',
'comment_text',
'comment_data' ],
323 [
'comment' => [
'JOIN', [
"comment_id = {$t['field']}" ] ] ]
327 wfLogWarning(
"Using deprecated fallback handling for comment $key" );
328 $row2 = (
object)[
'comment_text' => $row[
$key],
'comment_data' =>
null ];
330 if ( $row2 ===
null ) {
331 throw new InvalidArgumentException(
"\$row does not contain fields needed for comment $key" );
335 $cid = $row2->comment_id;
336 $text = $row2->comment_text;
337 $data = $row2->comment_data;
338 } elseif ( $this->stage <
MIGRATION_NEW && array_key_exists(
"{$key}_old", $row ) ) {
340 $text = $row[
"{$key}_old"];
353 if ( $data !==
null ) {
355 if ( !is_object( $data ) ) {
357 wfLogWarning(
"Invalid JSON object in comment: $data" );
361 $data = (
array)$data;
362 if ( isset( $data[
'_message'] ) ) {
364 ->setInterfaceMessageFlag(
true );
366 if ( !empty( $data[
'_null'] ) ) {
369 foreach ( $data
as $k => $v ) {
370 if ( substr( $k, 0, 1 ) ===
'_' ) {
399 if ( $this->
key !==
null ) {
404 if ( $row ===
null ) {
406 throw new InvalidArgumentException(
'$row must not be null' );
433 if ( $this->
key !==
null ) {
438 if ( $row ===
null ) {
440 throw new InvalidArgumentException(
'$row must not be null' );
469 # Truncate comment in a Unicode-sensitive manner
470 $comment->text = $this->lang->truncateForVisual( $comment->text, self::COMMENT_CHARACTER_LIMIT );
473 $dbData = $comment->data;
474 if ( !$comment->message instanceof
RawMessage ) {
475 if ( $dbData ===
null ) {
476 $dbData = [
'_null' =>
true ];
480 if ( $dbData !==
null ) {
482 $len = strlen( $dbData );
483 if ( $len > self::MAX_DATA_LENGTH ) {
485 throw new OverflowException(
"Comment data is too long ($len bytes, maximum is $max)" );
489 $hash =
self::hash( $comment->text, $dbData );
494 'comment_hash' => $hash,
495 'comment_text' => $comment->text,
496 'comment_data' => $dbData,
500 if ( !$comment->id ) {
504 'comment_hash' => $hash,
505 'comment_text' => $comment->text,
506 'comment_data' => $dbData,
533 $fields[
$key] = $this->lang->truncateForDatabase( $comment->text, 255 );
537 $tempTableStage = isset( $this->tempTables[
$key] )
540 $t = $this->tempTables[
$key];
542 $commentId = $comment->id;
543 $callback =
function ( $id )
use ( $dbw, $commentId,
$t, $func ) {
548 $t[
'field'] => $commentId,
555 $fields[
"{$key}_id"] = $comment->id;
559 return [ $fields, $callback ];
579 if ( $this->
key !==
null ) {
584 if ( $comment ===
null ) {
586 throw new InvalidArgumentException(
'$comment can not be null' );
590 $tempTableStage = isset( $this->tempTables[
$key] )
593 throw new InvalidArgumentException(
"Must use insertWithTempTable() for $key" );
623 if ( $this->
key !==
null ) {
628 if ( $comment ===
null ) {
630 throw new InvalidArgumentException(
'$comment can not be null' );
634 if ( !isset( $this->tempTables[
$key] ) ) {
635 throw new InvalidArgumentException(
"Must use insert() for $key" );
636 } elseif ( isset( $this->tempTables[
$key][
'deprecatedIn'] ) ) {
637 wfDeprecated( __METHOD__ .
" for $key", $this->tempTables[
$key][
'deprecatedIn'] );
642 $callback =
function () {
646 return [ $fields, $callback ];
655 $key =
count( $msg->getKeysToTry() ) > 1 ? $msg->getKeysToTry() : $msg->getKey();
658 if ( $param instanceof Message ) {
674 $key = array_shift( $data );
675 foreach ( $data
as &$param ) {
676 if ( is_object( $param ) ) {
677 $param = (
array)$param;
679 if ( is_array( $param ) &&
count( $param ) === 1 && isset( $param[
'message'] ) ) {
683 return new Message(
$key, $data );
692 public static function hash( $text, $data ) {
693 $hash = crc32( $text ) ^ crc32( (
string)$data );
697 if ( $hash >= 0x80000000 ) {