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

Wyświetl plik

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

Wyświetl plik

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