Получить список товаров заданной категории в WooCommerce

3 мар. 2018 г., 13:25:39
Просмотры: 16.3K
Голосов: 3

Я хочу получить список товаров определенной категории с помощью WP_Query, но это не работает как должно.

Я пробовал так:

$args = array( 
    'post_type' => 'product',
    'product_cat' => 17,
);
$products = new WP_Query($args);

Но это возвращает все товары из моего магазина... Я также пробовал с атрибутами 'cat', 'category' и 'category_name' с тем же результатом.

Пробовал использовать tax_query:

$args = array( 
    'post_type' => 'product',
    'tax_query' => array(
        'taxonomy' => 'product_cat',
        'terms'    => 17
    ),
);
$products = new WP_Query($args);

И это также возвращает все товары Я также пробовал с 'cat', 'category' и 'category_name' с тем же результатом.

Мне удалось получить обычные записи из заданной категории с помощью такого кода:

$args = array( 
    'post_type' => 'post',
    'cat'       => 22
);
$posts = new WP_Query($args);

Еще несколько деталей:

  • Я уверен, что у меня правильный ID категории.
  • tax_query также работал для обычных записей
  • edit: tax_query возвращает все товары, игнорируя мой атрибут product_cat

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

EDIT: фрагмент кода с tax_query был неправильным, поэтому я его изменил.

EDIT 2: Я попробовал несколько новых вещей, вот краткое содержание:

  • отключил все кастомные хуки: тот же результат
  • вручную создал экземпляр WC_Product по ID реального товара. Он показывает, что его атрибут category_ids пуст, хотя товар имеет категорию в админке... и страница таксономии категории также показывает правильные данные.
  • когда я делаю var_dump(get_the_terms($postID, 'category')); для обычной записи, это работает нормально

EDIT 3: - отключил все плагины кроме WooCommerce с тем же результатом... - когда я делаю var_dump(get_post_types());, тип записи product не отображается. И, естественно, когда я делаю var_dump(get_object_taxonomies('product'));, возвращается пустой массив.

14
Комментарии

Аргументы 'cat', 'category', 'category_name' и 'product_cat' не будут работать, потому что категории товаров являются отдельной таксономией от обычных категорий, и для запроса пользовательских таксономий вам нужен tax_query. В коде для tax_query, который я вижу здесь, нет ничего ошибочного. Либо ID действительно неправильный, либо product и product_cat — это неверные названия для типа записи и таксономии. Они были бы правильными, если вы используете WooCommerce. Вы его используете?

Jacob Peattie Jacob Peattie
3 мар. 2018 г. 13:45:58

Также убедитесь, что вы не используете хук pre_get_posts где-либо таким образом, что это может помешать данному запросу.

Jacob Peattie Jacob Peattie
3 мар. 2018 г. 13:51:41

Вы пробовали добавить 'suppress_filters' => false? Просто идея, которая пришла в голову. Не знаю, есть ли какие-то фильтры, которые нужно отключать, так как вы не упомянули, что используете для товаров.

Beee Beee
3 мар. 2018 г. 14:31:26

@JacobPeattie Я использую WooCommerce для этого. Что касается ID категории, я проверил параметры URL в админке при редактировании категории, так что он должен быть правильным. Как тогда найти правильную таксономию для категории товара?

@Beee 'suppress_filters ничего не меняет

Maayam Maayam
3 мар. 2018 г. 14:42:21

product_cat верно для WooCommerce. Это реальный код, который вы используете? Или пример? Проблема может быть в реальном коде, который отсутствует в этом примере, потому что данный код корректный.

Jacob Peattie Jacob Peattie
3 мар. 2018 г. 14:43:52

@JacobPeattie Я использую этот код как есть. Он находится в function.php дочерней темы, потому что я хочу создать вывод для пользовательского шорткода. Также у меня есть товары, сохранённые в нескольких разных категориях. Я работаю после парня, который добавил некоторые фильтры/хуки. Есть ли у вас идеи, что могло пойти не так?

Maayam Maayam
3 мар. 2018 г. 14:48:23

Даже если я использую несуществующий ID категории, он возвращает все продукты с версией tax_query

Maayam Maayam
3 мар. 2018 г. 14:54:02

"Я работаю после парня, который добавил какие-то фильтры/хуки." — возможно, один из хуков вызвал проблему? Попробуйте отключить один или несколько хуков, которые, по вашему мнению, могут быть причастны. Альтернативно, попробуйте var_dump( wc_get_products( array( 'category' => '{SLUG}', 'limit' => 1, ) ) ); (замените {SLUG} на реальный слаг категории). Просто чтобы проверить, работает ли это с использованием wc_get_products().

Sally CJ Sally CJ
3 мар. 2018 г. 15:55:21

Я попробовал вашу идею. Я отключил все кастомные хуки и попробовал ваш сниппет @Sally, но он возвращает пустой массив. Оказывается, когда я создаю экземпляр WC_Product, передавая ID продукта, его атрибут 'category_ids' пуст, хотя в админ-панели у него есть категория... Что я не понимаю, так это то, что когда я посещаю страницу категории, продукты из этой категории и только из неё отображаются. Значит, WordPress каким-то образом умеет делать этот запрос продуктов по категории

Maayam Maayam
3 мар. 2018 г. 16:04:18

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

Sally CJ Sally CJ
3 мар. 2018 г. 16:39:42

Ок, @Sally и остальные, спасибо за ваши ответы! К сожалению, мне до сих пор не удалось решить свою проблему... Я переключился на тему Twenty-Seventeen, отключил все плагины, кроме WooCommerce, но результат тот же... Однако я обнаружил кое-что ещё: когда я делаю var_dump(get_post_types());, тип записи product не отображается. И, естественно, при выполнении var_dump(get_object_taxonomies('product')); возвращается пустой массив... Есть ещё какие-то идеи? Я совершенно в тупике...

Maayam Maayam
3 мар. 2018 г. 17:13:53

Где вы выполняете этот код? Если вы делаете это слишком рано, то типы записей и таксономии ещё не будут зарегистрированы.

Jacob Peattie Jacob Peattie
3 мар. 2018 г. 17:24:46

Да, Джейкоб прав. Пользовательские типы записей обычно регистрируются во время хука init; так что если вы запускаете код до вызова этого хука, это может быть причиной проблемы. Попробуйте запустить код tax_query, который у вас в woocommerce_loaded. Пример Или другие хуки, такие как admin_init и т.д.

Sally CJ Sally CJ
3 мар. 2018 г. 17:34:12

О да, я добавлял этот код прямо в functions.php, вообще не используя хуки... Я поместил код в пользовательский шорткод (чтобы он выполнялся после инициализации всего) и когда шорткод вызывается, тип записи product и его таксономии отображаются правильно.

Когда я использую код tax_query, он всё равно возвращает все записи из моего магазина. Но теперь, когда я создаю экземпляр WC_product с его id, атрибут category_ids больше не пуст!

Пока я могу обойтись этим, но если у кого-то есть лучшее решение, я готов его рассмотреть. Подожду немного перед тем, как опубликовать полное решение.

Maayam Maayam
3 мар. 2018 г. 20:56:45
Показать остальные 9 комментариев
Все ответы на вопрос 2
0

Я знаю, что отвечаю на этот вопрос слишком поздно, но это может помочь другим.

$args = array(      
        'post_type' => 'product', // Тип записи - товар
        'post_status' => 'publish', // Статус - опубликовано
        'tax_query' => array(
                        array(
                            'taxonomy' => 'product_cat', // Таксономия - категория товара
                            'field'    => 'term_id', // Поле - ID термина
                            'terms'    => array($cat_id1,$cat_id2), // ID категорий
                            ),
                        ),
            );

$query = new WP_Query($args); // Создаем новый запрос

Протестировано и работает на WC 3.9.1

11 апр. 2020 г. 17:00:35
0

В итоге моя основная проблема оказалась в том, что я выполнял код прямо в functions.php (для тестирования). Код выполнялся до инициализации WooCommerce, поэтому не мог правильно получить товары. Несмотря на это, мне не удавалось заставить Wp_Query возвращать только товары из одной заданной категории. Он продолжал возвращать все товары из моей базы данных, поэтому я нашел обходной путь.

$category; //эта переменная содержит slug нужной категории
$productPosts = new WP_Query(array(
    'post_type' => 'product'
));

//Я мог бы использовать $productPosts->have_posts() здесь, но решил не использовать в моем конкретном контексте
foreach ($productPosts->posts as $p) {
    $currentProduct = new WC_Product_Variable($p->ID);

    //Я могу получить доступ только к ID категорий через WC_Product, поэтому создаю массив slug'ов категорий
    foreach ($currentProduct->get_category_ids() as $catId) {
        if( $term = get_term_by( 'id', $catId, 'product_cat' ) ){
            array_push($categories, $term->name); //добавляем в массив
        }
    }

    if(in_array($category, $categories)){ //если текущий товар имеет запрошенную категорию,
        //добавляем $currentProduct в массив $products
        array_push($products, $currentProduct);
    }
    else{//текущий товар не имеет запрошенной категории
    }
} //конец foreach, теперь у нас есть все товары нужной категории... в массиве $products

Это работает... Но, честно говоря, это кажется неправильным. Я делаю несколько запросов к базе данных для каждого товара, который хочу включить в итоговый массив... Разве так должен работать WooCommerce? Также я не уверен, как мне следует реализовать пагинацию с этими данными, но в данном случае это не моя забота...

Должен быть лучший способ сделать это, но пока я его не нашел...

5 мар. 2018 г. 09:55:58