Как создать/изменить WP_Query для поиска в заголовке поста ИЛИ пользовательском поле?

Вопрос или проблема

Мне нужно изменить или создать WP_Query, который будет искать поисковый термин как в заголовке поста, так и в пользовательском поле (называемом ‘my_field’).

Я читал и пытался несколько часов, но возвращаюсь к этому коду (ниже), который, увы, только ищет в ‘my_field’ и не учитывает заголовок поста.

function my_pre_get_posts_2( $query ) {
if ( is_admin() && $query->is_main_query() && $query->query['post_type'] === 'post' && isset($query->query['s']) ) {

    $search_word = $query->query['s'];

    $args = array(
        //'s' => $search_word, //Если я включаю эту строку, WP запрос, похоже, выполняет поиск по заголовку поста и my_field. Если я закомментирую эту строку, WP запрос ищет только в my_field
        'post_type' => 'post',
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => 'my_field',
                'value' => $search_word,
                'compare' => 'IN'
            ),
            array(
                'key' => 'post_title',
                'value' => $search_word,
                'compare' => 'IN',
            )
        )
    );

    //$query = new WP_Query( $args ); //Нужно изменить существующий WP_Query
    $query->init();
    $query->parse_query($args);
}

}
add_action( 'pre_get_posts', 'my_pre_get_posts_2' );

Причина, по которой мне нужно это сделать, заключается в том, что мне нужно изменить поведение кнопки ‘Поиск постов’ на странице ‘Все посты’ (админка), чтобы независимо от того, что ищет администратор, возвращались посты, которые имеют совпадающий заголовок поста или значение my_field.

Чтобы выполнить поиск с логическим оператором ИЛИ, я пытался объединить результаты WP_Query, как показано здесь – Могу ли я объединить 2 новых WP_Query($variable)? – в ответе guidod. Однако это не было хорошим решением и привело к непредсказуемому поведению.

Правильное решение, которое я нашел, заключалось в том, чтобы изменить запрос с помощью пользовательского запроса WP, как показано в коде (который требует некоторых изменений) здесь – http://codex.wordpress.org/Custom_Queries ..

Чтобы искать как в заголовке поста, так и в пользовательском поле, используя wp_query, вы не можете напрямую искать в поле post_title, поскольку это не пользовательское поле. Вместо этого вы можете использовать комбинацию параметров meta_query и post_title для достижения желаемых результатов.

function my_pre_get_posts_2( $query ) {
    if ( is_admin() && $query->is_main_query() && $query->query['post_type'] === 'post' && isset($query->query['s']) ) {

        $search_word = $query->query['s'];

        $args = array(
            'post_type' => 'post',
            'meta_query' => array(
                'relation' => 'OR',
                array(
                    'key' => 'my_field',
                    'value' => $search_word,
                    'compare' => 'LIKE' // Используйте LIKE для сопоставления частичных строк в пользовательских полях
                )
            ),
            's' => $search_word, // Поиск по заголовку поста
            'posts_per_page' => -1 // Отобразить все соответствующие посты
        );

        $query->set( 'meta_query', $args['meta_query'] ); // Установить meta_query
        $query->set( 's', $args['s'] ); // Установить поисковый термин для заголовка поста

    }
}
add_action( 'pre_get_posts', 'my_pre_get_posts_2' );

Ответ или решение

Чтобы создать или изменить WP_Query для поиска как в заголовках записей, так и в пользовательском поле (в нашем случае — это поле с именем 'my_field'), вам потребуется скорректировать вашу текущую функцию, чтобы включить обоих источника поиска.

Шаг 1: Обновление мета-запроса

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

Шаг 2: Использование функции pre_get_posts

Ниже приведен пример кода, который нужно реализовать. Этот код будет модифицировать основной запрос в админке WordPress, чтобы он искал как в заголовках, так и в пользовательских полях:

function my_pre_get_posts_2( $query ) {
    // Проверка, что это админка и основной запрос
    if ( is_admin() && $query->is_main_query() && $query->query['post_type'] === 'post' && isset($query->query['s']) ) {

        $search_word = $query->query['s'];

        $meta_query = array(
            'relation' => 'OR',
            array(
                'key' => 'my_field',
                'value' => $search_word,
                'compare' => 'LIKE' // Используем LIKE для поиска подстроки
            ),
            array(
                'key' => 'post_title',
                'value' => $search_word,
                'compare' => 'LIKE' // Используем LIKE для поиска подстроки в заголовке
            )
        );

        // Настраиваем запрос
        $query->set( 'meta_query', $meta_query ); // Устанавливаем мета-запрос
        $query->set( 's', '' ); // Очищаем стандартный поиск, чтобы избежать конфликтов
    }
}
add_action( 'pre_get_posts', 'my_pre_get_posts_2' );

Пояснение кода:

  1. Проверка условий: Мы проверяем, что функция вызывается в админке, это основной запрос и что запрашиваемый тип записей — 'post'.

  2. Создание meta_query: Создается массив meta_query, который включает два условия:

    • Поиск по полю my_field с использованием оператора LIKE для поиска подстроки.
    • Поиск по заголовку поста с тем же оператором.
  3. Настройка запроса:

    • С помощью $query->set() мы устанавливаем новый массив meta_query для выполнения пользовательского запроса.
    • Очищаем стандартный параметр поиска ('s'), чтобы избежать конфликтов и неправомерных совмещения условий поиска.

Результат

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

Рекомендации по оптимизации

  • Оптимизация поиска: Следите за производительностью, если ваша база данных содержит большое число записей. Рассмотрите возможность применения индексов для метаполей, с которыми вы часто работаете.
  • Проверка на правильность: Убедитесь, что вводимые данные корректны и проводите валидацию для предотвращения SQL-инъекций и других уязвимостей.

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

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

Капча загружается...