From 61a2f62ffd7db9fd83fc3ecff2a786370c1b7cec Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 17 Apr 2020 19:35:06 +0000 Subject: [PATCH] Comments: Use `comment` instead of an empty string for the `comment_type` DB field value in comments table. This is the first step to bring support for custom comment types into WordPress. Add a scheduled upgrade routine to update the type value for existing comments, in batches of 100 at a time. Props imath, aaroncampbell, jeremyfelt, dshanske. Fixes #49236. Built from https://develop.svn.wordpress.org/trunk@47597 git-svn-id: http://core.svn.wordpress.org/trunk@47372 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/ajax-actions.php | 2 +- wp-admin/includes/schema.php | 2 +- wp-admin/includes/upgrade.php | 16 ++++ wp-content/themes/twentyten/functions.php | 1 + wp-includes/class-wp-comment-query.php | 2 +- wp-includes/class-wp-comment.php | 3 +- wp-includes/comment.php | 87 +++++++++++++++++-- wp-includes/default-filters.php | 4 + .../class-wp-rest-comments-controller.php | 2 +- wp-includes/version.php | 4 +- 10 files changed, 111 insertions(+), 12 deletions(-) diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index d46e94ff24..3b551db6c0 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -1283,7 +1283,7 @@ function wp_ajax_replyto_comment( $action ) { $comment_author_email = wp_slash( $user->user_email ); $comment_author_url = wp_slash( $user->user_url ); $comment_content = trim( $_POST['content'] ); - $comment_type = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : ''; + $comment_type = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : 'comment'; if ( current_user_can( 'unfiltered_html' ) ) { if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) ) { diff --git a/wp-admin/includes/schema.php b/wp-admin/includes/schema.php index 614a37457a..da6c4b13ef 100644 --- a/wp-admin/includes/schema.php +++ b/wp-admin/includes/schema.php @@ -111,7 +111,7 @@ CREATE TABLE $wpdb->comments ( comment_karma int(11) NOT NULL default '0', comment_approved varchar(20) NOT NULL default '1', comment_agent varchar(255) NOT NULL default '', - comment_type varchar(20) NOT NULL default '', + comment_type varchar(20) NOT NULL default 'comment', comment_parent bigint(20) unsigned NOT NULL default '0', user_id bigint(20) unsigned NOT NULL default '0', PRIMARY KEY (comment_ID), diff --git a/wp-admin/includes/upgrade.php b/wp-admin/includes/upgrade.php index 8e3d78cc62..7bb6452ff0 100644 --- a/wp-admin/includes/upgrade.php +++ b/wp-admin/includes/upgrade.php @@ -283,6 +283,7 @@ Commenter avatars come from Gravatar.' 'comment_date' => $now, 'comment_date_gmt' => $now_gmt, 'comment_content' => $first_comment, + 'comment_type' => 'comment', ) ); @@ -834,6 +835,10 @@ function upgrade_all() { upgrade_530(); } + if ( $wp_current_db_version < 47597 ) { + upgrade_550(); + } + maybe_disable_link_manager(); maybe_disable_automattic_widgets(); @@ -2154,6 +2159,17 @@ function upgrade_530() { } } +/** + * Executes changes made in WordPress 5.5.0. + * + * @ignore + * @since 5.5.0 + */ +function upgrade_550() { + update_option( 'finished_updating_comment_type', 0 ); + wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); +} + /** * Executes network-level upgrade routines. * diff --git a/wp-content/themes/twentyten/functions.php b/wp-content/themes/twentyten/functions.php index 96629d1074..6c092f1074 100644 --- a/wp-content/themes/twentyten/functions.php +++ b/wp-content/themes/twentyten/functions.php @@ -418,6 +418,7 @@ if ( ! function_exists( 'twentyten_comment' ) ) : $GLOBALS['comment'] = $comment; switch ( $comment->comment_type ) : case '': + case 'comment': ?>
  • id="li-comment-">
    diff --git a/wp-includes/class-wp-comment-query.php b/wp-includes/class-wp-comment-query.php index d2ab03b127..486faa4e88 100644 --- a/wp-includes/class-wp-comment-query.php +++ b/wp-includes/class-wp-comment-query.php @@ -741,7 +741,7 @@ class WP_Comment_Query { case 'comment': case 'comments': - $comment_types[ $operator ][] = "''"; + $comment_types[ $operator ][] = "'comment'"; break; case 'pings': diff --git a/wp-includes/class-wp-comment.php b/wp-includes/class-wp-comment.php index e633eb5769..3ac8c226e9 100644 --- a/wp-includes/class-wp-comment.php +++ b/wp-includes/class-wp-comment.php @@ -114,9 +114,10 @@ final class WP_Comment { * Comment type. * * @since 4.4.0 + * @since 5.5.0 Default value changed to `comment`. * @var string */ - public $comment_type = ''; + public $comment_type = 'comment'; /** * Parent comment ID. diff --git a/wp-includes/comment.php b/wp-includes/comment.php index 4149c691f9..0da7d13e42 100644 --- a/wp-includes/comment.php +++ b/wp-includes/comment.php @@ -1853,7 +1853,8 @@ function wp_get_unapproved_comment_author_email() { * Inserts a comment into the database. * * @since 2.0.0 - * @since 4.4.0 Introduced `$comment_meta` argument. + * @since 4.4.0 Introduced the `$comment_meta` argument. + * @since 5.5.0 Default value for `$comment_type` argument changed to `comment`. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -1877,7 +1878,7 @@ function wp_get_unapproved_comment_author_email() { * @type int $comment_parent ID of this comment's parent, if any. Default 0. * @type int $comment_post_ID ID of the post that relates to the comment, if any. * Default 0. - * @type string $comment_type Comment type. Default empty. + * @type string $comment_type Comment type. Default 'comment'. * @type array $comment_meta Optional. Array of key/value pairs to be stored in commentmeta for the * new comment. * @type int $user_id ID of the user who submitted the comment. Default 0. @@ -1901,7 +1902,7 @@ function wp_insert_comment( $commentdata ) { $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; - $comment_type = ! isset( $data['comment_type'] ) ? '' : $data['comment_type']; + $comment_type = ! isset( $data['comment_type'] ) ? 'comment' : $data['comment_type']; $comment_parent = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent']; $user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id']; @@ -2043,9 +2044,10 @@ function wp_throttle_comment_flood( $block, $time_lastcomment, $time_newcomment * See {@link https://core.trac.wordpress.org/ticket/9235} * * @since 1.5.0 - * @since 4.3.0 'comment_agent' and 'comment_author_IP' can be set via `$commentdata`. + * @since 4.3.0 Introduced the `comment_agent` and `comment_author_IP` arguments. * @since 4.7.0 The `$avoid_die` parameter was added, allowing the function to * return a WP_Error object instead of dying. + * @since 5.5.0 Introduced the `comment_type` argument. * * @see wp_insert_comment() * @global wpdb $wpdb WordPress database abstraction object. @@ -2060,6 +2062,7 @@ function wp_throttle_comment_flood( $block, $time_lastcomment, $time_newcomment * @type string $comment_date The date the comment was submitted. Default is the current time. * @type string $comment_date_gmt The date the comment was submitted in the GMT timezone. * Default is `$comment_date` in the GMT timezone. + * @type string $comment_type Comment type. Default 'comment'. * @type int $comment_parent The ID of this comment's parent, if any. Default 0. * @type int $comment_post_ID The ID of the post that relates to the comment. * @type int $user_id The ID of the user who submitted the comment. Default 0. @@ -2122,6 +2125,10 @@ function wp_new_comment( $commentdata, $avoid_die = false ) { $commentdata['comment_date_gmt'] = current_time( 'mysql', 1 ); } + if ( empty( $commentdata['comment_type'] ) ) { + $commentdata['comment_type'] = 'comment'; + } + $commentdata = wp_filter_comment( $commentdata ); $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die ); @@ -3348,7 +3355,7 @@ function wp_handle_comment_submission( $comment_data ) { } } - $comment_type = ''; + $comment_type = 'comment'; if ( get_option( 'require_name_email' ) && ! $user->exists() ) { if ( '' == $comment_author_email || '' == $comment_author ) { @@ -3636,3 +3643,73 @@ function wp_comments_personal_data_eraser( $email_address, $page = 1 ) { function wp_cache_set_comments_last_changed() { wp_cache_set( 'last_changed', microtime(), 'comment' ); } + +/** + * Updates the comment type for a batch of comments. + * + * @since 5.5.0 + * + * @global wpdb $wpdb WordPress database abstraction object. + */ +function _wp_batch_update_comment_type() { + global $wpdb; + + $lock_name = 'update_comment_type.lock'; + + // Try to lock. + $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) ); + + if ( ! $lock_result ) { + $lock_result = get_option( $lock_name ); + + // Bail if we were unable to create a lock, or if the existing lock is still valid. + if ( ! $lock_result || ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) ) { + wp_schedule_single_event( time() + ( 5 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); + return; + } + } + + // Update the lock, as by this point we've definitely got a lock, just need to fire the actions. + update_option( $lock_name, time() ); + + // Check if there's still an empty comment type. + $empty_comment_type = $wpdb->get_var( + "SELECT comment_ID FROM $wpdb->comments + WHERE comment_type = '' + LIMIT 1" + ); + + // No empty comment type, we're done here. + if ( ! $empty_comment_type ) { + update_option( 'finished_updating_comment_type', true ); + delete_option( $lock_name ); + return; + } + + // Empty comment type found? We'll need to run this script again. + wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); + + // Update the `comment_type` field value to be `comment` for the next 100 rows of comments. + $wpdb->query( + "UPDATE {$wpdb->comments} + SET comment_type = 'comment' + WHERE comment_type = '' + ORDER BY comment_ID DESC + LIMIT 100" + ); + + delete_option( $lock_name ); +} + +/** + * In order to avoid the _wp_batch_update_comment_type() job being accidentally removed, + * check that it's still scheduled while we haven't finished updating comment types. + * + * @ignore + * @since 5.5.0 + */ +function _wp_check_for_scheduled_update_comment_type() { + if ( ! get_option( 'finished_updating_comment_type' ) && ! wp_next_scheduled( 'wp_update_comment_type_batch' ) ) { + wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'wp_update_comment_type_batch' ); + } +} diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php index b18dbe7544..fd5d9f32f2 100644 --- a/wp-includes/default-filters.php +++ b/wp-includes/default-filters.php @@ -438,6 +438,10 @@ add_action( 'split_shared_term', '_wp_check_split_terms_in_menus', 10, 4 ); add_action( 'split_shared_term', '_wp_check_split_nav_menu_terms', 10, 4 ); add_action( 'wp_split_shared_term_batch', '_wp_batch_split_terms' ); +// Comment type updates. +add_action( 'admin_init', '_wp_check_for_scheduled_update_comment_type' ); +add_action( 'wp_update_comment_type_batch', '_wp_batch_update_comment_type' ); + // Email notifications. add_action( 'comment_post', 'wp_new_comment_notify_moderator' ); add_action( 'comment_post', 'wp_new_comment_notify_postauthor' ); diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 8d241d7c63..f12082c3c0 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -585,7 +585,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller { return $prepared_comment; } - $prepared_comment['comment_type'] = ''; + $prepared_comment['comment_type'] = 'comment'; /* * Do not allow a comment to be created with missing or empty diff --git a/wp-includes/version.php b/wp-includes/version.php index 25f29d37f9..eecab2ad77 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,14 +13,14 @@ * * @global string $wp_version */ -$wp_version = '5.5-alpha-47596'; +$wp_version = '5.5-alpha-47597'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * * @global int $wp_db_version */ -$wp_db_version = 47018; +$wp_db_version = 47597; /** * Holds the TinyMCE version.