#49236 closed enhancement (fixed)
Use 'comment' instead of '' for the comment_type db field for comments
Reported by: | imath | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | 5.5 | Priority: | normal |
Severity: | normal | Version: | 5.4 |
Component: | Comments | Keywords: | has-patch early commit has-dev-note dev-reviewed |
Focuses: | Cc: |
Description
Following @aaroncampbell and @jeremyfelt suggestions on #35214 this ticket is a first step to bring custom comment types into WordPress. This first step's goal is to start using comment
for the comment_type
field value of the wp_comments
table.
To build the patch I've tried to make sure all functions/requests now use 'comment'
instead of ''
. I've tested the upgrade routine with some comments.
I haven't set the milestone as I'm unsure if this is something that is doable before 5.4-beta1. I imagine the upgrade routine might need some testing on websites having a lot of comments.
Attachments (6)
Change History (44)
#2
@
5 years ago
Hi @dshanske
Thanks a lot for pointing me to the split terms upgrade ticket. I will look into it once 5.4.0 is released, which means I think it's safer to move this 5.5.0 once this milestone will be created.
This ticket was mentioned in Slack in #core by imath. View the logs.
5 years ago
#5
@
5 years ago
- Keywords early added; needs-refresh removed
I've just refreshed the patch using a batch process similar to what was done to split terms. It would be great if we could progress on this ticket early during 5.5.0 dev cycle.
I've tested the patch successfully after using the WP CLI command wp comment generate --count=500 --post_id=1
Thanks in advance for your help.
This ticket was mentioned in Slack in #core by imath. View the logs.
5 years ago
This ticket was mentioned in Slack in #core by david.baumwald. View the logs.
5 years ago
This ticket was mentioned in Slack in #core by imath. View the logs.
5 years ago
#10
@
5 years ago
I've tested the most recent patch, and it works as intended. I also check that existing comments we slowly batch updated with a comment_type
of "comment". I'm hoping this catches a review and moves forward for 5.5.
#13
@
5 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
I'm seeing two issues in [47597]:
wp_insert_comment( [ 'comment_type' => '' ] );
will still insert an empty string due to theisset()
check.- In
WP_Comment_Query::get_comment_ids()
the previous$comment_types[ $operator ][] = "''";
line needs to be restored otherwise not yet migrated comments will be missing when usingget_comments( [ 'type' => 'comment' ] )
.
#14
@
5 years ago
Thanks for catching these issues @ocean90.
About the first one, I suggest to add 2 unit tests (see 49236.3.ut.patch), 1 for wp_handle_comment_submission()
and the other one for wp_insert_comment()
I agree we should commit your patch.
#18
@
5 years ago
I thought I would jump in to share my experience with this change, when maintaining themes.
In r47597, Twenty Ten had to be updated to take the new type into account and ensure that new comments get displayed properly on sites using that theme. This seems like a small change, but in practice I found that several themes, even popular ones that are actively maintained, use the same switch
method as in Twenty Ten and will be impacted by this change.
A dev note (with a cross-post to make/themes) will definitely be useful for theme developers that monitor core changes. However, I worry that some theme authors may not have enough time to implement those changes and get all sites updated before WordPress 5.5 rolls out. This is especially true for themes in the WordPress.org theme repository.
With this in mind, should we attempt to post that dev note as early as possible so theme authors can start working on updates today?
#23
@
4 years ago
Do we have any feeling on what impact this will have on sites with a large number of comments that need updating?
So, as an example, I've been asked this by a site owner that currently has around 4.5 million comments. Batching up in 100, do we have an idea of how long this might take and what's the impact whilst this is running?
#24
@
4 years ago
@imath I have a concern about how the SQL UPDATE
will bypass updates to the object cache. I believe it would be preferable follow the model of wp_delete_auto_drafts()
which grabs the post IDs and then loops over each to call wp_delete_post()
. In the same way, instead of doing:
<?php $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->comments} SET comment_type = 'comment' WHERE comment_type = '' ORDER BY comment_ID DESC LIMIT %d", $comment_batch_size ) );
Should it not rather do:
<?php $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM {$wpdb->comments} WHERE comment_type = '' ORDER BY comment_ID DESC LIMIT %d", $comment_batch_size ) ); foreach ( (array) $comment_ids as $comment_id ) { wp_update_comment( [ 'comment_ID' => $comment_id, 'comment_type' => 'comment', ] ); }
Otherwise, calls to get_comment()
will not include the updated comment_type
on sites with a persistent/external object cache.
#25
@
4 years ago
Hi @westonruter
Thanks a lot for your comment. I understand your concern. I'm fine with what you're suggesting, but I wonder if we could find a way that would require as less as possible database sollicitation.
If it only concerns the get_comment()
function what about doing :
function get_comment( &$comment = null, $output = OBJECT ) { // beginning of the code of the function if ( ! $_comment ) { return null; } if ( '' === $_comment->comment_type ) { $_comment->comment_type = 'comment'; } /** * Fires after a comment is retrieved.
Otherwise, what about doing:
$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM {$wpdb->comments} WHERE comment_type = '' ORDER BY comment_ID DESC LIMIT %d", $comment_batch_size ) ); $in_comment_ids = implode( ',', wp_parse_id_list( $comment_ids ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->comments} SET comment_type = 'comment' WHERE comment_ID IN ({$in_comment_ids}) ) ); clean_comment_cache( $comment_ids );
#26
@
4 years ago
Changing get_comment()
like so wouldn't be enough since it wouldn't account for people using WP_Comment
directly. So it would need to be done at a lower level, like:
-
src/wp-includes/class-wp-comment.php
a b final class WP_Comment { 186 186 return false; 187 187 } 188 188 189 if ( empty( $_comment->comment_type ) ) { 190 $_comment->comment_type = 'comment'; 191 } 192 189 193 wp_cache_add( $_comment->comment_ID, $_comment, 'comment' ); 190 194 }
So I think I prefer the second alternative you proposed, where UPDATE
is done followed by clean_comment_cache()
, although with one adjustment: add a safeguard in the WHERE
to double-confirm that the comment_type
is indeed empty. Like so:
-
src/wp-includes/comment.php
a b function _wp_batch_update_comment_type() { 3840 3840 $comment_batch_size = (int) apply_filters( 'wp_update_comment_type_batch_size', 100 ); 3841 3841 3842 3842 // Update the `comment_type` field value to be `comment` for the next batch of comments. 3843 $ wpdb->query(3843 $comment_ids = $wpdb->get_col( 3844 3844 $wpdb->prepare( 3845 " UPDATE {$wpdb->comments}3846 SET comment_type = 'comment'3845 "SELECT comment_ID 3846 FROM {$wpdb->comments} 3847 3847 WHERE comment_type = '' 3848 3848 ORDER BY comment_ID DESC 3849 3849 LIMIT %d", … … function _wp_batch_update_comment_type() { 3851 3851 ) 3852 3852 ); 3853 3853 3854 $in_comment_ids = implode( ',', wp_parse_id_list( $comment_ids ) ); 3855 3856 $wpdb->query( 3857 $wpdb->prepare( 3858 "UPDATE {$wpdb->comments} 3859 SET comment_type = 'comment' 3860 WHERE comment_type = '' AND comment_ID IN ({$in_comment_ids})" 3861 ) 3862 ); 3863 3864 clean_comment_cache( $comment_ids ); 3865 3854 3866 delete_option( $lock_name ); 3855 3867 }
#28
@
4 years ago
Hi,
49236.4.patch is using the second alternative with @westonruter's improvements. I've also included the unit test I used to build the patch just in case.
This ticket was mentioned in Slack in #core by imath. View the logs.
4 years ago
#31
@
4 years ago
- Keywords dev-feedback added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening for the 5.5 branch.
#32
follow-up:
↓ 33
@
4 years ago
- Keywords dev-reviewed added; dev-feedback removed
Looking at [48748], I'm wondering if we should bump the DB version to point to this commit in the upgrade routine. I don't think there is any benefit to a site that is running a development version (the upgrade routine will "run" again, but nothing will be updated and the caches will not clear because no comment IDs will be found), but may be good for accuracy.
Other than that, this looks good to backport. Marking dev-reviewed
pending feedback on my point above. (I'll update with a patch)
#33
in reply to:
↑ 32
@
4 years ago
Replying to desrosj:
Looking at [48748], I'm wondering if we should bump the DB version to point to this commit in the upgrade routine. I don't think there is any benefit to a site that is running a development version (the upgrade routine will "run" again, but nothing will be updated and the caches will not clear because no comment IDs will be found), but may be good for accuracy.
Yes, I was thinking of that and came to the same conclusion :) 49236-db-version-update.diff looks good, thanks!
#36
@
4 years ago
Posting this here as this ticket was refered to in #51082 by @jeremyfelt
.. Twenty Ten had to be updated to take the new type into account and ensure that new comments get displayed properly ..
Actually Twenty Ten and some other themes out there did it right.
They check the actual value of comment_type
, an empty string is a valid value.
Any new comment type would be not shown - as expected.
Most other themes including Twenty Eleven, Twenty Twelve and hundreds more https://wpdirectory.net/search/01EG85WWS35NAC1V7GH59XN2MW are doing it wrong.
They use callbacks with this code:
switch ( $comment->comment_type ) : case 'pingback' : case 'trackback' : break; default : // print normal comment here... break; endswitch;
These themes still "work" with the new behaviour of WP 5.5 but that's accidentally only and can/will lead to unexpected results if ever a new comment_type
will be introduced - each and every theme will have to be updated.
The correct way to implement this custom comment enhancement would be:
- Add a deprecated notice if
callback
param is used, keep rest of code for the time being.
- Add new param
callback_new
which can be used by themes to handle all including new comment types in future.
- Provide example code with
callback_new
in Twenty XXX which checks actual value ofcomment_type
, including a check for empty string, and has no/empty default case.
There imho was no need at all to change the default value of comment_type
and now mess around in years old rows in huge databases with unknown side effects and still get unexpected results with above mentioned themes without extra updates there...
Would urgently suggest to rethink this whole approach.
You might want to have a look at the batch processing of terms introduced in #30261 for a way to split conversion into smaller jobs run by cron.