mirror of
https://github.com/rlanvin/php-rrule.git
synced 2024-11-28 05: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)
|
||||
- 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 `$dtstart` parameter to `RRule` and `RSet` constsructor to specify dtstart when working with a RFC string without DTSTART.
|
||||
|
||||
### Fixed
|
||||
|
||||
- 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
|
||||
|
||||
### Fixed
|
||||
|
@ -193,20 +193,25 @@ class RRule implements RRuleInterface
|
||||
*
|
||||
* @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) ) {
|
||||
$parts = RfcParser::parseRRule($parts);
|
||||
$parts = array_change_key_case($parts, CASE_UPPER);
|
||||
}
|
||||
elseif ( is_array($parts) ) {
|
||||
$parts = RfcParser::parseRRule($parts, $dtstart);
|
||||
$parts = array_change_key_case($parts, CASE_UPPER);
|
||||
}
|
||||
else {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'The first argument must be a string or an array (%s provided)',
|
||||
gettype($parts)
|
||||
));
|
||||
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);
|
||||
}
|
||||
else {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'The first argument must be a string or an array (%s provided)',
|
||||
gettype($parts)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// validate extra parts
|
||||
|
@ -58,7 +58,7 @@ class RSet implements RRuleInterface
|
||||
*
|
||||
* @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) ) {
|
||||
$string = trim($string);
|
||||
@ -82,7 +82,7 @@ class RSet implements RRuleInterface
|
||||
$property_name = $tmp[0];
|
||||
switch ( strtoupper($property_name) ) {
|
||||
case 'DTSTART':
|
||||
if ( $dtstart !== null ) {
|
||||
if ( $default_dtstart || $dtstart !== null ) {
|
||||
throw new \InvalidArgumentException('Failed to parse RFC string, multiple DTSTART found');
|
||||
}
|
||||
$dtstart = $line;
|
||||
@ -108,14 +108,14 @@ class RSet implements RRuleInterface
|
||||
$rrule = $dtstart."\n".$rrule;
|
||||
}
|
||||
|
||||
$this->addRRule($rrule);
|
||||
$this->addRRule(new RRule($rrule, $default_dtstart));
|
||||
}
|
||||
|
||||
foreach ( $exrules as $rrule ) {
|
||||
if ( $dtstart ) {
|
||||
$rrule = $dtstart."\n".$rrule;
|
||||
}
|
||||
$this->addExRule($rrule);
|
||||
$this->addExRule(new RRule($rrule, $default_dtstart));
|
||||
}
|
||||
|
||||
foreach ( $rdates as $date ) {
|
||||
|
@ -22,7 +22,6 @@ namespace RRule;
|
||||
*/
|
||||
class RfcParser
|
||||
{
|
||||
|
||||
/**
|
||||
* High level "line".
|
||||
* Explode a line into property name, property parameters and property value
|
||||
@ -63,10 +62,14 @@ class RfcParser
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @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);
|
||||
$parts = array();
|
||||
@ -76,6 +79,12 @@ class RfcParser
|
||||
$nb_rrule = 0;
|
||||
$lines = explode("\n", $string);
|
||||
|
||||
if ( $dtstart ) {
|
||||
$nb_dtstart = 1;
|
||||
$dtstart_type = 'tzid';
|
||||
$parts['DTSTART'] = RRule::parseDate($dtstart);
|
||||
}
|
||||
|
||||
foreach ( $lines as $line ) {
|
||||
$property = self::parseLine($line, array(
|
||||
'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->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->assertEquals([
|
||||
$this->assertEquals(array(
|
||||
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')
|
||||
], $rrule->getOccurrences(5));
|
||||
), $rrule->getOccurrences(5));
|
||||
try {
|
||||
$rrule->getOccurrences();
|
||||
$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-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));
|
||||
try {
|
||||
$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(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
|
||||
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
|
||||
*/
|
||||
|
@ -511,6 +511,44 @@ class RSetTest extends PHPUnit_Framework_TestCase
|
||||
$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()
|
||||
{
|
||||
return array(
|
||||
|
Loading…
Reference in New Issue
Block a user