Ecommerce Shopify WordPress Discussion

Updating user custom metadata from WooCommerce order status change

I'm pretty new at coding and I have difficulties finding out why my code does not work properly. In WordPress/Woocommerce, I want to check if the customer has bought a product (box subscription), and if so, the customer can access a special content. For that, I used to put the information in the database in user_meta. Here is the code I used before when it worked : // Order check to activate private content add_action( 'woocommerce_order_status_changed', 'TB_verify_order_content', 10, 3 ); function TB_verify_order_content( $order_id, $old_status, $new_status ) { if( $new_status != 'processing' ) return; $order = wc_get_order( $order_id ); $user_id = $order->get_user_id(); // Check the product in the order $items = $order->get_items(); foreach ( $items as $item ) { $product_id = $item->get_product_id(); if( $product_id == 18899 ) { // Check date user put in form $item_meta_data = $item->get_formatted_meta_data( '_', true ); foreach( $item_meta_data as $the_data ) { if( $the_data->key == 'End Date' ) $enddate = $the_data->value; } // Check if it's a renew $renew = get_post_meta( $order_id, 'is_a_renew', true ); $is_a_renew = ( isset( $renew ) && $renew == 'yes' ) ? true : false; if( $enddate != '' ) { $first_date = date( 'd/m/Y' ); // Access to private content : setup at first subscription if ( !$is_a_renew ) { $tab_access = array( 'access_begining' => time(), 'access_first_date' => $first_date, 'access_end' => '-1', 'access_end_date' => '', 'end' => $enddate ); update_user_meta( $user_id, 'BO_access_content', $tab_access ); // End of subscription : subscription ID = Order ID of first order +1 $time_end = TB_end_of_subscription( $first_date, $enddate ); update_post_meta( $order_id+1, 'expired_date' , $time_end ); // Date of last payment : max 25 days before 3 years $time_end = DateTime::createFromFormat( 'd/m/Y', $enddate ); $time_end->modify( '- 25 days' ); $time_thirtysix = TB_end_of_subscription( $first_date, $enddate, 36 ); // 36th subscription month $tab_payments = array( 'date_dp' => date( 'd/m/Y', $time_end->getTimestamp() ), 'time_adp' => $time_thirtysix ); update_post_meta( $order_id, 'last_payment' , $tab_payments ); } // Data to check box and next box $num_box = TB_calculate_box( $first_date, $enddate ); $next_month = date( 'd/m/Y', mktime(0, 0, 0, date('m')+1, 5, date('Y') ) ); $tab_box = array( array( 'box' => $num_box, 'date' => $first_date ) ); if( $num_box < 36 ) $tab_box[] = array( 'box' => $num_box+1, 'date' => $next_month ); update_post_meta( $order_id, 'BO_envoi_box', $tab_box ); } } } } } } // Evaluating subscription month and verify end of subscription function TB_max_month_autorized( $tab_param ) { $return = -1; // Ongoing month $return = TB_calculate_month( $tab_param['access_first_date'], $tab_param['end'] ); // If subscription stops, changes content access autorization if( $tab_param['access_end'] != '-1' && $tab_param['access_end_date'] != '' ) { $return = TB_calculate_month( $tab_param['access_first_date'], $tab_param['acces_end_date'] ); } return $return; } // Add content in tab "My content" add_action( 'woocommerce_account_downloads_endpoint', 'TB_add_content' ); function TB_add_content() { // Getting user data $current_user = wp_get_current_user(); $access_autorized = false; $month_user = -1; if ( $current_user->ID > 0 ) { $tab_access = get_user_meta( $current_user->ID, 'BO_access_content', true ); // Calculation of subscription month and number of box if( isset( $tab_access ) && is_array( $tab_access ) && $tab_access['end'] != '' ) { $month_user = TB_max_month_autorized( $tab_access ); } // Subscription ongoing, list of accessible content if( $month_user > 0 ) { $query = new WP_Query( array( 'post_type' => 'page', 'meta_key' => '_wp_page_template', 'meta_value' => 'templates/template-private_page.php', 'order' => 'DESC', 'orderby' => 'menu_order', 'meta_key' => 'access_month', 'meta_value' => $month_user, 'meta_compare' => '<=', 'posts_per_page' => -1, ) ); if ( $query->have_posts() ) { while ( $query->have_posts() ) : $query->the_post(); $menu_order = get_post_field('menu_order', get_the_ID()); if ($menu_order < 100) { echo '<a class="button content_link" target="_blank" title="'.get_the_title().'" href="'.get_the_permalink().'">'; the_title(); echo '</a>'; echo '<br/>'; } endwhile; // end of the loop. } wp_reset_query(); } } } Then I wanted to add another condition for another product and it stopped working :( Here is the code I am currently using : // Order check to activate private content add_action( 'woocommerce_order_status_changed', 'TB_verify_order_content', 10, 3 ); function TB_verify_order_content( $order_id, $old_status, $new_status ) { // Check New product in the order foreach ( $items as $item ) { $product_id = $item->get_product_id(); if( $product_id == 19232 ) { update_user_meta( $user_id, 'BO_access_special_content', true ); } } } // Add content in tab "My content" add_action( 'woocommerce_account_downloads_endpoint', 'TB_add_content' ); function TB_add_content() { // Check if user bought product and Display Special Content $current_user = wp_get_current_user(); if ( $current_user->ID > 0 ) { $user_orders = wc_get_orders( array( 'customer_id' => $current_user->ID ) ); foreach ( $user_orders as $user_order ) { if ( get_post_meta( $user_order->get_id(), 'BO_access_special_content', true ) ) { $article_ids = array(19232); foreach ($article_ids as $article_id) { echo '<a class="button content_link" target="_blank" title="'.get_the_title($article_id).'" href="'.get_permalink($article_id).'">'; echo get_the_title($article_id); echo '</a><br/>'; } } } } } At this point, I don't know where the problem is, I checked in database and user_meta is empty when I perform real tests. I checked in database and it's empty. When I use my previous function.php template, database is filled with correct info. I emptied cache and still got no result.
In your recent code, first you save 'BO_access_special_content' custom field as user metadata but not as order metadata, so you don't need to query customer orders. Also, the hook woocommerce_order_status_changed has 4 available arguments. The last argument is the WC_Order object $order, so you don't need to get the order object, like in your previous code). If you don't add your new code in your previous functions, you need different unique function names, than previous existing ones. Also, there are some missing things in your first new function. Instead, try the following code replacement: // Order check to activate private content add_action( 'woocommerce_order_status_changed', 'TB_verify_order_content_2', 10, 4 ); function TB_verify_order_content_2( $order_id, $old_status, $new_status, $order ) { if( $new_status !== 'processing' ) return; $user_id = $order->get_customer_id(); // Check New product in the order foreach ( $order->get_items() as $item ) { $product_id = $item->get_product_id(); if( $product_id == 19232 ) { update_user_meta( $user_id, 'BO_access_special_content', true ); } } } // Add content in tab "My content" add_action( 'woocommerce_account_downloads_endpoint', 'TB_add_content_2' ); function TB_add_content_2() { global $current_user; if ( $current_user->ID > 0 ) { if ( get_user_meta( $current_user->ID, 'BO_access_special_content', true ) ) { $article_ids = array(19232); foreach ($article_ids as $article_id) { echo '<a class="button content_link" target="_blank" title="' . get_the_title($article_id) . '" href="'.get_permalink($article_id).'">'; echo get_the_title($article_id); echo '</a><br/>'; } } } } Now the code should work… As WooCommerce is migrating orders to custom tables, since WooCommerce 3 you need to use all available CRUD methods instead of old WordPress post meta functions. This is mandatory for newly WooCommerce High-Performance Order Storage (HPOS). For WooCommerce subscriptions, always try to use their methods and functions too. Here is the complete revised version from your previous and last code, merged… Try the following (untested as there is missing custom function and custom metadata usage): // Order check to activate private content add_action( 'woocommerce_order_status_changed', 'TB_verify_order_content', 10, 4 ); function TB_verify_order_content( $order_id, $old_status, $new_status, $order ) { if( $new_status !== 'processing' ) return; $user_id = $order->get_customer_id(); // Check the product in the order foreach ( $order->get_items() as $item ) { if( $item->get_product_id() == 18899 ) { // Check date user put in form $end_date = $item->get_meta('End Date'); // Check if it's a renew $renew = $order->get_meta('is_a_renew'); if( $end_date ) { $first_date = date( 'd/m/Y' ); // Access to private content : setup at first subscription if ( $renew !== 'yes' ) { update_user_meta( $user_id, 'BO_access_content', array( 'access_begining' => time(), 'access_first_date' => $first_date, 'access_end' => '-1', 'access_end_date' => '', 'end' => $end_date ) ); // End of subscription : subscription ID = Order ID of first order +1 $time_end = TB_end_of_subscription( $first_date, $end_date ); // Get the current WC_Subscription from order $subscription = current(wcs_get_subscriptions_for_order( $order_id, array('order_type' => 'any') )); $subscription->update_meta_data( 'expired_date' , $time_end ); $subscription->save(); // Date of last payment : max 25 days before 3 years $time_end = DateTime::createFromFormat( 'd/m/Y', $end_date ); $time_end->modify( '- 25 days' ); $order->update_meta_data('last_payment' , array( 'date_dp' => date( 'd/m/Y', $time_end->getTimestamp() ), 'time_adp' => TB_end_of_subscription( $first_date, $end_date, 36 ), // 36th subscription month )); } // Data to check box and next box $num_box = TB_calculate_box( $first_date, $end_date ); $next_month = date( 'd/m/Y', mktime(0, 0, 0, date('m')+1, 5, date('Y') ) ); $tab_box = array( array( 'box' => $num_box, 'date' => $first_date ) ); if( $num_box < 36 ) { $tab_box[] = array( 'box' => $num_box+1, 'date' => $next_month ); } $order->update_meta_data('BO_envoi_box', $tab_box ); $order->save(); } } elseif( $item->get_product_id() == 19232 ) { update_user_meta( $user_id, 'BO_access_special_content', true ); } } } // Evaluating subscription month and verify end of subscription function TB_max_month_autorized( $tab_param ) { // Ongoing month $return = TB_calculate_month( $tab_param['access_first_date'], $tab_param['end'] ); // If subscription stops, changes content access autorization if( $tab_param['access_end'] != '-1' && $tab_param['access_end_date'] != '' ) { $return = TB_calculate_month( $tab_param['access_first_date'], $tab_param['acces_end_date'] ); } return $return; } // Add content in tab "My content" add_action( 'woocommerce_account_downloads_endpoint', 'TB_add_content' ); function TB_add_content() { global $current_user; if ( $current_user->ID > 0 ) { $access_autorized = false; $month_user = -1; $tab_access = get_user_meta( $current_user->ID, 'BO_access_content', true ); // Calculation of subscription month and number of box if( isset( $tab_access ) && is_array( $tab_access ) && $tab_access['end'] != '' ) { $month_user = TB_max_month_autorized( $tab_access ); } // Subscription ongoing, list of accessible content if( $month_user > 0 ) { $query = new WP_Query( array( 'post_type' => 'page', 'meta_key' => '_wp_page_template', 'meta_value' => 'templates/template-private_page.php', 'order' => 'DESC', 'orderby' => 'menu_order', 'meta_key' => 'access_month', 'meta_value' => $month_user, 'meta_compare' => '<=', 'posts_per_page' => -1, ) ); if ( $query->have_posts() ) { while ( $query->have_posts() ) : $query->the_post(); $menu_order = get_post_field('menu_order', get_the_ID()); if ($menu_order < 100) { echo '<a class="button content_link" target="_blank" title="'.get_the_title().'" href="'.get_the_permalink().'">'; the_title(); echo '</a><br/>'; } endwhile; // end of the loop. } wp_reset_query(); } if ( get_user_meta( $current_user->ID, 'BO_access_special_content', true ) ) { $article_ids = array(19232); foreach ($article_ids as $article_id) { echo '<a class="button content_link" target="_blank" title="' . get_the_title($article_id) . '" href="'.get_permalink($article_id).'">'; echo get_the_title($article_id); echo '</a><br/>'; } } } } It should work.

January 12, 2024

TurboCommerce make the better internet purchasing globaly

Turbo Multi-language Translator

Make the better internet purchasing globaly

Turbosify SEO Speed Booster

5.0 (7) Free plan available
Get better conversions by improving store loading speed Installed

Turbo Multi-language Chat - AI Customer service in one hand

TurboCommerce make the better internet purchasing globaly
Our products

The help you need, when you need it

App by Turbo Engine

3 apps • 5.0 average rating

Turbosify Speed Booster

5.0 (7)
Get better conversions by optimizing shopify store Google page speed Installed

Turbosify Translator for Wordpress Woocommerce

5.0 (74) Free Wordpress Woocommerce Plugin
Translate your wordpress website to multiple language within 1 click, no configuration needed, no No technical required

Grow your business here

Whether you want to sell products down the street or around the world, we have all the tools you need.