Search with filters and title

The question:

I would like to search in custom_post by title and by the ACF fields.

So, I used the WP_Query WordPress function but I can’t filter by the title, just by the filters.

When I submit my form, I have this kind of URL:

http://example.com/?s=titre&filter1=condition1&filter2=condition2&filter3=condition3

My code:

$title = $_GET['s'];
$args = array(
    'pagename' => $title,
    'numberposts' => -1,
    'post_type' => 'my_custom_post',
    'meta_query' => array(
        array(
            'key' => 'filter_1',
            'value' => $_GET['condition_1']
        ),
        array(
            'key' => 'filter_2',
            'value' => $_GET['condition_2']
        ),
        array(
            'key' => 'filter_3',
            'value' => $_GET['condition_3']
        )
    )
);
$the_query = new WP_Query($args);

Do you have any idea to include the title in the search ?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

First, you are setting $_GET['filterN'] but you are trying to use $_GET['condition_N']. That is not ever going to work right.

Secondly, pagename is an “exact match” value, not a search parameter, and it only works with the “Page” post type (at least so far as I can tell). You are using a CPT and, presumably, you do not want an exact match. If you did the other query conditions would pointless. So that isn’t going to work correctly either.

The simplest thing you can do is the use the s parameter.

$title = esc_textarea( $_GET['s'] );
$args = array(
    's'           => $title,
    'numberposts' => -1,
    'post_type'   => 'my_custom_post',
    'meta_query'  => array(
        array(
            'key'   => 'filter_1',
            'value' => esc_attr( $_GET['filter1'] )
        ),
        array(
            'key'   => 'filter_2',
            'value' => esc_attr( $_GET['filter2'] )
        ),
        array(
            'key'   => 'filter_3',
            'value' => esc_attr( $_GET['filter3'] )
        )
    )
);
$the_query = new WP_Query( $args );

That will search the post title for your $title string. It will also search post_content. To only search the title you will need to filter the search part of the query.

function only_title_search_wpse_119422( $search ) {
    remove_filter( 'posts_search', 'only_title_search_wpse_119422' );

    global $wpdb;

    $pattern = "/({$wpdb->posts}.post_title[^)]+)/";
    preg_match_all( $pattern, $search, $matches );

    if ( ! empty( $matches[0] ) ) {
        $search = sprintf(
            " AND (%s)",
            implode( " AND ", $matches[0] )
        );
    }

    return $search;
}
add_filter( 'posts_search', 'only_title_search_wpse_119422' );

Add that immediately before your secondary query runs.

I can’t tell for sure, but I wonder if you shouldn’t be using a filter on pre_get_posts instead of the secondary query. The same basic ideas should apply in either case.

Note: Always use the esc_*() and other sanitization methods before using $_REQUEST/$_GET/$_POST values in database calls.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment