Woocommerce - как отображать только отложенные заказы с помощью шорткода

По умолчанию в таблице заказов Woocommerce отображается статус всех доступных заказов на странице Моя учетная запись, которая не может быть отсортирована по клиентам, поэтому мне нужен отдельный table для каждой уникальной статуи заказа (пример: «приостановлено») для отображения таблицы заказов, основанной только на требуемой статуе.

Я пробовал этот код, но он не выводит таблицу:

/* Shortcode To Display Only On-hold Orders On A Custom Page */

add_shortcode('account_on_hold', 'get_customer_orders_on_hold');

function get_customer_orders_on_hold() {


  if( $user = wp_get_current_user() ){

    // Get 'on-hold' customer ORDERS
        $on_hold_orders = wc_get_orders( array(
            'limit' => -1,
            'customer_id' => $user->ID,
            'status' => array('on-hold'),
        ) );

    }
    return $on_hold_orders ;
} 

Связанная тема: Получение общей суммы заказа клиента в состоянии ожидания в Woocommerce

Будем признательны за ваш совет!


person Omid Toraby    schedule 14.05.2021    source источник


Ответы (2)


Путь Руви хорош в настройке. В качестве альтернативы, если вы хотите, чтобы вывод был таким же, как my-account / orders, существует также метод для вызова шаблона.

add_shortcode('account_on_hold', 'get_customer_orders_on_hold');
function get_customer_orders_on_hold() {
    if( $user = wp_get_current_user() ){
        $customer_orders = wc_get_orders(
            array(
                'customer' => $user->ID,
                'limit' => -1,
                'page' => 1,
                'paginate' => true,
                'status' => array('on-hold'),
            )
        );
        ob_start();
        wc_get_template(
            'myaccount/orders.php',
            array(
                'current_page'    => 1,
                'customer_orders' => $customer_orders,
                'has_orders'      => 0 < $customer_orders->total,
            )
        );
        return ob_get_clean();
    }
} 

(Дополнение) Способ добавления настраиваемого меню на myaccount.

// Add custom endpoint
add_action( 'init', function () {
    add_rewrite_endpoint( 'on-hold-orders', EP_ROOT | EP_PAGES );
});

// Add custom menu
add_filter( 'woocommerce_account_menu_items', function ( $items ) {
    $new_items = array();
    foreach( $items as $key => $item ){// Loop menu items
        $new_items[$key] = $item;
        if( 'orders' == $key ) $new_items['on-hold-orders'] = __( 'On hold orders' ); 
    }
    return $new_items;
}, 20 );

// Output custom menu page template
add_action( 'woocommerce_account_on-hold-orders_endpoint', function( $current_page ) {
    $current_page = empty( $current_page ) ? 1 : absint( $current_page ); // With paginate
    $customer_orders = wc_get_orders( array(
        'customer' => get_current_user_id(),
        'page'     => $current_page,
        'paginate' => true,
        'status' => array('on-hold'),
    ));
    wc_get_template(
        'myaccount/orders.php',
        array(
            'current_page'    => absint( $current_page ),
            'customer_orders' => $customer_orders,
            'has_orders'      => 0 < $customer_orders->total,
        )
    );
} );
person Mizuho Ogino    schedule 15.05.2021
comment
Спасибо! Могу ли я разместить рядом с этой таблицей меню навигации по моей учетной записи? - person Omid Toraby; 15.05.2021
comment
В порядке. Вам не нужно использовать тег шорткода, если вы просто хотите добавить дополнительное меню на страницу Myaccount. Я откорректировал ответ. Попробуй. - person Mizuho Ogino; 16.05.2021
comment
Я забыл сказать. Возможно, вам потребуется обновить постоянные ссылки после функций вставки. - person Mizuho Ogino; 16.05.2021
comment
Отличный подход, работает как шарм! Еще раз спасибо! - person Omid Toraby; 16.05.2021

Вы можете использовать шаблон таблицы woocommerce для создания таблицы html. Вам нужно только поставить условную проверку перед ее генерацией.

woocommerce table template
+
if("On hold" == esc_html(wc_get_order_status_name($order->get_status())))

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

add_shortcode('account_on_hold', 'get_customer_orders_on_hold');

function get_customer_orders_on_hold()
{
  if ($user = wp_get_current_user()) {

  $on_hold_orders = wc_get_orders(array(
    'limit' => -1,
    'customer_id' => $user->ID,
    'status' => array('on-hold'),
  ));

  if ($on_hold_orders) :
?>
    <table class="woocommerce-orders-table woocommerce-MyAccount-orders shop_table shop_table_responsive my_account_orders account-orders-table">
      <thead>
        <tr>
          <?php foreach (wc_get_account_orders_columns() as $column_id => $column_name) : ?>
            <th class="woocommerce-orders-table__header woocommerce-orders-table__header-<?php echo esc_attr($column_id); ?>"><span class="nobr"><?php echo esc_html($column_name); ?></span></th>
          <?php endforeach; ?>
        </tr>
      </thead>

      <tbody>
        <?php
        foreach ($on_hold_orders as $order) {
          $order      = wc_get_order($order);
          $item_count = $order->get_item_count() - $order->get_item_count_refunded();
          if ("On hold" == esc_html(wc_get_order_status_name($order->get_status()))) :
        ?>
            <tr class="woocommerce-orders-table__row woocommerce-orders-table__row--status-<?php echo esc_attr($order->get_status()); ?> order">
              <?php foreach (wc_get_account_orders_columns() as $column_id => $column_name) : ?>
                <td class="woocommerce-orders-table__cell woocommerce-orders-table__cell-<?php echo esc_attr($column_id); ?>" data-title="<?php echo esc_attr($column_name); ?>">
                  <?php if (has_action('woocommerce_my_account_my_orders_column_' . $column_id)) : ?>
                    <?php do_action('woocommerce_my_account_my_orders_column_' . $column_id, $order); ?>

                  <?php elseif ('order-number' === $column_id) : ?>
                    <a href="<?php echo esc_url($order->get_view_order_url()); ?>">
                      <?php echo esc_html(_x('#', 'hash before order number', 'woocommerce') . $order->get_order_number()); ?>
                    </a>

                  <?php elseif ('order-date' === $column_id) : ?>
                    <time datetime="<?php echo esc_attr($order->get_date_created()->date('c')); ?>"><?php echo esc_html(wc_format_datetime($order->get_date_created())); ?></time>

                  <?php elseif ('order-status' === $column_id) : ?>
                    <?php echo esc_html(wc_get_order_status_name($order->get_status())); ?>

                  <?php elseif ('order-total' === $column_id) : ?>
                    <?php
                    echo wp_kses_post(sprintf(_n('%1$s for %2$s item', '%1$s for %2$s items', $item_count, 'woocommerce'), $order->get_formatted_order_total(), $item_count));
                    ?>

                  <?php elseif ('order-actions' === $column_id) : ?>
                    <?php
                    $actions = wc_get_account_orders_actions($order);

                    if (!empty($actions)) {
                      foreach ($actions as $key => $action) {
                        echo '<a href="' . esc_url($action['url']) . '" class="woocommerce-button button ' . sanitize_html_class($key) . '">' . esc_html($action['name']) . '</a>';
                      }
                    }
                    ?>
                  <?php endif; ?>
                </td>
              <?php endforeach; ?>
            </tr>
        <?php
          endif;
        }
        ?>
      </tbody>
    </table>

  <?php endif; ?>

<?php }
}

Проверено и работает.

person Ruvee    schedule 14.05.2021
comment
Спасибо, но предложенный вами код тоже не работает! Я получаю вывод (Массив) вместо содержимого столбцов таблицы. - person Omid Toraby; 15.05.2021
comment
Что ж, я протестировал его в своей лаборатории woocommerce по умолчанию, и он отлично работает. Чтобы вы могли заставить его работать, я думаю, нам нужно удалить оператор return. Я только что обновил свой ответ и удалил return $on_hold_orders; - person Ruvee; 15.05.2021
comment
Я думаю, что решение, предложенное Мидзухо Огино, чище и надежнее, чем мое собственное решение. - person Ruvee; 15.05.2021