Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WooCommerce Missing argument 1 for WC_Subscriptions_Manager::prepare_renewal()

I'm getting this in error logs whenever a cron runs to auto renew subscriptions for my client.

[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: Stack trace:, referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #0 [internal function]: WC_Subscriptions_Payment_Gateways::gateway_scheduled_subscription_payment(), referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #1 /var/home/hybrid/completehumanperformance.com/www/wp-includes/class-wp-hook.php(298): call_user_func_array('WC_Subscription...', Array), referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #2 /var/home/hybrid/completehumanperformance.com/www/wp-includes/class-wp-hook.php(323): WP_Hook->apply_filters('', Array), referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #3 /var/home/hybrid/completehumanperformance.com/www/wp-includes/plugin.php(515): WP_Hook->do_action(Array), referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #4 /var/home/hybrid/completehumanperformance.com/www/wp-cron.php(117): do_action_ref_array('woocommerce_sch...', Array), referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: #5 {main}, referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000
[Wed Nov 22 06:45:01 2017] [error] [client 204.187.12.186] FastCGI: server "/php-completehumanperformancecom.fpm" stderr: thrown in /var/home/hybrid/completehumanperformance.com/www/wp-content/plugins/woocommerce-subscrip..., referer: http://completehumanperformance.com/wp-cron.php?doing_wp_cron=1511361900.1951580047607421875000

summary: Missing argument 1 for WC_Subscriptions_Manager::prepare_renewal()

I've created the cron using a plugin called WP_Crontrol, with hook_name: woocommerce_scheduled_subscription_payment.

in the WP Crontrol panel, you do have an option to pass arguments - I tried adding $subscription_id (that's what the code asks for) but it didn't do anything.

So the question is - how can I get that cron job to process everything in the db? What bit of config am I missing?

Thanks

DISCLAIMER: I inherited this from a client who had been maintaining it on their own. It was like this when I got here, guv!

like image 207
WeeDom Avatar asked Oct 29 '22 22:10

WeeDom


1 Answers

As per the WooCommerce Subscriptions Manager Git Repo, this is the function that it is attempting to run:

/**
 * Sets up renewal for subscriptions managed by Subscriptions.
 *
 * This function is hooked early on the scheduled subscription payment hook.
 *
 * @param int $subscription_id The ID of a 'shop_subscription' post
 * @since 2.0
 */
public static function prepare_renewal( $subscription_id ) {
    $order_note = _x( 'Subscription renewal payment due:', 'used in order note as reason for why subscription status changed', 'woocommerce-subscriptions' );
    $renewal_order = self::process_renewal( $subscription_id, 'active', $order_note );
    // Backward compatibility with Subscriptions < 2.2.12 where we returned false for an unknown reason
    if ( false === $renewal_order ) {
        return $renewal_order;
    }
}

You can see from this, that it must recieve one parameter, which is an integer and has to correspond to a shop_subscription id.

So there's a couple of things you are going to want to do to resolve this properly. I am going off of the assumption that you do not want to dig too much into command line debugging so you do not accidentally fire cron jobs that are going to potentially change things in unexpected ways (usually a good idea when avoidable, particularly when it involves other peoples money).

  • First, make sure your error log is enabled with define( 'WP_DEBUG_LOG', true );
  • Second, you need to log the value of $subscription_id as it exists when it is passed to the job.

Something like this within the woocommerce_scheduled_subscription_payment hook:

error_log(sprintf('Parameter [%s] with type [%s] is the [$subscription_id], as passed to the job: [%s]', (string) $subscription_id, gettype( $subscription_id), 'WC_Subscriptions_Manager::prepare_renewal' ) );

This should pick up the id that is being passed and put it in your error log. Next, wait for the job to run again or manually run it.

After the job has run, you need to check the following things:

  • The message showed up in your log (duh)
  • The value of $subscription_id is an integer, and is not null or false.
  • The value of $subscription_id corresponds to a valid shop_subscription post id in your database.

This is probably in your posts table, but Woo is known to do some squirrelly things in the database on occasion, so if you can't find it in posts, then use a query like the following to find it:

SELECT DISTINCT TABLE_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'shop_subscription'
    AND TABLE_SCHEMA='YourDatabase';

You may have to fiddle with the above a bit to get the right field, but between PhpMyAdmin or some other MySql visualizing tool and querying INFORMATION_SCHEMA.COLUMNS, you shouldn't have that hard of a time finding it.

Provided that shows up, you have confirmed that you are passing a valid ID, so if it's still broken, your next step is to backtrace from within the actual Woo function and figure out why it's not providing the value.

This is digging into Wordpress internals a bit, so make sure you back up your site before you do this with git or a tar file or something so you don't leave hacks in the core or plugin. If it is still broken, run a backup at this point before proceeding.


The next thing (assuming you haven't found the actual problem yet) is to go into the WC_Subscriptions_Manager::prepare_renewal function and log two things from there (see the repo link at the top of this answer to help navigate). You want to log print_r( debug_backtrace(), 1) to log the full backtrace from Woo backwards (this will be big, don't leave it there after you are done unless you like massive log files that clutter up all of your disk space).

You will also want to log directly within that method the value of $subscription_id to insure that it is the same value it passed.

From the looks of your error, it appears that it is not being passed at all. That most likely indicates you got a null result from the database or hook, and your problem should be solved within the first part of this diagnosis. The second part is a redundancy to insure that you have actually corrected the problem.

  • The job will need to run for each step that modifies code. Wait for it's next execution, run it manually, or do a dryrun if that is possible to help with your debugging effort.

If the previous developer hacked the Woo plugin, you can use git to isolate all of his changes pretty easily by doing the following:

cd /path/to/plugin
git init
git add --all
git remote add origin [email protected]:wp-premium/woocommerce-subscriptions.git
git commit
git pull

then git diff one of the commits of a stable release from the github page. Any changes will show up in the diff

This should cover quickly debugging the job, and also isolating any other remnant problems you may have left over from the previous developer that you may not even be aware of as of yet.

like image 79
mopsyd Avatar answered Nov 15 '22 06:11

mopsyd