Make WordPress Core

Opened 16 years ago

Closed 16 years ago

Last modified 16 years ago

#8863 closed defect (bug) (fixed)

wp_set_comment_status action is not raised

Reported by: jehan's profile Jehan Owned by: jehan's profile Jehan
Milestone: 2.9 Priority: normal
Severity: normal Version: 2.8.4
Component: Comments Keywords:
Focuses: Cc:

Description

Hi,

I have a hook on the action 'wp_set_comment_status' and I made tests of changing the status (from an approved comment, to spam, or to moderation pending, then back, etc.) and the action hook has never been activated (I put some log writing on my function, and I could check it was not triggered...).

Maybe I can do a workaround, with edit_comment (is it triggered when only the status changes as well?), but I haven't tested it yet. And anyway it may be slightly more annoying than the wp_set_comment_status.

Seen on 2.7.

Attachments (3)

wp-includes--comment.php.diff (873 bytes) - added by josephscott 16 years ago.
transition_comment_status_test.php (430 bytes) - added by Captaffy 16 years ago.
Plugin used to test whether the transition_comment_status hook has fired
8863.patch (892 bytes) - added by hakre 16 years ago.

Download all attachments as: .zip

Change History (25)

#1 @DD32
16 years ago

2.7 has new comment status transition hooks: http://trac.wordpress.org/browser/trunk/wp-includes/comment.php#L800

For reference, here's the main location that 2.6 called the said hook: http://trac.wordpress.org/browser/branches/2.6/wp-includes/comment.php#L756

#2 @DD32
16 years ago

Yes, I completely missed that wp_set_comment_status is still present in 2.7, And i cant see why it wouldn't be fired.. (but have not tested it)

#3 @Jehan
16 years ago

  • Owner set to Jehan
  • Status changed from new to assigned

Ok I have precised the bug and found the issue (hence how to fix it). In fact this action is raised if you change the status from the wp-admin/edit-comment.php, which is the page where you can check several comments at once then do stuffs as delete, approve, unapprove them, etc.

But when you are in wp-admin/comment.php, which you can reach from a specific post, then clicking on the "Modify" button next to a comment, then it fails.
The case "editedcomment" calls edit_comment () [wp-admin/includes/comment.php], which calls itself wp_update_comment( $_POST) [wp-includes/comment.php].

The error is in this last file. When you call:
wp_transition_comment_status($comment_approved, $comment->comment_approved, $comment);
[line 1118 as of for now]
you have updated the comment in the database just before ($wpdb->query(...) lines 1094 to 1110). Hence $new_status == $old_status, hence the function wp_transition_comment_status does not fire "transition_comment_status".

Conclusion: the solution is to save the old status before running the query. For instance, simply add to line 1093:
$old_status = $commentcomment_approved?;

Tested and working on the 2.7 (not tested on the trunk, but it seems the same and the lines I quoted were from trunk seen on the web).

Is it clear enough or do you need a patch for the trunk?

#4 @Jehan
16 years ago

Oh in fact, my last message is not really answering to the issue. This will fire "transition_comment_status", which is not fired as well when a comment is edited from wp-admin/comment.php (but is fired from wp-admin/edit-comment.php). But the original issue was for "wp_set_comment_status"!

This is even more complicated because wp_set_comment_status itself calls transition_comment_status and it looks like there is the same bug in it (the comment is updated in the database before reloading it, then firing the action with $old_status being in fact the new one)... It would need to be changed as well. In fact, thinking out loud, I think I will do more tests, it is possible that even though it is fired in wp-admin/edit-comment.php, maybe it is with the wrong arguments... I'll get back to you soon.

#5 @hakre
16 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

i've taken a look into the issue.

the problem seems to be solved. in wp-includes/comment.php wp_transition_comment_status() only fires the hook transition_comment_status if the status really changes.

comment.php within the admin includes does not have a function of the names referenced here. I would suggest to close this Issue until further reopening with a reproduceable test (against bleeding).

#6 @josephscott
16 years ago

  • Keywords has-patch added
  • Resolution fixed deleted
  • Status changed from closed to reopened

I've confirmed that this is a problem -trunk. Even though wp_transition_comment_status() was being called, the new and old status that were being passed to it were always the same when using the comment edit form. wp_transition_comment_status() checks and only fires off the actions if they are different. Since they are always the same when using the comment edit form the comment status change actions never fired.

A simple patch has been added to this ticket that tracks the status passed to wp_update_comment() and the current status for the comment that is pulled from the database, then uses those when calling wp_transition_comment_status(). This ensures that if the status was changed the correct values are used and the transition actions fire.

#7 @ryan
16 years ago

Should the form change to use comment_approved instead of comment_status?

#8 @josephscott
16 years ago

Calling it comment_status always made more sense to me, but comment_approved might be more consistent with rest of WP.

#9 @Denis-de-Bernardy
16 years ago

  • Milestone changed from 2.7.2 to 2.8

#10 @automattor
16 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [11124]) Fix status transitions from edit comment form. Props josephscott. fixes #8863

#11 @Captaffy
16 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

wp_transition_comment_status() is still being passed the same action for $new_status and $old_status when doing bulk editing on /wp-admin/edit-comments.php

It is behaving correctly when changing comment statuses one at a time using the ajax buttons.

Seen on 2.8.3 and 2.8.4

#12 @hakre
16 years ago

  • Keywords reporter-feedback added

Please specifiy a step-by-step description on how to reproduce.

#13 @Captaffy
16 years ago

  1. Create a post and publish it.
  1. While still logged in, leave two comments on the post. (Since you're still logged in, they will automatically be approved).
  1. Go to the Edit Comments screen (/wp-admin/edit-comments.php) and check the checkbox for the two new comments.
  1. In the Bulk Actions dropdown, select Unapprove and click Apply.
  1. The comments will be unapproved, but the transition_comment_status hook will not be fired for either of the comments.

This is because the $new_status and $old_status values passed in to the wp_transition_comment_status() function (/wp-includes/comment.php line 811) are both 'approved'. This causes the if-block at line 824 not to be entered and the hook not to be fired.

A possible fix for this is to move the line '$comment = get_comment($comment_id);' in the wp_set_comment_status() function (/wp-includes/comment.php) at line 1066 to line 1055, before the comment status update is done.

#14 @hakre
16 years ago

Thanks for clarification, but I was not able to reproduce step 5. How to test wether or not that hook has been fired? You use a plugin for that? How to make it measureable?

@Captaffy
16 years ago

Plugin used to test whether the transition_comment_status hook has fired

#15 @Captaffy
16 years ago

I've attached a plugin you can use to test whether the hook has fired - transition_comment_status_test.php

If you follow the steps I outlined previously, the attachment will not fire.
If you use the ajax buttons, you will see the text in the plugin displayed on the page, indicating that it has fired. (Note that if you use it with the ajax buttons, you will have to reload the Edit Comments page manually for the comments to show their proper status, since the 'exit;' call in the plugin interferes with the ajax ui changes.)

To see that the $old_status and $new_status values are the same in wp_transition_comment_status when doing bulk editing, add the following -
echo $new_status . ' ' . $old_status . ' '; exit;
to line 823 in /wp-includes/comment.php

#16 @hakre
16 years ago

  • Keywords needs-test added; reporter-feedback removed
  • Milestone changed from 2.8 to 2.9
  • Version changed from 2.7 to 2.8.4

I was able to reproduce against current trunk. Thanks for the plugin.

Attached you will find a patch that should fix it. The transation was run all time against new & new status, looks like a simple regression to me.

Please apply the patch and test.

#17 @hakre
16 years ago

  • Keywords needs-testing added; needs-test removed

#18 @Captaffy
16 years ago

You've got a stray semi-colon in this line -
wp_transition_comment_status($comment_status, $comment_old->comment_approved;, $comment);

Other than that, it works and I haven't noticed any problems.

@hakre
16 years ago

#19 @hakre
16 years ago

Updated the patch to correct the semicolon issue.

#20 @hakre
16 years ago

  • Keywords tested added; needs-testing removed

#21 @ryan
16 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [11860]) Pass correct old status when transitioning comment status. Props hakre. fixes #8863

#22 @hakre
16 years ago

  • Keywords has-patch tested removed

Thanks for getting this solved to everbody involved. Credits must go to Captaffy as well, he did the first patch and the testcase.

Note: See TracTickets for help on using tickets.