mirror of
https://github.com/rlanvin/php-rrule.git
synced 2025-02-20 09:54:16 +01:00
Making sure DateTime objects are cloned
To avoid problems with cache corruption because DateTime are mutable
This commit is contained in:
parent
85d349f438
commit
65886d99a2
@ -11,6 +11,7 @@
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix bug preventing the iteration of multiple instances of RRule at the same time
|
- Fix bug preventing the iteration of multiple instances of RRule at the same time
|
||||||
|
- Fix various bugs causing corruption of the cache in some circumstances (related to DateTime object being mutable)
|
||||||
|
|
||||||
## [1.0.1] - 2016-03-11
|
## [1.0.1] - 2016-03-11
|
||||||
|
|
||||||
|
@ -666,7 +666,11 @@ class RRule implements RRuleInterface
|
|||||||
|
|
||||||
// cached version already computed
|
// cached version already computed
|
||||||
if ( $this->total !== null ) {
|
if ( $this->total !== null ) {
|
||||||
return $this->cache;
|
$res = array();
|
||||||
|
foreach ( $this->cache as $occurrence ) {
|
||||||
|
$res[] = clone $occurrence; // we have to clone because DateTime is not immutable
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = array();
|
$res = array();
|
||||||
@ -710,7 +714,7 @@ class RRule implements RRuleInterface
|
|||||||
if ( $end !== null && $occurrence > $end ) {
|
if ( $end !== null && $occurrence > $end ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$res[] = $occurrence;
|
$res[] = clone $occurrence;
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
@ -956,7 +960,7 @@ class RRule implements RRuleInterface
|
|||||||
{
|
{
|
||||||
if ( isset($this->cache[$offset]) ) {
|
if ( isset($this->cache[$offset]) ) {
|
||||||
// found in cache
|
// found in cache
|
||||||
return $this->cache[$offset];
|
return clone $this->cache[$offset];
|
||||||
}
|
}
|
||||||
elseif ( $this->total !== null ) {
|
elseif ( $this->total !== null ) {
|
||||||
// cache complete and not found in cache
|
// cache complete and not found in cache
|
||||||
@ -1406,7 +1410,7 @@ class RRule implements RRuleInterface
|
|||||||
$dtstart = $occurrence;
|
$dtstart = $occurrence;
|
||||||
next($this->cache);
|
next($this->cache);
|
||||||
$total += 1;
|
$total += 1;
|
||||||
return $occurrence;
|
return clone $occurrence; // since DateTime is not immutable, avoid any problem
|
||||||
}
|
}
|
||||||
reset($this->cache);
|
reset($this->cache);
|
||||||
// now set use_cache to false to skip the all thing on next iteration
|
// now set use_cache to false to skip the all thing on next iteration
|
||||||
@ -1622,7 +1626,7 @@ class RRule implements RRuleInterface
|
|||||||
if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART
|
if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART
|
||||||
$total += 1;
|
$total += 1;
|
||||||
$this->cache[] = $occurrence;
|
$this->cache[] = $occurrence;
|
||||||
return $occurrence; // yield
|
return clone $occurrence; // yield
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1647,7 +1651,7 @@ class RRule implements RRuleInterface
|
|||||||
if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART
|
if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART
|
||||||
$total += 1;
|
$total += 1;
|
||||||
$this->cache[] = $occurrence;
|
$this->cache[] = $occurrence;
|
||||||
return $occurrence; // yield
|
return clone $occurrence; // yield
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset($timeset);
|
reset($timeset);
|
||||||
|
@ -1787,4 +1787,63 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(date_create('2007-01-09'), $rrule[2]);
|
$this->assertEquals(date_create('2007-01-09'), $rrule[2]);
|
||||||
$this->assertEquals(null, $rrule[4]);
|
$this->assertEquals(null, $rrule[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDateTimeMutableReferenceBug()
|
||||||
|
{
|
||||||
|
$rrule = new RRule(array(
|
||||||
|
'freq' => 'daily',
|
||||||
|
'count' => 10,
|
||||||
|
'dtstart' => '2007-01-01'
|
||||||
|
));
|
||||||
|
|
||||||
|
// offsetGet
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0]);
|
||||||
|
$rrule[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with offsetGet (uncached)');
|
||||||
|
$rrule[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with offsetGet (cached)');
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
$rrule->clearCache();
|
||||||
|
foreach ( $rrule as $occurrence ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrence);
|
||||||
|
$occurrence->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with foreach (uncached)');
|
||||||
|
|
||||||
|
foreach ( $rrule as $occurrence ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrence);
|
||||||
|
$occurrence->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with foreach (cached)');
|
||||||
|
|
||||||
|
// getOccurences
|
||||||
|
$occurrences = $rrule->getOccurrences();
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrences[0]);
|
||||||
|
$occurrences[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-02'), $occurrences[0]);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with getOccurences (uncached version)');
|
||||||
|
|
||||||
|
$occurrences = $rrule->getOccurrences();
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrences[0]);
|
||||||
|
$occurrences[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-02'), $occurrences[0]);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with getOccurences (cached version)');
|
||||||
|
|
||||||
|
// getOccurrencesBetween
|
||||||
|
$occurrences = $rrule->getOccurrencesBetween(null, null);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrences[0]);
|
||||||
|
$occurrences[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-02'), $occurrences[0]);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with getOccurences (uncached version)');
|
||||||
|
|
||||||
|
$occurrences = $rrule->getOccurrencesBetween(null, null);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $occurrences[0]);
|
||||||
|
$occurrences[0]->modify('+1 day');
|
||||||
|
$this->assertEquals(date_create('2007-01-02'), $occurrences[0]);
|
||||||
|
$this->assertEquals(date_create('2007-01-01'), $rrule[0], 'No modification possible with getOccurences (cached version)');
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user