From c3213e64fd8c820fb82f230ce6f5342f701aaa5f Mon Sep 17 00:00:00 2001 From: rlanvin Date: Mon, 21 Mar 2016 21:55:40 +0200 Subject: [PATCH] Using references for easier reading --- CHANGELOG.md | 2 + src/RRule.php | 312 ++++++++++++++++++++++++++------------------------ src/RSet.php | 64 ++++++----- 3 files changed, 201 insertions(+), 177 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46b9b57..e82d474 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Fix bug preventing the iteration of multiple instances of RRule at the same time + ## [1.0.1] - 2016-03-11 ### Fixed diff --git a/src/RRule.php b/src/RRule.php index 40857f2..30ffce8 100755 --- a/src/RRule.php +++ b/src/RRule.php @@ -1352,6 +1352,20 @@ class RRule implements \Iterator, \ArrayAccess, \Countable */ protected function iterate($reset = false) { + // for readability's sake, and because scope of the variables should be local anyway + $year = & $this->_year; + $month = & $this->_month; + $day = & $this->_day; + $hour = & $this->_hour; + $minute = & $this->_minute; + $second = & $this->_second; + $dayset = & $this->_dayset; + $masks = & $this->_masks; + $timeset = & $this->_timeset; + $dtstart = & $this->_dtstart; + $total = & $this->_total; + $use_cache = & $this->_use_cache; + if ( $reset ) { $this->_year = $this->_month = $this->_day = null; $this->_hour = $this->_minute = $this->_second = null; @@ -1363,82 +1377,82 @@ class RRule implements \Iterator, \ArrayAccess, \Countable } // go through the cache first - if ( $this->_use_cache ) { + if ( $use_cache ) { while ( ($occurrence = current($this->cache)) !== false ) { // echo "Cache hit\n"; - $this->_dtstart = $occurrence; + $dtstart = $occurrence; next($this->cache); - $this->_total += 1; + $total += 1; return $occurrence; } reset($this->cache); // now set use_cache to false to skip the all thing on next iteration // and start filling the cache instead - $this->_use_cache = false; + $use_cache = false; // if the cache as been used up completely and we now there is nothing else - if ( $this->_total === $this->total ) { + if ( $total === $this->total ) { // echo "Cache used up, nothing else to compute\n"; return null; } // echo "Cache used up with occurrences remaining\n"; - if ( $this->_dtstart ) { + if ( $dtstart ) { // so we skip the last occurrence of the cache if ( $this->freq === self::SECONDLY ) { - $this->_dtstart->modify('+'.$this->interval.'second'); + $dtstart->modify('+'.$this->interval.'second'); } else { - $this->_dtstart->modify('+1second'); + $dtstart->modify('+1second'); } } } - // stop once $this->_total has reached COUNT - if ( $this->count && $this->_total >= $this->count ) { - $this->total = $this->_total; + // stop once $total has reached COUNT + if ( $this->count && $total >= $this->count ) { + $this->total = $total; return null; } - if ( $this->_dtstart === null ) { - $this->_dtstart = clone $this->dtstart; + if ( $dtstart === null ) { + $dtstart = clone $this->dtstart; } - if ( $this->_year === null ) { + if ( $year === null ) { if ( $this->freq === self::WEEKLY ) { // we align the start date to the WKST, so we can then // simply loop by adding +7 days. The Python lib does some // calculation magic at the end of the loop (when incrementing) // to realign on first pass. - $tmp = clone $this->_dtstart; + $tmp = clone $dtstart; $tmp->modify('-'.pymod($this->dtstart->format('N') - $this->wkst,7).'days'); - list($this->_year,$this->_month,$this->_day,$this->_hour,$this->_minute,$this->_second) = explode(' ',$tmp->format('Y n j G i s')); + list($year,$month,$day,$hour,$minute,$second) = explode(' ',$tmp->format('Y n j G i s')); unset($tmp); } else { - list($this->_year,$this->_month,$this->_day,$this->_hour,$this->_minute,$this->_second) = explode(' ',$this->_dtstart->format('Y n j G i s')); + list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dtstart->format('Y n j G i s')); } // remove leading zeros - $this->_minute = (int) $this->_minute; - $this->_second = (int) $this->_second; + $minute = (int) $minute; + $second = (int) $second; } // we initialize the timeset - if ( $this->_timeset == null ) { + if ( $timeset == null ) { if ( $this->freq < self::HOURLY ) { // daily, weekly, monthly or yearly // we don't need to calculate a new timeset - $this->_timeset = $this->timeset; + $timeset = $this->timeset; } else { // initialize empty if it's not going to occurs on the first iteration if ( - ($this->freq >= self::HOURLY && $this->byhour && ! in_array($this->_hour, $this->byhour)) - || ($this->freq >= self::MINUTELY && $this->byminute && ! in_array($this->_minute, $this->byminute)) - || ($this->freq >= self::SECONDLY && $this->bysecond && ! in_array($this->_second, $this->bysecond)) + ($this->freq >= self::HOURLY && $this->byhour && ! in_array($hour, $this->byhour)) + || ($this->freq >= self::MINUTELY && $this->byminute && ! in_array($minute, $this->byminute)) + || ($this->freq >= self::SECONDLY && $this->bysecond && ! in_array($second, $this->bysecond)) ) { - $this->_timeset = array(); + $timeset = array(); } else { - $this->_timeset = $this->getTimeSet($this->_hour, $this->_minute, $this->_second); + $timeset = $this->getTimeSet($hour, $minute, $second); } } } @@ -1449,97 +1463,97 @@ class RRule implements \Iterator, \ArrayAccess, \Countable // 1. get an array of all days in the next interval (day, month, week, etc.) // we filter out from this array all days that do not match the BYXXX conditions // to speed things up, we use days of the year (day numbers) instead of date - if ( $this->_dayset === null ) { + if ( $dayset === null ) { // rebuild the various masks and converters // these arrays will allow fast date operations // without relying on date() methods - if ( empty($this->_masks) || $this->_masks['year'] != $this->_year || $this->_masks['month'] != $this->_month ) { - $this->_masks = array('year' => '','month'=>''); + if ( empty($masks) || $masks['year'] != $year || $masks['month'] != $month ) { + $masks = array('year' => '','month'=>''); // only if year has changed - if ( $this->_masks['year'] != $this->_year ) { - $this->_masks['leap_year'] = is_leap_year($this->_year); - $this->_masks['year_len'] = 365 + (int) $this->_masks['leap_year']; - $this->_masks['next_year_len'] = 365 + is_leap_year($this->_year + 1); - $this->_masks['weekday_of_1st_yearday'] = date_create($this->_year."-01-01 00:00:00")->format('N'); - $this->_masks['yearday_to_weekday'] = array_slice(self::$WEEKDAY_MASK, $this->_masks['weekday_of_1st_yearday']-1); - if ( $this->_masks['leap_year'] ) { - $this->_masks['yearday_to_month'] = self::$MONTH_MASK_366; - $this->_masks['yearday_to_monthday'] = self::$MONTHDAY_MASK_366; - $this->_masks['yearday_to_monthday_negative'] = self::$NEGATIVE_MONTHDAY_MASK_366; - $this->_masks['last_day_of_month'] = self::$LAST_DAY_OF_MONTH_366; + if ( $masks['year'] != $year ) { + $masks['leap_year'] = is_leap_year($year); + $masks['year_len'] = 365 + (int) $masks['leap_year']; + $masks['next_year_len'] = 365 + is_leap_year($year + 1); + $masks['weekday_of_1st_yearday'] = date_create($year."-01-01 00:00:00")->format('N'); + $masks['yearday_to_weekday'] = array_slice(self::$WEEKDAY_MASK, $masks['weekday_of_1st_yearday']-1); + if ( $masks['leap_year'] ) { + $masks['yearday_to_month'] = self::$MONTH_MASK_366; + $masks['yearday_to_monthday'] = self::$MONTHDAY_MASK_366; + $masks['yearday_to_monthday_negative'] = self::$NEGATIVE_MONTHDAY_MASK_366; + $masks['last_day_of_month'] = self::$LAST_DAY_OF_MONTH_366; } else { - $this->_masks['yearday_to_month'] = self::$MONTH_MASK; - $this->_masks['yearday_to_monthday'] = self::$MONTHDAY_MASK; - $this->_masks['yearday_to_monthday_negative'] = self::$NEGATIVE_MONTHDAY_MASK; - $this->_masks['last_day_of_month'] = self::$LAST_DAY_OF_MONTH; + $masks['yearday_to_month'] = self::$MONTH_MASK; + $masks['yearday_to_monthday'] = self::$MONTHDAY_MASK; + $masks['yearday_to_monthday_negative'] = self::$NEGATIVE_MONTHDAY_MASK; + $masks['last_day_of_month'] = self::$LAST_DAY_OF_MONTH; } if ( $this->byweekno ) { - $this->buildWeeknoMask($this->_year, $this->_month, $this->_day, $this->_masks); + $this->buildWeeknoMask($year, $month, $day, $masks); } } // everytime month or year changes if ( $this->byweekday_nth ) { - $this->buildNthWeekdayMask($this->_year, $this->_month, $this->_day, $this->_masks); + $this->buildNthWeekdayMask($year, $month, $day, $masks); } - $this->_masks['year'] = $this->_year; - $this->_masks['month'] = $this->_month; + $masks['year'] = $year; + $masks['month'] = $month; } // calculate the current set - $this->_dayset = $this->getDaySet($this->_year, $this->_month, $this->_day, $this->_masks); + $dayset = $this->getDaySet($year, $month, $day, $masks); $filtered_set = array(); - foreach ( $this->_dayset as $this->_yearday ) { - if ( $this->bymonth && ! in_array($this->_masks['yearday_to_month'][$this->_yearday], $this->bymonth) ) { + foreach ( $dayset as $yearday ) { + if ( $this->bymonth && ! in_array($masks['yearday_to_month'][$yearday], $this->bymonth) ) { continue; } - if ( $this->byweekno && ! isset($this->_masks['yearday_is_in_weekno'][$this->_yearday]) ) { + if ( $this->byweekno && ! isset($masks['yearday_is_in_weekno'][$yearday]) ) { continue; } if ( $this->byyearday ) { - if ( $this->_yearday < $this->_masks['year_len'] ) { - if ( ! in_array($this->_yearday + 1, $this->byyearday) && ! in_array(- $this->_masks['year_len'] + $this->_yearday,$this->byyearday) ) { + if ( $yearday < $masks['year_len'] ) { + if ( ! in_array($yearday + 1, $this->byyearday) && ! in_array(- $masks['year_len'] + $yearday,$this->byyearday) ) { continue; } } - else { // if ( ($this->_yearday >= $this->_masks['year_len'] - if ( ! in_array($this->_yearday + 1 - $this->_masks['year_len'], $this->byyearday) && ! in_array(- $this->_masks['next_year_len'] + $this->_yearday - $mask['year_len'], $this->byyearday) ) { + else { // if ( ($yearday >= $masks['year_len'] + if ( ! in_array($yearday + 1 - $masks['year_len'], $this->byyearday) && ! in_array(- $masks['next_year_len'] + $yearday - $mask['year_len'], $this->byyearday) ) { continue; } } } if ( ($this->bymonthday || $this->bymonthday_negative) - && ! in_array($this->_masks['yearday_to_monthday'][$this->_yearday], $this->bymonthday) - && ! in_array($this->_masks['yearday_to_monthday_negative'][$this->_yearday], $this->bymonthday_negative) ) { + && ! in_array($masks['yearday_to_monthday'][$yearday], $this->bymonthday) + && ! in_array($masks['yearday_to_monthday_negative'][$yearday], $this->bymonthday_negative) ) { continue; } - if ( $this->byweekday && ! in_array($this->_masks['yearday_to_weekday'][$this->_yearday], $this->byweekday) ) { + if ( $this->byweekday && ! in_array($masks['yearday_to_weekday'][$yearday], $this->byweekday) ) { continue; } - if ( $this->byweekday_nth && ! isset($this->_masks['yearday_is_nth_weekday'][$this->_yearday]) ) { + if ( $this->byweekday_nth && ! isset($masks['yearday_is_nth_weekday'][$yearday]) ) { continue; } - $filtered_set[] = $this->_yearday; + $filtered_set[] = $yearday; } - $this->_dayset = $filtered_set; + $dayset = $filtered_set; // if BYSETPOS is set, we need to expand the timeset to filter by pos // so we make a special loop to return while generating - if ( $this->bysetpos && $this->_timeset ) { + if ( $this->bysetpos && $timeset ) { $filtered_set = array(); foreach ( $this->bysetpos as $pos ) { - $n = count($this->_timeset); + $n = count($timeset); if ( $pos < 0 ) { - $pos = $n * count($this->_dayset) + $pos; + $pos = $n * count($dayset) + $pos; } else { $pos = $pos - 1; @@ -1547,15 +1561,15 @@ class RRule implements \Iterator, \ArrayAccess, \Countable $div = (int) ($pos / $n); // daypos $mod = $pos % $n; // timepos - if ( isset($this->_dayset[$div]) && isset($this->_timeset[$mod]) ) { - $this->_yearday = $this->_dayset[$div]; - $time = $this->_timeset[$mod]; + if ( isset($dayset[$div]) && isset($timeset[$mod]) ) { + $yearday = $dayset[$div]; + $time = $timeset[$mod]; // used as array key to ensure uniqueness - $tmp = $this->_year.':'.$this->_yearday.':'.$time[0].':'.$time[1].':'.$time[2]; + $tmp = $year.':'.$yearday.':'.$time[0].':'.$time[1].':'.$time[2]; if ( ! isset($filtered_set[$tmp]) ) { $occurrence = \DateTime::createFromFormat( 'Y z', - "$this->_year $this->_yearday", + "$year $yearday", $this->dtstart->getTimezone() ); $occurrence->setTime($time[0], $time[1], $time[2]); @@ -1564,25 +1578,25 @@ class RRule implements \Iterator, \ArrayAccess, \Countable } } sort($filtered_set); - $this->_dayset = $filtered_set; + $dayset = $filtered_set; } } // 2. loop, generate a valid date, and return the result (fake "yield") // at the same time, we check the end condition and return null if // we need to stop - if ( $this->bysetpos && $this->_timeset ) { - while ( ($occurrence = current($this->_dayset)) !== false ) { + if ( $this->bysetpos && $timeset ) { + while ( ($occurrence = current($dayset)) !== false ) { // consider end conditions if ( $this->until && $occurrence > $this->until ) { - $this->total = $this->_total; // save total for count() cache + $this->total = $total; // save total for count() cache return null; } - next($this->_dayset); - if ( $occurrence >= $this->_dtstart ) { // ignore occurrences before DTSTART - $this->_total += 1; + next($dayset); + if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART + $total += 1; $this->cache[] = $occurrence; return $occurrence; // yield } @@ -1590,57 +1604,57 @@ class RRule implements \Iterator, \ArrayAccess, \Countable } else { // normal loop, without BYSETPOS - while ( ($this->_yearday = current($this->_dayset)) !== false ) { - $occurrence = \DateTime::createFromFormat('Y z', "$this->_year $this->_yearday",$this->dtstart->getTimezone()); + while ( ($yearday = current($dayset)) !== false ) { + $occurrence = \DateTime::createFromFormat('Y z', "$year $yearday",$this->dtstart->getTimezone()); - while ( ($time = current($this->_timeset)) !== false ) { + while ( ($time = current($timeset)) !== false ) { $occurrence->setTime($time[0], $time[1], $time[2]); // consider end conditions if ( $this->until && $occurrence > $this->until ) { - $this->total = $this->_total; // save total for count() cache + $this->total = $total; // save total for count() cache return null; } - next($this->_timeset); - if ( $occurrence >= $this->_dtstart ) { // ignore occurrences before DTSTART - $this->_total += 1; + next($timeset); + if ( $occurrence >= $dtstart ) { // ignore occurrences before DTSTART + $total += 1; $this->cache[] = $occurrence; return $occurrence; // yield } } - reset($this->_timeset); - next($this->_dayset); + reset($timeset); + next($dayset); } } // 3. we reset the loop to the next interval - $this->_days_increment = 0; + $days_increment = 0; switch ( $this->freq ) { case self::YEARLY: - // we do not care about $this->_month or $this->_day not existing, + // we do not care about $month or $day not existing, // they are not used in yearly frequency - $this->_year = $this->_year + $this->interval; + $year = $year + $this->interval; break; case self::MONTHLY: // we do not care about the day of the month not existing // it is not used in monthly frequency - $this->_month = $this->_month + $this->interval; - if ( $this->_month > 12 ) { - $div = (int) ($this->_month / 12); - $mod = $this->_month % 12; - $this->_month = $mod; - $this->_year = $this->_year + $div; - if ( $this->_month == 0 ) { - $this->_month = 12; - $this->_year = $this->_year - 1; + $month = $month + $this->interval; + if ( $month > 12 ) { + $div = (int) ($month / 12); + $mod = $month % 12; + $month = $mod; + $year = $year + $div; + if ( $month == 0 ) { + $month = 12; + $year = $year - 1; } } break; case self::WEEKLY: - $this->_days_increment = $this->interval*7; + $days_increment = $this->interval*7; break; case self::DAILY: - $this->_days_increment = $this->interval; + $days_increment = $this->interval; break; // For the time frequencies, things are a little bit different. @@ -1651,121 +1665,121 @@ class RRule implements \Iterator, \ArrayAccess, \Countable // call the DateTime method at the very end. case self::HOURLY: - if ( empty($this->_dayset) ) { + if ( empty($dayset) ) { // an empty set means that this day has been filtered out // by one of the BYXXX rule. So there is no need to // examine it any further, we know nothing is going to // occur anyway. // so we jump to one iteration right before next day - $this->_hour += ((int) ((23 - $this->_hour) / $this->interval)) * $this->interval; + $hour += ((int) ((23 - $hour) / $this->interval)) * $this->interval; } $found = false; for ( $j = 0; $j < self::$REPEAT_CYCLES[self::HOURLY]; $j++ ) { - $this->_hour += $this->interval; - $div = (int) ($this->_hour / 24); - $mod = $this->_hour % 24; + $hour += $this->interval; + $div = (int) ($hour / 24); + $mod = $hour % 24; if ( $div ) { - $this->_hour = $mod; - $this->_days_increment += $div; + $hour = $mod; + $days_increment += $div; } - if ( ! $this->byhour || in_array($this->_hour, $this->byhour)) { + if ( ! $this->byhour || in_array($hour, $this->byhour)) { $found = true; break; } } if ( ! $found ) { - $this->total = $this->_total; // save total for count cache + $this->total = $total; // save total for count cache return null; // stop the iterator } - $this->_timeset = $this->getTimeSet($this->_hour, $this->_minute, $this->_second); + $timeset = $this->getTimeSet($hour, $minute, $second); break; case self::MINUTELY: - if ( empty($this->_dayset) ) { - $this->_minute += ((int) ((1439 - ($this->_hour*60+$this->_minute)) / $this->interval)) * $this->interval; + if ( empty($dayset) ) { + $minute += ((int) ((1439 - ($hour*60+$minute)) / $this->interval)) * $this->interval; } $found = false; for ( $j = 0; $j < self::$REPEAT_CYCLES[self::MINUTELY]; $j++ ) { - $this->_minute += $this->interval; - $div = (int) ($this->_minute / 60); - $mod = $this->_minute % 60; + $minute += $this->interval; + $div = (int) ($minute / 60); + $mod = $minute % 60; if ( $div ) { - $this->_minute = $mod; - $this->_hour += $div; - $div = (int) ($this->_hour / 24); - $mod = $this->_hour % 24; + $minute = $mod; + $hour += $div; + $div = (int) ($hour / 24); + $mod = $hour % 24; if ( $div ) { - $this->_hour = $mod; - $this->_days_increment += $div; + $hour = $mod; + $days_increment += $div; } } - if ( (! $this->byhour || in_array($this->_hour, $this->byhour)) && - (! $this->byminute || in_array($this->_minute, $this->byminute)) ) { + if ( (! $this->byhour || in_array($hour, $this->byhour)) && + (! $this->byminute || in_array($minute, $this->byminute)) ) { $found = true; break; } } if ( ! $found ) { - $this->total = $this->_total; // save total for count cache + $this->total = $total; // save total for count cache return null; // stop the iterator } - $this->_timeset = $this->getTimeSet($this->_hour, $this->_minute, $this->_second); + $timeset = $this->getTimeSet($hour, $minute, $second); break; case self::SECONDLY: - if ( empty($this->_dayset) ) { - $this->_second += ((int) ((86399 - ($this->_hour*3600 + $this->_minute*60 + $this->_second)) / $this->interval)) * $this->interval; + if ( empty($dayset) ) { + $second += ((int) ((86399 - ($hour*3600 + $minute*60 + $second)) / $this->interval)) * $this->interval; } $found = false; for ( $j = 0; $j < self::$REPEAT_CYCLES[self::SECONDLY]; $j++ ) { - $this->_second += $this->interval; - $div = (int) ($this->_second / 60); - $mod = $this->_second % 60; + $second += $this->interval; + $div = (int) ($second / 60); + $mod = $second % 60; if ( $div ) { - $this->_second = $mod; - $this->_minute += $div; - $div = (int) ($this->_minute / 60); - $mod = $this->_minute % 60; + $second = $mod; + $minute += $div; + $div = (int) ($minute / 60); + $mod = $minute % 60; if ( $div ) { - $this->_minute = $mod; - $this->_hour += $div; - $div = (int) ($this->_hour / 24); - $mod = $this->_hour % 24; + $minute = $mod; + $hour += $div; + $div = (int) ($hour / 24); + $mod = $hour % 24; if ( $div ) { - $this->_hour = $mod; - $this->_days_increment += $div; + $hour = $mod; + $days_increment += $div; } } } - if ( ( ! $this->byhour || in_array($this->_hour, $this->byhour) ) - && ( ! $this->byminute || in_array($this->_minute, $this->byminute) ) - && ( ! $this->bysecond || in_array($this->_second, $this->bysecond) ) ) { + if ( ( ! $this->byhour || in_array($hour, $this->byhour) ) + && ( ! $this->byminute || in_array($minute, $this->byminute) ) + && ( ! $this->bysecond || in_array($second, $this->bysecond) ) ) { $found = true; break; } } if ( ! $found ) { - $this->total = $this->_total; // save total for count cache + $this->total = $total; // save total for count cache return null; // stop the iterator } - $this->_timeset = $this->getTimeSet($this->_hour, $this->_minute, $this->_second); + $timeset = $this->getTimeSet($hour, $minute, $second); break; } // here we take a little shortcut from the Python version, by using DateTime - if ( $this->_days_increment ) { - list($this->_year,$this->_month,$this->_day) = explode('-',date_create("$this->_year-$this->_month-$this->_day")->modify("+ $this->_days_increment days")->format('Y-n-j')); + if ( $days_increment ) { + list($year,$month,$day) = explode('-',date_create("$year-$month-$day")->modify("+ $days_increment days")->format('Y-n-j')); } - $this->_dayset = null; // reset the loop + $dayset = null; // reset the loop } - $this->total = $this->_total; // save total for count cache + $this->total = $total; // save total for count cache return null; // stop the iterator } diff --git a/src/RSet.php b/src/RSet.php index b631e8b..b1c7fc5 100755 --- a/src/RSet.php +++ b/src/RSet.php @@ -224,49 +224,57 @@ class RSet implements \Iterator, \ArrayAccess, \Countable */ protected function iterate($reset = false) { + $rlist = & $this->_rlist; + $rlist_iterator = & $this->_rlist_iterator; + $exlist = & $this->_exlist; + $exlist_iterator = & $this->_exlist_iterator; + $previous_occurrence = & $this->_previous_occurrence; + $total = & $this->_total; + if ( $reset ) { $this->_rlist = $this->_rlist_iterator = null; $this->_exlist = $this->_exlist_iterator = null; $this->_previous_occurrence = null; + $this->_total = 0; } - if ( $this->_rlist === null ) { + if ( $rlist === null ) { // rrules + rdate - $this->_rlist = new \SplMinHeap(); - $this->_rlist_iterator = new \MultipleIterator(\MultipleIterator::MIT_NEED_ANY); - $this->_rlist_iterator->attachIterator(new \ArrayIterator($this->rdates)); + $rlist = new \SplMinHeap(); + $rlist_iterator = new \MultipleIterator(\MultipleIterator::MIT_NEED_ANY); + $rlist_iterator->attachIterator(new \ArrayIterator($this->rdates)); foreach ( $this->rrules as $rrule ) { - $this->_rlist_iterator->attachIterator($rrule); + $rlist_iterator->attachIterator($rrule); } - $this->_rlist_iterator->rewind(); + $rlist_iterator->rewind(); // exrules + exdate - $this->_exlist = new \SplMinHeap(); - $this->_exlist_iterator = new \MultipleIterator(\MultipleIterator::MIT_NEED_ANY); + $exlist = new \SplMinHeap(); + $exlist_iterator = new \MultipleIterator(\MultipleIterator::MIT_NEED_ANY); - $this->_exlist_iterator->attachIterator(new \ArrayIterator($this->exdates)); + $exlist_iterator->attachIterator(new \ArrayIterator($this->exdates)); foreach ( $this->exrules as $rrule ) { - $this->_exlist_iterator->attachIterator($rrule); + $exlist_iterator->attachIterator($rrule); } - $this->_exlist_iterator->rewind(); + $exlist_iterator->rewind(); } while ( true ) { - foreach ( $this->_rlist_iterator->current() as $date ) { + foreach ( $rlist_iterator->current() as $date ) { if ( $date !== null ) { - $this->_rlist->insert($date); + $rlist->insert($date); } } - $this->_rlist_iterator->next(); // advance the iterator for the next call + $rlist_iterator->next(); // advance the iterator for the next call - if ( $this->_rlist->isEmpty() ) { + if ( $rlist->isEmpty() ) { break; // exit the loop to stop the iterator } - $occurrence = $this->_rlist->top(); - $this->_rlist->extract(); // remove the occurence from the heap + $occurrence = $rlist->top(); + $rlist->extract(); // remove the occurence from the heap - if ( $occurrence == $this->_previous_occurrence ) { + if ( $occurrence == $previous_occurrence ) { continue; // skip, was already considered } @@ -276,20 +284,20 @@ class RSet implements \Iterator, \ArrayAccess, \Countable // as occurence (in which case it is discarded) $exclude = false; while ( true ) { - foreach ( $this->_exlist_iterator->current() as $date ) { + foreach ( $exlist_iterator->current() as $date ) { if ( $date !== null ) { - $this->_exlist->insert($date); + $exlist->insert($date); } } - $this->_exlist_iterator->next(); // advance the iterator for the next call + $exlist_iterator->next(); // advance the iterator for the next call - if ( $this->_exlist->isEmpty() ) { - break; // break this loop only + if ( $exlist->isEmpty() ) { + break 1; // break this loop only } - $exdate = $this->_exlist->top(); + $exdate = $exlist->top(); if ( $exdate < $occurrence ) { - $this->_exlist->extract(); + $exlist->extract(); continue; } elseif ( $exdate == $occurrence ) { @@ -301,17 +309,17 @@ class RSet implements \Iterator, \ArrayAccess, \Countable } } - $this->_previous_occurrence = $occurrence; + $previous_occurrence = $occurrence; if ( $exclude ) { continue; } - $this->_total += 1; + $total += 1; return $occurrence; // = yield } - $this->total = $this->_total; // save total for count cache + $this->total = $total; // save total for count cache return null; // stop the iterator } } \ No newline at end of file