Intereting Posts
Запрос пользовательского типа сообщения и вывод на временную шкалу Использование функций gettext WordPress в библиотеке вне плагина или области темы Сохранение данных FTP в wp-config.php Перенаправление на текущую страницу после входа в систему Виджет входа в боковую панель с печатью ошибок, возвращает ошибку Redeclare функция в дочерней теме Изменить состояние логотипа на основе URL-адреса Чтобы удалить уведомления плагина для пользователей, не являющихся администраторами Добавление медиа и прикрепление изображений к страницам Пользовательский тип сообщения – как установить флажок, чтобы обновить мета-поле до нуля Как добавить внешний удаленный JS-источник в Gravity Forms? отправка различного уведомления по электронной почте при регистрации на основе роли пользователя Как ограничить страницы подменю плагина администратором / подписчиками? интерактивная диаграмма с положительным результатом Пользовательские часовые пояса? Hack? Плагин?

Используя мета-запрос ('meta_query') с поисковым запросом ('s')

Попытка создать поиск, который не только выполняет поиск по умолчанию (название, контент и т. Д.), Но и специальное настраиваемое поле.

Мой текущий запрос:

$args = array( 'post_type' => 'post', 's' => $query, 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) ); $search = new WP_Query( $args ) ... 

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

Есть идеи?

Solutions Collecting From Web of "Используя мета-запрос ('meta_query') с поисковым запросом ('s')"

Я искал часы для решения этой проблемы. Слияние массивов – это не путь, особенно когда запросы сложны, и вы должны быть в состоянии добавить к мета-запросам в будущем. Оптимистично красивое решение состоит в том, чтобы изменить 's' на тот, который позволяет как искать заголовки, так и мета-поля.

 add_action( 'pre_get_posts', function( $q ) { if( $title = $q->get( '_meta_or_title' ) ) { add_filter( 'get_meta_sql', function( $sql ) use ( $title ) { global $wpdb; // Only run once: static $nr = 0; if( 0 != $nr++ ) return $sql; // Modified WHERE $sql['where'] = sprintf( " AND ( %s OR %s ) ", $wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title), mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) ) ); return $sql; }); } }); 

Применение:

 $meta_query = array(); $args = array(); $search_string = "test"; $meta_query[] = array( 'key' => 'staff_name', 'value' => $search_string, 'compare' => 'LIKE' ); $meta_query[] = array( 'key' => 'staff_email', 'value' => $search_string, 'compare' => 'LIKE' ); //if there is more than one meta query 'or' them if(count($meta_query) > 1) { $meta_query['relation'] = 'OR'; } // The Query $args['post_type'] = "staff"; $args['_meta_or_title'] = $search_string; //not using 's' anymore $args['meta_query'] = $meta_query; $the_query = new WP_Query($args) 

С помощью измененной версии этого ответа можно уменьшить количество кода.

 $q1 = new WP_Query( array( 'post_type' => 'post', 'posts_per_page' => -1, 's' => $query )); $q2 = new WP_Query( array( 'post_type' => 'post', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) )); $result = new WP_Query(); $result->posts = array_unique( array_merge( $q1->posts, $q2->posts ), SORT_REGULAR ); $result->post_count = count( $result->posts ); 

Согласно предложению Ника Перкинса , мне пришлось объединить два запроса так:

 $q1 = get_posts(array( 'fields' => 'ids', 'post_type' => 'post', 's' => $query )); $q2 = get_posts(array( 'fields' => 'ids', 'post_type' => 'post', 'meta_query' => array( array( 'key' => 'speel', 'value' => $query, 'compare' => 'LIKE' ) ) )); $unique = array_unique( array_merge( $q1->posts, $q2->posts ) ); $posts = get_posts(array( 'post_type' => 'posts', 'post__in' => $unique, 'post_status' => 'publish', 'posts_per_page' => -1 )); if( $posts ) : foreach( $posts as $post ) : setup_postdata($post); // now use standard loop functions like the_title() etc. enforeach; endif; 

Это своего рода хак, но он работает. Вам нужно добавить фильтр posts_clauses. Эта функция проверки фильтра для любого слова запроса существует в настраиваемом поле «speel», а оставшийся запрос остается нетронутым.

 function custom_search_where($pieces) { // filter for your query if (is_search() && !is_admin()) { global $wpdb; $keywords = explode(' ', get_query_var('s')); $query = ""; foreach ($keywords as $word) { // skip possible adverbs and numbers if (is_numeric($word) || strlen($word) <= 2) continue; $query .= "((mypm1.meta_key = 'speel')"; $query .= " AND (mypm1.meta_value LIKE '%{$word}%')) OR "; } if (!empty($query)) { // add to where clause $pieces['where'] = str_replace("(((wp_posts.post_title LIKE '%", "( {$query} ((wp_posts.post_title LIKE '%", $pieces['where']); $pieces['join'] = $pieces['join'] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)"; } } return ($pieces); } add_filter('posts_clauses', 'custom_search_where', 20, 1); 

у меня была та же проблема, для моего нового сайта я просто добавил новый мета-заголовок:

functions.php

 add_action('save_post', 'title_to_meta'); function title_to_meta($post_id) { update_post_meta($post_id, 'title', get_the_title($post_id)); } 

А потом просто добавьте что-то вроде этого:

 $sub = array('relation' => 'OR'); $sub[] = array( 'key' => 'tags', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $sub[] = array( 'key' => 'description', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $sub[] = array( 'key' => 'title', 'value' => $_POST['q'], 'compare' => 'LIKE', ); $params['meta_query'] = $sub; 

Что вы думаете об этом обходном пути?

Я оптимизировал @Stabir Kira немного ответил

 function wp78649_extend_search( $query ) { $search_term = filter_input( INPUT_GET, 's', FILTER_SANITIZE_NUMBER_INT) ?: 0; if ( $query->is_search && !is_admin() && $query->is_main_query() && //your extra condition ) { $query->set('meta_query', [ [ 'key' => 'meta_key', 'value' => $search_term, 'compare' => '=' ] ]); add_filter( 'get_meta_sql', function( $sql ) { global $wpdb; static $nr = 0; if( 0 != $nr++ ) return $sql; $sql['where'] = mb_eregi_replace( '^ AND', ' OR', $sql['where']); return $sql; }); } return $query; } add_action( 'pre_get_posts', 'wp78649_extend_search'); 

Теперь вы можете искать по (название, содержание, эскрипция) или (мета-поле) или (оба из них).