-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft of a Proxy class to work with Event
- Loading branch information
Showing
5 changed files
with
350 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <[email protected]> | ||
* @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'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <[email protected]> | ||
* @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); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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()]); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'))); | ||
} | ||
} |