0

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 ?

  • This is possible a duplicate of this question – birgire Oct 19 '13 at 16:48
3

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.

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.