The correct way to Display recently purchased Products in Member’s area

Written by Tommy
Posted on Mon, 05/10/2021 - 09:28

Share Everywhere

Trước khi thực hiện hướng dẫn này, tôi khuyên bạn nên xem hướng dẫn Mục đơn hàng và hướng dẫn menu tài khoản của tôi. Và đây là những gì chúng tôi sẽ tạo ra.

Ok, now I’m going to do some stuff with $wpdb and WP_Query but before implementing the code, please read these key points.

  • You can’t access WooCommerce tables this way: $wpdb->woocommerce_order_itemmeta! Use $wpdb->prefix . 'woocommerce_order_itemmeta instead.
  • The post_author column in $wpdb->posts table is not a customer ID, the customer IDs are stored in $wpdb->postmeta under _customer_user meta key.
  • We need only one _product_id value from wp_woocommerce_order_itemmeta table. So $wpdb->get_col() is pretty good for this purpose.
  • WooCommerce has a native function wc_customer_bought_product( $email, $user_id, $id ) that allows to check if this customer purchased a specific product. You may think that it is OK to loop through all the products and a condition with this function inside the loop. No, it is not OK! Imagine if a WooCommerce shop has 20K products.
  • Keep in mind, that rewrite endpoint purchased-products on line 17 should be the part of the action on line 3 woocommerce_account_{REWRITE ENDPOINT}_endpoint. And do not forget to go to Settings > Permalinks and to Save Changes once you insert this code, otherwise you will receive 404 error trying to access this page.

The code below is for you custom (child) theme functions.php file or for your custom plugin.

add_filter ( 'woocommerce_account_menu_items', 'misha_purchased_products_link', 40 );
add_action( 'init', 'misha_add_products_endpoint' );
add_action( 'woocommerce_account_purchased-products_endpoint', 'misha_populate_products_page' );
// here we hook the My Account menu links and add our custom one
function misha_purchased_products_link( $menu_links ){
	// we use array_slice() because we want our link to be on the 3rd position
	return array_slice( $menu_links, 0, 2, true )
	+ array( 'purchased-products' => 'Purchased Products' )
	+ array_slice( $menu_links, 2, NULL, true );
// here we register our rewrite rule
function misha_add_products_endpoint() {
	add_rewrite_endpoint( 'purchased-products', EP_PAGES );
// here we populate the new page with the content
function misha_populate_products_page() {
	global $wpdb;
	// this SQL query allows to get all the products purchased by the current user
	// in this example we sort products by date but you can reorder them another way
	$purchased_products_ids = $wpdb->get_col( $wpdb->prepare(
		SELECT      itemmeta.meta_value
		FROM        " . $wpdb->prefix . "woocommerce_order_itemmeta itemmeta
		INNER JOIN  " . $wpdb->prefix . "woocommerce_order_items items
		            ON itemmeta.order_item_id = items.order_item_id
		INNER JOIN  $wpdb->posts orders
		            ON orders.ID = items.order_id
		INNER JOIN  $wpdb->postmeta ordermeta
		            ON orders.ID = ordermeta.post_id
		WHERE       itemmeta.meta_key = '_product_id'
		            AND ordermeta.meta_key = '_customer_user'
		            AND ordermeta.meta_value = %s
		ORDER BY    orders.post_date DESC
	) );
	// some orders may contain the same product, but we do not need it twice
	$purchased_products_ids = array_unique( $purchased_products_ids );
	// if the customer purchased something
	if( !empty( $purchased_products_ids ) ) :
		// it is time for a regular WP_Query
		$purchased_products = new WP_Query( array(
			'post_type' => 'product',
			'post_status' => 'publish',
			'post__in' => $purchased_products_ids,
			'orderby' => 'post__in'
		) );
		echo '<div class="woocommerce columns-3">';
		while ( $purchased_products->have_posts() ) : $purchased_products->the_post();
			wc_get_template_part( 'content', 'product' );
		echo '</div>';
		echo 'Nothing purchased yet.';

Bạn có thể thêm bất kỳ biểu tượng nào vào phần tử menu của mình bằng một vài dòng mã CSS, bạn có thể đọc thêm về nó tại đây.

body.woocommerce-account ul li.woocommerce-MyAccount-navigation-link--purchased-products a:before{
	content: "\f1b2";

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Profile picture for user Tommy
Câu nói tâm đắc: “Điều tuyệt với nhất trong cuộc sống là làm được những việc mà người khác tin là không thể!”