wp_schedule_event is executing but the function related to the hook is not running

I have an OOP plugin, The purpose of the plugin is to catch scheduled posts, save them in cron, then 2 minutes after they are published, to run a custom function on them.

This is the stripped-down class with the relevant parts to the question:

class fb_linter {

    function __construct() {

        add_action('init', array($this,'init') );
        add_action('admin_init', array($this,'admin_init') );
        add_action('admin_menu', array($this,'admin_menu') );

        add_action( 'future_post',  array(&$this, 'on_post_scheduled'), 10, 2 );
        add_action( 'activate_cron', array(&$this,'post_notification'), 10, 1);

        }

    function on_post_scheduled( $ID, $post ) {
        $title = $post->post_title;
        if ($post->post_status == 'future') {
            wp_schedule_single_event(get_post_time('U', true , $post->ID) + 120, 'activate_cron', array($post->ID));
        }
    }

    function post_notification($post_id) {
        $title = get_the_title($post_id);
        $permalink = get_permalink($post_id);
        $headers="From: My Name <[email protected]>" . "\r\n";
        wp_mail('[email protected]', 'Post ' . $title', $headers);
    }
}

I’m able to get the action in the cron, means I can see activate_cron inside Crontrol & Crony menus, but the function post_notification never executing.

When I transfer the add_action call of activate_cron and the function post_notifications to functions.php, everything works correctly.

I kept digging for the last 3 days for a solution, but I couldn’t get it to work.

Any advices?

1
1

So your constructor is probably not being executed before the cron event is being run. If your instantiating the fb_linter class too late then your call to add_action won’t happen in time. Try using the singleton design pattern for your class and then instantiate it right after you declare it and it should work just fine.

something like

class fb_linter {
    public static function get_instance(){
        static $instance;
        if( ! isset( $instance ) )
            $instance = new self();

        return $instance;
    }

    ...
}
fb_linter::get_instance();

Leave a Comment