0

On WordPress' admin Comments Screen, when searching comments, I'd like the option to only return comments where the author entered something in the optional URL/website field. I am not looking for a way to search within the URL field, but rather, just a way to exclude comments with an empty URL field from my regular comment search.

I've come up with the following working solution that lets me include 'has:url' in my search query to achieve what I want:

add_filter('pre_get_comments','set_has_url_flag');
function set_has_url_flag($query){
    global $pagenow;
    global $onlyhasurl;

    if($pagenow == 'edit-comments.php' && strpos($query->query_vars['search'],"has:url")!==FALSE){
        $query->query_vars['search'] = trim(preg_replace('!\s+!', ' ', str_replace("has:url","",$query->query_vars['search'])));
        $onlyhasurl = TRUE;
        return $query;
    }
    return $query;
}

add_filter('the_comments', 'filter_comments_for_has_url_flag');
function filter_comments_for_has_url_flag($comments){
    global $pagenow;
    global $onlyhasurl;

    if($pagenow == 'edit-comments.php' && isset($onlyhasurl) && $onlyhasurl===TRUE){
        foreach($comments as $key => $value){
            if(empty($value->comment_author_url)){ 
                unset($comments[$key]);
                continue;
            }
        }
    }
    return $comments;
}

The issue with my solution is that it removes comments with empty URL fields AFTER the query is performed, so the number of comments displayed on each page of the Comments Screen varies depending on how many comments were removed because they had an empty 'author_url' value.

Can someone come up with a better way to do this that filters comments before the query is made, so that paging through comments works correctly?

0

We can set the author_url argument of WP_Comment_Query as null (empty string will not work) to search for comments that don't have an author url. Currently (ver 4.8.1) the has_author_url isn't supported.

Using a sub-query to exclude those comments, with no author_url, using comment__not_in, should work, but wouldn't probably scale well. Setting fields as ids would reduce the query data.

Alternatively we can create a helper plugin like this one, to support the _has_author_url input argument for WP_Comment_Query:

<?php
/**
 * Plugin Name: WPSE-278861: Support for the _has_author_url WP_Comment_Query argument
 */
add_filter( 'comments_clauses', function( Array $clauses, \WP_Comment_Query $query ) use ( &$wpdb ) 
{
    if(    isset( $query->query_vars['_has_author_url'] ) 
        && true === $query->query_vars['_has_author_url'] 
    )
        $clauses['where'] = " {$wpdb->comments}.comment_author_url != '' ";

    return $clauses;

}, 10, 2 );

and then use it to support the has:url comments search parameter, on the edit-comments.php screen:

add_action( 'pre_get_comments', function ( \WP_Comment_Query $query )
{
    // Only target the `edit-comments.php` screen
    if( ! did_action( 'load-edit-comments.php' ) )
        return;

    // Only target the search comment's query
    if( ! isset( $query->query_vars['search'] ) )
        return;

    // Only target 'has:url' searches
    if( false === strpos( $query->query_vars['search'], 'has:url' ) )
        return;

    // strip 'has:url' (I leave it as is from the OP)
    $query->query_vars['search'] = trim( 
        preg_replace(
            '!\s+!', ' ', 
            str_replace( 'has:url', '', $query->query_vars['search'] )
        )
    );

    // Query for comments with an author url    
    $query->query_vars['_has_author_url'] = true;

}, 10, 2 );

Note that we got rid of the global variables $onlyhasurl and $pagenow.

This is untested, but hopefully you can adjust it to your needs!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.