67 private $joinCache = [];
99 if ( !array_key_exists( $key, $this->joinCache ) ) {
104 $alias =
"comment_$key";
105 $tables[$alias] =
'comment';
106 $joins[$alias] = [
'JOIN',
"{$alias}.comment_id = {$key}_id" ];
108 $fields[
"{$key}_text"] =
"{$alias}.comment_text";
109 $fields[
"{$key}_data"] =
"{$alias}.comment_data";
110 $fields[
"{$key}_cid"] =
"{$alias}.comment_id";
112 $this->joinCache[$key] = [
119 return $this->joinCache[$key];
136 if ( array_key_exists(
"{$key}_text", $row ) && array_key_exists(
"{$key}_data", $row ) ) {
137 $cid = $row[
"{$key}_cid"] ??
null;
138 $text = $row[
"{$key}_text"];
139 $data = $row[
"{$key}_data"];
142 if ( array_key_exists(
"{$key}_id", $row ) ) {
144 throw new InvalidArgumentException(
145 "\$row does not contain fields needed for comment $key and getComment(), but "
146 .
"does have fields for getCommentLegacy()"
149 $id = $row[
"{$key}_id"];
151 ->select( [
'comment_id',
'comment_text',
'comment_data' ] )
153 ->where( [
'comment_id' => $id ] )
154 ->caller( __METHOD__ )->fetchRow();
156 if ( $row2 ===
null &&
$fallback && isset( $row[$key] ) ) {
157 wfLogWarning(
"Using deprecated fallback handling for comment $key" );
158 $row2 = (object)[
'comment_text' => $row[$key],
'comment_data' =>
null ];
160 if ( $row2 ===
null ) {
161 throw new InvalidArgumentException(
"\$row does not contain fields needed for comment $key" );
165 $cid = $row2->comment_id;
166 $text = $row2->comment_text;
167 $data = $row2->comment_data;
180 if ( $data !==
null ) {
181 $data = FormatJson::decode( $data,
true );
182 if ( !is_array( $data ) ) {
184 wfLogWarning(
"Invalid JSON object in comment: $data" );
188 if ( isset( $data[
'_message'] ) ) {
189 $msg = self::decodeMessage( $data[
'_message'] )
192 if ( !empty( $data[
'_null'] ) ) {
195 foreach ( $data as $k => $v ) {
196 if ( substr( $k, 0, 1 ) ===
'_' ) {
204 return new CommentStoreComment( $cid, $text, $msg, $data );
224 if ( $row ===
null ) {
226 throw new InvalidArgumentException(
'$row must not be null' );
229 return $this->getCommentInternal(
null, $key, $row,
$fallback );
252 if ( $row ===
null ) {
254 throw new InvalidArgumentException(
'$row must not be null' );
257 return $this->getCommentInternal( $db, $key, $row,
$fallback );
283 # Truncate comment in a Unicode-sensitive manner
284 $comment->text = $this->lang->truncateForVisual( $comment->text, self::COMMENT_CHARACTER_LIMIT );
286 if ( !$comment->id ) {
287 $dbData = $comment->data;
288 if ( !$comment->message instanceof
RawMessage ) {
289 $dbData ??= [
'_null' => true ];
290 $dbData[
'_message'] = self::encodeMessage( $comment->message );
292 if ( $dbData !==
null ) {
293 $dbData = FormatJson::encode( (
object)$dbData,
false, FormatJson::ALL_OK );
294 $len = strlen( $dbData );
295 if ( $len > self::MAX_DATA_LENGTH ) {
297 throw new OverflowException(
"Comment data is too long ($len bytes, maximum is $max)" );
301 $hash = self::hash( $comment->text, $dbData );
303 ->select(
'comment_id' )
306 'comment_hash' => $hash,
307 'comment_text' => $comment->text,
308 'comment_data' => $dbData,
310 ->caller( __METHOD__ )->fetchField();
313 ->insertInto(
'comment' )
314 ->row( [
'comment_hash' => $hash,
'comment_text' => $comment->text,
'comment_data' => $dbData ] )
315 ->caller( __METHOD__ )->execute();
318 $comment->id = (int)$commentId;
341 if ( $comment ===
null ) {
343 throw new InvalidArgumentException(
'$comment can not be null' );
348 return [
"{$key}_id" => $comment->id ];
356 private static function encodeMessage(
Message $msg ) {
359 foreach (
$params as &$param ) {
360 if ( $param instanceof
Message ) {
362 'message' => self::encodeMessage( $param )
366 array_unshift(
$params, $key );
375 private static function decodeMessage( $data ) {
376 $key = array_shift( $data );
377 foreach ( $data as &$param ) {
378 if ( is_object( $param ) ) {
379 $param = (array)$param;
381 if ( is_array( $param ) && count( $param ) === 1 && isset( $param[
'message'] ) ) {
382 $param = self::decodeMessage( $param[
'message'] );
385 return new Message( $key, $data );
394 private static function hash( $text, $data ) {
395 $hash = crc32( $text ) ^ crc32( (
string)$data );
399 if ( $hash >= 0x80000000 ) {