Made in Pennsylvania, USA 🇺🇸 by Breakfast
Logged-out Users Run Your WordPress Cron Jobs
💡 Code that works in a plugin might not behave the same in a scheduled wp-cron job.
Things That Don’t Always Work in WordPress Cron Jobs
get_posts()calls that return posts with unpublished statuses
Workaround: use$wpdbqueries to retrieve posts or force admintax_inputparameter duringwp_insert_post()orwp_update_post()calls
Workaround: usewp_set_object_terms()or force_adminwp_get_update_data()- Other functions or codes that call
current_user_can()orcurrent_user_can_for_blog()
Why do wp-cron jobs behave differently?
WordPress cron jobs are triggered by any visitor to your site on or after the scheduled time. A logged-out visitor could be running your WordPress cron job.
Any code that uses current_user_can() to restrict permissions can behave differently during wp-cron, including get_posts() and wp_update_post() calls.
SOLUTIONS
1. Test Your Code as a Logged-Out Visitor
Testing wp-cron job code with a tool that runs tasks on demand (like the fantastic Advanced Cron Manager) will fool you into believing the code will always run as an Administrator user. It’s not true. Use a short interval during development so it’s easier to trigger jobs as a logged-out visitor.
2. Briefly Force Administrator
Use wp_set_current_user() to explicitly use an Administrator account at the beginning of your job’s code, and restore the original user ID even if zero to avoid leaking Administrator privileges.
$user_id = get_current_user_id(); //could be 0
wp_set_current_user( 1 ); //1 is the user ID of an Administrator
//do the stuff that needs to run as an admin
$drafts = get_posts( array(
'post_status' => 'draft', //drafts aren't accessible to logged-out users
) );
//don't leak Administrator privileges, restore the previous user even
wp_set_current_user( $user_id );
2. Use Real Cron
Almost every hosting company on the planet has written an article about triggering wp-cron with a real cron job. Here’s one at Kinsta.