Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/wp cron #33

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
# OS generated files #
######################

.DS_Store*
ehthumbs.db
._*
*~
.svn
.cvs
*.bak
*.swp
Thumbs.db
.DS_Store
.idea
pimple.json
.phpstorm.meta.php

# Project specific #
#######################
/vendor
composer.lock
83 changes: 83 additions & 0 deletions src/Cron/Abstract_Cron.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace Tribe\Project\Cron;

/**
* Class Cron
*
* Extend this class to create custom WordPress cron jobs.
*
* @package Tribe\Project\Cron
*/
abstract class Abstract_Cron {

/**
* The hook name to schedule the job on
*
* @var string
*/
protected $hook;

/**
* A valid WordPress schedule, e.g. hourly, twicedaily, daily
*
* @see wp_get_schedules()
*
* @var string How often the cron job runs in seconds
*/
protected $recurrence;

/**
* The arguments to pass to the hook when cron job runs
*
* @var array
*/
protected $args;

/**
* Abstract_Cron constructor.
*
* @param string $hook
* @param string $recurrence see wp_get_schedules(), e.g. hourly, twicedaily, daily
* @param array $args
*/
public function __construct( string $hook, string $recurrence, array $args = [] ) {
$this->hook = $hook;
$this->recurrence = $recurrence;
$this->args = $args;
}

/**
* Registers the cron job
*
* @param Abstract_Cron $instance
*/
public function register( Abstract_Cron $instance ) {
add_action( $this->hook, [ $instance, 'run' ], 10, 1 );
}

/**
* Enables the cron job
*/
public function enable() {
if ( ! wp_next_scheduled( $this->hook ) ) {
wp_schedule_event( time(), $this->recurrence, $this->hook, $this->args );
}
}

/**
* Disables the cron job
*/
public function disable() {
wp_clear_scheduled_hook( $this->hook );
}

/**
* Executes when the cron job runs
*
* @param array $args
*
* @return mixed
*/
abstract public function run( array $args = [] );
}
65 changes: 65 additions & 0 deletions src/Cron/Abstract_Schedule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Tribe\Project\Cron;

/**
* Class Abstract_Schedule
*
* Extend this class to create a custom WordPress schedule to use with cron jobs.
*
* @package Tribe\Project\Cron
*/
abstract class Abstract_Schedule {

/**
* The unique array key of your schedule, e.g. five_seconds
*
* @var string
*/
const KEY = '';

/**
* The interval in seconds this schedule will repeat
*
* @var int
*/
const INTERVAL = 0;

/**
* The nice name your schedule will show if ever displayed
*
* @var string
*/
protected $display;

/**
* Abstract_Schedule constructor.
*
* @param string $display
*/
public function __construct( string $display ) {
if ( static::KEY === '' ) {
throw new \LogicException( 'A cron schedule requires an array key.' );
}

if ( static::INTERVAL < 1 ) {
throw new \LogicException( 'A cron schedule requires an interval greater than 0 seconds.' );
}

$this->display = $display;
}

/**
* Returns the schedule formatted for the 'cron_schedules' filter.
*
* @return array
*/
public function get(): array {
$schedules[ static::KEY ] = [
'interval' => static::INTERVAL,
'display' => esc_html__( $this->display, 'tribe' ),
];

return (array) $schedules;
}
}
181 changes: 181 additions & 0 deletions src/Cron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# moderntribe/square1-cron

This package provides some abstract classes to be used to create both custom schedules and cron jobs in WordPress.

### Example Custom Schedule

##### src/Cron/Thirty_Minutes.php

```
<?php declare( strict_types=1 );

namespace Tribe\Project\Cron;

use Tribe\Libs\Cron\Abstract_Schedule;

class Thirty_Minutes extends Abstract_Schedule {

/** @var string array friendly key name **/
const KEY = 'thirty_minutes';

/** @var int 30 minutes in seconds */
const INTERVAL = 1800;
}

```
### Example Cron Job

##### src/Cron/My_Cron.php

```
<?php declare( strict_types=1 );

namespace Tribe\Project\Cron;

use Tribe\Libs\Cron\Abstract_Cron;

class My_Cron extends Abstract_Cron {

/**
* Executes when the cron job runs
*
* @param array $args
*
* @return mixed
*/
public function run( array $args = [] ) {
update_option( 'my_cron_option', 'ran', false );
}

}

```

### Example Service Provider

##### src/Service_Providers/Cron_Provider.php

```
<?php

namespace Tribe\Project\Service_Providers;

use Pimple\Container;
use Tribe\Project\Container\Service_Provider;
use Tribe\Project\Cron\Thirty_Minutes;
use Tribe\Project\Cron\Schedule_Collection;
use Tribe\Project\Cron\My_Cron;
use Tribe\Libs\Cron\Abstract_Cron;

class Cron_Provider extends Service_Provider {

public function register( Container $container ) {
$this->schedules( $container );
$this->cron_jobs( $container );
}

private function schedules( Container $container ) {
$container[ 'cron.thirty_minutes' ] = function() {
return new Thirty_Minutes( 'Thirty Minutes' );
};

$container[ 'cron.schedule_collection' ] = function( Container $container ) {
return new Schedule_Collection( $container[ 'cron.thirty_minutes' ] );
};

foreach( $container[ 'cron.schedule_collection' ] as $schedule ) {
add_filter( 'cron_schedules', function( $schedules ) use ( $schedule ) {
return array_merge( $schedules, $schedule->get() );
}, 10, 1 );
}
}

private function cron_jobs( Container $container ) {
$container[ 'cron.my_cron' ] = function() {
return new My_Cron( 'my_cron', Thirty_Minutes::KEY );
};

$container[ 'cron.cron_collection' ] = function( Container $container ) {
return [
$container[ 'cron.my_cron' ],
];
};

/** @var Abstract_Cron $cron */
foreach( $container[ 'cron.cron_collection' ] as $cron ) {
$cron->register( $cron );
}
}
}
```

Don't forget to register the above provider in `src/Core.php`

### Activating Cron Jobs

Cron jobs need to be enabled, but only once. One solution is to use [square1-schema](https://github.com/moderntribe/square1-schema)
to do this.

##### src/Schema/Cron_Schema.php

```
<?php declare( strict_types=1 );

namespace Tribe\Project\Schema;

use Tribe\Libs\Schema\Schema;
use Tribe\Project\Cron\Abstract_Cron;

class Cron_Schema extends Schema {

protected $schema_version = 1;

public function get_updates() {
return [
1 => [ $this, 'enable_cron_jobs' ]
];
}

/**
* Enable Cron Jobs
*/
public function enable_cron_jobs() {
$container = tribe_project()->container();

/** @var Abstract_Cron $cron */
foreach( $container[ 'cron.cron_collection' ] as $cron ) {
$cron->enable();
}
}
}
```

##### src/Service_Providers/Schema_Provider.php

```
<?php

namespace Tribe\Project\Service_Providers;

use Pimple\Container;
use Tribe\Project\Container\Service_Provider;
use Tribe\Project\Schema\Cron_Schema;

class Schema_Provider extends Service_Provider {

public function register( Container $container ) {
$container[ 'schema.cron' ] = function () {
return new Cron_Schema();
};

add_action( 'admin_init', function () use ( $container ) {
if ( ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && ! wp_doing_cron() ) {
if ( $container[ 'schema.cron' ]->update_required() ) {
$container[ 'schema.cron' ]->do_updates();
}
}
}, 10, 0 );
}

}
```
Loading