WordPress как на ладони

Поиск по произвольным полям

Нашел небольшое дополнение, которое ищет по произвольным полям

но поиск работает сразу по всем полям, а нужно, чтобы работал только по заданным

В итоге вот код

function cf_search_join( $join ) {
	global $wpdb;

	if ( is_search() ) {
		$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
	}

	return $join;
}
add_filter('posts_join', 'cf_search_join' );

function cf_search_where( $where ) {
	global $pagenow, $wpdb;

	if ( is_search() ) {
		$where = preg_replace(
		"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
		"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
	}

	return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

function cf_search_distinct( $where ) {
	global $wpdb;

	if ( is_search() ) {
		return "DISTINCT";
	}

	return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
0
lethalblo
4.8 лет назад 15
  • 0
    Kama9616

    Через pre_get_posts измени параметры запроса на станице is_search(). Используй параметры meta_query.

    Примерно так:

    add_action( 'pre_get_posts', 'search_query_by_meta', 1 );
    function search_query_by_meta( $query ) {
    
    	// Выходим, если это админ-панель или не основной запрос.
    	if( is_admin() || ! $query->is_main_query() )
    		return;
    
    	if( ! is_search() )
    		return;
    
    	$search = get_query_var('s');
    
    	$query->set( 'meta_query', [
    		'relation' => 'OR',
    		[
    			'key'     => 'key_name_1',
    			'value'   => $search,
    			'compare' => 'LIKE'
    		],
    		[
    			'key'     => 'key_name_2',
    			'value'   => $search,
    			'compare' => 'LIKE'
    		]
    	] );
    
    }
    lethalblo 4.8 лет назад

    то есть этот код нужно добавить в файл search.php

    И целиком он должен примерно вот так?

    add_action( 'pre_get_posts', 'search_query_by_meta', 1 );
    function search_query_by_meta( $query ) {
    
    	// Выходим, если это админ-панель или не основной запрос.
    	if( is_admin() || ! $query->is_main_query() )
    		return;
    
    	if( ! is_search() )
    		return;
    
    	$search = get_query_var('s');
    
    	$query->set( 'meta_query', [
    		'relation' => 'OR',
    		[
    			'key'     => 'video',
    			'value'   => $search,
    			'compare' => 'LIKE'
    		],
    		[
    			'key'     => 'kp',
    			'value'   => $search,
    			'compare' => 'LIKE'
    		]
    	] );
    
    }
    
    $query = new WP_Query( $args );
    
    // Цикл
    if ( $query->have_posts() ) {
    	while ( $query->have_posts() ) {
    		$query->the_post();
    		echo '<li>' . get_the_title() . '</li>';
    	}
    } else {
    	// Постов не найдено
    }
    // Возвращаем оригинальные данные поста. Сбрасываем $post.
    wp_reset_postdata();
    lethalblo 4.8 лет назад

    Действительно поиск начал работать если убрать

    if( is_admin() || ! $query->is_main_query() )
    		return;

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

    Kama 4.8 лет назад

    Его нужно добавить в functions.php и не рекомендую удалять указанные строки... Этот код будет работать для базового (основного) запроса на странице поиска.

    А если делать так как ты сделал: создавать отдельный запрос, то не нужны никакие хуки, просто передай параметры в WP_Query( параметры ) и все...

    Комментировать
  • 0
    Glum697

    Можно в where добавить нужные ключи

    OR (".$wpdb->postmeta.".meta_value LIKE $1 
    AND ".$wpdb->postmeta.".meta_key='key_name')

    Или так

    OR (".$wpdb->postmeta.".meta_value LIKE $1 
    AND ".$wpdb->postmeta.".meta_key IN ('key_name_1', 'key_name_2') )
    lethalblo 4.8 лет назад

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

    Glum 4.8 лет назад

    Я не дебажил, но должно работать

    function cf_search_where( $where ) {
    	global $pagenow, $wpdb;
    
    	if ( is_search() ) {
    		$where = preg_replace(
    			"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
    			"(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1 AND " . $wpdb->postmeta . ".meta_key IN ( 'key_name_1', 'key_name_2' ) )", $where );
    	}
    
    	return $where;
    }
    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация