mirror of
https://github.com/rlanvin/php-rrule.git
synced 2024-11-28 05:24:10 +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
|
||||
|
||||
- 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
|
||||
|
||||
|
@ -666,7 +666,11 @@ class RRule implements RRuleInterface
|
||||
|
||||
// cached version already computed
|
||||
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();
|
||||
@ -710,7 +714,7 @@ class RRule implements RRuleInterface
|
||||
if ( $end !== null && $occurrence > $end ) {
|
||||
break;
|
||||
}
|
||||
$res[] = $occurrence;
|
||||
$res[] = clone $occurrence;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
@ -956,7 +960,7 @@ class RRule implements RRuleInterface
|
||||
{
|
||||
if ( isset($this->cache[$offset]) ) {
|
||||
// found in cache
|
||||
return $this->cache[$offset];
|
||||
return clone $this->cache[$offset];
|
||||
}
|
||||
elseif ( $this->total !== null ) {
|
||||
// cache complete and not found in cache
|
||||
@ -1406,7 +1410,7 @@ class RRule implements RRuleInterface
|
||||
$dtstart = $occurrence;
|
||||
next($this->cache);
|
||||
$total += 1;
|
||||
return $occurrence;
|
||||
return clone $occurrence; // since DateTime is not immutable, avoid any problem
|
||||
}
|
||||
reset($this->cache);
|
||||
// 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
|
||||
$total += 1;
|
||||
$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
|
||||
$total += 1;
|
||||
$this->cache[] = $occurrence;
|
||||
return $occurrence; // yield
|
||||
return clone $occurrence; // yield
|
||||
}
|
||||
}
|
||||
reset($timeset);
|
||||
|
@ -1787,4 +1787,63 @@ class RRuleTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(date_create('2007-01-09'), $rrule[2]);
|
||||
$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…
Reference in New Issue
Block a user