Skip Navigation

[Resolved] Set associated member profile to draft when WooCommerce Subscription ends

This thread is resolved. Here is a description of the problem and solution.

Problem:

The customer reported that the custom code attached to the hook "woocommerce_subscription_status_updated" for changing the user's profile post status, was not working.

Solution:

Suggested some changes to the original code.
( ref: https://toolset.com/forums/topic/set-associated-member-profile-to-draft-when-woocommerce-subscription-ends/#post-2253905 )

Relevant Documentation:

n/a

This support ticket is created 3 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Karachi (GMT+05:00)

This topic contains 4 replies, has 2 voices.

Last updated by JEN 3 years ago.

Assisted by: Waqar.

Author
Posts
#2250149

JEN

*Tell us what you are trying to do?*

I am building a subscription directory site with Toolset (my first time using Toolset) using WooCommerce Subscriptions for payment. When the subscription ends, fails or is cancelled the associated listing should be set back to Draft.

*Is there any documentation that you are following?*

I am following the instructions here:
https://toolset.com/forums/topic/member-profiles-being-made-active-inactive-based-on-subscription-status/

Here is the code I am using (in functions.php of child theme):

add_action( 'woocommerce_subscription_status_updated', 'status_update_callback', 1, 3); 
 
function status_update_callback( $subscription, $old_status, $new_status ) {
  
$updated_sub_user_id = $subscription->get_user_id();

$args = array(
    'author'        =>  $updated_sub_user_id,
    'post_type'     => 'listing',
    'orderby'       =>  'post_date',
    'order'         =>  'ASC',
    'posts_per_page' => 1
    );
$member_profile_post = new WP_Query( $args );

$mp_post_id = $member_profile_post; // your member profile post id
$mp_post_args = array( 'ID' => $mp_post_id, 'post_status' => 'draft' );
wp_update_post($mp_post_args);
 
}

*Is there a similar example that we can see?*
Looks like the person in the support request above got it working but no example site is listed.

*What is the link to your site?*
hidden link

Thanks!

#2250485

Hi,

Thank you for contacting us and I'd be happy to assist.

The code that you shared looks fine, but I do feel that line# 16 needs some adjustment:


$mp_post_id = $member_profile_post; // your member profile post id

The "$member_profile_post" includes the full post object and not just the post ID, so it would be better to replace it with:


$mp_post_id = $member_profile_posts[0]->ID; // your member profile post id

When the "$mp_post_id" will contain the correct target "listing" post, the next part to update the post's status should work.

If the code still doesn't work, I'll recommend using WordPress debug log to track which part of the function is working and from where exactly it starts to fail.
( ref: hidden link )

I hope this helps and please let me know if you need any further assistance around this.

regards,
Waqar

#2251239

JEN

Hi Waqar,

Thanks for the assistance!

I made the change suggested it's still not working so I turned on debug log and found some errors:

First, here is the new code:

// set Listing to draft if subscription expires

add_action( 'woocommerce_subscription_status_updated', 'status_update_callback', 1, 3); 
 
function status_update_callback( $subscription, $old_status, $new_status ) {
  
$updated_sub_user_id = $subscription->get_user_id();

$args = array(
    'author'        =>  $updated_sub_user_id,
    'post_type'     => 'listing',
    'orderby'       =>  'post_date',
    'order'         =>  'ASC',
    'posts_per_page' => 1
    );
$member_profile_post = new WP_Query( $args );

$mp_post_id = $member_profile_post[0]->ID; 
$mp_post_args = array( 'ID' => $mp_post_id, 'post_status' => 'draft' );
wp_update_post($mp_post_args);
 
}

Here are the errors. Note that the first error was a typo $member_profile_posts instead of $member_profile_posts.

Here's the output from the log:

[22-Dec-2021 23:48:22 UTC] PHP Notice:  Undefined variable: member_profile_posts in /wp-content/themes/generatepress_ied/functions.php on line 52
[22-Dec-2021 23:48:22 UTC] PHP Notice:  Trying to get property 'ID' of non-object in /wp-content/themes/generatepress_ied/functions.php on line 52
[23-Dec-2021 02:17:29 UTC] PHP Fatal error:  Uncaught Error: Cannot use object of type WP_Query as array in /wp-content/themes/generatepress_ied/functions.php:52
Stack trace:
#0 /wp-includes/class-wp-hook.php(303): status_update_callback(Object(WC_Subscription), 'active', 'on-hold')
#1 /wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters(NULL, Array)
#2 /wp-includes/plugin.php(470): WP_Hook->do_action(Array)
#3 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(584): do_action('woocommerce_sub...', Object(WC_Subscription), 'active', 'on-hold')
#4 /wp-content/plugins/woocommerce/includes/class-wc-order.php(222): WC_Subscription->status_transition()
#5 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(529): WC_Order->save()
#6 /home/j2a2w/ie in /wp-content/themes/generatepress_ied/functions.php on line 52
[23-Dec-2021 03:22:46 UTC] PHP Fatal error:  Uncaught Error: Cannot use object of type WP_Query as array in /wp-content/themes/generatepress_ied/functions.php:52
Stack trace:
#0 /wp-includes/class-wp-hook.php(303): status_update_callback(Object(WC_Subscription), 'on-hold', 'active')
#1 /wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters(NULL, Array)
#2 /wp-includes/plugin.php(470): WP_Hook->do_action(Array)
#3 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(584): do_action('woocommerce_sub...', Object(WC_Subscription), 'on-hold', 'active')
#4 /wp-content/plugins/woocommerce/includes/class-wc-order.php(222): WC_Subscription->status_transition()
#5 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(529): WC_Order->save()
#6 /home/j2a2w/ie in /wp-content/themes/generatepress_ied/functions.php on line 52
[23-Dec-2021 03:22:48 UTC] PHP Fatal error:  Uncaught Error: Cannot use object of type WP_Query as array in /wp-content/themes/generatepress_ied/functions.php:52
Stack trace:
#0 /wp-includes/class-wp-hook.php(303): status_update_callback(Object(WC_Subscription), 'expired', 'on-hold')
#1 /wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters(NULL, Array)
#2 /wp-includes/plugin.php(470): WP_Hook->do_action(Array)
#3 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(584): do_action('woocommerce_sub...', Object(WC_Subscription), 'expired', 'on-hold')
#4 /wp-content/plugins/woocommerce/includes/class-wc-order.php(222): WC_Subscription->status_transition()
#5 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(529): WC_Order->save()
#6 /home/j2a2w/ in /wp-content/themes/generatepress_ied/functions.php on line 52

Line 52 in functions.php = $mp_post_id = $member_profile_post[0]->ID;

Also seeing errors in WooCommerce logs:

12-22-2021 @ 22:22:46 - scheduled action 425 (subscription payment) failed to finish processing due to the following error: Uncaught Error: Cannot use object of type WP_Query as array in /wp-content/themes/generatepress_ied/functions.php:52
Stack trace:
#0 /wp-includes/class-wp-hook.php(303): status_update_callback(Object(WC_Subscription), 'on-hold', 'active')
#1 /wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters(NULL, Array)
#2 /wp-includes/plugin.php(470): WP_Hook->do_action(Array)
#3 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(584): do_action('woocommerce_sub...', Object(WC_Subscription), 'on-hold', 'active')
#4 /wp-content/plugins/woocommerce/includes/class-wc-order.php(222): WC_Subscription->status_transition()
#5 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(529): WC_Order->save()
#6 /home/j2a2w/ie
12-22-2021 @ 22:22:46 - action args: subscription_id: 646
12-22-2021 @ 22:22:48 - scheduled action 426 (subscription expiration) failed to finish processing due to the following error: Uncaught Error: Cannot use object of type WP_Query as array in /wp-content/themes/generatepress_ied/functions.php:52
Stack trace:
#0 /wp-includes/class-wp-hook.php(303): status_update_callback(Object(WC_Subscription), 'expired', 'on-hold')
#1 /wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters(NULL, Array)
#2 /wp-includes/plugin.php(470): WP_Hook->do_action(Array)
#3 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(584): do_action('woocommerce_sub...', Object(WC_Subscription), 'expired', 'on-hold')
#4 /wp-content/plugins/woocommerce/includes/class-wc-order.php(222): WC_Subscription->status_transition()
#5 /wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php(529): WC_Order->save()
#6 /home/j2a2w/
12-22-2021 @ 22:22:48 - action args: subscription_id: 646

and this in admin panel:

An error has occurred while processing recent subscription related events. For steps on how to fix the affected subscriptions and to learn more about the possible causes of this error, please read our guide here.
Affected events:
subscription payment for #646
subscription expiration for #646
To see further details about these errors, view the failed-scheduled-actions log file from the WooCommerce logs screen.

THANK YOU!

#2253905

Thanks for writing back.

The fatal error from the logs can be fixed by replacing the "WP_Query" function with the "get_posts" function:
( ref: https://developer.wordpress.org/reference/functions/get_posts/ )


function status_update_callback( $subscription, $old_status, $new_status ) {
	$updated_sub_user_id = $subscription->get_user_id();

	$args = array(
	'author'        =>  $updated_sub_user_id,
	'post_type'     => 'listing',
	'orderby'       =>  'post_date',
	'order'         =>  'ASC',
	'posts_per_page' => 1
	);
	
	$member_profile_post = get_posts( $args );
	if(!empty($member_profile_post)) {
		$mp_post_id = $member_profile_post[0]->ID; 
		$mp_post_args = array( 'ID' => $mp_post_id, 'post_status' => 'draft' );
		wp_update_post($mp_post_args);
	}
}

Note: Since this custom code is not directly related to Toolset plugins and functions, I can only share some pointers about PHP and WordPress code best practices, in general.

If for some reason, this customization still doesn't work, it would be best to get in touch with the official support of the WooCommerce Subscriptions plugin, for the most accurate and up-to-date information about its available hooks.

#2253923

JEN

Hi Waqar!

That did the trick. Thank you so much!

Jen