Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I need to do a WP_Query with a LIKE on the post_title.

I started with this regular WP_Query:

$wp_query = new WP_Query( 
    array (
        'post_type'        => 'wp_exposants',
        'posts_per_page'   => '1',
        'post_status'      => 'publish',
        'orderby'          => 'title', 
        'order'            => 'ASC',
        'paged'            => $paged
    )
); 

But what I actually want to do looks like this in SQL:

$query = "
        SELECT      *
        FROM        $wpdb->posts
        WHERE       $wpdb->posts.post_title LIKE '$param2%'
        AND         $wpdb->posts.post_type = 'wp_exposants'
        ORDER BY    $wpdb->posts.post_title
";
$wpdb->get_results($query);

The output prints the results i'm excpecting, but I use the regular <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?> to display the results.
And that is not working with $wpdb->get_results().

How can I achieve what I described here?

share|improve this question

2 Answers 2

up vote 16 down vote accepted

I would solve this with a filter on WP_Query. One that detects an extra query variable and uses that as the prefix of the title.

add_filter( 'posts_where', 'wpse18703_posts_where', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
    global $wpdb;
    if ( $wpse18703_title = $wp_query->get( 'wpse18703_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( like_escape( $wpse18703_title ) ) . '%\'';
    }
    return $where;
}

This way you can still call WP_Query, you just pass the title as the wpse18703_title argument (or change the name to something shorter).

share|improve this answer
    
That works perfectly, thank you :) –  Ludo May 30 '11 at 15:24
    
Thanks for this! :) –  Till Oct 17 '11 at 18:49
    
This one is somehow missing the $wpdb->prepare(). –  kaiser Nov 6 '12 at 15:46
    
@kaiser: It's been a long time, but I think this was not possible with prepare(). $wpdb->prepare('LIKE "%s%%"', 'banana') would return "LIKE ''banana'%'", so we have to construct the query ourselves, and do the escaping too. –  Jan Fabry Nov 6 '12 at 19:36
1  
@JanFabry Happy to see you agaaaaaaaain! :) Drop by in chat some time, hm? StopPress would be happy to see you. About that prepare(). Yeah, that's tricky and I had to try that several times, before I got around it. From something I just made: $wpdb->prepare( ' AND {$wpdb->posts}.post_title LIKE %s ', esc_sql( '%'.like_escape( trim( $term ) ).'%' ) ). And I'm pretty sure the esc_sql() is unnecessary and just paranoid. –  kaiser Nov 7 '12 at 10:35

Simplified:

function title_filter( $where, &$wp_query )
        {
            global $wpdb;
            if ( $search_term = $wp_query->get( 'search_prod_title' ) ) {
                $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
            }
            return $where;
        }

  $args = array(
    'post_type' => 'product',
    'posts_per_page' => $page_size,
    'paged' => $page,
    'search_prod_title' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'
  );

  add_filter( 'posts_where', 'title_filter', 10, 2 );
  $wp_query = new WP_Query($args);
  remove_filter( 'posts_where', 'title_filter', 10, 2 );
  return $wp_query;
share|improve this answer
5  
Please include an explanation along with your code. –  s_ha_dum Apr 19 '13 at 13:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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