Настройка фильтра для пользовательской таблицы WP LIST

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

Я разрабатываю плагин, который отображает информацию о заказах, показывает данные для выставления счета, купленный продукт и дату поездки. Мне нужно создать фильтры для таблицы, которые позволят выбирать конкретное имя продукта или дату поездки, что-то вроде этого Это то, что мне нужно, моя таблица выглядит так: Моя таблица Как я могу сделать работающие фильтры?

class Employees_List_Table extends WP_List_Table
{
      private $users_data;

      private function get_users_data($search = "")
      {
            global $wpdb;

            if (!empty($search)) {
                  return $wpdb->get_results(
                        "SELECT
                        woi.order_item_name AS order_items,
                        order_id,
                        post_date,
                        p.post_status AS order_status,
                        MAX(
                            CASE WHEN pm.meta_key = '_billing_first_name' AND p.id = pm.post_id THEN pm.meta_value
                        END
                    ) AS '_billing_first_name',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_last_name' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS '_billing_last_name',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_email' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS 'billing_email',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_phone' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS 'billing_phone',
                    MAX(
                        CASE WHEN woim.meta_key = 'Дата поездки' AND p.id = pm.post_id THEN woim.meta_value
                    END
                    ) AS 'travel_date',
                    MAX(
                        CASE WHEN woim.meta_key = '_qty' AND p.id = pm.post_id THEN woim.meta_value
                    END
                    ) AS 'kiekis',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_phone'
                    ) AS 'plucked_billing_phone',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_email'
                    ) AS 'plucked_billing_email',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_first_name'
                    ) AS 'plucked_billing_first_name',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_last_name'
                    ) AS 'plucked_billing_last_name',
                    (
                        SELECT
                            woim.meta_value
                        FROM
                        wp_woocommerce_order_itemmeta woim
                        WHERE
                            woi.order_item_id = woim.order_item_id AND woim.meta_key LIKE 'Дата поездки'
                    ) AS 'plucked_travel_date',
                    (
                        SELECT
                        woim.meta_value
                        FROM
                        wp_woocommerce_order_itemmeta woim
                        WHERE
                            woi.order_item_id = woim.order_item_id AND woim.meta_key LIKE '_qty'
                    ) AS 'plucked_kiekis'
                    FROM
                        wp_woocommerce_order_items woi
                    LEFT JOIN wp_posts p ON
                        woi.order_id = p.ID
                    LEFT JOIN wp_woocommerce_order_itemmeta woim ON
                        woi.order_item_id = woim.order_item_id
                    LEFT JOIN wp_postmeta pm ON
                        woi.order_id = pm.post_id
                    WHERE
                        order_id LIKE '%{$search}%' OR order_item_name LIKE '%{$search}%' OR pm.meta_value LIKE '%{$search}%' OR woim.meta_value LIKE '%{$search}%' AND p.post_type="shop_order"
                    GROUP BY
                        woi.order_item_id
                        ",
                        ARRAY_A
                  );

            } else {
                  return $wpdb->get_results(
                        "SELECT
                        woi.order_item_name AS order_items,
                        order_id,
                        post_date,
                        p.post_status AS order_status,
                        MAX(
                            CASE WHEN pm.meta_key = '_billing_first_name' AND p.id = pm.post_id THEN pm.meta_value
                        END
                    ) AS '_billing_first_name',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_last_name' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS '_billing_last_name',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_email' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS 'billing_email',
                    MAX(
                        CASE WHEN pm.meta_key = '_billing_phone' AND p.id = pm.post_id THEN pm.meta_value
                    END
                    ) AS 'billing_phone',
                    MAX(
                        CASE WHEN woim.meta_key = 'Дата поездки' AND p.id = pm.post_id THEN woim.meta_value
                    END
                    ) AS 'travel_date',
                    MAX(
                        CASE WHEN woim.meta_key = '_qty' AND p.id = pm.post_id THEN woim.meta_value
                    END
                    ) AS 'kiekis',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_phone'
                    ) AS 'plucked_billing_phone',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_email'
                    ) AS 'plucked_billing_email',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_first_name'
                    ) AS 'plucked_billing_first_name',
                    (
                        SELECT
                            pm.meta_value
                        FROM
                            wp_postmeta pm
                        WHERE
                            woi.order_id = pm.post_id AND pm.meta_key LIKE '_billing_last_name'
                    ) AS 'plucked_billing_last_name',
                    (
                        SELECT
                            woim.meta_value
                        FROM
                        wp_woocommerce_order_itemmeta woim
                        WHERE
                            woi.order_item_id = woim.order_item_id AND woim.meta_key LIKE 'Дата поездки'
                    ) AS 'plucked_travel_date',
                    (
                        SELECT
                        woim.meta_value
                        FROM
                        wp_woocommerce_order_itemmeta woim
                        WHERE
                            woi.order_item_id = woim.order_item_id AND woim.meta_key LIKE '_qty'
                    ) AS 'plucked_kiekis'
                    FROM
                        wp_woocommerce_order_items woi
                    LEFT JOIN wp_posts p ON
                        woi.order_id = p.ID
                    LEFT JOIN wp_woocommerce_order_itemmeta woim ON
                        woi.order_item_id = woim.order_item_id
                    LEFT JOIN wp_postmeta pm ON
                        woi.order_id = pm.post_id
                    GROUP BY
                        woi.order_item_id",
                        ARRAY_A
                  );
            }
      }

      // Определить столбцы таблицы
      function get_columns()
      {

            $columns = array(
                  'cb'            => '<input type="checkbox" />',
                  'order_id' => 'ID заказа',
                  'post_date' => 'Дата',
                  'order_items' => 'Купленные поездки',
                  'plucked_kiekis' => 'Количество путешественников',
                  'plucked_billing_first_name'    => 'Имя',
                  'plucked_billing_last_name'     => 'Фамилия',
                  'plucked_billing_email'      => 'Email',
                  'plucked_billing_phone'   => 'Тел. номер',
                  'plucked_travel_date'   => 'Дата поездки',
                  'order_status' => 'Статус'

            );
            return $columns;

      }

      // Привязать таблицу с колонками, данными и всем
      function prepare_items()
      {
            if (isset($_POST['page']) && isset($_POST['s'])) {
                  $this->users_data = $this->get_users_data($_POST['s']);
            } else {
                  $this->users_data = $this->get_users_data();
            }

            $columns = $this->get_columns();
            $hidden = array();
            $sortable = $this->get_sortable_columns();
            $this->_column_headers = array($columns, $hidden, $sortable);

            /* страницация */
            $per_page = 20;
            $current_page = $this->get_pagenum();
            $total_items = count($this->users_data);

            $this->users_data = array_slice($this->users_data, (($current_page - 1) * $per_page), $per_page);

            $this->set_pagination_args(array(
                  'total_items' => $total_items, // общее количество элементов
                  'per_page'    => $per_page // элементы для отображения на странице
            ));

            usort($this->users_data, array(&$this, 'usort_reorder'));

            $this->items = $this->users_data;
      }

      // привязать данные к колонке
      function column_default($item, $column_name)
      {

            switch ($column_name) {
                  case 'order_id':
                        case 'post_date':
                        case 'order_items':
                              return $item[$column_name];
                        case 'plucked_billing_first_name':
                        case 'plucked_billing_last_name' :
                              case 'plucked_billing_email':
                              case 'plucked_billing_phone':
                                    case 'plucked_travel_date': 
                                    case 'order_status':
                                          case 'plucked_kiekis':
                              return ucwords($item[$column_name]);

                        default:
                              return print_r($item, true); //Показать весь массив для устранения неполадок
            }
      }

      // Для отображения флажка с каждой строкой
      function column_cb($item)
      {
            return sprintf(
                  '<input type="checkbox" name="user[]" value="%s" />',
                  $item['ID']
            );
      }

      // Добавить сортировку к столбцам
      protected function get_sortable_columns()
      {
            $sortable_columns = array(
                  'order_id'  => array('order_id', false),
                  'post_date' => array('post_date', false),
                  'plucked_billing_first_name'   => array('plucked_billing_first_name', true),
                  'plucked_billing_last_name'   => array('plucked_billing_last_name', true),
                  'plucked_billing_email'   => array('plucked_billing_email', true),
                  'plucked_billing_phone'   => array('plucked_billing_phone', true),
                  'order_items'   => array('order_items', true),
                  'plucked_travel_date'   => array('plucked_travel_date', true),
                  'order_status' => array('order_status', true),
                  'plucked_kiekis' => array('plucked_kiekis', true)
            );
            return $sortable_columns;
      }

      // Функция сортировки
      function usort_reorder($a, $b)
      {
            // Если сортировки нет, по умолчанию - пользовательский логин
            $orderby = (!empty($_GET['orderby'])) ? $_GET['orderby'] : 'order_id';
            // Если порядка нет, по умолчанию - по возрастанию
            $order = (!empty($_GET['order'])) ? $_GET['order'] : 'asc';
            // Определить порядок сортировки
            $result = strcmp($a[$orderby], $b[$orderby]);
            // Отправить окончательное направление сортировки в usort
            return ($order === 'asc') ? $result : -$result;
      }

}

Чтобы отобразить таблицу:

function rezervuotos_keliones()
{
      // Создание экземпляра
      $empTable = new Employees_List_Table();
      echo '<div class="wrap"><h2>Резервированные поездки</h2>';

    // Подготовка таблицы
      $empTable->prepare_items();
      ?>
            <form method="post">
                  <input type="hidden" name="page" value="rezervuotos_keliones" />
                  <?php $empTable->search_box('Поиск', 'search_id'); ?>
            </form>
      <?php
      // Отображение таблицы
      $empTable->display();
      echo '</div>';

}

Вам нужно создать метод extra_tablenav в вашем Employees_List_Table

Документация для метода: https://developer.wordpress.org/reference/classes/wp_list_table/extra_tablenav/

Пример использования в документации WP.org: https://developer.wordpress.org/reference/classes/wp_links_list_table/extra_tablenav/

Другой пример:


  protected function extra_tablenav($which){
         if($which == "top"){ ?>
             <div class="alignleft actions bulkactions">
                 <select name="user_role" id="user_role" >
                     <option value="">Все пользователи</option>
                     <option value="admin">Администраторы</option>
                     <option value="editor">Редакторы</option>
                 </select>
             </div>
             <?php
         }
         if($which == "bottom"){
             //Элементы / фильтры после таблицы будут здесь
             ?><div style="display:none;"></div><?php
         }
     }

При выполнении запроса к базе данных вам необходимо извлечь значение выпадающего списка из запроса (используйте методы WP для санитации должным образом) и вставить его в запрос.

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

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

Вот как это можно сделать, ступенчато объясняя каждый шаг:

1. Добавление метода extra_tablenav

Добавьте следующий метод в ваш класс Employees_List_Table. Он поможет создать выпадающее меню на верхней панели таблицы:

protected function extra_tablenav($which) {
    if ($which == "top") { 
        ?>
        <div class="alignleft actions bulkactions">
            <select name="product_name" id="product_name">
                <option value="">Выберите продукт</option>
                <?php
                // Получаем уникальные названия продуктов
                global $wpdb;
                $products = $wpdb->get_col("SELECT DISTINCT order_item_name FROM wp_woocommerce_order_items");
                foreach ($products as $product) {
                    echo '<option value="' . esc_attr($product) . '">' . esc_html($product) . '</option>';
                }
                ?>
            </select>
            <input type="submit" class="button" value="Фильтровать"/>
        </div>
        <?php
    }
}

2. Обработка фильтров в методе prepare_items

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

function prepare_items() {
    global $wpdb;

    $product_name = isset($_POST['product_name']) ? sanitize_text_field($_POST['product_name']) : '';
    $travel_date = isset($_POST['travel_date']) ? sanitize_text_field($_POST['travel_date']) : '';

    $this->users_data = $this->get_users_data($product_name, $travel_date);

    // Остальная часть вашего метода prepare_items остается без изменений
}

3. Изменение метода get_users_data

Измените метод get_users_data, чтобы он принимал параметры фильтрации:

private function get_users_data($product_name = "", $travel_date = "") {
    global $wpdb;

    $conditions = [];
    if (!empty($product_name)) {
        $conditions[] = "woi.order_item_name LIKE '%{$wpdb->esc_like($product_name)}%'";
    }
    if (!empty($travel_date)) {
        $conditions[] = "woim.meta_value LIKE '%{$wpdb->esc_like($travel_date)}%'";
    }

    $query = "SELECT ..."; // ваш ранее написанный SQL-запрос
    if (!empty($conditions)) {
        $query .= " WHERE " . implode(' AND ', $conditions);
    }

    return $wpdb->get_results($query, ARRAY_A);
}

4. Обновление формы для фильтрации

Чтобы добавить дополнительное поле для фильтрации по дате поездки, вам также нужно обновить ваш метод extra_tablenav, чтобы включить выпадающее меню или текстовое поле для выбора даты поездки.

<input type="text" name="travel_date" id="travel_date" placeholder="Введите дату поездки" />

Таким образом, у вас будет форма с двумя фильтрами – один для названия продукта, другой для даты поездки. Обязательно проверьте результат, чтобы убедиться, что фильтры работают как задумано.

5. Отображение убедительных результатов

Наконец, после применения фильтров, результаты должны правильно отображаться в таблице. Если у вас есть ошибки или что-то не отображается, проверьте логику SQL-запроса и отладьте его.

Заключение

Следуя этим шагам, вы сможете создать фильтры для вашей таблицы в WordPress и улучшить пользовательский опыт при просмотре заказов. Убедитесь, что вы протестировали различные сценарии использования, чтобы гарантировать корректную работу вашего плагина.

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

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