The Riskio Event Scheduler library provides a way to manage recurring events using Martin Fowler's Recurring Event pattern.
- PHP 5.6 or higher
- Nicolò Pignatelli's value objects 3.0 or higher
The documentation will help you to understand how to use and extend Schedule.
The schedule represented by Riskio\EventScheduler\Scheduler
class allows you to know if any event occurs at a given date.
To start, you must instantiate Riskio\EventScheduler\Scheduler
and schedule some events
using Riskio\EventScheduler\Scheduler::schedule
method.
This example schedule an event with DayInMonth
temporal expression. So, the event will occur at 15th day of each coming months.
use Riskio\EventScheduler\Scheduler;
use Riskio\EventScheduler\TemporalExpression;
$scheduler = new Scheduler();
$scheduledEvent = $scheduler->schedule('event_name', new TemporalExpression\DayInMonth(15));
If you want to unschedule this event, you can provide the returned instance of Riskio\EventScheduler\SchedulableEvent
to the Riskio\EventScheduler\Scheduler::unschedule
method.
$scheduler->schedule($scheduledEvent);
A temporal expression implements Riskio\EventScheduler\TemporalExpression\TemporalExpressionInterface
that provides useful isOccurring
method to
check if an event occur or not at a given date represented by an instance of DateTimeInterface
.
$temporalExpression = new TemporalExpression();
$isOccuring = $temporalExpression->isOccuring('event', $date);
By default, there are some temporal expressions that you can use to define event recurrence.
- class: Riskio\EventScheduler\TemporalExpression\EachDay
use Riskio\EventScheduler\TemporalExpression\EachDay;
$expression = new EachDay();
- class: Riskio\EventScheduler\TemporalExpression\DayInWeek
- parameters: day (1-7)
use Riskio\EventScheduler\TemporalExpression\DayInWeek;
use Riskio\EventScheduler\ValueObject\WeekDay;
$expression = new DayInWeek(WeekDay::MONDAY);
$expression = DayInWeek::monday();
- class: Riskio\EventScheduler\TemporalExpression\DayInMonth
- parameters: day (1-31)
use Riskio\EventScheduler\TemporalExpression\DayInMonth;
$expression = new DayInMonth(15);
- class: Riskio\EventScheduler\TemporalExpression\WeekInYear
- parameters: month (1-12)
use Riskio\EventScheduler\TemporalExpression\WeekInYear;
use Riskio\EventScheduler\ValueObject\Month;
$expression = new WeekInYear(15);
- class: Riskio\EventScheduler\TemporalExpression\MonthInYear
- parameters: month (1-12)
use Riskio\EventScheduler\TemporalExpression\MonthInYear;
use Riskio\EventScheduler\ValueObject\Month;
$expression = new MonthInYear(Month::JANUARY);
$expression = MonthInYear::january();
- class: Riskio\EventScheduler\TemporalExpression\Semester
- parameters: semester (1-2)
use Riskio\EventScheduler\TemporalExpression\Semester;
$expression = new Semester(1);
- class: Riskio\EventScheduler\TemporalExpression\Trimester
- parameters: trimester (1-4)
use Riskio\EventScheduler\TemporalExpression\Trimester;
$expression = new Trimester(1);
- class: Riskio\EventScheduler\TemporalExpression\Year
- parameters: year
use Riskio\EventScheduler\TemporalExpression\Year;
$expression = new Year(2015);
- class: Riskio\EventScheduler\TemporalExpression\LeapYear
use Riskio\EventScheduler\TemporalExpression\LeapYear;
$expression = new LeapYear();
- class: Riskio\EventScheduler\TemporalExpression\From
- parameters:
DateTimeInterface
instance
use DateTime;
use Riskio\EventScheduler\TemporalExpression\From;
$date = new DateTime();
$expression = new From($date);
- class: Riskio\EventScheduler\TemporalExpression\Until
- parameters:
DateTimeInterface
instance
use DateTime;
use Riskio\EventScheduler\TemporalExpression\Until;
$date = new DateTime();
$expression = new Until($date);
- class: Riskio\EventScheduler\TemporalExpression\RangeEachYear
- parameters:
- start month (1-12)
- end month (1-12)
- start day (1-31)
- end day (1-31)
use Riskio\EventScheduler\TemporalExpression\RangeEachYear;
// From January to March inclusive
$expression = new RangeEachYear(1, 3);
// From January 10 to March 20
$expression = new RangeEachYear(1, 3, 10, 20);
In order to create complex temporal expressions, you can use composite temporal expressions that allow to build combinaisons of previous ones.
An event is occuring at a given date if it lies within all temporal expressions.
use DateTime;
use Riskio\EventScheduler\TemporalExpression\Collection\Intersection;
use Riskio\EventScheduler\TemporalExpression\DayInMonth;
use Riskio\EventScheduler\TemporalExpression\MonthInYear;
$intersection = new Intersection();
$intersection->addElement(new DayInMonth(15));
$intersection->addElement(MonthInYear::january());
$intersection->isOccuring('event', new DateTime('2015-01-15')); // returns true
$intersection->isOccuring('event', new DateTime('2015-01-16')); // returns false
$intersection->isOccuring('event', new DateTime('2015-02-15')); // returns false
An event is occuring at a given date if it lies within at least one temporal expression.
use DateTime;
use Riskio\EventScheduler\TemporalExpression\Collection\Union;
use Riskio\EventScheduler\TemporalExpression\DayInMonth;
use Riskio\EventScheduler\TemporalExpression\MonthInYear;
$union = new Union();
$intersection->addElement(new DayInMonth(15));
$intersection->addElement(MonthInYear::january());
$intersection->isOccuring('event', new DateTime('2015-01-15')); // returns true
$intersection->isOccuring('event', new DateTime('2015-01-16')); // returns false
$intersection->isOccuring('event', new DateTime('2015-02-15')); // returns true
An event is occuring at a given date if it lies within first temporal expression and not within the second one.
use DateTime;
use Riskio\EventScheduler\TemporalExpression\DayInMonth;
use Riskio\EventScheduler\TemporalExpression\Difference;
use Riskio\EventScheduler\TemporalExpression\MonthInYear;
$difference = new Difference(MonthInYear::january(), new DayInMonth(15));
$intersection->isOccuring('event', new DateTime('2015-01-15')); // returns false
$intersection->isOccuring('event', new DateTime('2015-01-16')); // returns true
$intersection->isOccuring('event', new DateTime('2015-02-15')); // returns false
You can create temporal expressions that match your special needs by implementing Riskio\EventScheduler\TemporalExpression\TemporalExpressionInterface
.
After detailing the different temporal expressions available, consider a concrete case with complex temporal expression that could be used in real life.
In the example below, we include every Saturday and Sunday except on July and August.
use Riskio\EventScheduler\TemporalExpression\Collection\Union;
use Riskio\EventScheduler\TemporalExpression\DayInWeek;
use Riskio\EventScheduler\TemporalExpression\Difference;
use Riskio\EventScheduler\TemporalExpression\MonthInYear;
$includedWeekDays = new Union();
$union->addElement(DayInWeek::saturday());
$union->addElement(DayInWeek::sunday());
$excludedMonths = new Union();
$union->addElement(MonthInYear::july());
$union->addElement(MonthInYear::august());
$expression = new Difference($includedWeekDays, $excludedMonths);