Запрос на основе заголовка, с ‘сравнить’ => ‘В’

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

Я хочу сделать запрос на основе названия с предопределенной переменной. Я не могу заставить это работать. Что я упускаю?

Сделать запрос без ‘compare’ не проблема.

    $args = array('post_type' => 'udbyder', 
                  'posts_per_page' => -1, 
                  'order' => 'ASC',
                  'meta_query' => array(
                  'relation' => 'AND',
                    array(
                    'key' => 'title',
                    'value' => $test,
                    'compare' => 'IN'
    ) 
));

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

Способ, которым вы можете это сделать, это отфильтровать SQL непосредственно, чтобы добавить вашу логику. Вы даже можете сделать это так, чтобы могли добавить пользовательский аргумент к WP_Query, который я назову ‘titles‘, который позволит вам передать массив названий постов. Чтобы поддержать этот аргумент, добавьте этот фильтр к posts_where:

function wpse_308130_posts_where( $where, $query ) {
    global $wpdb;

    // Проверьте, установлен ли наш пользовательский аргумент в текущем запросе.
    if ( $query->get( 'titles' ) ) {
        $titles = $query->get( 'titles' );

        // Экранируем переданные названия и добавляем кавычки.
        $titles = array_map( function( $title ) {
            return "'" . esc_sql( $title ) . "'";
        }, $titles );

        // Объединяем в строку для использования в IN() операторе.
        $titles = implode( ',', $titles );

        // Добавляем WHERE условие к SQL запросу.
        $where .= " AND $wpdb->posts.post_title IN ($titles)";
    }

    return $where;
}
add_filter( 'posts_where', 'wpse_308130_posts_where', 10, 2 );

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

$posts = new WP_Query( array(
    'post_type'      => 'udbyder', 
    'posts_per_page' => -1, 
    'order'          => 'ASC',
    'titles'         => ['Название одно', 'Название два'],
) );

Это вернет посты с названиями “Название одно” или “Название два”.

.

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

Вопрос о том, как выполнить запрос на основе заголовка с использованием переменной в WordPress, требует понимания некоторых специфических нюансов работы функции WP_Query. В вашем примере вы пытаетесь использовать параметр ‘compare’ с ‘IN’ в запросе, основанном на метаполях (‘meta_query’). Однако следует помнить, что заголовок поста не является метаполем, и вы не сможете выполнять поиск по заголовку поста с помощью ‘meta_query’.

Как решить данную задачу

Понимание проблемы

Запрос через WP_Query без использования ‘compare’ работает, поскольку вы можете выполнять выборку по заголовку напрямую. Однако использование ‘compare’ с ‘IN’ в рамках meta_query не сработает, поскольку заголовок не сохраняется в метаполях.

Для выполнения запроса на основе заголовка поста с несколькими значениями вам нужно внести изменения в SQL-запрос, который генерируется WP_Query. Это можно достичь с помощью фильтра posts_where.

Создание пользовательского фильтра

Вот как вы можете создать этот пользовательский фильтр для добавления ваших заголовков в условие WHERE:

function wpse_308130_posts_where( $where, $query ) {
    global $wpdb;

    // Проверяем, установлен ли наш пользовательский аргумент
    if ( $query->get( 'titles' ) ) {
        $titles = $query->get( 'titles' );

        // Экранируем переданные заголовки и добавляем кавычки
        $titles = array_map( function( $title ) {
            return "'" . esc_sql( $title ) . "'";
        }, $titles );

        // Объединяем в строку для использования в IN()
        $titles = implode( ',', $titles );

        // Добавляем условие WHERE к SQL-запросу
        $where .= " AND $wpdb->posts.post_title IN ($titles)";
    }

    return $where;
}
add_filter( 'posts_where', 'wpse_308130_posts_where', 10, 2 );

Использование нового параметра в запросе

Теперь, когда фильтр создан, вы можете использовать ваш новый аргумент ‘titles’ в запросе:

$posts = new WP_Query( array(
    'post_type'      => 'udbyder', 
    'posts_per_page' => -1, 
    'order'          => 'ASC',
    'titles'         => ['Title one', 'Title two'],
) );

Этот запрос вернет посты с заголовками "Title one" или "Title two".

Заключение

Использование фильтра posts_where позволяет расширить возможности WP_Query, предоставляя вам возможность фильтровать посты по заголовкам, как если бы они были обычными метаполями. Это решение эффективно и совместимо с другими параметрами WP_Query, предоставляя возможность гибкого запроса данных.

Убедитесь, что вы правильно экранируете заголовки, чтобы избежать уязвимостей SQL-инъекций. Employing the above methods will not only help with your current requirement but also improve your overall understanding of modifying WordPress queries.

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

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