mirror of
https://github.com/rlanvin/php-rrule.git
synced 2024-11-29 06:24:10 +01:00
Add $dtstart optional arg when creating from a string
This commit is contained in:
parent
7437503a73
commit
e2f42382d4
@ -8,11 +8,16 @@
|
|||||||
- RSet constructor now accepts a string to build a RSET from a RFC string [#26](https://github.com/rlanvin/php-rrule/issues/26)
|
- RSet constructor now accepts a string to build a RSET from a RFC string [#26](https://github.com/rlanvin/php-rrule/issues/26)
|
||||||
- New factory method `RRule::createFromRfcString()` to build either a RRule or a RSet from a string
|
- New factory method `RRule::createFromRfcString()` to build either a RRule or a RSet from a string
|
||||||
- Add a `$limit` parameter to `getOccurrences()` and `getOccurrencesBetween()` to make working with infinite rule easier
|
- Add a `$limit` parameter to `getOccurrences()` and `getOccurrencesBetween()` to make working with infinite rule easier
|
||||||
|
- Add a `$dtstart` parameter to `RRule` and `RSet` constsructor to specify dtstart when working with a RFC string without DTSTART.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- When creating a RRule, the RFC parser will not accept multiple DTSTART or RRULE lines
|
- When creating a RRule, the RFC parser will not accept multiple DTSTART or RRULE lines
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
- `RRule::parseRfcString` is deprecated. Note: it wasn't part of the documentation in the first place, but just in case someone is using it, it's not removed yet.
|
||||||
|
|
||||||
## [1.4.2] - 2017-03-29
|
## [1.4.2] - 2017-03-29
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -193,13 +193,17 @@ class RRule implements RRuleInterface
|
|||||||
*
|
*
|
||||||
* @param mixed $parts An assoc array of parts, or a RFC string.
|
* @param mixed $parts An assoc array of parts, or a RFC string.
|
||||||
*/
|
*/
|
||||||
public function __construct($parts)
|
public function __construct($parts, $dtstart = null)
|
||||||
{
|
{
|
||||||
if ( is_string($parts) ) {
|
if ( is_string($parts) ) {
|
||||||
$parts = RfcParser::parseRRule($parts);
|
$parts = RfcParser::parseRRule($parts, $dtstart);
|
||||||
$parts = array_change_key_case($parts, CASE_UPPER);
|
$parts = array_change_key_case($parts, CASE_UPPER);
|
||||||
}
|
}
|
||||||
elseif ( is_array($parts) ) {
|
else {
|
||||||
|
if ( $dtstart ) {
|
||||||
|
throw new \InvalidArgumentException('$dtstart argument has no effect if not constructing from a string');
|
||||||
|
}
|
||||||
|
if ( is_array($parts) ) {
|
||||||
$parts = array_change_key_case($parts, CASE_UPPER);
|
$parts = array_change_key_case($parts, CASE_UPPER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -208,6 +212,7 @@ class RRule implements RRuleInterface
|
|||||||
gettype($parts)
|
gettype($parts)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validate extra parts
|
// validate extra parts
|
||||||
$unsupported = array_diff_key($parts, $this->rule);
|
$unsupported = array_diff_key($parts, $this->rule);
|
||||||
|
@ -58,7 +58,7 @@ class RSet implements RRuleInterface
|
|||||||
*
|
*
|
||||||
* @param string $string a RFC compliant text block
|
* @param string $string a RFC compliant text block
|
||||||
*/
|
*/
|
||||||
public function __construct($string = null)
|
public function __construct($string = null, $default_dtstart = null)
|
||||||
{
|
{
|
||||||
if ( $string && is_string($string) ) {
|
if ( $string && is_string($string) ) {
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
@ -82,7 +82,7 @@ class RSet implements RRuleInterface
|
|||||||
$property_name = $tmp[0];
|
$property_name = $tmp[0];
|
||||||
switch ( strtoupper($property_name) ) {
|
switch ( strtoupper($property_name) ) {
|
||||||
case 'DTSTART':
|
case 'DTSTART':
|
||||||
if ( $dtstart !== null ) {
|
if ( $default_dtstart || $dtstart !== null ) {
|
||||||
throw new \InvalidArgumentException('Failed to parse RFC string, multiple DTSTART found');
|
throw new \InvalidArgumentException('Failed to parse RFC string, multiple DTSTART found');
|
||||||
}
|
}
|
||||||
$dtstart = $line;
|
$dtstart = $line;
|
||||||
@ -108,14 +108,14 @@ class RSet implements RRuleInterface
|
|||||||
$rrule = $dtstart."\n".$rrule;
|
$rrule = $dtstart."\n".$rrule;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addRRule($rrule);
|
$this->addRRule(new RRule($rrule, $default_dtstart));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $exrules as $rrule ) {
|
foreach ( $exrules as $rrule ) {
|
||||||
if ( $dtstart ) {
|
if ( $dtstart ) {
|
||||||
$rrule = $dtstart."\n".$rrule;
|
$rrule = $dtstart."\n".$rrule;
|
||||||
}
|
}
|
||||||
$this->addExRule($rrule);
|
$this->addExRule(new RRule($rrule, $default_dtstart));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $rdates as $date ) {
|
foreach ( $rdates as $date ) {
|
||||||
|
@ -22,7 +22,6 @@ namespace RRule;
|
|||||||
*/
|
*/
|
||||||
class RfcParser
|
class RfcParser
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High level "line".
|
* High level "line".
|
||||||
* Explode a line into property name, property parameters and property value
|
* Explode a line into property name, property parameters and property value
|
||||||
@ -63,10 +62,14 @@ class RfcParser
|
|||||||
/**
|
/**
|
||||||
* Parse both DTSTART and RRULE (and EXRULE).
|
* Parse both DTSTART and RRULE (and EXRULE).
|
||||||
*
|
*
|
||||||
* It's impossible to accuractly parse a RRULE in isolation (without the DTSTART)
|
* It's impossible to accuratly parse a RRULE in isolation (without the DTSTART)
|
||||||
* as some tests depends on DTSTART (notably the date format for UNTIL).
|
* as some tests depends on DTSTART (notably the date format for UNTIL).
|
||||||
|
*
|
||||||
|
* @param string $string The RFC-like string
|
||||||
|
* @param mixed $dtstart The default dtstart to be used (if not in the string)
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
static public function parseRRule($string)
|
static public function parseRRule($string, $dtstart = null)
|
||||||
{
|
{
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
$parts = array();
|
$parts = array();
|
||||||
@ -76,6 +79,12 @@ class RfcParser
|
|||||||
$nb_rrule = 0;
|
$nb_rrule = 0;
|
||||||
$lines = explode("\n", $string);
|
$lines = explode("\n", $string);
|
||||||
|
|
||||||
|
if ( $dtstart ) {
|
||||||
|
$nb_dtstart = 1;
|
||||||
|
$dtstart_type = 'tzid';
|
||||||
|
$parts['DTSTART'] = RRule::parseDate($dtstart);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ( $lines as $line ) {
|
foreach ( $lines as $line ) {
|
||||||
$property = self::parseLine($line, array(
|
$property = self::parseLine($line, array(
|
||||||
'name' => sizeof($lines) > 1 ? null : 'RRULE' // allow missing property name for single-line RRULE
|
'name' => sizeof($lines) > 1 ? null : 'RRULE' // allow missing property name for single-line RRULE
|
||||||
|
@ -1726,12 +1726,12 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
|||||||
));
|
));
|
||||||
|
|
||||||
$this->assertCount(1, $rrule->getOccurrences(1));
|
$this->assertCount(1, $rrule->getOccurrences(1));
|
||||||
$this->assertEquals([date_create('2017-01-01')], $rrule->getOccurrences(1));
|
$this->assertEquals(array(date_create('2017-01-01')), $rrule->getOccurrences(1));
|
||||||
$this->assertCount(5, $rrule->getOccurrences(5));
|
$this->assertCount(5, $rrule->getOccurrences(5));
|
||||||
$this->assertEquals([
|
$this->assertEquals(array(
|
||||||
date_create('2017-01-01'),date_create('2017-01-02'),date_create('2017-01-03'),
|
date_create('2017-01-01'),date_create('2017-01-02'),date_create('2017-01-03'),
|
||||||
date_create('2017-01-04'),date_create('2017-01-05')
|
date_create('2017-01-04'),date_create('2017-01-05')
|
||||||
], $rrule->getOccurrences(5));
|
), $rrule->getOccurrences(5));
|
||||||
try {
|
try {
|
||||||
$rrule->getOccurrences();
|
$rrule->getOccurrences();
|
||||||
$this->fail('Expected exception (infinite rule) not thrown');
|
$this->fail('Expected exception (infinite rule) not thrown');
|
||||||
@ -1749,7 +1749,7 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->assertCount(1, $rrule->getOccurrencesBetween('2017-01-01', null, 1));
|
$this->assertCount(1, $rrule->getOccurrencesBetween('2017-01-01', null, 1));
|
||||||
$this->assertCount(1, $rrule->getOccurrencesBetween('2017-02-01', '2017-12-31', 1));
|
$this->assertCount(1, $rrule->getOccurrencesBetween('2017-02-01', '2017-12-31', 1));
|
||||||
$this->assertEquals([date_create('2017-02-01')], $rrule->getOccurrencesBetween('2017-02-01', '2017-12-31', 1));
|
$this->assertEquals(array(date_create('2017-02-01')), $rrule->getOccurrencesBetween('2017-02-01', '2017-12-31', 1));
|
||||||
$this->assertCount(5, $rrule->getOccurrencesBetween('2017-01-01', null, 5));
|
$this->assertCount(5, $rrule->getOccurrencesBetween('2017-01-01', null, 5));
|
||||||
try {
|
try {
|
||||||
$rrule->getOccurrencesBetween('2017-01-01', null);
|
$rrule->getOccurrencesBetween('2017-01-01', null);
|
||||||
@ -1856,6 +1856,10 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
|||||||
array("\nDTSTART:19970512\nRRULE:FREQ=YEARLY;COUNT=3\n\n",
|
array("\nDTSTART:19970512\nRRULE:FREQ=YEARLY;COUNT=3\n\n",
|
||||||
array(date_create('1997-05-12'),date_create('1998-05-12'),date_create('1999-05-12'))
|
array(date_create('1997-05-12'),date_create('1998-05-12'),date_create('1999-05-12'))
|
||||||
),
|
),
|
||||||
|
// CRLF
|
||||||
|
array("\r\nDTSTART:19970512\r\nRRULE:FREQ=YEARLY;COUNT=3\r\n\r\n",
|
||||||
|
array(date_create('1997-05-12'),date_create('1998-05-12'),date_create('1999-05-12'))
|
||||||
|
),
|
||||||
|
|
||||||
// no DTSTART
|
// no DTSTART
|
||||||
array("RRULE:FREQ=YEARLY;COUNT=3",
|
array("RRULE:FREQ=YEARLY;COUNT=3",
|
||||||
@ -1903,6 +1907,25 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRfcStringParserWithDtStart()
|
||||||
|
{
|
||||||
|
$rrule = new RRule('RRULE:FREQ=YEARLY');
|
||||||
|
$this->assertEquals(date_create(), $rrule[0]);
|
||||||
|
|
||||||
|
$rrule = new RRule('RRULE:FREQ=YEARLY', date_create('2017-01-01'));
|
||||||
|
$this->assertEquals(date_create('2017-01-01'), $rrule[0]);
|
||||||
|
|
||||||
|
$rrule = new RRule('RRULE:FREQ=YEARLY', '2017-01-01');
|
||||||
|
$this->assertEquals(date_create('2017-01-01'), $rrule[0]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$rrule = new RRule("DTSTART:19970512\nRRULE:FREQ=YEARLY", date_create('2017-01-01'));
|
||||||
|
$this->fail('Expected InvalidArgumentException (too many dtstart) not thrown');
|
||||||
|
} catch ( \InvalidArgumentException $e ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://github.com/rlanvin/php-rrule/issues/25
|
* @see https://github.com/rlanvin/php-rrule/issues/25
|
||||||
*/
|
*/
|
||||||
|
@ -511,6 +511,44 @@ class RSetTest extends PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals($occurrences, $object->getOccurrences());
|
$this->assertEquals($occurrences, $object->getOccurrences());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testParseRfcStringWithDtStart()
|
||||||
|
{
|
||||||
|
$rset = new RSet(
|
||||||
|
"RRULE:FREQ=DAILY;COUNT=3\nEXRULE:FREQ=DAILY;INTERVAL=2;COUNT=1"
|
||||||
|
);
|
||||||
|
$this->assertEquals(array(
|
||||||
|
date_create('+1day'),
|
||||||
|
date_create('+2day')
|
||||||
|
), $rset->getOccurrences());
|
||||||
|
|
||||||
|
$rset = new RSet(
|
||||||
|
"RRULE:FREQ=DAILY;COUNT=3\nEXRULE:FREQ=DAILY;INTERVAL=2;COUNT=1",
|
||||||
|
'2017-01-01'
|
||||||
|
);
|
||||||
|
$this->assertEquals(array(
|
||||||
|
date_create('2017-01-02'),
|
||||||
|
date_create('2017-01-03')
|
||||||
|
), $rset->getOccurrences());
|
||||||
|
|
||||||
|
$rset = new RSet(
|
||||||
|
"RRULE:FREQ=DAILY;COUNT=3\nEXRULE:FREQ=DAILY;INTERVAL=2;COUNT=1",
|
||||||
|
date_create('2017-01-01')
|
||||||
|
);
|
||||||
|
$this->assertEquals(array(
|
||||||
|
date_create('2017-01-02'),
|
||||||
|
date_create('2017-01-03')
|
||||||
|
), $rset->getOccurrences());
|
||||||
|
|
||||||
|
try {
|
||||||
|
$rset = new RSet(
|
||||||
|
"DTSTART:DTSTART;TZID=America/New_York:19970901T090000\nRRULE:FREQ=DAILY;COUNT=3\nEXRULE:FREQ=DAILY;INTERVAL=2;COUNT=1",
|
||||||
|
date_create('2017-01-01')
|
||||||
|
);
|
||||||
|
$this->fail('Expected InvalidArgumentException (too many start date) not thrown');
|
||||||
|
} catch ( InvalidArgumentException $e ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public function quirkyRfcStrings()
|
public function quirkyRfcStrings()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
Loading…
Reference in New Issue
Block a user