Skip to content

WP Cron

Dan Alvidrez edited this page Jul 23, 2018 · 36 revisions

Integrating your plugin with WpCron is pretty straight forward:

Add Cron Class to App

<?php namespace App;
use App\Helpers\LumenHelper;
class Cron {

    protected $helper;
    const HOOK = 'my_plugin_cron';
    const INTERVAL = 'five_min';

    /**
     * Cron Constructor
     * @param $helper LumenHelper
     */
      public function __construct(
	    LumenHelper $helper
      ){
	$this->helper = $helper;
      }

    /**
     * Task Runs Next At
     * @return \Carbon\Carbon
     */
    public static function runsNextAt(){
        return \Carbon\Carbon::createFromTimestamp(wp_next_scheduled( self::HOOK));
    }

    /**
     * Installation Status
     * @return bool
     */
    public static function status(){
        return (bool) count(array_filter(_get_cron_array(), function($item){
            return array_has($item,self::HOOK);
        }));
    }

    /**
     * Install
     * @return bool
     */
    public function install(){
        //Add the scheduled event, if it has not been added.
        if(!wp_next_scheduled( self::HOOK)) {
            //Add the scheduled event.
            wp_schedule_event(\Carbon\Carbon::now()->timestamp, self::INTERVAL, self::HOOK);

            //Log the result.
            $this->helper->logger()->info('Cron Task Installed!');
            return true;
        }
        return false;
    }

    /**
     * UnInstall
     * @return void
     */
    public function uninstall(){
        wp_unschedule_hook(self::HOOK);
        $this->helper->logger()->info('Cron Task UnInstalled!');
    }

    /**
     * Handle the Scheduled Event
     * @throws \Throwable
     */
    public function handle(){
        //Do your custom CRON Task, or call the artisan scheduled tasks.

        if(!$app->runningInConsole()){
          $kernel = $this->helper->make('Illuminate\Contracts\Console\Kernel');
          $kernel->call('schedule:run');
          $this->helper->logger()->info('Cron Task Completed Successfully!');
          $this->helper->logger()->info("{$kernel->output()}");
        }
    }
}

Add Custom Cron Intervals to WpServiceProvider

/** Custom Cron Schedule **/
add_filter('cron_schedules', function($schedules) {
    return array_merge($schedules, array(
        'five_min' => array(
            'interval' => 5 * 60,
            'display'  => esc_html__( 'Every Five Minutes' ),
        )
    ));
});

Add the Cron Task Action Hook to WpServiceProvider

/** Cron Action **/
$wpHelper->addAction(\App\Cron::HOOK, function(){
    $cron = $this->app->make(\App\Cron::class);
    $cron->handle();
});

Use Loops Safely (in Cron handle method)

//Set Timeout to Max Execution Time
//Minus 1 Second (estimated time for single loop iteration).
$timeout = ini_get('max_execution_time') - 1;

//Start Timer
$runtime = microtime(true);

do {

//Do Something in Loop Safely...
//Use Database Transactions & Chunking or you'll be sorry!

} while ((microtime(true) - $runtime) < $timeout);

Runs Next (Carbon Instance)

$next = Cron::runsNextAt();
$next->isPast() ? 'Running Now...' : "Runs {$next->diffForHumans()} from now."

Installation Status: (bool)

Cron::status();

Install / UnInstall in WpServiceProvider

$cron = $this->app->make(\App\Cron::class);
$cron->install();
$cron->uninstall();