implement frequency cache, actually only set in some cases : count recurrence or using lastOccurrence()

master
Tanguy Pruvot 2010-10-30 20:54:42 +02:00
rodzic dd982d53f9
commit ca0dcc1af0
3 zmienionych plików z 55 dodań i 17 usunięć

Wyświetl plik

@ -15,7 +15,7 @@
*/
class SG_iCal_VEvent {
const DEFAULT_CONFIRMED = true;
protected $uid;
protected $start;
protected $end;
@ -24,10 +24,12 @@ class SG_iCal_VEvent {
protected $summary;
protected $description;
protected $location;
public $recurrence;
public $freq; //getFrequency()
public $data;
/**
* Constructs a new SG_iCal_VEvent. Needs the SG_iCalReader
* supplied so it can query for timezones.
@ -35,6 +37,7 @@ class SG_iCal_VEvent {
* @param SG_iCalReader $ical
*/
public function __construct($data, SG_iCal $ical) {
$this->uid = $data['uid']->getData();
unset($data['uid']);
@ -42,7 +45,7 @@ class SG_iCal_VEvent {
$this->recurrence = new SG_iCal_Recurrence($data['rrule']);
unset($data['rrule']);
}
if( isset($data['dtstart']) ) {
$this->start = $this->getTimestamp($data['dtstart'], $ical);
unset($data['dtstart']);
@ -67,8 +70,8 @@ class SG_iCal_VEvent {
//ok..
} elseif ($count) {
//if count is set, then figure out the last occurrence and set that as the end date
$freq = new SG_iCal_Freq($this->recurrence->rrule, $start);
$until = $freq->lastOccurrence($this->start);
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $start);
$until = $this->freq->lastOccurrence($this->start);
} else {
//forever... limit to 3 years
$this->recurrence->setUntil('+3 years');
@ -94,6 +97,20 @@ class SG_iCal_VEvent {
$this->data = SG_iCal_Line::Remove_Line($data);
}
/**
* Returns the Event Occurrences Iterator (if recurrence set)
* @return SG_iCal_Freq
*/
public function getFrequency() {
if (! isset($this->freq)) {
if ( isset($this->recurrence) ) {
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $this->start);
}
}
return $this->freq;
}
/**
* Returns the UID of the event
* @return string

Wyświetl plik

@ -11,8 +11,8 @@ $ICS = "basic.ics";
$ical = new SG_iCalReader($ICS);
$query = new SG_iCal_Query();
//$evts = $ical->getEvents();
$evts = $query->Between($ical,strtotime('20100901'),strtotime('20101131'));
$evts = $ical->getEvents();
//$evts = $query->Between($ical,strtotime('20100901'),strtotime('20101131'));
$data = array();
@ -30,7 +30,8 @@ foreach($evts as $id => $ev) {
if (isset($ev->recurrence)) {
$count = 1;
$start = $ev->getStart();
$freq = new SG_iCal_Freq($ev->recurrence->rrule, $start);
//$freq = new SG_iCal_Freq($ev->recurrence->rrule, $start);
$freq = $ev->getFrequency();
while (($next = $freq->nextOccurrence($start)) > 0 ) {
if (!$next or $count >= 200) break;
$count++;

Wyświetl plik

@ -31,11 +31,13 @@ class SG_iCal_Freq {
protected $rules = array('freq'=>'yearly', 'interval'=>1);
protected $start = 0;
protected $freq = '';
public $cache;
/**
* Constructs a new Freqency-rule
* @param $rule string
* @param $start int Unix-timestamp (important!)
* @param $start int Unix-timestamp (important : Need to be the start of Event)
*/
public function __construct( $rule, $start ) {
$this->start = $start;
@ -65,11 +67,14 @@ class SG_iCal_Freq {
$this->rules['bymonthday'] = date('d', $this->start);
}
}
//set until, and cache
if( isset($this->rules['count']) ) {
$ts = $this->firstOccurrence();
$this->cache[0] = $ts;
for($i=1; $i<$this->rules['count']; $i++) {
$ts = $this->findNext($ts);
$this->cache[$i] = $ts;
}
$this->rules['until'] = $ts;
}
@ -82,14 +87,24 @@ class SG_iCal_Freq {
* @return int
*/
public function previousOccurrence( $offset ) {
$t1 = $this->start;
while( ($t2 = $this->findNext($t1)) < $offset) {
if( $t2 == false ){
break;
if (!empty($this->cache)) {
reset($this->cache);
while( ($t2 = next($this->cache)) < $offset) {
if( $t2 == false ){
break;
}
$ts = $t2;
}
} else {
$ts = $this->start;
while( ($t2 = $this->findNext($ts)) < $offset) {
if( $t2 == false ){
break;
}
$ts = $t2;
}
$t1 = $t2;
}
return $t1;
return $ts;
}
/**
@ -116,9 +131,14 @@ class SG_iCal_Freq {
* @return int timestamp
*/
public function lastOccurrence() {
if (!empty($this->cache)) {
return end($this->cache);
}
$i=0; $this->cache[0] = $this->start;
$ts = $next = $this->findNext($this->start);
while ($next) {
$ts = $next;
$i++; $this->cache[$i] = $ts;
$next = $this->findNext($ts);
}
return $ts;