WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#32362 closed defect (bug) (fixed)

Comments count: wp_count_comments() should not count spam toward totals

Reported by: afercia Owned by: wonderboymusic
Milestone: 4.4 Priority: normal
Severity: normal Version: 4.2
Component: Comments Keywords: needs-unit-tests has-patch
Focuses: Cc:

Description

Or at least shouldn't be used to update the "displaying items" count the way it is now. Quickly discussed with @boone on Slack, going to provide an example, trying to do my best. In the Comments screen, the default view shows just the approved + pending comments. Say wp_count_comments() returns the following result (that's the comments count in my local environment):

object(stdClass)#339 (6) {
  ["moderated"] => string(1) "6"
  ["approved"] => string(2) "34"
  ["post-trashed"] => string(1) "2"
  ["spam"] => string(2) "14"
  ["trash"] => string(1) "8"
  ["total_comments"] => int(54)
}

and the "per page" option is 20, the default. The initial view will show these numbers, notice the "40 items" count displayed on the right:

https://cldup.com/B4cGksm5u1.png

Now trash a comment, all the counts will be updated via JavaScript avoiding to call wp_count_comments() and the highlighted count will correctly show "39":

https://cldup.com/SYnC3PZjLJ.png

Now click on the "undo" link: I should get again "40 items" and instead I get "54", the pagination will show 3 pages too:

https://cldup.com/E7m-6vlGQk.png

Checking _wp_ajax_delete_comment_response() see https://core.trac.wordpress.org/browser/tags/4.2/src/wp-admin/includes/ajax-actions.php#L353 I can see two cases where wp_count_comments() is called and returns the 'total_comments' count, which is not the number we need here. We need approved + pending while 'total_comments' includes spam too. The two cases are:

  • when you're on a "page break" and this is our example case: 40/20 = 0
  • randomly when a generated number between 1 and the $per_page value will be 1

the second one looks a bit arbitrary to me and doesn't exactly reflects what the comment in the code say ("and about 1 other time per page"). Anyways, there's always a chance you get the wrong number and that could happen on your first click or after several ones.

Fixing wp_count_comments() to exclude "spam" from 'total_comments' would be trivial but I'm not sure if this is used somewhere else or could affect plugins.

Maybe, wp_count_comments() should return also a 'all' count in addition to the existing ones ?

Please also notice that when you're in the "All" view, meaning: /wp-admin/edit-comments.php?comment_status=all things are a bit different since "all" doesn't exist as comment count type and thus _wp_ajax_delete_comment_response will use the decremented value $total += $delta. Introducing a "all" count could probably make this a bit more consistent.

Related: #17275, #11200 see also #19903

Attachments (2)

32362.diff (600 bytes) - added by dipesh.kakadiya 3 years ago.
Problem is $total count is 0 and in '_wp_ajax_delete_comment_response' we have check ( ! $total ) )
32362_1.diff (1.5 KB) - added by dipesh.kakadiya 3 years ago.
Added all argument for get_comment_count

Download all attachments as: .zip

Change History (16)

#1 follow-up: @boonebgorges
3 years ago

  • Keywords needs-patch needs-unit-tests added
  • Milestone changed from Awaiting Review to Future Release

I poked around the plugin repo a little bit to see what people are doing with wp_count_comments(). In many cases, they're not looking at 'total_comments' at all. In many other cases, excluding 'spam' from that count would probably fix bugs in the plugins. That being said, I don't think it's worth breaking backward compatibility for such a widely used function, even if the current functionality is kinda odd.

So I'd lean toward introducing an 'all' parameter, and then using it as appropriate in core.

This ticket was mentioned in Slack in #core by afercia. View the logs.


3 years ago

#3 in reply to: ↑ 1 @afercia
3 years ago

Replying to boonebgorges:

So I'd lean toward introducing an 'all' parameter, and then using it as appropriate in core.

Thanks @boonebgorges :) I could make a patch but definitely can't do unit test. Would greatly appreciate some devs eyes on this.

This ticket was mentioned in Slack in #core by afercia. View the logs.


3 years ago

@dipesh.kakadiya
3 years ago

Problem is $total count is 0 and in '_wp_ajax_delete_comment_response' we have check ( ! $total ) )

#5 @dipesh.kakadiya
3 years ago

  • Keywords has-patch added; needs-patch removed

#6 @dipesh.kakadiya
3 years ago

@boonebgorges

total_comments = approved + awaiting_moderation all = spam + approved + awaiting_moderation

is above equation right for comment count?

#7 @afercia
3 years ago

"all" should be just approved + moderated, that's the whole point of this ticket :)

@dipesh.kakadiya
3 years ago

Added all argument for get_comment_count

#8 @dipesh.kakadiya
3 years ago

@boonebgorges @afercia

Patch with introducing an 'all' parameter and used it in _wp_ajax_delete_comment_response.

#9 @wonderboymusic
3 years ago

  • Milestone changed from Future Release to 4.4
  • Owner set to wonderboymusic
  • Status changed from new to assigned

#10 @wonderboymusic
3 years ago

Thanks @dipesh.kakadiya, can you give me steps to reproduce the bug? I can't seem to get the wrong numbers to show up...

#11 @dipesh.kakadiya
3 years ago

@wonderboymusic

  1. Go to comment page
  2. From list of comment make any comment as spam
  3. Then top right side total numer will decrease ( working perfectly)
  4. After click on undo link comment is revert back from spam but on right corner total comment count is not increase.

For more description you can check ticket description.

#12 @wonderboymusic
3 years ago

I can't reproduce: https://wordpress.slack.com/files/wonderboymusic/F0AHGD75J/32362.mov

Can you check the database of the comment you are spamming, and tell me if it has multiple values for _wp_trash_meta_status?

#13 @afercia
3 years ago

@wonderboymusic to reproduce:

  • make sure your "per page" screen option is set to 20
  • seen your video, your initial view shows 42 items. Make sure it lists 40 or 41 items.
Last edited 3 years ago by afercia (previous) (diff)

#14 @wonderboymusic
3 years ago

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

In 34161:

In _wp_ajax_delete_comment_response(), read the new 'all' prop returned by get_comment_count() via wp_count_comments() when setting $total. 'all' doesn't include spam in its count.

Updates unit tests.

Props dipesh.kakadiya.
Fixes #32362.

Note: See TracTickets for help on using tickets.