Получить список товаров заданной категории в WooCommerce
Я хочу получить список товаров определенной категории с помощью 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'));
, возвращается пустой массив.

Я знаю, что отвечаю на этот вопрос слишком поздно, но это может помочь другим.
$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

В итоге моя основная проблема оказалась в том, что я выполнял код прямо в 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? Также я не уверен, как мне следует реализовать пагинацию с этими данными, но в данном случае это не моя забота...
Должен быть лучший способ сделать это, но пока я его не нашел...
