kopia lustrzana https://github.com/friendica/SG-iCalendar
code cleanup
rodzic
f9e8612eb6
commit
e03b95f43d
|
@ -1,10 +1,10 @@
|
||||||
<?php // BUILD: Remove line
|
<?php // BUILD: Remove line
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to store Frequency-rules in. Will allow a easy way to find the
|
* A class to store Frequency-rules in. Will allow a easy way to find the
|
||||||
* last and next occurrence of the rule.
|
* last and next occurrence of the rule.
|
||||||
*
|
*
|
||||||
* No - this is so not pretty. But.. ehh.. You do it better, and I will
|
* No - this is so not pretty. But.. ehh.. You do it better, and I will
|
||||||
* gladly accept patches.
|
* gladly accept patches.
|
||||||
*
|
*
|
||||||
* Created by trail-and-error on the examples given in the RFC.
|
* Created by trail-and-error on the examples given in the RFC.
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
* TODO: Update to a better way of doing calculating the different options.
|
* TODO: Update to a better way of doing calculating the different options.
|
||||||
* Instead of only keeping track of the best of the current dates found
|
* Instead of only keeping track of the best of the current dates found
|
||||||
* it should instead keep a array of all the calculated dates within the
|
* it should instead keep a array of all the calculated dates within the
|
||||||
* period.
|
* period.
|
||||||
* This should fix the issues with multi-rule + multi-rule interference,
|
* This should fix the issues with multi-rule + multi-rule interference,
|
||||||
* and make it possible to implement the SETPOS rule.
|
* and make it possible to implement the SETPOS rule.
|
||||||
* By pushing the next period onto the stack as the last option will
|
* By pushing the next period onto the stack as the last option will
|
||||||
* (hopefully) remove the need for the awful simpleMode
|
* (hopefully) remove the need for the awful simpleMode
|
||||||
*
|
*
|
||||||
* @package SG_iCalReader
|
* @package SG_iCalReader
|
||||||
|
@ -27,19 +27,19 @@ class SG_iCal_Freq {
|
||||||
protected $knownRules = array('month', 'weekno', 'day', 'monthday', 'yearday', 'hour', 'minute'); //others : 'setpos', 'second'
|
protected $knownRules = array('month', 'weekno', 'day', 'monthday', 'yearday', 'hour', 'minute'); //others : 'setpos', 'second'
|
||||||
protected $ruleModifiers = array('wkst');
|
protected $ruleModifiers = array('wkst');
|
||||||
protected $simpleMode = true;
|
protected $simpleMode = true;
|
||||||
|
|
||||||
protected $rules = array('freq'=>'yearly', 'interval'=>1);
|
protected $rules = array('freq'=>'yearly', 'interval'=>1);
|
||||||
protected $start = 0;
|
protected $start = 0;
|
||||||
protected $freq = '';
|
protected $freq = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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!)
|
||||||
*/
|
*/
|
||||||
public function __construct( $rule, $start ) {
|
public function __construct( $rule, $start ) {
|
||||||
$this->start = $start;
|
$this->start = $start;
|
||||||
|
|
||||||
$rules = array();
|
$rules = array();
|
||||||
foreach( explode(';', $rule) AS $v) {
|
foreach( explode(';', $rule) AS $v) {
|
||||||
list($k, $v) = explode('=', $v);
|
list($k, $v) = explode('=', $v);
|
||||||
|
@ -50,7 +50,7 @@ class SG_iCal_Freq {
|
||||||
$this->rules['until'] = strtotime($this->rules['until']);
|
$this->rules['until'] = strtotime($this->rules['until']);
|
||||||
}
|
}
|
||||||
$this->freq = strtolower($this->rules['freq']);
|
$this->freq = strtolower($this->rules['freq']);
|
||||||
|
|
||||||
|
|
||||||
foreach( $this->knownRules AS $rule ) {
|
foreach( $this->knownRules AS $rule ) {
|
||||||
if( isset($this->rules['by' . $rule]) ) {
|
if( isset($this->rules['by' . $rule]) ) {
|
||||||
|
@ -59,7 +59,7 @@ class SG_iCal_Freq {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->simpleMode) {
|
if(!$this->simpleMode) {
|
||||||
if(! (isset($this->rules['byday']) || isset($this->rules['bymonthday']) || isset($this->rules['byyearday']))) {
|
if(! (isset($this->rules['byday']) || isset($this->rules['bymonthday']) || isset($this->rules['byyearday']))) {
|
||||||
$this->rules['bymonthday'] = date('d', $this->start);
|
$this->rules['bymonthday'] = date('d', $this->start);
|
||||||
|
@ -74,7 +74,7 @@ class SG_iCal_Freq {
|
||||||
$this->rules['until'] = $n;
|
$this->rules['until'] = $n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the previous (most recent) occurrence of the rule from the
|
* Returns the previous (most recent) occurrence of the rule from the
|
||||||
* given offset
|
* given offset
|
||||||
|
@ -91,7 +91,7 @@ class SG_iCal_Freq {
|
||||||
}
|
}
|
||||||
return $t1;
|
return $t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next occurrence of this rule after the given offset
|
* Returns the next occurrence of this rule after the given offset
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
|
@ -113,36 +113,36 @@ class SG_iCal_Freq {
|
||||||
}
|
}
|
||||||
return $next;
|
return $next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the next time after the given offset that the rule
|
* Calculates the next time after the given offset that the rule
|
||||||
* will apply.
|
* will apply.
|
||||||
*
|
*
|
||||||
* The approach to finding the next is as follows:
|
* The approach to finding the next is as follows:
|
||||||
* First we establish a timeframe to find timestamps in. This is
|
* First we establish a timeframe to find timestamps in. This is
|
||||||
* between $offset and the end of the period that $offset is in.
|
* between $offset and the end of the period that $offset is in.
|
||||||
*
|
*
|
||||||
* We then loop though all the rules (that is a Prerule in the
|
* We then loop though all the rules (that is a Prerule in the
|
||||||
* current freq.), and finds the smallest timestamp inside the
|
* current freq.), and finds the smallest timestamp inside the
|
||||||
* timeframe.
|
* timeframe.
|
||||||
*
|
*
|
||||||
* If we find something, we check if the date is a valid recurrence
|
* If we find something, we check if the date is a valid recurrence
|
||||||
* (with validDate). If it is, we return it. Otherwise we try to
|
* (with validDate). If it is, we return it. Otherwise we try to
|
||||||
* find a new date inside the same timeframe (but using the new-
|
* find a new date inside the same timeframe (but using the new-
|
||||||
* found date as offset)
|
* found date as offset)
|
||||||
*
|
*
|
||||||
* If no new timestamps were found in the period, we try in the
|
* If no new timestamps were found in the period, we try in the
|
||||||
* next period
|
* next period
|
||||||
*
|
*
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function findNext($offset) {
|
public function findNext($offset) {
|
||||||
$echo = false;
|
$debug = false;
|
||||||
|
|
||||||
//make sure the offset is valid
|
//make sure the offset is valid
|
||||||
if( $offset === false || (isset($this->rules['until']) && $offset > $this->rules['until']) ) {
|
if( $offset === false || (isset($this->rules['until']) && $offset > $this->rules['until']) ) {
|
||||||
if($echo) echo 'STOP: ' . date('r', $offset) . "\n";
|
if($debug) echo 'STOP: ' . date('r', $offset) . "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,12 +150,12 @@ class SG_iCal_Freq {
|
||||||
|
|
||||||
//set the timestamp of the offset (ignoring hours and minutes unless we want them to be
|
//set the timestamp of the offset (ignoring hours and minutes unless we want them to be
|
||||||
//part of the calculations.
|
//part of the calculations.
|
||||||
if($echo) echo 'O: ' . date('r', $offset) . "\n";
|
if($debug) echo 'O: ' . date('r', $offset) . "\n";
|
||||||
$hour = (in_array($this->freq, array('hourly','minutely')) && $offset > $this->start) ? date('H', $offset) : date('H', $this->start);
|
$hour = (in_array($this->freq, array('hourly','minutely')) && $offset > $this->start) ? date('H', $offset) : date('H', $this->start);
|
||||||
$minute = (($this->freq == 'minutely' || isset($this->rules['byminute'])) && $offset > $this->start) ? date('i', $offset) : date('i', $this->start);
|
$minute = (($this->freq == 'minutely' || isset($this->rules['byminute'])) && $offset > $this->start) ? date('i', $offset) : date('i', $this->start);
|
||||||
$t = mktime($hour, $minute, date('s', $this->start), date('m', $offset), date('d', $offset), date('Y',$offset));
|
$t = mktime($hour, $minute, date('s', $this->start), date('m', $offset), date('d', $offset), date('Y',$offset));
|
||||||
if($echo) echo 'START: ' . date('r', $t) . "\n";
|
if($debug) echo 'START: ' . date('r', $t) . "\n";
|
||||||
|
|
||||||
if( $this->simpleMode ) {
|
if( $this->simpleMode ) {
|
||||||
if( $offset < $t ) {
|
if( $offset < $t ) {
|
||||||
return $t;
|
return $t;
|
||||||
|
@ -166,10 +166,10 @@ class SG_iCal_Freq {
|
||||||
}
|
}
|
||||||
return $next;
|
return $next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$eop = $this->findEndOfPeriod($offset);
|
$eop = $this->findEndOfPeriod($offset);
|
||||||
if($echo) echo 'EOP: ' . date('r', $eop) . "\n";
|
if($debug) echo 'EOP: ' . date('r', $eop) . "\n";
|
||||||
|
|
||||||
foreach( $this->knownRules AS $rule ) {
|
foreach( $this->knownRules AS $rule ) {
|
||||||
if( $found && isset($this->rules['by' . $rule]) ) {
|
if( $found && isset($this->rules['by' . $rule]) ) {
|
||||||
if( $this->isPrerule($rule, $this->freq) ) {
|
if( $this->isPrerule($rule, $this->freq) ) {
|
||||||
|
@ -180,7 +180,7 @@ class SG_iCal_Freq {
|
||||||
if( $imm === false ) {
|
if( $imm === false ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if($echo) echo strtoupper($rule) . ': ' . date('r', $imm) . ' A: ' . ((int) ($imm > $offset && $imm < $eop)) . "\n";
|
if($debug) echo strtoupper($rule) . ': ' . date('r', $imm) . ' A: ' . ((int) ($imm > $offset && $imm < $eop)) . "\n";
|
||||||
if( $imm > $offset && $imm < $eop && ($_t == null || $imm < $_t) ) {
|
if( $imm > $offset && $imm < $eop && ($_t == null || $imm < $_t) ) {
|
||||||
$_t = $imm;
|
$_t = $imm;
|
||||||
}
|
}
|
||||||
|
@ -198,18 +198,18 @@ class SG_iCal_Freq {
|
||||||
return $this->start;
|
return $this->start;
|
||||||
} else if( $found && ($t != $offset)) {
|
} else if( $found && ($t != $offset)) {
|
||||||
if( $this->validDate( $t ) ) {
|
if( $this->validDate( $t ) ) {
|
||||||
if($echo) echo 'OK' . "\n";
|
if($debug) echo 'OK' . "\n";
|
||||||
return $t;
|
return $t;
|
||||||
} else {
|
} else {
|
||||||
if($echo) echo 'Invalid' . "\n";
|
if($debug) echo 'Invalid' . "\n";
|
||||||
return $this->findNext($t);
|
return $this->findNext($t);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if($echo) echo 'Not found' . "\n";
|
if($debug) echo 'Not found' . "\n";
|
||||||
return $this->findNext( $this->findStartingPoint( $offset, $this->rules['interval'] ) );
|
return $this->findNext( $this->findStartingPoint( $offset, $this->rules['interval'] ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the starting point for the next rule. It goes $interval
|
* Finds the starting point for the next rule. It goes $interval
|
||||||
* 'freq' forward in time since the given offset
|
* 'freq' forward in time since the given offset
|
||||||
|
@ -229,14 +229,14 @@ class SG_iCal_Freq {
|
||||||
}
|
}
|
||||||
|
|
||||||
$sp = strtotime($t, $offset);
|
$sp = strtotime($t, $offset);
|
||||||
|
|
||||||
if( $truncate ) {
|
if( $truncate ) {
|
||||||
$sp = $this->truncateToPeriod($sp, $this->freq);
|
$sp = $this->truncateToPeriod($sp, $this->freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sp;
|
return $sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the earliest timestamp posible outside this perioid
|
* Finds the earliest timestamp posible outside this perioid
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
|
@ -245,11 +245,11 @@ class SG_iCal_Freq {
|
||||||
public function findEndOfPeriod($offset) {
|
public function findEndOfPeriod($offset) {
|
||||||
return $this->findStartingPoint($offset, 1);
|
return $this->findStartingPoint($offset, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the timestamp to the beginning of the
|
* Resets the timestamp to the beginning of the
|
||||||
* period specified by freq
|
* period specified by freq
|
||||||
*
|
*
|
||||||
* Yes - the fall-through is on purpose!
|
* Yes - the fall-through is on purpose!
|
||||||
*
|
*
|
||||||
* @param int $time
|
* @param int $time
|
||||||
|
@ -283,7 +283,7 @@ class SG_iCal_Freq {
|
||||||
$d = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']);
|
$d = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']);
|
||||||
return $d;
|
return $d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the BYDAY rule to the given timestamp
|
* Applies the BYDAY rule to the given timestamp
|
||||||
* @param string $rule
|
* @param string $rule
|
||||||
|
@ -293,24 +293,24 @@ class SG_iCal_Freq {
|
||||||
private function ruleByday($rule, $t) {
|
private function ruleByday($rule, $t) {
|
||||||
$dir = ($rule{0} == '-') ? -1 : 1;
|
$dir = ($rule{0} == '-') ? -1 : 1;
|
||||||
$dir_t = ($dir == 1) ? 'next' : 'last';
|
$dir_t = ($dir == 1) ? 'next' : 'last';
|
||||||
|
|
||||||
|
|
||||||
$d = $this->weekdays[substr($rule,-2)];
|
$d = $this->weekdays[substr($rule,-2)];
|
||||||
$s = $dir_t . ' ' . $d . ' ' . date('H:i:s',$t);
|
$s = $dir_t . ' ' . $d . ' ' . date('H:i:s',$t);
|
||||||
|
|
||||||
if( $rule == substr($rule, -2) ) {
|
if( $rule == substr($rule, -2) ) {
|
||||||
if( date('l', $t) == ucfirst($d) ) {
|
if( date('l', $t) == ucfirst($d) ) {
|
||||||
$s = 'today ' . date('H:i:s',$t);
|
$s = 'today ' . date('H:i:s',$t);
|
||||||
}
|
}
|
||||||
|
|
||||||
$_t = strtotime($s, $t);
|
$_t = strtotime($s, $t);
|
||||||
|
|
||||||
if( $_t == $t && in_array($this->freq, array('monthly', 'yearly')) ) {
|
if( $_t == $t && in_array($this->freq, array('monthly', 'yearly')) ) {
|
||||||
// Yes. This is not a great idea.. but hey, it works.. for now
|
// Yes. This is not a great idea.. but hey, it works.. for now
|
||||||
$s = 'next ' . $d . ' ' . date('H:i:s',$t);
|
$s = 'next ' . $d . ' ' . date('H:i:s',$t);
|
||||||
$_t = strtotime($s, $_t);
|
$_t = strtotime($s, $_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_t;
|
return $_t;
|
||||||
} else {
|
} else {
|
||||||
$_f = $this->freq;
|
$_f = $this->freq;
|
||||||
|
@ -323,10 +323,10 @@ class SG_iCal_Freq {
|
||||||
$_t = $this->truncateToPeriod($t, $this->freq);
|
$_t = $this->truncateToPeriod($t, $this->freq);
|
||||||
}
|
}
|
||||||
$this->freq = $_f;
|
$this->freq = $_f;
|
||||||
|
|
||||||
$c = preg_replace('/[^0-9]/','',$rule);
|
$c = preg_replace('/[^0-9]/','',$rule);
|
||||||
$c = ($c == '') ? 1 : $c;
|
$c = ($c == '') ? 1 : $c;
|
||||||
|
|
||||||
$n = $_t;
|
$n = $_t;
|
||||||
while($c > 0 ) {
|
while($c > 0 ) {
|
||||||
if( $dir == 1 && $c == 1 && date('l', $t) == ucfirst($d) ) {
|
if( $dir == 1 && $c == 1 && date('l', $t) == ucfirst($d) ) {
|
||||||
|
@ -335,11 +335,11 @@ class SG_iCal_Freq {
|
||||||
$n = strtotime($s, $n);
|
$n = strtotime($s, $n);
|
||||||
$c--;
|
$c--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $n;
|
return $n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ruleBymonth($rule, $t) {
|
private function ruleBymonth($rule, $t) {
|
||||||
$_t = mktime(date('H',$t), date('i',$t), date('s',$t), $rule, date('d', $t), date('Y', $t));
|
$_t = mktime(date('H',$t), date('i',$t), date('s',$t), $rule, date('d', $t), date('Y', $t));
|
||||||
if( $t == $_t && isset($this->rules['byday']) ) {
|
if( $t == $_t && isset($this->rules['byday']) ) {
|
||||||
|
@ -349,14 +349,14 @@ class SG_iCal_Freq {
|
||||||
return $_t;
|
return $_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ruleBymonthday($rule, $t) {
|
private function ruleBymonthday($rule, $t) {
|
||||||
if( $rule < 0 ) {
|
if( $rule < 0 ) {
|
||||||
$rule = date('t', $t) + $rule + 1;
|
$rule = date('t', $t) + $rule + 1;
|
||||||
}
|
}
|
||||||
return mktime(date('H',$t), date('i',$t), date('s',$t), date('m', $t), $rule, date('Y', $t));
|
return mktime(date('H',$t), date('i',$t), date('s',$t), date('m', $t), $rule, date('Y', $t));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ruleByyearday($rule, $t) {
|
private function ruleByyearday($rule, $t) {
|
||||||
if( $rule < 0 ) {
|
if( $rule < 0 ) {
|
||||||
$_t = $this->findEndOfPeriod();
|
$_t = $this->findEndOfPeriod();
|
||||||
|
@ -376,12 +376,12 @@ class SG_iCal_Freq {
|
||||||
} else {
|
} else {
|
||||||
$_t = $this->truncateToPeriod($t, $this->freq);
|
$_t = $this->truncateToPeriod($t, $this->freq);
|
||||||
$d = '+';
|
$d = '+';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sub = (date('W', $_t) == 1) ? 2 : 1;
|
$sub = (date('W', $_t) == 1) ? 2 : 1;
|
||||||
$s = $d . abs($rule - $sub) . ' weeks ' . date('H:i:s',$t);
|
$s = $d . abs($rule - $sub) . ' weeks ' . date('H:i:s',$t);
|
||||||
$_t = strtotime($s, $_t);
|
$_t = strtotime($s, $_t);
|
||||||
|
|
||||||
return $_t;
|
return $_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,17 +389,17 @@ class SG_iCal_Freq {
|
||||||
$_t = mktime($rule, date('i',$t), date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
|
$_t = mktime($rule, date('i',$t), date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
|
||||||
return $_t;
|
return $_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ruleByminute($rule, $t) {
|
private function ruleByminute($rule, $t) {
|
||||||
$_t = mktime(date('h',$t), $rule, date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
|
$_t = mktime(date('h',$t), $rule, date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
|
||||||
return $_t;
|
return $_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function validDate( $t ) {
|
private function validDate( $t ) {
|
||||||
if( isset($this->rules['until']) && $t > $this->rules['until'] ) {
|
if( isset($this->rules['until']) && $t > $this->rules['until'] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isset($this->rules['bymonth']) ) {
|
if( isset($this->rules['bymonth']) ) {
|
||||||
$months = explode(',', $this->rules['bymonth']);
|
$months = explode(',', $this->rules['bymonth']);
|
||||||
if( !in_array(date('m', $t), $months)) {
|
if( !in_array(date('m', $t), $months)) {
|
||||||
|
@ -438,10 +438,10 @@ class SG_iCal_Freq {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isPrerule($rule, $freq) {
|
private function isPrerule($rule, $freq) {
|
||||||
if( $rule == 'year')
|
if( $rule == 'year')
|
||||||
return false;
|
return false;
|
||||||
|
@ -456,11 +456,11 @@ class SG_iCal_Freq {
|
||||||
return true;
|
return true;
|
||||||
if( $rule == 'day' && in_array($freq, array('yearly', 'monthly', 'weekly')))
|
if( $rule == 'day' && in_array($freq, array('yearly', 'monthly', 'weekly')))
|
||||||
return true;
|
return true;
|
||||||
if( $rule == 'hour' && in_array($freq, array('yearly', 'monthly', 'weekly', 'daily')))
|
if( $rule == 'hour' && in_array($freq, array('yearly', 'monthly', 'weekly', 'daily')))
|
||||||
return true;
|
return true;
|
||||||
if( $rule == 'minute' )
|
if( $rule == 'minute' )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue