Фильтрация элементов заказа Woocommerce $ по категории (сроку)

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

У меня есть шаблон печати для заказов Woocommerce, в котором перечислены продукты обычным способом, порядок, в котором они хранятся в массиве, который, в свою очередь, является порядком, в котором они были помещены в корзину и т. Д. Однако мы хотим, чтобы они были сгруппированы по категориям (срокам) . Таким образом, это будет означать, что сначала будут перечислены все элементы под term_id 17, затем все term_id 18 и т. Д.

В идеале это был бы автоматический процесс, при котором код считывает все используемые Условия, затем проходит их по одному и выводит все продукты для этого Срока, которые находятся в корзине. Но я еще не приблизился к этому этапу.

До сих пор у меня был частичный успех с этим кодом:

foreach ($order->get_items() as $item) {

     $product_id = $item['product_id'];

     $meta = $item['item_meta'];
     $meta = array_filter($meta, function ($key) {
     return !in_array($key, Order::getHiddenKeys());
}, ARRAY_FILTER_USE_KEY);

$terms = get_the_terms ( $product_id, 'product_cat' );

foreach ( $terms as $term ) {
    $cat_id = $term->term_id;
    
    if($cat_id === 18) {
        var_dump($item['name']);
    }
}

Это приведет к успешному сбросу элементов заказа, отнесенных к категории term_id 18. Однако, если я изменю оператор IF следующим образом:

if($cat_id === 18) {
    var_dump($item['name']);
} elseif($cat_id === 17) {
    var_dump($item['name']);
}

Я ожидал, что он выведет элементы term_id 18, а затем элементы term_id 17 ПОСЛЕ. К сожалению, он просто показывает массив в порядке по умолчанию: 17, затем 18, несмотря на то, что код построен таким образом.

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

function test ($var) {
    foreach ( $terms as $term ) {
        $cat_id = $term->term_id;
    
        if($cat_id === 18) {
            print_r($item['name']);
        }
    }
    return $var;
}
    
foreach ($order->get_items() as $item) {

    $product_id = $item['product_id'];

    $meta = $item['item_meta'];
    $meta = array_filter($meta, function ($key) {
    return !in_array($key, Order::getHiddenKeys());
}, ARRAY_FILTER_USE_KEY);
    
$terms = get_the_terms ( $product_id, 'product_cat' );

print_r(array_filter($terms, "test"));

Я знаю, что это в значительной степени неправильно, но я просто не могу понять это. Я нормально отношусь к базовому использованию PHP и Wordpress PHP, но Woocommerce намного сложнее! Буду очень признателен за любую помощь с этим, пожалуйста.

Напомню, что я хочу, чтобы продукты были напечатаны / отображены эхом / и т. Д. В порядке категорий (автоматически, если кто-то чувствует себя очень щедрым, лол). Я действительно не возражаю, как это достигается, если это, очевидно, безопасно и надежно.

Приносим извинения за длинный пост и огромное спасибо заранее.


person Feel Content    schedule 19.01.2021    source источник
comment
Ваш код немного устарел, так как WooCommerce 3 ищет этот поток для элементов заказа в цикле ... Теперь сортируем элементы заказа на основе категории продукта сложно, так как вы можете настроить множество категорий для продукта ... Лучше всего отсортировать элементы корзины перед размещением заказа (посмотреть эту ветку)   -  person LoicTheAztec    schedule 20.01.2021
comment
Я знал, что это был не лучший подход с момента перехода на Woocommerce 3, но я изо всех сил пытался найти примеры кода в тех строках, которые я искал, поэтому я выбрал этот подход. В частности сортировка по категориям. Я обязательно прочитаю темы, которые вы выделили, но на данный момент сортировка в корзине - это резервный план, поскольку я взаимодействую с третьей стороной и не могу гарантировать, что ничто не помешает ей, прежде чем она дойдет до этого точка, отсюда и такой подход.   -  person Feel Content    schedule 20.01.2021


Ответы (1)


Мне кажется, что вы зацикливаете заказы, но не зацикливаете категории, которые хотите их упорядочить.

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

// Group items into Categories - If you have a custom order you wish, pre-populate this array, or you can sort after
$categories = [];
foreach ($order->get_items() as $item) {
    $product_id = $item['product_id'];
    $terms = get_the_terms($product_id, 'product_cat');
    $cat_id = $terms[0]->term_id;
    $categories[$cat_id][] = $item;
}

// Loop Categories
foreach($categories as $category => $items){
    echo sprintf("<h1>%s</h1>", $category);
    //Loop Items in Category
    foreach ($items as $item) {
        print_r($item['name']);
    }
}
person Jay Hewitt    schedule 19.01.2021
comment
О, это почти готово! Он перечисляет идентификатор категории, а затем содержимое, всего 5 раз, что является количеством элементов в заказе. Я собираюсь подобрать его утром и посмотреть, смогу ли я его настроить. - person Feel Content; 20.01.2021
comment
Нет, не обращай на это внимания, это я был тупицей. Я случайно поместил его в другую петлю! Этот код работает отлично. - person Feel Content; 20.01.2021
comment
Одно дело, прежде чем я помечу его как принятый ответ. Насколько легко настроить порядок категорий при таком подходе? Если я правильно это читаю, вы можете просто изменить переменную $ Categories на список целых чисел, и она будет работать до тех пор, пока вы удалите строку, присваивающую $ cat_id $ категориям. - person Feel Content; 20.01.2021
comment
Если категории установлены, и вы счастливы жестко их запрограммировать, то, если вы заранее установите массив $ категорий, это все, что вам нужно сделать. например следующее установит порядок 18,17, а затем последует что-нибудь еще - $ Categories = [18 = ›[], 17 =› []]; - person Jay Hewitt; 20.01.2021
comment
В качестве альтернативы, если вы просто хотите отсортировать по названию категории, то перед тем, как зациклить категории, вы можете выполнить сортировку по ключевым словам - ksort ($ Categories) для ASC и krsort ($ Categories) для DESC. - person Jay Hewitt; 20.01.2021
comment
Это примерно то, о чем я подумал, спасибо за пояснение. В настоящее время это использование должно быть абсолютно идеальным, но я просто хотел дважды проверить свои возможности, пока мы говорили об этом. Еще раз спасибо, приятель! - person Feel Content; 20.01.2021