WordPress 3.5 has introduced meta queries for the WP_Comment_Query class, which allows us to retrieve comments from the database that have specific meta values and/or keys attached to theme, just like we have been able to do with posts since 3.2.
It is a pretty straight forward process. We simply pass an array to the meta_query argument with the keys / values we want to query, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $args = array( 'meta_query' => array( array( 'key' => 'your_meta_key', 'value' => 'meta_value' ) ) ); $comments_query = new WP_Comment_Query; $comments = $comments_query->query( $args ); if( $comments ) : foreach( $comments as $comment ) : // do stuff with comments here endforeach; endif; |
You can also query multiple meta values/keys, like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $args = array( 'meta_query' => array( array( 'key' => 'your_meta_key', 'value' => 'meta_value' ), array( 'key' => 'second_key', 'value' => 'value_2' ) ) ); $comments_query = new WP_Comment_Query; $comments = $comments_query->query( $args ); if( $comments ) : foreach( $comments as $comment ) : // do stuff with comments here endforeach; endif; |
When passing multiple keys/values, WordPress will assume an AND relation for the meta fields, meaning that only comments with both meta keys and values will be returned. You can change this, however, to an OR relation so that comments with one or both meta keys/values are returned:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | $args = array( 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'your_meta_key', 'value' => 'meta_value' ), array( 'key' => 'second_key', 'value' => 'value_2' ) ) ); $comments_query = new WP_Comment_Query; $comments = $comments_query->query( $args ); if( $comments ) : foreach( $comments as $comment ) : // do stuff with comments here endforeach; endif; |
If you have never worked with comment meta before, here are some related functions you will find useful:
Would be useful in combination with plugins like Feature Comments (http://wordpress.org/extend/plugins/feature-comments/), ilke I use on CSS-Tricks to highlight good comments. I could make a widget (or whatever) to display the most recent featured comments.
That’s a great idea. How do you currently mark comments as featured? In the admin or the front end?
Both! It injects links into the comment threads so you can click from there. Or, you can mark it Ajax-y style from the admin area where you mark stuff as spam/delete/edit/etc, AND you can use radio buttons to mark them from the screen where you edit comments in the full-on edit-mode.
Alright, I have a question. I’m trying to use your featured comment plugin and then sort by featured comments so those show at the top.
So how do I apply this to wp_list_comments? It accepts $comments, which is the result of the normal get_comments() query. So in your example would I execute that query before wp_list_comments and then pass the final $comments through wp_list_comments?
I would suggest you use the pre_get_comments hook, which works just like pre_get_posts, to apply your meta query before wp_list_comments() is called.
Alright, this is way more complex than I original thought.
The query args don’t work right because when you set
'orderby' => 'meta_value',
'meta_key' => 'featured',
or similar, it *only* grabs the comments that are marked featured.
Additionally it seems the pre_get_comments only doesn’t fire on wp_list_comments. It does when you use get_comments() (which runs a straight query like you have in your code) but that isn’t required to pass to wp_list_comments but is optional.
I’m starting to think giving the current limitations and dealing with threading what I originally set out to do isn’t possible.
Oh dang, I hadn’t thought about that. Maybe an idea would be to actually do two comment queries, one for featured and then one (normal) for all others. That way you’d end up with two comment loops and they’d be stacked on top of each other. You could easily exclude featured comments from showing up in the bottom set.
Yeah so I actually tried that when I was messing with everything. For top level comments that works, however replies are all screwy. If you reply to a top level featured comment, the reply does not inherit the featured status, so when its posted it shows with the “normal” comments below.
I’m not sure how, but basically there needs to be a check when a comment is posted, that if the parent is featured then make it featured as well.
Ah, that’s an interesting problem. I can see a couple of possible solutions:
Add a helper function to get comment IDs for all replies of featured comments so that these can be passed to an exclude parameter
Apply the “featured” status to child (reply) comments when marking a parent as featured. This would also include marking a child as featured if it is left on an already-featured comment
Thoughts?
I think there are two parts that would need to be done.
The first would deal with featuring/unfeaturing comments. It would need to perform the action on all child comments regardless of depth. So if I mark a comment featured that has 3 levels, all of them get marked featured.
The second thing would be for making replies after a comment has already been marked. I’m not sure where this would be hooked, but basically on comment post it needs to get the parent comment ID and check to see if it is featured, and if it is then inherit that.
Needless to say at first glance I didn’t think this would be that big of a deal, but then I forgot how screwy the comments are 😛
This has definitely turned into a bit of a rabbit hole 😀
I’m going to do some updates to the plugin next week so I’ll see if I can work some of this in.
It’s a bummer that WP_Comment_Query doesn’t allow for custom selection of columns. Query optimization is a good thing, and having the ability to choose a single column, or any specific number of columns would be nice.
Hello,
I am looking for an Custom Query for the Commenting.
Thanks for Sharing.