Заполните выпадающий список значениями метаданных из всех записей пользовательского типа записи.

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

У меня есть CPT “Инвентаризация”, и я пытаюсь отобразить выпадающий список всех производителей. У меня есть форма и функция pre_get_posts, так что когда пользователь выбирает производителя, страница обновляется и показывает только инвентарь с этим производителем.

ПРОБЛЕМА: После выбора производителя и обновления страницы только этот производитель отображается как вариант! Независимо от того, что я пробую (я не буду перечислять все здесь, потому что пробовал около 10 разных циклов) для создания вариантов выбора, я не могу сделать так, чтобы всегда отображались ВСЕ производители.

Я прочитал несколько десятков статей (буквально) и не могу найти решение, которое работает.

Вот что у меня сейчас:

FUNCTIONS.PHP

function my_pre_get_posts( $query ) {
    // не изменять запросы в админке
    if( is_admin() ) {
        return $query;      
    }

    // изменять только запросы для типа поста 'inventory'
    if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'inventory' ) {
        
        // разрешить URL изменять запрос
        if( isset($_GET['item_oem']) ) {
            $query->set('meta_key', 'item_oem');
            $query->set('meta_value', $_GET['item_oem']);
            $query->set( 'meta_compare', '=' );
        } 
    }
    // вернуть
    return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');

ЦИКЛ:

        <?php // использую get прямо сейчас, чтобы увидеть строку запроса и подтвердить функциональность ?> 
        <form method="get" action="" onchange="submit();">

            <?php 
                $posts = get_posts( array(
                'post_type' => 'inventory',
                'posts_per_page' => -1,
                'orderby' => 'date',
                'order' => 'DESC',
            ));

            if ( $posts ): ?>

            <select name="item_oem" id="select-oem">
                <?php foreach( $posts as $post ): ?>
                    <option value="<?php the_field('item_oem'); ?>"> <?php the_field('item_oem'); ?> </option>
                <?php endforeach; ?>
            </select>
        <?php endif; ?>
        <?php wp_reset_postdata(); ?>

        </form>

Так что это ДАЕТ мне полный список производителей. Но, как только вы выберете один и перезагрузите страницу, чтобы показать только инвентарь с этим производителем, выбранный производитель становится единственным вариантом в выборе.

Как мне переопределить это и всегда показывать ВСЕ мета-значения для ключа мета ‘item_oem’??

Большое спасибо!

Вот решение, которое я придумал, и оно работает должным образом.

<form method="get" action="" onchange="submit();">
        <div class="input-group">
            <?php
            global $wpdb;
            $meta_key = 'item_oem';
            $data = $wpdb->get_results($wpdb->prepare( "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key) , ARRAY_N  ); ?>
            <select class="custom-select" id="oems" aria-label="oems" name="item_oem" >
                <option selected>Поиск по OEM</option>
                <?php foreach( $data as $value ): ?>
                    <option value="<?php echo $value[0]; ?>"><?php echo $value[0]; ?> </option>
                <?php endforeach; ?>
          </select>
          <div class="input-group-append">
            <a href="/inventory" class="btn btn-secondary" type="button">Сбросить фильтр</a>
          </div>
        </div>
    </form>

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

Заполнение выпадающего списка с мета-значениями всех записей пользовательского типа записи

Введение

Ваша задача заключается в создании выпадающего списка, который будет отображать всех производителей (Mfrs) из пользовательского типа записи (Custom Post Type) "Инвентарь" в WordPress. Проблема в том, что после выбора одного из производителей и обновления страницы, выпадающий список показывает только выбранного производителя, вместо всех доступных опций. В этой статье мы рассмотрим, как правильно реализовать данную функциональность, используя запросы к базе данных WordPress.

Проблема

Ваша текущая реализация использует функцию pre_get_posts для фильтрации записей по установленному значению мета-ключа item_oem. Однако, когда пользователь выбирает производителя и страница обновляется, выпадающий список запрашивает записи, отфильтрованные по этому значению, тем самым отображая только один вариант в списке.

Решение

Для решения данной проблемы можно использовать прямые SQL-запросы к базе данных, чтобы получить все уникальные значения мета-ключа item_oem — это позволит избежать проблемы с необходимостью фильтрации элементов выпадающего списка.

Вот шаги, которые нужно выполнить:

  1. Создание формы с выпадающим списком для выбора Mfr:
    Используйте глобальный $wpdb для получения всех уникальных значений item_oem и корректного отображения их в выпадающем списке.

  2. Использование запроса к базе данных:
    Для извлечения уникальных значений мета-ключа item_oem, выполните SQL-запрос через $wpdb.

Пример реализации

Ознакомьтесь с обновленным кодом для вашей формы:

<form method="get" action="" onchange="submit();">
    <div class="input-group">
        <?php
        global $wpdb;
        $meta_key = 'item_oem';
        $data = $wpdb->get_results($wpdb->prepare( 
            "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s", 
            $meta_key 
        ), ARRAY_N);
        ?>
        <select class="custom-select" id="oems" aria-label="Mfrs" name="item_oem">
            <option selected>Поиск по OEM</option>
            <?php foreach ($data as $value): ?>
                <option value="<?php echo esc_attr($value[0]); ?>"><?php echo esc_html($value[0]); ?></option>
            <?php endforeach; ?>
        </select>
        <div class="input-group-append">
            <a href="/inventory" class="btn btn-secondary" type="button">Сбросить фильтр</a>
        </div>
    </div>
</form>

Объяснение кода

  1. Глобальный доступ к $wpdb: Используем переменную $wpdb, чтобы получить доступ к таблицам базы данных.
  2. SQL-запрос: Запрос SELECT DISTINCT извлекает все уникальные значения мета-ключа item_oem из таблицы postmeta.
  3. Заполнение выпадающего списка: Каждый элемент выпадающего списка создается динамически с помощью цикла foreach, обеспечивая отображение всех производителей.
  4. Экранирование данных: Использование функций esc_attr() и esc_html() гарантирует безопасность и корректное отображение данных.

Заключение

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

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

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