implement EXDATE exclusions

master
Tanguy Pruvot 2010-10-30 22:44:07 +02:00
rodzic 642115b1cc
commit 5743c6221e
4 zmienionych plików z 47 dodań i 27 usunięć

Wyświetl plik

@ -26,6 +26,7 @@ class SG_iCal_VEvent {
protected $location;
public $recurrence;
public $excluded;
public $freq; //getFrequency()
public $data;
@ -37,20 +38,28 @@ class SG_iCal_VEvent {
* @param SG_iCalReader $ical
*/
public function __construct($data, SG_iCal $ical) {
$this->uid = $data['uid']->getData();
unset($data['uid']);
if ( isset($data['rrule']) ) {
$this->recurrence = new SG_iCal_Recurrence($data['rrule']);
unset($data['rrule']);
//exclusions
if ( isset($data['exdate']) ) {
foreach ($data['exdate'] as $exdate) {
$this->excluded[] = $this->getTimestamp($exdate, $ical);
}
unset($data['exdate']);
}
}
if( isset($data['dtstart']) ) {
$this->start = $this->getTimestamp($data['dtstart'], $ical);
unset($data['dtstart']);
}
if( isset($data['dtend']) ) {
$this->end = $this->getTimestamp($data['dtend'], $ical);
unset($data['dtend']);
@ -59,7 +68,7 @@ class SG_iCal_VEvent {
$this->end = $this->start + $dur->getDuration();
unset($data['duration']);
}
//google cal set dtend as end of initial event (duration)
if ( isset($this->recurrence) ) {
//if there is a recurrence rule
@ -70,7 +79,7 @@ class SG_iCal_VEvent {
//ok..
} elseif ($count) {
//if count is set, then figure out the last occurrence and set that as the end date
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $start);
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $start, $this->excluded);
$until = $this->freq->lastOccurrence($this->start);
} else {
//forever... limit to 3 years
@ -105,7 +114,7 @@ class SG_iCal_VEvent {
public function getFrequency() {
if (! isset($this->freq)) {
if ( isset($this->recurrence) ) {
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $this->start);
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $this->start, $this->excluded);
}
}
return $this->freq;

Wyświetl plik

@ -31,6 +31,7 @@ class SG_iCal_Freq {
protected $rules = array('freq'=>'yearly', 'interval'=>1);
protected $start = 0;
protected $freq = '';
protected $excluded;
public $cache;
@ -39,8 +40,9 @@ class SG_iCal_Freq {
* @param $rule string
* @param $start int Unix-timestamp (important : Need to be the start of Event)
*/
public function __construct( $rule, $start ) {
public function __construct( $rule, $start, $excluded=array()) {
$this->start = $start;
$this->excluded = $excluded;
$rules = array();
foreach( explode(';', $rule) AS $v) {
@ -53,7 +55,6 @@ class SG_iCal_Freq {
}
$this->freq = strtolower($this->rules['freq']);
foreach( $this->knownRules AS $rule ) {
if( isset($this->rules['by' . $rule]) ) {
if( $this->isPrerule($rule, $this->freq) ) {
@ -68,13 +69,11 @@ class SG_iCal_Freq {
}
}
//set until, and cache
//set until
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;
}
@ -88,10 +87,12 @@ class SG_iCal_Freq {
public function getAllOccurrences() {
if (empty($this->cache)) {
//build cache
$i=0; $this->cache[0] = $this->start;
unset($this->cache);
$this->cache[] = $this->start;
$next = $this->findNext($this->start);
while ($next) {
$i++; $this->cache[$i] = $next;
//if (!in_array($next, $this->excluded))
$this->cache[] = $next;
$next = $this->findNext($next);
}
}
@ -106,7 +107,7 @@ class SG_iCal_Freq {
*/
public function previousOccurrence( $offset ) {
if (!empty($this->cache)) {
$t2=$this->cache[0];
$t2=$this->start;
foreach($this->cache as $ts) {
if ($ts >= $offset)
return $t2;
@ -151,11 +152,9 @@ class SG_iCal_Freq {
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;
@ -185,7 +184,6 @@ class SG_iCal_Freq {
* @return int
*/
public function findNext($offset) {
if (!empty($this->cache)) {
foreach($this->cache as $ts) {
if ($ts > $offset)
@ -214,10 +212,11 @@ class SG_iCal_Freq {
if( $this->simpleMode ) {
if( $offset < $t ) {
return $t;
}
$next = $this->findStartingPoint( $t, $this->rules['interval'], false );
if( !$this->validDate( $next ) ) {
return $this->findNext($next);
} else {
$next = $this->findStartingPoint( $t, $this->rules['interval'], false );
if( !$this->validDate( $next ) ) {
return $this->findNext($next);
}
}
return $next;
}
@ -250,19 +249,23 @@ class SG_iCal_Freq {
}
if( $offset < $this->start && $this->start < $t ) {
return $this->start;
$ts = $this->start;
} else if( $found && ($t != $offset)) {
if( $this->validDate( $t ) ) {
if($debug) echo 'OK' . "\n";
return $t;
$ts = $t;
} else {
if($debug) echo 'Invalid' . "\n";
return $this->findNext($t);
$ts = $this->findNext($t);
}
} else {
if($debug) echo 'Not found' . "\n";
return $this->findNext( $this->findStartingPoint( $offset, $this->rules['interval'] ) );
$ts = $this->findNext( $this->findStartingPoint( $offset, $this->rules['interval'] ) );
}
if ($ts && in_array($ts, $this->excluded))
return $this->findNext($ts);
return $ts;
}
/**
@ -454,6 +457,10 @@ class SG_iCal_Freq {
if( isset($this->rules['until']) && $t > $this->rules['until'] ) {
return false;
}
if (in_array($t, $this->excluded)) {
return false;
}
if( isset($this->rules['bymonth']) ) {
$months = explode(',', $this->rules['bymonth']);

Wyświetl plik

@ -119,8 +119,13 @@ class SG_iCal_Parser {
if( array_search($s, $sections) !== false ) {
// This section is in the main section
if( $section == $s ) {
// It _is_ the main section
$current_data[$s][$line->getIdent()] = $line;
// It _is_ the main section else
if ($line->getIdent() != "exdate")
$current_data[$s][$line->getIdent()] = $line;
else {
//exdate could appears more that once
$current_data[$s][$line->getIdent()][] = $line;
}
} else {
// Sub section
$current_data[$s][$section][$line->getIdent()] = $line;

Wyświetl plik

@ -42,7 +42,6 @@ class SG_iCal_Recurrence {
'byyearday', 'byyearno', 'bymonth', 'bysetpos'
);
/**
* Creates an recurrence object with a passed in line. Parses the line.
* @param object $line an SG_iCal_Line object which will be parsed to get the