WooCommerce виджет категорий товаров - скрыть категории с отсутствующими в наличии товарами
Я использую WooCommerce на своем сайте WordPress и имею виджет в сайдбаре, показывающий все категории товаров. Он настроен скрывать пустые категории, и это работает хорошо. Однако он по-прежнему показывает категории, которые содержат только товары, отсутствующие в наличии - это я хотел бы изменить.
Техническое объяснение: товары WooCommerce являются пользовательским типом записи (product
), категории товаров - это пользовательская таксономия (product_cat
), а количество на складе - это пользовательское поле товаров (_stock
). Виджет категорий товаров WooCommerce отображает их с помощью wp_list_categories()
. Я пытался копаться в коде в поисках вызова фильтра, к которому можно было бы подключиться, но не смог найти.
Есть ли хороший способ сделать это без модификации основного кода или кода WooCommerce? Может быть, где-то есть хук/фильтр, который я пропустил, который позволил бы проверить значение пользовательского поля?
Используйте фильтры woocommerce_product_categories_widget_args
и woocommerce_get_availability
в пользовательской функции для фильтрации виджета категорий товаров для отсутствующих в наличии продуктов.
Посмотрите, что у вас получится с этими фильтрами, и если возникнут трудности, опубликуйте свой код здесь.
Вот пример кода с моего сайта, который может помочь вам начать:
add_filter( 'woocommerce_product_categories_widget_args', 'wpsites_exclude_product_cat_widget' );
function wpsites_exclude_product_cat_widget( $args ) {
$args['exclude'] = array('16','46');
return $args;
}
Все хуки для WooCommerce вы можете найти по ссылке.

+1. Я как раз думал об этом подходе, но в обратном порядке... используя параметр 'include'. Если запросить все товары в каждой категории, то как только вы найдете 1 товар в наличии, можно добавить его в массив 'included' и перейти к следующей категории, вместо проверки каждой категории. Похоже, это старый вопрос (я не всегда замечаю даты), но он меня заинтриговал.

Написал ниже после того, как нашел эту ветку в поиске Google. Предполагаю, что сам запрос можно оптимизировать, мои знания SQL слабоваты. Интересно, как этот подход по скорости сравнится с идеей @helgatheviking использовать циклы.
https://gist.github.com/karpstrucking/1f6139d6899b1709f545

Я не уверен, что это возможно, так как, насколько я знаю, в функции wp_list_categories()
нет места, где проверялся бы статус постов/товаров в категории. Даже если бы такая проверка была, вам пришлось бы запрашивать множество товаров во ВСЕХ категориях, что было бы крайне неэффективно.
Возможно, вы могли бы заменить WC_Product_Cat_Dropdown_Walker
и реализовать свою проверку там.
Ответственная функция, судя по всему, принимает другой Walker:
/**
* Обход категорий товаров.
*
* @return mixed
*/
function wc_walk_category_dropdown_tree() {
global $woocommerce;
if ( ! class_exists( 'WC_Product_Cat_Dropdown_Walker' ) )
include_once( WC()->plugin_path() . '/includes/walkers/class-product-cat-dropdown-walker.php' );
$args = func_get_args();
// Пользовательские настройки передаются третьим параметром
if ( empty( $args[2]['walker']) || !is_a($args[2]['walker'], 'Walker' ) )
$walker = new WC_Product_Cat_Dropdown_Walker;
else
$walker = $args[2]['walker'];
return call_user_func_array(array( &$walker, 'walk' ), $args );
}
Таким образом, если вы дублируете виджет, вы могли бы изменить
// Придется использовать это, пока не исправят баг http://core.trac.wordpress.org/ticket/13258
wc_product_dropdown_categories( array(
'show_counts' => $c,
'hierarchical' => $h,
'show_uncategorized' => 0,
'orderby' => $o
) );
на
// Придется использовать это, пока не исправят баг http://core.trac.wordpress.org/ticket/13258
wc_product_dropdown_categories( array(
'show_counts' => $c,
'hierarchical' => $h,
'show_uncategorized' => 0,
'orderby' => $o,
'walker' => 'InStock_Categories'
) );
И тогда вам нужно будет создать и подключить класс Walker InStock_Categories
. Этот подход полностью непроверен, но я просто делюсь идеями.

Если вы перейдете в WooCommerce => Настройки и выберете вкладку 'Склад', вы увидите опцию 'Скрыть отсутствующие товары из каталога'. Если включить эту опцию, то отсутствующие товары не будут отображаться, и если в категории нет доступных для продажи товаров (отсутствуют на складе или без цены), она также будет скрыта.
Обновление
Хорошо, я прочитал 'виджет' и полностью проигнорировал это в своем ответе.
Насколько мне известно, виджет WooCommerce "Категории товаров" не поддерживает фильтрацию товаров/категорий. Так что нет хуков или фильтров, о которых я знаю.
Но вы можете легко скопировать один файл и модифицировать его как самостоятельный виджет, который не будет перезаписан при обновлении WooCommerce.
Надеюсь, это поможет.

Опция включена. Товары, отсутствующие в наличии, не отображаются на страницах магазина, но они все еще учитываются в количестве товаров категории, а категории, содержащие только отсутствующие товары, по-прежнему отображаются в виджете.

Он поддерживает фильтрацию категорий в виджете, которую также можно использовать с условными тегами WooCommerce.

@BradDalton Не могли бы вы добавить ответ на этот вопрос со ссылками на соответствующую документацию? Это значительно улучшит качество вопроса/ответа.
