/ Wordpress / Расширение стандартного поиска

Расширение стандартного поиска

15.10.2022

62

Включение в поиск метаполей

// Добавляем в поиск метаполе
function me_search_query( $query ) {
	if ( $query->is_search ) {
		$meta_query_args = array(
			array(
				'key' => 'meta_key', //нужное поле
				'value' => $query->query_vars['s'],
				'compare' => 'LIKE',
			),
		);
		$query->set('meta_query', $meta_query_args);
		add_filter( 'get_meta_sql', 'me_replace_and_with_or' );
	};
}

function me_replace_and_with_or( $sql ) {
	if ( 1 === strpos( $sql['where'], 'AND' ) ) {
		$sql['where'] = substr( $sql['where'], 4 );
		$sql['where'] = ' OR ' . $sql['where'];
	}

	//make sure that this filter will fire only once for the meta query
	remove_filter( 'get_meta_sql', 'me_replace_and_with_or' );
	return $sql;
}

add_filter( 'pre_get_posts', 'me_search_query');
Добавление в поиск нескольких метаполей
У этого способа есть существенный недостаток, в результатах поиска выводятся все типы записей, в т.ч. attachment

Правильный способ

Не могу сказать насчет оптимизации запроса с точки зрения обращения к базе данных, но я смог добиться нужного результата. Создав в pre_get_posts 2 запроса с условием: один обычный и один по метаполю, в результате получаем либо записи по запросу (стандартный поиск), либо записи по метаполю.

remove_action( ‘pre_get_posts’, __FUNCTION__ ); — обязательно, иначе будет бесконечный цикл и сервер вернет 502 Bad Gateway.

function custom_search_query( $query ) {
	if ( !is_admin() && $query->is_search ) {
		
		remove_action( 'pre_get_posts', __FUNCTION__ ); // чтобы не было бесконечного цикла
		
		$search = get_posts( array(
			's' => get_query_var('s'),
			'posts_per_page' => -1,
			'fields' => 'ids'
		) );
		
		if (empty($search)) {
			$search = get_posts( array(
				'meta_query' => array( array(
					'key' => 'sku',
					'value' => get_query_var('s'),
					'compare' => 'LIKE'
				) ),
				'posts_per_page' => -1,
				'fields' => 'ids'
			) );			
		}
		
		if (!empty($search)) {
		
			$query->set('s', ''); //отключаем поиск по слову
			$query->set('post__in', $search);
			$query->set('post_type', 'post');
			
		}

	};
}
add_filter( 'pre_get_posts', 'custom_search_query');

Изначально я прорабатывал это методом объединения двух массивов, но подумал что это более затратно по запросам:

function custom_search_query( $query ) {
	if ( !is_admin() && $query->is_search ) {
		
		remove_action( 'pre_get_posts', __FUNCTION__ ); // чтобы не было бесконечного цикла
		
		$search = get_posts( array(
			's' => get_query_var('s'),
			'posts_per_page' => -1,
			'fields' => 'ids'
		) );
		
		$second = get_posts( array(
			'meta_query' => array( array(
				'key' => 'sku',
				'value' => get_query_var('s'),
			) ),
			'posts_per_page' => -1,
			'fields' => 'ids'
		) );
		
		$result = array_merge($first, $second);
		
		$query->set('s', '');	
		$query->set('post__in', $result);
		$query->set('post_type', 'post');	

	};
}
add_filter( 'pre_get_posts', 'custom_search_query');

Но может быть как метод где-нибудь пригодится.

Поиск только по метаполю

Данная функция отключает поиск по слову в заголовке записи и ищет по соответствию значения в метаполе.

function custom_search_query( $query ) {
	if ( !is_admin() && $query->is_search ) {
		global $wp_query;
        if ($wp_query->post_count == 0) {
			
			$query->set('meta_query', array(
				array(
					'key' => 'sku',
					'value' => get_query_var('s'),
					'compare' => 'IN'
				)
			));
			//$query->set('post_type', 'post');			
			$query->set( 's', ''); // отключаем поиск по слову
			
		}
	};
}
add_filter( 'pre_get_posts', 'custom_search_query');

Поделиться в соц. сетях:

  • Комментарии
  • Вложения

Добавить комментарий

Пока нет комментариев. Будь первым!

Расширение стандартного поиска
.htaccess
Рекомендации для вас.htaccessOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.