WP_Query с "post_title LIKE 'something%'"?
5 ответ
- голосов
-
- 2011-05-30
Я бы решил эту проблему с помощью фильтра в
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
(или измените имя на что-то более короткое).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( $wpdb->esc_like( $wpse18703_title ) ) . '%\''; } return $where; }
This way you can still call
WP_Query
, you just pass the title as thewpse18703_title
argument (or change the name to something shorter).-
Здесь почему-то не хватает `$ wpdb->prepare ()`.This one is somehow missing the `$wpdb->prepare()`.
- 1
- 2012-11-06
- kaiser
-
@kaiser: Прошло много времени,но я думаю,что это было невозможно с `prepare ()`.`$ wpdb->prepare ('LIKE"% s %% "','banana')` вернет "LIKE ''banana '%'" `,поэтому мы должны сами построить запрос и выполнить экранирование.@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.
- 0
- 2012-11-06
- Jan Fabry
-
@JanFabry Рад видеть тебя агааааааааин!:) Загляни в чат как-нибудь,а?StopPress будет рад вас видеть.О том,что `prepare ()`.Да,это сложно,и мне пришлось попробовать это несколько раз,прежде чем я дошел до этого.Из того,что я только что сделал: `$ wpdb->prepare ('AND {$ wpdb->posts} .post_title LIKE% s',esc_sql ('%'. Like_escape (trim ($term)). '%'))`.И я почти уверен,что `esc_sql ()` не нужен и просто параноик.@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.
- 1
- 2012-11-07
- kaiser
-
Похоже,вы не можете искать строку с `'' (апострофом) внутри.Я думаю,это из-за побега?Я еще не нашел решенияIt seems that you can't search a string with `'` (apostrophe) inside. I guess it's because of escaping ? I didn't find the solution yet
- 0
- 2018-08-30
- Vincent Decaux
-
- 2013-04-19
Упрощенно:
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;
Simplified:
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;
-
Пожалуйста,включите объяснение вместе с вашим кодом.Please include an explanation along with your code.
- 13
- 2013-04-19
- s_ha_dum
-
Большое упрощениеGreat simplification
- 2
- 2014-11-10
- Timo Huovinen
-
Я думаю,что код объясняется сам собой,по крайней мере,для меня.Спасибо,что поделились полным сценарием.Code is i think self explained, atleast for me. Thanks for sharing complete script.
- 2
- 2017-08-08
- Hassan Dad Khan
-
Используйте '$ wpdb->esc_like (' вместо 'esc_sql (like_escape ('Use '$wpdb->esc_like (' instead of 'esc_sql( like_escape('
- 2
- 2018-02-19
- fdrv
-
@fdrv Вы правы,но согласно wp docs $ wpdb->esc_like по-прежнему нуженesc_sql ().Поэтому я думаю,что правильный код будетesc_sql ($ wpdb->esc_like ($ search_term))@fdrv You are right but according to wp docs $wpdb->esc_like still need esc_sql(). So I think the correct code would be esc_sql( $wpdb->esc_like( $search_term ) )
- 0
- 2019-10-18
- Waqas Bukhary
-
`like_escape` устарел 4.0.0 Используйте` wpdb ::esc_like``like_escape` deprecated 4.0.0 Use `wpdb::esc_like`
- 0
- 2020-03-14
- Empty Brain
-
remove_filter использует только 3 аргумента,последний можно удалить.`remove_filter` only uses 3 arguments, the last one can be removed.
- 2
- 2020-06-24
- Skatox
-
- 2015-01-02
Хотели обновить этот код,над которым вы работали,для 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);
Wanted to update this code you guys worked on for the wordpress 4.0 and above as esc_sql() is deprecated in 4.0 higher.
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; }
Rest of the stuff is same.
Also I want to point out you can use s variable within WP_Query arguments to pass search terms, which will also search for post title i believe.
Like this:
$args = array( 'post_type' => 'post', 's' => $search_term, 'post_status' => 'publish', 'orderby' => 'title', 'order' => 'ASC' ); $wp_query = new WP_Query($args);
-
Что такое search_prod_title?Должен ли я изменить это на что-нибудь другое?What exactly `search_prod_title` is? Should i change this to something else?
- 0
- 2017-03-24
- Antonios Tsimourtos
-
С каких это пор "esc_sql" становится лишним?Это не.`$ wpdb->escape` - это хотя ... https://developer.wordpress.org/reference/functions/esc_sql/Since when is `esc_sql` depricated? It's not. `$wpdb->escape` is though... https://developer.wordpress.org/reference/functions/esc_sql/
- 0
- 2018-02-02
- Jeremy
-
Обратите внимание,что параметр s также выполняет поиск по содержимому публикации,что может быть нежелательной целью.знак равноNote that the s parameter searches the post content as well, which may not be the desired aim. =)
- 1
- 2018-04-19
- Christine Cooper
-
`like_escape` устарел` 4.0.0` Используйте `wpdb ::esc_like``like_escape` deprecated `4.0.0` Use `wpdb::esc_like`
- 0
- 2020-03-14
- Empty Brain
-
- 2018-04-19
С некоторыми уязвимыми решениями,опубликованными здесь,я пришел с немного упрощенной и очищенной версией.
Сначала мы создаем функцию для фильтра
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
он будет выполнять поиск по заголовку сообщения,а также также и по содержанию сообщения.Как насчет параметра
title
,который был добавлен в WP 4.4?Передача поискового запроса в параметр
title
:$args = array( 'title' => $search_term, );
С учетом регистра и
LIKE
,а не%LIKE%
. Это означает,что поиск по запросуhello
не вернет сообщение с заголовкомHello World
илиHello
.With some vulnerable solution posted here, I come with a bit simplified and sanitized version.
First, we create a function for the
posts_where
filter which allows you to only show posts matching specific conditions: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; }
Now we add
cc_search_post_title
into our query arguments:$args = array( 'cc_search_post_title' => $search_term, // search post title only 'post_status' => 'publish', );
And finally wrap the filter around the query:
add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 ); $query = new WP_Query($args); remove_filter( 'posts_where', 'cc_post_title_filter', 10 );
Using get_posts()
Certain functions which retrieve posts do not run filters, so the posts_where filter functions you attach will not modify the query. If you plan to use
get_posts()
to query your posts, you need to setsuppress_filters
to false in your argument array:$args = array( 'cc_search_post_title' => $search_term, 'suppress_filters' => FALSE, 'post_status' => 'publish', );
Now you can use
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 );
What about the
s
parameter?The
s
parameter is available:$args = array( 's' => $search_term, );
While adding your search term into the
s
parameter work and it will search the post title, it will also search the post content.What about the
title
parameter which was added with WP 4.4?Passing a search term into the
title
parameter:$args = array( 'title' => $search_term, );
Is case sensitive and
LIKE
, not%LIKE%
. This mean search forhello
will not return post with titleHello World
orHello
.-
Превосходно.Я искалpost_title в качестве параметра и,очевидно,ничего не нашел.Excellent. I was looking for 'post_title' as a parameter and, obviously, didn't find anything.
- 0
- 2019-09-13
- MastaBaba
-
Я получаю сообщение об ошибке с запросом wp или получаю сообщения: «E_WARNING Ошибка в файле» class-wp-hook.php «в строке 288: Параметр 2 для cc_post_title_filter () должен быть ссылкой,заданное значениеI'm getting an error with wp query or get posts: "E_WARNING Error in file »class-wp-hook.php« at line 288: Parameter 2 to cc_post_title_filter() expected to be a reference, value given
- 0
- 2020-03-03
- Elkrat
-
@Elkrat Удалите `&` из `& $ wp_query` в` cc_post_title_filter`.@Elkrat Remove the `&` from `&$wp_query` in `cc_post_title_filter`.
- 0
- 2020-05-05
- Mattimator
-
- 2015-04-28
Основываясь на других ответах до меня,чтобы обеспечить гибкость в ситуации,когда вы хотите найти сообщение,которое содержит слово в мета-поле ИЛИ в заголовке сообщения,я даю эту опцию через аргумент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);
Building on other answers before me, to provide flexibility in the situation where you want to search a post that contains a word in a meta field OR in the title of the post, I give that option via the argument "title_filter_relation." In this implementation, I only allow for "OR" or "AND" inputs with a default of "AND."
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; }
Here's an example of the code in action for a very simple post type "faq" where the question is the post title itself:
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);
-
Хорошее понимание,добавление настраиваемых «переменных запросов» к аргументам запроса,передаваемым в `WP_Query`,чтобы иметь к ним доступ в фильтре`posts_where`.Good insight, adding custom "query vars" to the query args passed to `WP_Query` in order to be able to access them within the `posts_where` filter.
- 1
- 2017-02-04
- Tom Auger
Мне нужно выполнить
WP_Query
сLIKE
вpost_title
.Я начал с этого обычного
WP_Query
:Но то,что я действительно хочу сделать в SQL,выглядит так:
На выходе печатаются ожидаемые мной результаты,но я использую обычный
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
,чтобы отобразить результаты.И это не работает с
$wpdb->get_results()
.Как мне достичь того,что я здесь описал?