mirror of
https://github.com/rlanvin/php-rrule.git
synced 2024-11-28 05:24:10 +01:00
parent
5e84e08893
commit
b2f0dd16b1
@ -15,6 +15,7 @@
|
||||
- `getNthOccurrencesBefore`
|
||||
- `getNthOccurrencesAfter`
|
||||
- `getNthOccurrencesFrom`
|
||||
- New classes: `Proxy` and `Event` to work with events (a date + a duration) instead of simple occurrence (a date)
|
||||
|
||||
## [1.6.3] - 2019-01-13
|
||||
|
||||
|
102
src/Event.php
Executable file
102
src/Event.php
Executable file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file.
|
||||
*
|
||||
* @author Rémi Lanvin <remi@cloudconnected.fr>
|
||||
* @link https://github.com/rlanvin/php-rrule
|
||||
*/
|
||||
|
||||
namespace RRule;
|
||||
|
||||
/**
|
||||
* Helper class to work with event (a start time and a duration)
|
||||
*/
|
||||
class Event
|
||||
{
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
protected $start_date;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
protected $end_date;
|
||||
|
||||
/**
|
||||
* @var \DateInterval
|
||||
*/
|
||||
protected $duration;
|
||||
|
||||
public function __construct(\DateTimeInterface $start_date, $duration)
|
||||
{
|
||||
$this->start_date = $start_date;
|
||||
$this->duration = self::parseDuration($duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function occursAt($date)
|
||||
{
|
||||
$date = RRule::parseDate($date);
|
||||
|
||||
return $this->start_date >= $date && $this->getEnd() <= $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return clone $this->start_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateInterval
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
if ( $this->end_date === null ) {
|
||||
$this->end_date = $this->start_date->add($this->duration);
|
||||
}
|
||||
|
||||
return clone $this->end_date;
|
||||
}
|
||||
|
||||
static public function parseDuration($duration)
|
||||
{
|
||||
if ( is_numeric($duration) ) {
|
||||
if ( $duration < 0 ) {
|
||||
throw new \InvalidArgumentException("Duration must be a positive integer");
|
||||
}
|
||||
|
||||
// duration is a integer in seconds
|
||||
return \DateInterval::createFromDateString("$duration seconds");
|
||||
}
|
||||
|
||||
if ( is_string($duration) ) {
|
||||
if ( $duration[0] == 'P' ) {
|
||||
// 'P3M'
|
||||
return new \DateInterval($duration);
|
||||
}
|
||||
else {
|
||||
// '3 months'
|
||||
return \DateInterval::createFromDateString($duration);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Could not parse the duration');
|
||||
}
|
||||
}
|
145
src/Proxy.php
Executable file
145
src/Proxy.php
Executable file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file.
|
||||
*
|
||||
* @author Rémi Lanvin <remi@cloudconnected.fr>
|
||||
* @link https://github.com/rlanvin/php-rrule
|
||||
*/
|
||||
|
||||
namespace RRule;
|
||||
|
||||
/**
|
||||
* Simple proxy class to convert the results into something else.
|
||||
*
|
||||
* Designed as an example how to work with events (date+duration) instead of occurrences (date only).
|
||||
*
|
||||
* Example:
|
||||
* $rrule = new Proxy(
|
||||
* new RRule("DTSTART:20170101\nRRULE:FREQ=DAILY;COUNT=2;INTERVAL=10"),
|
||||
* function (\DateTimeInterface $occurrence) {
|
||||
* return new Event($occurrence, 3600);
|
||||
* }
|
||||
* );
|
||||
*/
|
||||
class Proxy implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var RRuleInterface
|
||||
*/
|
||||
protected $rrule;
|
||||
|
||||
/**
|
||||
* @var \Callable
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
public function __construct(RRuleInterface $rrule, callable $factory)
|
||||
{
|
||||
$this->rrule = $rrule;
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Iterator
|
||||
*/
|
||||
public function getOccurrences($limit = null)
|
||||
{
|
||||
$occurrences = $this->rrule->getOccurrences($limit);
|
||||
return new ProxyIterator(new \ArrayIterator($occurrences), $this->factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Iterator
|
||||
*/
|
||||
public function getOccurrencesBetween($begin, $end, $limit = null)
|
||||
{
|
||||
$occurrences = $this->rrule->getOccurrencesBetween($begin, $end, $limit);
|
||||
return new ProxyIterator(new \ArrayIterator($occurrences), $this->factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Iterator
|
||||
*/
|
||||
public function getOccurrencesAfter($date, $inclusive = false, $limit = null)
|
||||
{
|
||||
$occurrences = $this->rrule->getNthOccurrenceAfter($date, $inclusive, $limit);
|
||||
return new ProxyIterator(new \ArrayIterator($occurrences), $this->factory);
|
||||
}
|
||||
|
||||
public function getNthOccurrenceAfter($date, $index)
|
||||
{
|
||||
$occurrence = $this->rrule->getNthOccurrenceAfter($date, $index);
|
||||
return call_user_func_array($this->factory, [$occurrence]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Iterator
|
||||
*/
|
||||
public function getOccurrencesBefore($date, $inclusive = false, $limit = null)
|
||||
{
|
||||
$occurrences = $this->rrule->getOccurrencesBefore($date, $inclusive, $limit);
|
||||
return new ProxyIterator(new \ArrayIterator($occurrences), $this->factory);
|
||||
}
|
||||
|
||||
public function getNthOccurrenceBefore($date, $index)
|
||||
{
|
||||
$occurrence = $this->rrule->getNthOccurrenceBefore($date, $index);
|
||||
return call_user_func_array($this->factory, [$occurrence]);
|
||||
}
|
||||
|
||||
public function getNthOccurrenceFrom($date, $index)
|
||||
{
|
||||
$occurrence = $this->rrule->getNthOccurrenceFrom($date, $index);
|
||||
return call_user_func_array($this->factory, [$occurrence]);
|
||||
}
|
||||
|
||||
public function isFinite()
|
||||
{
|
||||
return $this->rrule->isFinite();
|
||||
}
|
||||
|
||||
public function isInfinite()
|
||||
{
|
||||
return $this->rrule->isInfinite();
|
||||
}
|
||||
|
||||
public function occursAt($date)
|
||||
{
|
||||
return $this->rrule->occursAt();
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->rrule->offsetExists($offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$occurrence = $this->rrule->offsetGet($offset);
|
||||
return call_user_func_array($this->factory, [$occurrence]);
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
return $this->rrule->offsetSet($offset, $value);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
return $this->rrule->offsetUnset($offset);
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return $this->rrule->count();
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new ProxyIterator($this->rrule, $this->factory);
|
||||
}
|
||||
|
||||
}
|
20
src/ProxyIterator.php
Executable file
20
src/ProxyIterator.php
Executable file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace RRule;
|
||||
|
||||
class ProxyIterator extends \IteratorIterator
|
||||
{
|
||||
protected $factory;
|
||||
|
||||
public function __construct(\Traversable $iterator, callable $factory)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
parent::__construct($iterator);
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
return call_user_func_array($this->factory, [parent::current()]);
|
||||
}
|
||||
|
||||
}
|
82
tests/ProxyTest.php
Executable file
82
tests/ProxyTest.php
Executable file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace RRule\Tests;
|
||||
|
||||
use RRule\RRule;
|
||||
use RRule\Proxy;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProxyTest extends TestCase
|
||||
{
|
||||
public function testIterator()
|
||||
{
|
||||
$proxy = new Proxy(
|
||||
new RRule([
|
||||
'FREQ' => 'MONTHLY',
|
||||
'COUNT' => 3,
|
||||
'BYMONTHDAY' => 31,
|
||||
'DTSTART' => '1997-09-02'
|
||||
]),
|
||||
function (\DateTimeInterface $occurrence) {
|
||||
return new \RRule\Event($occurrence, 3600);
|
||||
}
|
||||
);
|
||||
|
||||
$expected = [
|
||||
new \RRule\Event(date_create('1997-10-31'), 3600),
|
||||
new \RRule\Event(date_create('1997-12-31'), 3600),
|
||||
new \RRule\Event(date_create('1998-01-31'), 3600),
|
||||
];
|
||||
|
||||
$n = 0;
|
||||
foreach ( $proxy as $event ) {
|
||||
$this->assertEquals($expected[$n],$event);
|
||||
$n++;
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetOccurrences()
|
||||
{
|
||||
$proxy = new Proxy(
|
||||
new RRule([
|
||||
'FREQ' => 'MONTHLY',
|
||||
'COUNT' => 3,
|
||||
'BYMONTHDAY' => 31,
|
||||
'DTSTART' => '1997-09-02'
|
||||
]),
|
||||
function (\DateTimeInterface $occurrence) {
|
||||
return new \RRule\Event($occurrence, 3600);
|
||||
}
|
||||
);
|
||||
|
||||
$expected = [
|
||||
new \RRule\Event(date_create('1997-10-31'), 3600),
|
||||
new \RRule\Event(date_create('1997-12-31'), 3600),
|
||||
new \RRule\Event(date_create('1998-01-31'), 3600),
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, iterator_to_array($proxy->getOccurrences()));
|
||||
}
|
||||
|
||||
public function testGetOccurrencesBetween()
|
||||
{
|
||||
$proxy = new Proxy(
|
||||
new RRule([
|
||||
'FREQ' => 'MONTHLY',
|
||||
'COUNT' => 3,
|
||||
'BYMONTHDAY' => 31,
|
||||
'DTSTART' => '1997-09-02'
|
||||
]),
|
||||
function (\DateTimeInterface $occurrence) {
|
||||
return new \RRule\Event($occurrence, 3600);
|
||||
}
|
||||
);
|
||||
|
||||
$expected = [
|
||||
new \RRule\Event(date_create('1997-10-31'), 3600),
|
||||
new \RRule\Event(date_create('1997-12-31'), 3600)
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, iterator_to_array($proxy->getOccurrencesBetween('1997-10-31', '1997-12-31')));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user