ludo
  • 0
Новичок

WP_Query с «post_title LIKE ‘something%'»?

  • 0

Мне нужно сделать WP_Query с a LIKE на post_title .

Я начал с этого обычного 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
    )
); 

Но то, что я на самом деле хочу сделать, выглядит так в 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);

Вывод печатает результаты, которые я ожидаю, но я использую обычный <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?> для отображения результатов.

И это не работает с $wpdb->get_results() .

Как я могу достичь того, что я описал здесь?

Share
  1. Я бы решил это с помощью фильтра WP_Query . Тот, который обнаруживает дополнительную переменную запроса и использует ее в качестве префикса заголовка.

    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( $wpdb->esc_like( $wpse18703_title ) ) . '%'';
        }
        return $where;
    }
    

    Таким образом, вы все еще можете вызывать WP_Query, вы просто передаете заголовок в качестве wpse18703_title аргумента (или меняете имя на что-то более короткое).

    • 0
  2. Упрощенный:

    function title_filter( $where, &$wp_query )
    {
        global $wpdb;
        // 2. pull the custom query in here:
        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,
        // 1. define a custom query var here to pass your term through:
        '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 );
    return $wp_query;
    
    • 0
  3. Хотел обновить этот код, над которым вы, ребята, работали, для wordpress 4.0 и выше, поскольку esc_sql() устарела в 4.0 выше.

    function title_filter($where, &$wp_query){
        global $wpdb;
    
        if($search_term = $wp_query->get( 'search_prod_title' )){
            /*using the esc_like() in here instead of other esc_sql()*/
            $search_term = $wpdb->esc_like($search_term);
            $search_term = ' '%' . $search_term . '%'';
            $where .= ' AND ' . $wpdb->posts . '.post_title LIKE '.$search_term;
        }
    
        return $where;
    }
    

    Остальные вещи такие же.

    Также я хочу отметить, что вы можете использовать переменную s в аргументах WP_Query для передачи условий поиска, которые, как я полагаю, также будут искать заголовок сообщения.

    Так:

    $args = array(
        'post_type' => 'post',
        's' => $search_term,
        'post_status' => 'publish',
        'orderby'     => 'title', 
        'order'       => 'ASC'        
    );
    $wp_query = new WP_Query($args);
    
    • 0
  4. С некоторым уязвимым решением, опубликованным здесь, я предлагаю немного упрощенную и очищенную версию.

    Во-первых, мы создаем функцию для posts_where фильтра, которая позволяет отображать только сообщения, соответствующие определенным условиям:

    function cc_post_title_filter($where, &$wp_query) {
        global $wpdb;
        if ( $search_term = $wp_query->get( 'cc_search_post_title' ) ) {
            $where .= ' AND ' . $wpdb->posts . '.post_title LIKE '%' . $wpdb->esc_like( $search_term ) . '%'';
        }
        return $where;
    }
    

    Теперь добавим cc_search_post_title в аргументы нашего запроса:

    $args = array(
        'cc_search_post_title' => $search_term, // search post title only
        'post_status' => 'publish',
    );
    

    И, наконец, оберните фильтр вокруг запроса:

    add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
    $query = new WP_Query($args);
    remove_filter( 'posts_where', 'cc_post_title_filter', 10 );
    

    Использование get_posts()

    Некоторые функции, которые извлекают сообщения, не запускают фильтры, поэтому прикрепленные функции фильтрации posts_where не изменят запрос. Если вы планируете использовать get_posts() для запроса своих сообщений, вам нужно установить suppress_filters значение false в массиве аргументов:

    $args = array(
        'cc_search_post_title' => $search_term,
        'suppress_filters' => FALSE,
        'post_status' => 'publish',
    );
    

    Теперь вы можете использовать get_posts() :

    add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
    $posts = get_posts($args);
    remove_filter( 'posts_where', 'cc_post_title_filter', 10 );
    

    Что с s параметром?

    Параметр s доступен:

    $args = array(
        's' => $search_term,
    );
    

    При добавлении поискового запроса в s параметр work и поиск будет выполняться по заголовку сообщения, а также по содержимому сообщения.

    А как насчет title параметра, который был добавлен с WP 4.4?

    Передача поискового запроса в title параметр:

    $args = array(
        'title' => $search_term,
    );
    

    С учетом регистра и LIKE, нет %LIKE% . Это означает, что поиск hello не вернет сообщения с заголовком Hello World или Hello .

    • 0
  5. Опираясь на другие ответы до меня, чтобы обеспечить гибкость в ситуации, когда вы хотите найти сообщение, содержащее слово в метаполе ИЛИ в заголовке сообщения, я даю эту опцию через аргумент «title_filter_relation». В этой реализации я допускаю только ввод «ИЛИ» или «И» со значением по умолчанию «И».

    function title_filter($where, &$wp_query){
        global $wpdb;
        if($search_term = $wp_query->get( 'title_filter' )){
            $search_term = $wpdb->esc_like($search_term); //instead of esc_sql()
            $search_term = ' '%' . $search_term . '%'';
            $title_filter_relation = (strtoupper($wp_query->get( 'title_filter_relation'))=='OR' ? 'OR' : 'AND');
            $where .= ' '.$title_filter_relation.' ' . $wpdb->posts . '.post_title LIKE '.$search_term;
        }
        return $where;
    }
    

    Вот пример кода в действии для очень простого типа сообщения «faq», где вопрос является самим заголовком сообщения:

    add_filter('posts_where','title_filter',10,2);
    $s1 = new WP_Query( array(
        'post_type' => 'faq',
        'posts_per_page' => -1,
        'title_filter' => $q,
        'title_filter_relation' => 'OR',
        'post_status' => 'publish',
        'orderby'     => 'title', 
        'order'       => 'ASC',
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => 'faq_answer',
                'value' => $q,
                'compare' => 'LIKE'
            )
        )
    ));
    remove_filter('posts_where','title_filter',10,2);
    
    • 0

Оставить ответ

You must login to add an answer.