Выведем все купленные товары клиентом в личном кабинете, как на маркетплейсе. В Woocommerce есть вкладка с заказами, но найти купленный товар через поиск или визуально его найти очень неудобно. Давайте исправим это!
Если у вас карточки товара сделаны через стандартный виджет Woocommerce, то используйте этот способ.
В моём способе вам нужен плагин jetengine.
Добавим сниппет-код:
add_action( 'jet-engine/register-macros', function() {
if ( ! class_exists( '\Jet_Engine_Base_Macros' ) ) {
return;
}
class Purchased_Products_Macro extends \Jet_Engine_Base_Macros {
public function macros_tag() { return 'purchased_products'; }
public function macros_name() { return esc_html__( 'Purchased products', 'jet-engine' ); }
public function macros_args() { return array(); }
public function macros_callback( $args = array() ) {
if ( ! function_exists( 'WC' ) ) {
return '0';
}
$use_hpos = class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' )
&& \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
if ( ! $use_hpos ) {
return '0';
}
$user_id = get_current_user_id();
if ( ! $user_id ) {
return '0';
}
$cache_key = 'je_purchased_products_unique_hpos_uid_' . $user_id;
$cache_ttl = apply_filters( 'je_purchased_products_cache_ttl', 15 * MINUTE_IN_SECONDS ); // 15 мин по умолчанию
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return (string) $cached;
}
global $wpdb;
$table_orders = $wpdb->prefix . 'wc_orders';
$table_items = $wpdb->prefix . 'wc_order_items';
$table_itemmeta = $wpdb->prefix . 'wc_order_itemmeta';
$sql = $wpdb->prepare(
"SELECT CAST(meta_product.meta_value AS UNSIGNED) AS product_id,
MAX(o.date_created_gmt) AS last_date
FROM {$table_items} items
INNER JOIN {$table_orders} o
ON items.order_id = o.id
INNER JOIN {$table_itemmeta} meta_product
ON meta_product.order_item_id = items.order_item_id
AND meta_product.meta_key = '_product_id'
WHERE o.type = 'shop_order'
AND o.status = 'wc-completed'
AND o.customer_id = %d
AND items.order_item_type = 'line_item'
GROUP BY meta_product.meta_value
ORDER BY last_date DESC",
$user_id
);
$rows = $wpdb->get_results( $sql );
if ( empty( $rows ) ) {
set_transient( $cache_key, '0', $cache_ttl );
return '0';
}
$product_ids = array();
foreach ( $rows as $row ) {
$pid = (int) $row->product_id;
if ( $pid > 0 ) {
$product_ids[] = $pid;
}
}
if ( empty( $product_ids ) ) {
set_transient( $cache_key, '0', $cache_ttl );
return '0';
}
$result = implode( ',', $product_ids );
set_transient( $cache_key, $result, $cache_ttl );
return $result;
}
}
new Purchased_Products_Macro();
} );
function je_pp_unique_clear_cache_by_order_uid( $order ) {
if ( is_numeric( $order ) ) {
$order = wc_get_order( $order );
}
if ( ! $order instanceof WC_Order ) {
return;
}
if ( method_exists( $order, 'get_type' ) && 'shop_order' !== $order->get_type() ) {
return;
}
$user_id = (int) $order->get_customer_id();
if ( $user_id > 0 ) {
delete_transient( 'je_purchased_products_unique_hpos_uid_' . $user_id );
}
}
add_action( 'woocommerce_order_status_changed', function( $order_id, $old_status, $new_status, $order ) {
je_pp_unique_clear_cache_by_order_uid( $order ?: $order_id );
}, 10, 4 );
add_action( 'woocommerce_order_refunded', function( $order_id, $refund_id ) {
je_pp_unique_clear_cache_by_order_uid( $order_id );
}, 10, 2 );
add_action( 'woocommerce_order_partially_refunded', function( $order_id, $refund_id ) {
je_pp_unique_clear_cache_by_order_uid( $order_id );
}, 10, 2 );Далее создайте вкладку в личном кабинете и выведите все купленные товары через listing grid с настройками:

