PKG 版本文件提交。

This commit is contained in:
YUCHENG HU 2013-01-30 22:02:55 -05:00
parent a1009f166c
commit 75f8f2c916
920 changed files with 92398 additions and 0 deletions

View File

@ -0,0 +1,2 @@
<?php
class qCal_DateTime_Exception_InvalidTimezone extends qCal_DateTime_Exception {}

View File

@ -0,0 +1,6 @@
<?php
class qCal_DateTime_Exception_InvalidWeekday extends qCal_DateTime_Exception {
// w00t!
}

View File

@ -0,0 +1,62 @@
<?php
/**
* Date period object - rather than a point in time, this object represents a PERIOD of time. So,
* it consists of a start and end point in time
*
* @package qCal
* @subpackage qCal_Date
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_DateTime_Period {
/**
* Start and end date/times
*/
protected $start, $end;
/**
* Constructor
*/
public function __construct($start, $end) {
if (!($start instanceof qCal_DateTime)) {
$start = qCal_DateTime::factory($start);
}
if (!($end instanceof qCal_DateTime)) {
$end = qCal_DateTime::factory($end);
}
$this->start = $start;
$this->end = $end;
if ($this->getSeconds() < 0) {
throw new qCal_DateTime_Exception_InvalidPeriod("The start date must come before the end date.");
}
}
/**
* Converts to how many seconds between the two. because this is the smallest increment
* used in this class, seconds are used to determine other increments
*/
public function getSeconds() {
return $this->end->getUnixTimestamp() - $this->start->getUnixTimestamp();
}
/**
* Returns start date
*/
public function getStart() {
return $this->start;
}
/**
* Returns end date
*/
public function getEnd() {
return $this->end;
}
}

View File

@ -0,0 +1,452 @@
<?php
/**
* This is a class that is used within qCal_Value_Recur to internally store a recur property
* @todo The RFC says that invalid byXXX rule parts should simply be ignored. So I'm not sure if
* I should be hurling exceptions at the poor user all over the place like I am in here.
*/
abstract class qCal_DateTime_Recur {
/**
* @var array An array of week days. Used throughout this class to validate input.
*/
protected $weekdays = array(
'MO' => 'Monday',
'TU' => 'Tuesday',
'WE' => 'Wednesday',
'TH' => 'Thursday',
'FR' => 'Friday',
'SA' => 'Saturday',
'SU' => 'Sunday',
);
/**
* @var qCal_Date The start date/time of the recurrence
*/
protected $dtstart;
/**
* @var string frequency of the recurrence
*/
protected $freq;
/**
* @var qCal_Date The date/time which the recurrence ends
*/
protected $until;
/**
* @var integer The amount of recurrences
*/
protected $count;
/**
* @var integer Interval of recurrence (for every 3 days, "3" would be the interval)
*/
protected $interval;
/**
* @var integer|array An integer between 0 and 59 (for multiple, set as an array)
*/
protected $bysecond;
/**
* @var integer|array An integer between 0 and 59 (or an array of integers for multiple)
*/
protected $byminute;
/**
* @var integer|array An integer or array of integers between 0 and 23
*/
protected $byhour;
/**
* @var string If present, represents the nth occurrence of a specific day within monthly or yearly
* so it can be something like +1MO (or simply 1MO) for the first monday within the month, whereas
* -1MO for the last monday of the month. Or it can be simply MO to represent every monday within the month
*/
protected $byday;
/**
* @var integer|array An integer or array of integers. -31 to -1 or 1 to 31. -10 would mean the tenth to last
* day of the month. [1,5,-5] would be the 1st, 5th, and 5th to last days of the month
*/
protected $bymonthday;
/**
* @var integer|array An integer or array of integers. -366 to -1 or 1 to 366. -306 represents the 306th to last
* day of the year (March 1st)
*/
protected $byyearday;
/**
* @var integer|array An integer or array of integers. -53 to -1 or 1 to 53. Only valid for yearly rules.
* 3 represents the third week of the year.
*/
protected $byweekno;
/**
* @var integer|array An integer or array of integers. 1 to 12. 3 would represent March
*/
protected $bymonth;
/**
* @var integer If present, it indicates the nth occurrence of the specific occurrence within the set of
* events specified by this recurrence rule
*/
protected $bysetpos;
/**
* @var string Must be one of the weekdays specified above (2 char). Specifies the day on which the work week
* starts. This is significant when a weekly rule has an interval greater than 1 and a byday rule part is specified.
* This is also significant when in a yearly rule when a byweekno rule part is specified. Defaults to "MO"
*/
protected $wkst = "MO";
/**
* Constructor
* @param $freq string Must be one of the freqtypes specified above.
* @throws qCal_Date_Exception_InvalidRecur if a frequency other than those specified above is passed in
*/
public function __construct($dtstart = null) {
$this->dtstart = is_null($dtstart) ? null : qCal_DateTime::factory($dtstart);
}
/**
* Specifies the date when the recurrence stops, inclusively. If not present, and there is no count specified,
* then the recurrence goes on "forever".
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $until string|qCal_Date|DateTime If time is specified, it must be UTC
* @throws qCal_Date_Exception_InvalidRecur
* @return self
*/
public function until($until = null) {
if (is_null($until)) return $this->until;
if ($this->count()) throw new qCal_DateTime_Exception_InvalidRecur('A recurrence count and an until date cannot both be specified');
$this->until = qCal_DateTime::factory($until);
return $this;
}
/**
* Specifies the amount of recurrences before the recurrence ends. If neither this nor "until" is specified,
* the recurrence repeats "forever".
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $count integer The amount of recurrences before it stops
* @throws qCal_Date_Exception_InvalidRecur
* @return self
*/
public function count($count = null) {
if (is_null($count)) return $this->count;
if ($this->until()) throw new qCal_DateTime_Exception_InvalidRecur('A recurrence count and an until date cannot both be specified');
$this->count = (integer) $count;
return $this;
}
/**
* Specifies the start of the work-week, which is Monday by default
*/
public function wkst($wkst = null) {
if (is_null($wkst)) return $this->wkst;
$abbrs = array_keys($this->weekdays);
if (!in_array($wkst, $abbrs)) throw new qCal_DateTime_Exception_InvalidRecur('"' . $wkst . '" is not a valid week day, must be one of the following: ' . implode(', ', $abbrs));
$this->wkst = $wkst;
// @todo I wonder if re-sorting the weekdays array would help me in any way...
}
/**
* Specifies the interval of recurrences
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $interval integer The interval of recurrences, for instance every "3" days
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function interval($interval = null) {
if (is_null($interval)) return $this->interval;
$this->interval = (integer) $interval;
return $this;
}
/**
* Specifies a rule which will happen on every nth second.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $second integer|array Can be an integer (or array of ints) between 0 and 59
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function bySecond($second = null) {
if (is_null($second)) return $this->bysecond;
if (!is_array($second)) $second = array($second);
$this->bysecond = $second;
return $this;
}
/**
* Specifies a rule which will happen on every nth minute
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $minute integer|array Can be an integer (or array of ints) between 0 and 59
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMinute($minute = null) {
if (is_null($minute)) return $this->byminute;
if (!is_array($minute)) $minute = array($minute);
$this->byminute = $minute;
return $this;
}
/**
* Specifies a rule which will happen on every nth hour
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $hour integer|array Can be an integer (or array of ints) between 0 and 23
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byHour($hour = null) {
if (is_null($hour)) return $this->byhour;
if (!is_array($hour)) $hour = array($hour);
$this->byhour = $hour;
return $this;
}
/**
* Specifies a rule which will happen on whichever day is specified. For instance, "MO" would
* mean every monday.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* Sets $this->byday into an array of arrays like array('SU' => 1) for '1SU' and array('SU' => 0) for 'SU'
* @param $day string|array Must be one of the 2-char week days specified above. Can be preceded by
* a positive or negative integer to represent, for instance, the third monday of the month (3MO) or second to last
* Sunday of the month (-2SU)
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byDay($day = null) {
if (is_null($day)) {
$ret = array();
foreach ($this->byday as $val) {
$num = (current($val) == 0) ? "" : current($val);
$ret[] = $num . key($val);
}
return $ret;
}
if (!is_array($day)) $day = array($day);
$days = array();
foreach ($day as $d) {
// optional plus or minus followed by a series of digits as group 1
// two-character week day as group 2
if (preg_match('/^([+-]?[0-9]+)?(MO|TU|WE|TH|FR|SA|SU)$/', $d, $matches)) {
$num = ($matches[1] == "") ? "0" : $matches[1];
$wday = $matches[2];
if (substr($num, 0, 1) == "+") {
$num = substr($num, 1);
}
$days[] = array($wday => $num);
}
}
$this->byday = $days;
return $this;
}
/**
* Specifies a rule which will happen on the month days specified. For instance, 23 would mean the 23rd of every month.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 31 or -31 to 1 (or an array of those values)
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMonthDay($monthday = null) {
if (is_null($monthday)) return $this->bymonthday;
if (!is_array($monthday)) $monthday = array($monthday);
$this->bymonthday = $monthday;
return $this;
}
/**
* Specifies a rule which will happen on the nth day of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 366 or -366 to -1.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byYearDay($yearday = null) {
if (is_null($yearday)) return $this->byyearday;
if (!is_array($yearday)) $yearday = array($yearday);
$this->byyearday = $yearday;
return $this;
}
/**
* Specifies a rule which will happen on the nth week of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 53 or -53 to -1.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byWeekNo($weekno = null) {
if (is_null($weekno)) return $this->byweekno;
if (!is_array($weekno)) $weekno = array($weekno);
$this->byweekno = $weekno;
return $this;
}
/**
* Specifies a rule which will happen on the nth month of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 12
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMonth($month = null) {
if (is_null($month)) return $this->bymonth;
if (!is_array($month)) $month = array($month);
$this->bymonth = $month;
return $this;
}
/**
* Indicates the nth occurrence of the specific occurrence within the set of
* events specified by the rule.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @todo I don't really understand how this works... :( Figure out wtf it is for.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function bySetPos($setpos = null) {
if (is_null($setpos)) return $this->bysetpos;
$this->bysetpos = (integer) $setpos;
return $this;
}
/**
* Factory method generates the correct recur type based on the string it is passed: "yearly, weekly, etc."
* @param string The frequency type of recurrence rule you want to generate
* @param mixed The start date/time for the recurrence. Accepts anything qCal_Date accepts
*/
static public function factory($freq, $start) {
$freq = ucfirst(strtolower($freq));
$className = "qCal_DateTime_Recur_" . $freq;
$fileName = str_replace("_", DIRECTORY_SEPARATOR, $className) . ".php";
qCal_Loader::loadFile($fileName);
$class = new $className($start);
return $class;
}
/**
* Fetches instances of the recurrence rule in the given time period. Because recurrences
* could potentially go on forever, there is no way to fetch ALL instances of a recurrence rule
* other than providing a date range that spans the entire length of the recurrence.
*
* The way this will need to work is, depending on the frequency, I will find all possible
* occurrence of the rule. For instance, if this is a "monthly" rule, I'll find out which month
* to start in, then find all occurrence possible. Then narrow down by the other rules I guess.
*
* @idea Maybe I should build classes for each of the frequency types. That way I could loop over
* the object and get methods like qCal_DateTime_Recur_Monthly::isNthDay('SU') to find out what sunday
* of the month it is... stuff like that... I dunno... ?
*
* @throws qCal_DateTime_Exception_InvalidRecur
* @todo The giant switch in this method is a glaring code smell, but it works for now. I will refactor
* after version 0.1 and remove the switch (probably will implement qCal_DateTime_Recur_Yearly, qCal_DateTime_Recur_Monthly, etc.)
*/
public function getRecurrences($start, $end) {
$start = qCal_DateTime::factory($start);
$end = qCal_DateTime::factory($end);
if ($start->getUnixTimestamp() > $end->getUnixTimestamp()) throw new qCal_DateTime_Exception_InvalidRecur('Start date must come before end date');
if (!$this->interval) throw new qCal_DateTime_Exception_InvalidRecur('You must specify an interval');
$rules = array(
'bymonth' => array(),
'byweekno' => array(),
'byyearday' => array(),
'byday' => array(),
);
// byMonth rules
if (is_array($this->bymonth)) {
foreach ($this->bymonth as $bymonth) {
$rules['bymonth'][] = new qCal_DateTime_Recur_Rule_ByMonth($bymonth);
}
}
// byWeekNo rules
if (is_array($this->byweekno)) {
foreach ($this->byweekno as $byweekno) {
$rules['byweekno'][] = new qCal_DateTime_Recur_Rule_ByWeekNo($byweekno);
}
}
// byYearDay rules
if (is_array($this->byyearday)) {
foreach ($this->byyearday as $byyearday) {
$rules['byyearday'][] = new qCal_DateTime_Recur_Rule_ByYearDay($byyearday);
}
}
// byMonthDay rules (these get applied to bymonth rules)
if (is_array($this->bymonthday)) {
foreach ($this->bymonthday as $bymonthday) {
$bmdrule = new qCal_DateTime_Recur_Rule_ByMonthDay($bymonthday);
foreach ($rules['bymonth'] as $bymonth) {
$bymonth->attach($bmdrule);
}
}
}
// byDay rules (these get applied to bymonth rules if they exist, otherwise simply to year)
if (is_array($this->byday)) {
foreach ($this->byday as $byday) {
$bdrule = new qCal_DateTime_Recur_Rule_ByDay($byday);
if (is_array($rules['bymonth']) && !empty($rules['bymonth'])) {
foreach ($rules['bymonth'] as $bymonth) {
$bymonth->attach($bdrule);
}
} else {
$rules['byday'][] = $bdrule;
}
}
}
// byHour rules (these get applied to each rule above)
if (is_array($this->byhour)) {
foreach ($this->byhour as $byhour) {
$bhrule = new qCal_DateTime_Recur_Rule_ByHour($byhour);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bhrule);
}
}
}
}
// byMinute rules (these get applied to each rule above)
if (is_array($this->byminute)) {
foreach ($this->byminute as $byminute) {
$bmrule = new qCal_DateTime_Recur_Rule_ByMinute($byminute);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bmrule);
}
}
}
}
// bySecond rules (these get applied to each rule above)
if (is_array($this->bysecond)) {
foreach ($this->bysecond as $bysecond) {
$bsrule = new qCal_DateTime_Recur_Rule_BySecond($bysecond);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bsrule);
}
}
}
}
return $this->doGetRecurrences($rules, $start, $end);
}
/**
* Each type of rule needs to determine its recurrences so this is left abstract
* to be implemented by children.
*/
abstract protected function doGetRecurrences($rules, $start, $end);
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Daily extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Hourly extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Minutely extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Monthly extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,35 @@
<?php
abstract class qCal_DateTime_Recur_Rule {
/**
* @var array The sub-rules of this rule.
*/
protected $rules = array();
/**
* @var mixed The value of this rule
*/
protected $value;
/**
* Constructor
* @param The value of the rule. If this is a ByMonth rule, then 1 would mean January
*/
public function __construct($value) {
$this->value = $value;
}
/**
* Attach rules to this rule. For instance, if this is a byMonth rule, then
* we can attach byDay rules like "-1SU" for the last Sunday of the month.
*/
public function attach(qCal_DateTime_Recur_Rule $rule) {
$this->rules[] = $rule;
}
/**
* Creates the recurrences for this rule. Left to children to do this.
*/
abstract public function getRecurrences();
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByDay extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByHour extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByMinute extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,14 @@
<?php
class qCal_DateTime_Recur_Rule_ByMonth extends qCal_DateTime_Recur_Rule {
/**
* If there are sub-rules then this rule may return more than one instance or it
* may return none.
*/
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByMonthDay extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_BySecond extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_BySetPos extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByWeekNo extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Rule_ByYearDay extends qCal_DateTime_Recur_Rule {
public function getRecurrences() {
return array();
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Secondly extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,10 @@
<?php
class qCal_DateTime_Recur_Weekly extends qCal_DateTime_Recur {
protected function doGetRecurrences($rules, $start, $end) {
// do stuff!
}
}

View File

@ -0,0 +1,143 @@
<?php
class qCal_DateTime_Recur_Yearly extends qCal_DateTime_Recur {
/**
* @todo This is a god method that really should be split out into each
* of the qCal_DateTime_Recur_Rule_ByXXX classes. For now I did all the logic
* here to keep it simple and not confuse myself more than necessary.
*/
protected function doGetRecurrences($rules, $start, $end) {
// an array to store recurrences
$recurrences = array();
// start day, year, and month
$sday = $start->format('d');
$smonth = $start->format('m');
$syear = $start->format('Y');
// end day, year, and month
$eday = $end->format('d');
$emonth = $end->format('m');
$eyear = $end->format('Y');
// loop over years, by increment
$year = $syear;
while ($year <= $eyear) {
// if byMonth is specified...
if (count($this->byMonth())) {
// loop over each month
for ($month = 1; $month <= 12; $month++) {
// if this is the start year still and we haven't reached the start month, skip ahead
if ($year == $syear && $month < $smonth) {
continue;
}
// if this is the end year and we have passed the end month, break out of loop
if ($year == $eyear && $month > $emonth) {
break;
}
// if this is not one of the bymonths, continue as well
if (!in_array($month, $this->byMonth())) {
continue;
}
// now we need to loop over each day of the month to look for byday or bymonthday
$thismonth = new qCal_Date(); // used to determine total days in the current month
$thismonth->setDate($year, $month, 1);
$weekdays = array(
'MO' => 0,
'TU' => 0,
'WE' => 0,
'TH' => 0,
'FR' => 0,
'SA' => 0,
'SU' => 0,
);
// @todo For now this only allows 1SU, SU, but not -1SU (no negatives for now)
for ($day = 1; $day <= $thismonth->format('t'); $day++) {
$alreadyadded = false;
$date = new qCal_Date;
$date->setDate($year, $month, $day);
$date->setTime(0, 0, 0);
$wdname = strtoupper(substr($date->format('l'), 0, 2));
// keep track of how many of each day of the week have gone by
$weekdays[$wdname]++;
// if byDay is specified...
// @todo this is inconsistent, I don't use the getter here because of its special functionality.
// I need to either remove the special functionality or not use getters elsewhere in this method
$byday = $this->byday;
if (count($byday)) {
// by day is broken into an array of arrays like array('TH' => 0), array('FR' => 1), array('MO' => -2) etc.
// with zero meaning every instance of that particular day should be included and number meaning the Nth of that day
foreach ($byday as $val) {
// if at least one of this wday has gone by...
$num = current($val);
if ($weekdays[$wdname] > 0) {
// check if it is the right week day and if a digit is specified (like 1SU) that it is checked as well
if ($wdname == key($val) && ($weekdays[$wdname] == $num || $num == 0)) {
$recurrences[] = $date;
$alreadyadded = true;
}
}
}
}
// if byMonthDay is specified...
if (count($this->byMonthDay())) {
foreach ($this->byMonthDay() as $mday) {
// only add this day if it hasn't been added already
if ($mday == $day && !$alreadyadded) {
$recurrences[] = $date;
}
}
}
// now loop over each hour and add hours
if (count($this->byHour())) {
$hourrecurrences = array();
foreach ($this->byHour() as $hour) {
$new = new qCal_Date();
$new = $new->copy($date);
$new->setTime($hour, 0, 0);
$hourrecurrences[] = $new;
}
}
// now loop over byHours and add byMinutes
if (count($this->byMinute())) {
if (!isset($minuterecurrences)) $minuterecurrences = array();
foreach ($this->byMinute() as $minute) {
$new = new qCal_Date();
$new = $new->copy($date);
$new->setTime(0, $minute, 0);
}
}
// now loop over byMinutes and add bySeconds
}
}
}
// if in the first year we don't find an instance, don't do the interval, just increment a year
if ($year == $syear && count($recurrences)) $year += $this->interval();
else ($year++);
}
// now loop over weeks to get byWeekNo
foreach ($recurrences as $date) {
// pr($date->format("r"));
}
// exit;
return $recurrences;
// for bymonth, it would make the most sense to loop over each month until the specified one
// is found. Then loop over each day to find its sub-rules.
// for byweekno, it would make the most sense to loop over each week until the specified one
// is found. Then apply any sub-rules (actually I'm not sure how byhour and its ilk would be applied in this situation... need to read the rfc)
}
}

View File

@ -0,0 +1,62 @@
<?php
class qCal_Time_Timezone {
protected $format = "P";
public function __construct($timezone = null) {
if (!is_null($timezone)) {
date_default_timezone_set($timezone);
}
}
public function getOffsetSeconds() {
return date("Z");
}
public function getOffsetHours() {
return date("O");
}
public function getOffset() {
return date("P");
}
public function getAbbreviation() {
return date("T");
}
public function isDaylightSavings() {
return (boolean) date("I");
}
public function getName() {
return date("e");
}
public function format($format) {
return date($format);
}
public function __toString() {
return $this->format($this->format);
}
}

View File

@ -0,0 +1,11 @@
<?php
/**
* Base qCal Exception
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Exception extends Exception {
}

View File

@ -0,0 +1,6 @@
<?php
class qCal_Exception_FileNotFound extends qCal_Exception {
// hooty
}

View File

@ -0,0 +1,12 @@
<?php
/**
* Invalid Component Exception - when an attempt is made to attach a component to another component, and it isn't allowed
* this exception is thrown, for instance attempting to attach a calendar to a todo
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Exception_InvalidComponent extends qCal_Exception {
}

View File

@ -0,0 +1,2 @@
<?php
class qCal_Exception_InvalidFile extends qCal_Exception {}

View File

@ -0,0 +1,12 @@
<?php
/**
* Invalid Property Exception - when an attempt is made to add a certain property
* to a component that doesn't allow said property, this exception is thrown.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Exception_InvalidProperty extends qCal_Exception {
}

View File

@ -0,0 +1,12 @@
<?php
/**
* Invalid Property Value Exception - if a property requires a certain type of value, and it is given
* the wrong value type, it will throw this exception.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Exception_InvalidPropertyValue extends qCal_Exception {
}

View File

@ -0,0 +1,6 @@
<?php
class qCal_Exception_MissingComponent extends qCal_Exception {
// represents an exception that is thrown when a component requires that another component be its child
}

View File

@ -0,0 +1,12 @@
<?php
/**
* Invalid Property Value Exception - if a component requires a certain property, and is instantiated
* without that property, this exception is thrown.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Exception_MissingProperty extends qCal_Exception {
}

View File

@ -0,0 +1,43 @@
<?php
/**
* qCal_Loader
* Loads files from the file system. Looks through the entire include path
*/
class qCal_Loader {
/**
* Load a class
*/
static public function loadClass($name) {
$path = str_replace("_", DIRECTORY_SEPARATOR, $name) . ".php";
self::loadFile($path);
}
/**
* Loads a file or throws an exception
*/
static public function loadFile($filename) {
if (!self::fileExists($filename)) {
throw new qCal_Exception_InvalidFile("$filename does not exist.");
}
require_once $filename;
}
/**
* Looks through the include path for file name
*/
static public function fileExists($filename) {
$includepath = get_include_path();
$includepath = explode(PATH_SEPARATOR, $includepath);
foreach ($includepath as $path) {
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
if (file_exists($path . $filename)) return true;
}
return false;
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* qCal_Parser
* The parser accepts an array of qCal_Parser_Token objects and converts them
* to actual formatted icalendar data (in one of many formats). The default is
* qCal_Parser_iCal which is complient with RFC 2445, but there are others as well,
* such as qCal_Parser_xCal (xml) or qCal_Parser_hCal (microformats).
*
* @package qCal
* @subpackage qCal_Parser
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Parser {
/**
* @param array containing any options the particular parser accepts
*/
protected $options;
/**
* Constructor
* Pass in an array of options
* @todo Come up with list of available options
* @param array parser options
*/
public function __construct($options = array()) {
// set defaults...
$this->options = array(
'searchpath' => get_include_path(),
);
$this->options = array_merge($this->options, $options);
}
/**
* @todo What should this accept? filename? actual string content? either?
* @todo Maybe even create a parse() for raw string and a parseFile() for a file name?
*/
public function parse($content, $lexer = null) {
if (is_null($lexer)) {
$lexer = new qCal_Parser_Lexer_iCalendar($content);
}
$this->lexer = $lexer;
return $this->doParse($this->lexer->tokenize());
}
/**
* Parse a file. The searchpath defaults to the include path. Also, if the filename
* provided is an absolute path, the searchpath is not used. This is determined by
* either the file starting with a forward slash, or a drive letter (for Windows)
* @todo Throw an exception if file doesn't exist
* @todo I'm not really sure that it should default to the include path. That's not really what the include path is for, is it?
* @todo Test for path starting with a drive letter for windows (or find a better way to detect that)
*/
public function parseFile($filename) {
// @todo This is hacky... but it works
if (substr($filename, 0, 1) == '/' || substr($filename, 0, 3) == 'C:\\') {
if (file_exists($filename)) {
$content = file_get_contents($filename);
return $this->parse($content);
}
} else {
$paths = explode(PATH_SEPARATOR, $this->options['searchpath']);
foreach ($paths as $path) {
$fname = $path . DIRECTORY_SEPARATOR . $filename;
if (file_exists($fname)) {
$content = file_get_contents($fname);
return $this->parse($content);
}
}
}
throw new qCal_Exception_FileNotFound('File cannot be found: "' . $filename . '"');
}
/**
* Override doParse in a child class if necessary
*/
protected function doParse($tokens) {
$properties = array();
foreach ($tokens['properties'] as $propertytoken) {
$params = array();
foreach ($propertytoken['params'] as $paramtoken) {
$params[$paramtoken['param']] = $paramtoken['value'];
}
try {
$properties[] = qCal_Property::factory($propertytoken['property'], $propertytoken['value'], $params);
} catch (qCal_Exception $e) {
// @todo There should be a better way of determining what went wrong during parsing/lexing than this
// do nothing...
// pr($e);
}
}
$component = qCal_Component::factory($tokens['component'], $properties);
foreach ($tokens['children'] as $child) {
$childcmpnt = $this->doParse($child);
$component->attach($childcmpnt);
}
return $component;
}
}

View File

@ -0,0 +1,34 @@
<?php
/**
* qCal_Parser_Lexer
* Not sure if I like the name of this class, but what can you do?
* Anyway, this class converts a string into "tokens" which are then
* fed to the parser
*
* @package qCal
* @subpackage qCal_Parser
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
abstract class qCal_Parser_Lexer {
/**
* @var string input text
*/
protected $content;
/**
* Constructor
* @param string containing the text to be tokenized
*/
public function __construct($content) {
$this->content = $content;
}
/**
* Tokenize content into tokens that can be used to build iCalendar objects
*/
abstract public function tokenize();
}

View File

@ -0,0 +1,120 @@
<?php
/**
* qCal_Parser_Lexer_iCalendar
* The lexer for iCalendar RFC 2445 format. Other formats will need their
* own lexer. The lexer converts text to an array of "tokens", which, at least
* for now, are just arrays.
*
* @package qCal
* @subpackage qCal_Parser
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that multi-value properties are taken care of properly
*/
class qCal_Parser_Lexer_iCalendar extends qCal_Parser_Lexer {
/**
* @var string character(s) used to terminate lines
*/
protected $line_terminator;
/**
* Constructor
*/
public function __construct($content) {
parent::__construct($content);
$this->line_terminator = chr(13) . chr(10);
}
/**
* Return a list of tokens (to be fed to the parser)
* @returns array tokens
*/
public function tokenize() {
$lines = $this->unfold($this->content);
// loop through chunks of input text by separating by properties and components
// and create tokens for each one, creating a multi-dimensional array of tokens to return
$stack = array();
foreach ($lines as $line) {
// begin a component
if (preg_match('#^BEGIN:([a-z]+)$#i', $line, $matches)) {
// create new array representing the new component
$array = array(
'component' => $matches[1],
'properties' => array(),
'children' => array(),
);
$stack[] = $array;
} elseif (strpos($line, "END:") === 0) {
// end component, pop the stack
$child = array_pop($stack);
if (empty($stack)) {
$tokens = $child;
} else {
$parent =& $stack[count($stack)-1];
array_push($parent['children'], $child);
}
} else {
// continue component
if (preg_match('#^([^:]+):"?([^\n]+)?"?$#i', $line, $matches)) {
// @todo What do I do with empty values?
$value = isset($matches[2]) ? $matches[2] : "";
$component =& $stack[count($stack)-1];
// if line is a property line, start a new property, but first determine if there are any params
$property = $matches[1];
$params = array();
$propparts = explode(";", $matches[1]);
if (count($propparts) > 1) {
foreach ($propparts as $key => $part) {
// the first one is the property name
if ($key == 0) {
$property = $part;
} else {
// the rest are params
// @todo Quoted param values need to be taken care of...
list($paramname, $paramvalue) = explode("=", $part, 2);
$params[] = array(
'param' => $paramname,
'value' => $paramvalue,
);
}
}
}
$proparray = array(
'property' => $property,
'value' => $value,
'params' => $params,
);
$component['properties'][] = $proparray;
}
}
}
return $tokens;
}
/**
* Unfold the file before trying to parse it
*/
protected function unfold($content) {
$return = array();
$lines = explode($this->line_terminator, $content);
foreach ($lines as $line) {
$checkempty = trim($line);
if (empty($checkempty)) continue;
$chr1 = substr($line, 0, 1);
$therest = substr($line, 1);
// if character 1 is a whitespace character... (tab or space)
if ($chr1 == chr(9) || $chr1 == chr(32)) {
$return[count($return)-1] .= $therest;
} else {
$return[] = $line;
}
}
return $return;
}
}

View File

@ -0,0 +1,289 @@
<?php
/**
* Base component property class. version, attach, rrule are all examples
* of component properties.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* A property is the definition of an individual attribute describing a
* calendar or a calendar component. A property takes the form defined
* by the "contentline" notation defined in section 4.1.1.
*
* The following is an example of a property:
*
* DTSTART:19960415T133000Z
*
* This memo imposes no ordering of properties within an iCalendar
* object.
*
* Property names, parameter names and enumerated parameter values are
* case insensitive. For example, the property name "DUE" is the same as
* "due" and "Due", DTSTART;TZID=US-Eastern:19980714T120000 is the same
* as DtStart;TzID=US-Eastern:19980714T120000.
*/
abstract class qCal_Property {
/**
* Property name (dtstart, rrule, etc)
* This can be auto-generated from the class name
* @var string
*/
protected $name;
/**
* Property value
* @var qCal_Value object
*/
protected $value;
/**
* Default value - if set to false, there is no default value
* @var mixed
*/
protected $default = false;
/**
* Property Data Type (this name gets converted to class name)
* @var string
*/
protected $type;
/**
* Property parameters
* @var array
*/
protected $params = array();
/**
* Contains a list of components this property is allowed to be specified
* for
* @var array
*/
protected $allowedComponents = array();
/**
* Some properties can be specified multiple times in a component. This
* determines whether or not that is allowed for this property.
*/
protected $allowMultiple = false;
/**
* Class constructor
*
* @todo Cast $value to whatever data type this is ($this->type)
* @todo Determine if there can be multiple params of the same name
*/
public function __construct($value = null, $params = array()) {
if (is_null($this->name)) $this->name = $this->getPropertyNameFromClassName(get_class($this));
foreach ($params as $pname => $pval) {
$this->setParam($pname, $pval);
}
// this must be set after parameters because the VALUE parameter can affect it
$this->setValue($value);
}
/**
* Generates a qCal_Property class based on property name, params, and value
* which can come directly from an icalendar file
* @todo I need a way to detect INVALID properties as they are being parsed. This
* way there can be an option to NOT stop on errors. To just log and then continue.
*/
static public function factory($name, $value, $params = array()) {
$className = self::getClassNameFromPropertyName($name);
$fileName = str_replace("_", DIRECTORY_SEPARATOR, $className) . ".php";
try {
qCal_Loader::loadFile($fileName);
$class = new $className($value, $params);
} catch (qCal_Exception_InvalidFile $e) {
// if there is no class available for this property, check if it is non-standard
$xname = strtoupper(substr($name, 0, 2));
// non-standard property
if ($xname == "X-") {
$class = new qCal_Property_NonStandard($value, $params, $name);
} else {
// if it's not a non-standard property, rethrow
throw $e;
}
}
return $class;
}
/**
* Returns the property name (formatted and exactly to spec)
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Returns the property value (as a string)
* If you want the actual object, use getValueObject()
* I wish I could just pass the object back and have php do some overloading magicness, but
* it doesn't know how :(
* @return string
*/
public function getValue() {
return $this->value->__toString();
}
/**
* Just returns getValue()
*/
public function __toString() {
return $this->getValue();
}
/**
* Returns raw value object (or for multi-value, an array)
* @return string
*/
public function getValueObject() {
return $this->value;
}
/**
* Sets the property value
* @param mixed
*/
public function setValue($value) {
// if value sent is null and this property doesn't have a default value,
// the property can't be created, so throw an invalidpropertyvalue exception
if (is_null($value)) {
if ($this->default === false) {
// this is caught by factory and reported as a conformance error
throw new qCal_Exception_InvalidPropertyValue($this->getName() . ' property must have a value');
} else {
$value = $this->default;
}
}
$this->value = $this->convertValue($value);
return $this;
}
/**
* Converts a value into whatever internal storage mechanism the property uses
*/
protected function convertValue($value) {
return qCal_Value::factory($this->getType(), $value);
}
/**
* Returns the property type
* @return string
*/
public function getType() {
return $this->type;
}
/**
* Check if this is a property of a certain component. Some properties
* can only be set on certain Components. This method looks inside this
* property's $allowedComponents and returns true if $component is allowed
*
* @return boolean True if this is a property of $component, false otherwise
* @param qCal_Component The component we're evaluating
**/
public function of(qCal_Component $component) {
return in_array($component->getName(), $this->allowedComponents);
}
/**
* Retreive the value of a parameter
*
* @return mixed parameter value
*/
public function getParam($name) {
if (isset($this->params[strtoupper($name)])) {
return $this->params[strtoupper($name)];
}
}
/**
* Returns an array of all params
*/
public function getParams() {
return $this->params;
}
/**
* Set the value of a parameter
*/
public function setParam($name, $value) {
$name = strtoupper($name);
// if value param has been passed in, change the type of this property to its value
if ($name == "VALUE") {
$value = strtoupper($value);
$this->type = $value;
}
$this->params[$name] = $value;
return $this;
}
/**
* Determine's this property's name from the class name by adding a dash after
* every capital letter and upper-casing
*
* @return string The RFC property name
* @todo This method is flawed. The class name XLvFoo gets converted to X-L-VFOO when
* it should be X-LV-FOO
**/
protected function getPropertyNameFromClassName($classname) {
// determine the property name by class name
$parts = explode("_", $classname);
end($parts);
// find where capital letters are and insert dash
$chars = str_split(current($parts));
// make a copy @todo Why make a copy?
$newchars = $chars;
foreach ($chars as $pos => $char) {
// don't add a dash for the first letter
if (!$pos) continue;
$num = ord($char);
// if character is a capital letter
if ($num >= 65 && $num <= 90) {
// insert dash
array_splice($newchars, $pos, 0, '-');
}
}
return strtoupper(implode("", $newchars));
}
/**
* Determine's this property's class name from the property name
*
* @return string The property class name
**/
protected function getClassNameFromPropertyName($name) {
// remove dashes, capitalize properly
$parts = explode("-", $name);
$property = "";
foreach ($parts as $part) $property .= trim(ucfirst(strtolower($part)));
// get the class, and instantiate
$className = "qCal_Property_" . $property;
return $className;
}
/**
* Is this property allowed to be specified multiple times in a component?
* @return boolean
*/
public function allowMultiple() {
return (boolean) $this->allowMultiple;
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* Action Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: ACTION
*
* Purpose: This property defines the action to be invoked when an alarm
* is triggered.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be specified once in a "VALARM"
* calendar component.
*
* Description: Each "VALARM" calendar component has a particular type
* of action associated with it. This property specifies the type of
* action
*
* Format Definition: The property is defined by the following notation:
*
* action = "ACTION" actionparam ":" actionvalue CRLF
*
* actionparam = *(";" xparam)
*
* actionvalue = "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE"
* / iana-token / x-name
*
* Example: The following are examples of this property in a "VALARM"
* calendar component:
*
* ACTION:AUDIO
*
* ACTION:DISPLAY
*
* ACTION:PROCEDURE
*/
class qCal_Property_Action extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VALARM');
}

View File

@ -0,0 +1,65 @@
<?php
/**
* Attach Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: ATTACH
*
* Purpose: The property provides the capability to associate a document
* object with a calendar component.
*
* Value Type: The default value type for this property is URI. The
* value type can also be set to BINARY to indicate inline binary
* encoded content information.
*
* Property Parameters: Non-standard, inline encoding, format type and
* value data type property parameters can be specified on this
* property.
*
* Conformance: The property can be specified in a "VEVENT", "VTODO",
* "VJOURNAL" or "VALARM" calendar components.
*
* Description: The property can be specified within "VEVENT", "VTODO",
* "VJOURNAL", or "VALARM" calendar components. This property can be
* specified multiple times within an iCalendar object.
*
* Format Definition: The property is defined by the following notation:
*
* attach = "ATTACH" attparam ":" uri CRLF
*
* attach =/ "ATTACH" attparam ";" "ENCODING" "=" "BASE64"
* ";" "VALUE" "=" "BINARY" ":" binary
*
* attparam = *(
*
* ; the following is optional,
* ; but MUST NOT occur more than once
*
* (";" fmttypeparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following are examples of this property:
*
* ATTACH:CID:jsmith.part3.960817T083000.xyzMail@host1.com
*
* ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
* reports/r-960812.ps
*/
class qCal_Property_Attach extends qCal_Property {
protected $type = 'URI';
protected $allowedComponents = array('VALARM','VEVENT','VJOURNAL','VTODO');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,144 @@
<?php
/**
* Attendee Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that allowedComponents is correct. I am still a little
* confused about how this property works. It is apparent that it is
* used differently based on compoenent. I think the correct place
* to put logic like that is in the component itself.
*
* RFC 2445 Definition
*
* Property Name: ATTENDEE
*
* Purpose: The property defines an "Attendee" within a calendar
* component.
*
* Value Type: CAL-ADDRESS
*
* Property Parameters: Non-standard, language, calendar user type,
* group or list membership, participation role, participation status,
* RSVP expectation, delegatee, delegator, sent by, common name or
* directory entry reference property parameters can be specified on
* this property.
*
* Conformance: This property MUST be specified in an iCalendar object
* that specifies a group scheduled calendar entity. This property MUST
* NOT be specified in an iCalendar object when publishing the calendar
* information (e.g., NOT in an iCalendar object that specifies the
* publication of a calendar user's busy time, event, to-do or journal).
* This property is not specified in an iCalendar object that specifies
* only a time zone definition or that defines calendar entities that
* are not group scheduled entities, but are entities only on a single
* user's calendar.
*
* Description: The property MUST only be specified within calendar
* components to specify participants, non-participants and the chair of
* a group scheduled calendar entity. The property is specified within
* an "EMAIL" category of the "VALARM" calendar component to specify an
* email address that is to receive the email type of iCalendar alarm.
*
* The property parameter CN is for the common or displayable name
* associated with the calendar address; ROLE, for the intended role
* that the attendee will have in the calendar component; PARTSTAT, for
* the status of the attendee's participation; RSVP, for indicating
* whether the favor of a reply is requested; CUTYPE, to indicate the
* type of calendar user; MEMBER, to indicate the groups that the
* attendee belongs to; DELEGATED-TO, to indicate the calendar users
* that the original request was delegated to; and DELEGATED-FROM, to
* indicate whom the request was delegated from; SENT-BY, to indicate
* whom is acting on behalf of the ATTENDEE; and DIR, to indicate the
* URI that points to the directory information corresponding to the
* attendee. These property parameters can be specified on an "ATTENDEE"
* property in either a "VEVENT", "VTODO" or "VJOURNAL" calendar
* component. They MUST not be specified in an "ATTENDEE" property in a
* "VFREEBUSY" or "VALARM" calendar component. If the LANGUAGE property
* parameter is specified, the identified language applies to the CN
* parameter.
*
* A recipient delegated a request MUST inherit the RSVP and ROLE values
* from the attendee that delegated the request to them.
*
* Multiple attendees can be specified by including multiple "ATTENDEE"
* properties within the calendar component.
*
* Format Definition: The property is defined by the following notation:
*
* attendee = "ATTENDEE" attparam ":" cal-address CRLF
*
* attparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" cutypeparam) / (";"memberparam) /
* (";" roleparam) / (";" partstatparam) /
* (";" rsvpparam) / (";" deltoparam) /
* (";" delfromparam) / (";" sentbyparam) /
* (";"cnparam) / (";" dirparam) /
* (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following are examples of this property's use for a to-
* do:
*
* ORGANIZER:MAILTO:jsmith@host1.com
* ATTENDEE;MEMBER="MAILTO:DEV-GROUP@host2.com":
* MAILTO:joecool@host2.com
* ATTENDEE;DELEGATED-FROM="MAILTO:immud@host3.com":
* MAILTO:ildoit@host1.com
*
* The following is an example of this property used for specifying
* multiple attendees to an event:
*
* ORGANIZER:MAILTO:jsmith@host1.com
* ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Henry Cabot
* :MAILTO:hcabot@host2.com
* ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com"
* ;PARTSTAT=ACCEPTED;CN=Jane Doe:MAILTO:jdoe@host1.com
*
* The following is an example of this property with a URI to the
* directory information associated with the attendee:
*
* ATTENDEE;CN=John Smith;DIR="ldap://host.com:6666/o=eDABC%
* 20Industries,c=3DUS??(cn=3DBJim%20Dolittle)":MAILTO:jimdo@
* host1.com
*
* The following is an example of this property with "delegatee" and
* "delegator" information for an event:
*
* ORGANIZER;CN=John Smith:MAILTO:jsmith@host.com
* ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;DELEGATED-FROM=
* "MAILTO:iamboss@host2.com";CN=Henry Cabot:MAILTO:hcabot@
* host2.com
* ATTENDEE;ROLE=NON-PARTICIPANT;PARTSTAT=DELEGATED;DELEGATED-TO=
* "MAILTO:hcabot@host2.com";CN=The Big Cheese:MAILTO:iamboss
* @host2.com
* ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Jane Doe
* :MAILTO:jdoe@host1.com
*
* Example: The following is an example of this property's use when
* another calendar user is acting on behalf of the "Attendee":
*
* ATTENDEE;SENT-BY=MAILTO:jan_doe@host1.com;CN=John Smith:MAILTO:
* jsmith@host1.com
*/
class qCal_Property_Attendee extends qCal_Property {
protected $type = 'CAL-ADDRESS';
// If I'm reading the RFC correctly above, this property can be specified
// on the following components, but I'm still a bit confused about it. I
// need to read up on it more to really understand
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VALARM');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,48 @@
<?php
/**
* Calendar Scale Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: CALSCALE
*
* Purpose: This property defines the calendar scale used for the
* calendar information specified in the iCalendar object.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: Property can be specified in an iCalendar object. The
* default value is "GREGORIAN".
*
* Description: This memo is based on the Gregorian calendar scale. The
* Gregorian calendar scale is assumed if this property is not specified
* in the iCalendar object. It is expected that other calendar scales
* will be defined in other specifications or by future versions of this
* memo.
*
* Format Definition: The property is defined by the following notation:
*
* calscale = "CALSCALE" calparam ":" calvalue CRLF
*
* calparam = *(";" xparam)
*
* calvalue = "GREGORIAN" / iana-token
*
* Example: The following is an example of this property:
*
* CALSCALE:GREGORIAN
*/
class qCal_Property_Calscale extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VCALENDAR');
protected $default = "GREGORIAN";
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Categories Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: CATEGORIES
*
* Purpose: This property defines the categories for a calendar
* component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard and language property parameters
* can be specified on this property.
*
* Conformance: The property can be specified within "VEVENT", "VTODO"
* or "VJOURNAL" calendar components.
*
* Description: This property is used to specify categories or subtypes
* of the calendar component. The categories are useful in searching for
* a calendar component of a particular type and category. Within the
* "VEVENT", "VTODO" or "VJOURNAL" calendar components, more than one
* category can be specified as a list of categories separated by the
* COMMA character (US-ASCII decimal 44).
*
* Format Definition: The property is defined by the following notation:
*
* categories = "CATEGORIES" catparam ":" text *("," text)
* CRLF
*
* catparam = *(
*
* ; the following is optional,
* ; but MUST NOT occur more than once
*
* (";" languageparam ) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following are examples of this property:
*
* CATEGORIES:APPOINTMENT,EDUCATION
*
* CATEGORIES:MEETING
*/
class qCal_Property_Categories extends qCal_Property_MultiValue {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,59 @@
<?php
/**
* Classification Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: CLASS
*
* Purpose: This property defines the access classification for a
* calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified once in a "VEVENT",
* "VTODO" or "VJOURNAL" calendar components.
*
* Description: An access classification is only one component of the
* general security system within a calendar application. It provides a
* method of capturing the scope of the access the calendar owner
* intends for information within an individual calendar entry. The
* access classification of an individual iCalendar component is useful
* when measured along with the other security components of a calendar
* system (e.g., calendar user authentication, authorization, access
* rights, access role, etc.). Hence, the semantics of the individual
* access classifications cannot be completely defined by this memo
* alone. Additionally, due to the "blind" nature of most exchange
* processes using this memo, these access classifications cannot serve
* as an enforcement statement for a system receiving an iCalendar
* object. Rather, they provide a method for capturing the intention of
* the calendar owner for the access to the calendar component.
*
* Format Definition: The property is defined by the following notation:
*
* class = "CLASS" classparam ":" classvalue CRLF
*
* classparam = *(";" xparam)
*
* classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token
* / x-name
* ;Default is PUBLIC
*
* Example: The following is an example of this property:
*
* CLASS:PUBLIC
*/
class qCal_Property_Class extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT', 'VTODO','VJOURNAL');
protected $default = "PUBLIC";
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Comment Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Purpose: This property specifies non-processing information intended
* to provide a comment to the calendar user.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: This property can be specified in "VEVENT", "VTODO",
* "VJOURNAL", "VTIMEZONE" or "VFREEBUSY" calendar components.
*
* Description: The property can be specified multiple times.
*
* Format Definition: The property is defined by the following notation:
*
* comment = "COMMENT" commparam ":" text CRLF
*
* commparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following is an example of this property:
*
* COMMENT:The meeting really needs to include both ourselves
* and the customer. We can't hold this meeting without them.
* As a matter of fact\, the venue for the meeting ought to be at
*
* their site. - - John
*
* The data type for this property is TEXT.
*/
class qCal_Property_Comment extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT', 'VTODO','VJOURNAL','VTIMEZONE','VFREEBUSY');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,41 @@
<?php
/**
* Completed Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: COMPLETED
*
* Purpose: This property defines the date and time that a to-do was
* actually completed.
*
* Value Type: DATE-TIME
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified in a "VTODO" calendar
* component.
*
* Description: The date and time MUST be in a UTC format.
*
* Format Definition: The property is defined by the following notation:
*
* completed = "COMPLETED" compparam ":" date-time CRLF
*
* compparam = *(";" xparam)
*
* Example: The following is an example of this property:
*
* COMPLETED:19960401T235959Z
*/
class qCal_Property_Completed extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VTODO');
}

View File

@ -0,0 +1,80 @@
<?php
/**
* Contact Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: CONTACT
*
* Purpose: The property is used to represent contact information or
* alternately a reference to contact information associated with the
* calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: The property can be specified in a "VEVENT", "VTODO",
* "VJOURNAL" or "VFREEBUSY" calendar component.
*
* Description: The property value consists of textual contact
* information. An alternative representation for the property value can
* also be specified that refers to a URI pointing to an alternate form,
* such as a vCard [RFC 2426], for the contact information.
*
* Format Definition: The property is defined by the following notation:
*
* contact = "CONTACT" contparam ":" text CRLF
*
* contparam = *(
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following is an example of this property referencing
* textual contact information:
*
* CONTACT:Jim Dolittle\, ABC Industries\, +1-919-555-1234
*
* The following is an example of this property with an alternate
* representation of a LDAP URI to a directory entry containing the
* contact information:
*
* CONTACT;ALTREP="ldap://host.com:6666/o=3DABC%20Industries\,
* c=3DUS??(cn=3DBJim%20Dolittle)":Jim Dolittle\, ABC Industries\,
* +1-919-555-1234
*
* The following is an example of this property with an alternate
* representation of a MIME body part containing the contact
* information, such as a vCard [RFC 2426] embedded in a [MIME-DIR]
* content-type:
*
* CONTACT;ALTREP="CID=<part3.msg970930T083000SILVER@host.com>":Jim
* Dolittle\, ABC Industries\, +1-919-555-1234
*
* The following is an example of this property referencing a network
* resource, such as a vCard [RFC 2426] object containing the contact
* information:
*
* CONTACT;ALTREP="http://host.com/pdi/jdoe.vcf":Jim
* Dolittle\, ABC Industries\, +1-919-555-1234
*/
class qCal_Property_Contact extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VFREEBUSY');
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Dated/Time Created Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: CREATED
*
* Purpose: This property specifies the date and time that the calendar
* information was created by the calendar user agent in the calendar
* store.
*
* Note: This is analogous to the creation date and time for a file
* in the file system.
*
* Value Type: DATE-TIME
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified once in "VEVENT", "VTODO"
* or "VJOURNAL" calendar components.
*
* Description: The date and time is a UTC value.
*
* Format Definition: The property is defined by the following notation:
*
* created = "CREATED" creaparam ":" date-time CRLF
*
* creaparam = *(";" xparam)
*
* Example: The following is an example of this property:
*
* CREATED:19960329T133000Z
*/
class qCal_Property_Created extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,72 @@
<?php
/**
* Description Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: DESCRIPTION
*
* Purpose: This property provides a more complete description of the
* calendar component, than that provided by the "SUMMARY" property.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: The property can be specified in the "VEVENT", "VTODO",
* "VJOURNAL" or "VALARM" calendar components. The property can be
* specified multiple times only within a "VJOURNAL" calendar component.
*
* Description: This property is used in the "VEVENT" and "VTODO" to
* capture lengthy textual decriptions associated with the activity.
*
* This property is used in the "VJOURNAL" calendar component to capture
* one more textual journal entries.
*
* This property is used in the "VALARM" calendar component to capture
* the display text for a DISPLAY category of alarm, to capture the body
* text for an EMAIL category of alarm and to capture the argument
* string for a PROCEDURE category of alarm.
*
* Format Definition: The property is defined by the following notation:
*
* description = "DESCRIPTION" descparam ":" text CRLF
*
* descparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following is an example of the property with formatted
* line breaks in the property value:
*
* DESCRIPTION:Meeting to provide technical review for "Phoenix"
* design.\n Happy Face Conference Room. Phoenix design team
* MUST attend this meeting.\n RSVP to team leader.
*
* The following is an example of the property with folding of long
* lines:
*
* DESCRIPTION:Last draft of the new novel is to be completed
* for the editor's proof today.
*/
class qCal_Property_Description extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT', 'VTODO','VJOURNAL','VALARM');
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Date/Time End Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Find a way of making sure that if there is a DTSTART, that its date
* is earlier than that of this property.
*
* RFC 2445 Definition
*
* Property Name: DTEND
*
* Purpose: This property specifies the date and time that a calendar
* component ends.
*
* Value Type: The default value type is DATE-TIME. The value type can
* be set to a DATE value type.
*
* Property Parameters: Non-standard, value data type, time zone
* identifier property parameters can be specified on this property.
*
* Conformance: This property can be specified in "VEVENT" or
* "VFREEBUSY" calendar components.
*
* Description: Within the "VEVENT" calendar component, this property
* defines the date and time by which the event ends. The value MUST be
* later in time than the value of the "DTSTART" property.
*
* Within the "VFREEBUSY" calendar component, this property defines the
* end date and time for the free or busy time information. The time
* MUST be specified in the UTC time format. The value MUST be later in
* time than the value of the "DTSTART" property.
*
* Format Definition: The property is defined by the following notation:
*
* dtend = "DTEND" dtendparam":" dtendval CRLF
*
* dtendparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
* (";" tzidparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* dtendval = date-time / date
* ;Value MUST match value type
*
* Example: The following is an example of this property:
*
* DTEND:19960401T235959Z
*
* DTEND;VALUE=DATE:19980704
*/
class qCal_Property_Dtend extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VFREEBUSY','DAYLIGHT','STANDARD');
}

View File

@ -0,0 +1,53 @@
<?php
/**
* Dated/Time Stamp Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that this is specified in UTC format.
*
* RFC 2445 Definition
*
* Property Name: DTSTAMP
*
* Purpose: The property indicates the date/time that the instance of
* the iCalendar object was created.
*
* Value Type: DATE-TIME
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be included in the "VEVENT", "VTODO",
* "VJOURNAL" or "VFREEBUSY" calendar components.
*
* Description: The value MUST be specified in the UTC time format.
*
* This property is also useful to protocols such as [IMIP] that have
* inherent latency issues with the delivery of content. This property
* will assist in the proper sequencing of messages containing iCalendar
* objects.
*
* This property is different than the "CREATED" and "LAST-MODIFIED"
* properties. These two properties are used to specify when the
* particular calendar data in the calendar store was created and last
* modified. This is different than when the iCalendar object
* representation of the calendar service information was created or
* last modified.
* Format Definition: The property is defined by the following notation:
*
* dtstamp = "DTSTAMP" stmparam ":" date-time CRLF
*
* stmparam = *(";" xparam)
*
* Example:
*
* DTSTAMP:19971210T080000Z
*/
class qCal_Property_Dtstamp extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VFREEBUSY');
}

View File

@ -0,0 +1,80 @@
<?php
/**
* Date/Time Start Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that if there is an DTEND property, its date is after
* this property's date.
*
* RFC 2445 Definition
*
* Property Name: DTSTART
*
* Purpose: This property specifies when the calendar component begins.
*
* Value Type: The default value type is DATE-TIME. The time value MUST
* be one of the forms defined for the DATE-TIME value type. The value
* type can be set to a DATE value type.
*
* Property Parameters: Non-standard, value data type, time zone
* identifier property parameters can be specified on this property.
*
* Conformance: This property can be specified in the "VEVENT", "VTODO",
* "VFREEBUSY", or "VTIMEZONE" calendar components.
*
* Description: Within the "VEVENT" calendar component, this property
* defines the start date and time for the event. The property is
* REQUIRED in "VEVENT" calendar components. Events can have a start
* date/time but no end date/time. In that case, the event does not take
* up any time.
*
* Within the "VFREEBUSY" calendar component, this property defines the
* start date and time for the free or busy time information. The time
* MUST be specified in UTC time.
*
* Within the "VTIMEZONE" calendar component, this property defines the
* effective start date and time for a time zone specification. This
* property is REQUIRED within each STANDARD and DAYLIGHT part included
* in "VTIMEZONE" calendar components and MUST be specified as a local
* DATE-TIME without the "TZID" property parameter.
*
* Format Definition: The property is defined by the following notation:
*
* dtstart = "DTSTART" dtstparam ":" dtstval CRLF
*
* dtstparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
* (";" tzidparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* *(";" xparam)
*
* )
*
* dtstval = date-time / date
* ;Value MUST match value type
*
* Example: The following is an example of this property:
*
* DTSTART:19980118T073000Z
*/
class qCal_Property_Dtstart extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VFREEBUSY','VTIMEZONE','VJOURNAL','STANDARD','DAYLIGHT');
/**
* Strange that in the notes for this, it says:
* Conformance: This property can be specified in the "VEVENT", "VTODO",
* "VFREEBUSY", or "VTIMEZONE" calendar components.
* But in the notes for journal it says that dtstart is allowed in a journal
*/
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Date/Time Due Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that the date of this is equal to or after the DTSTART
* date, if specified.
*
* RFC 2445 Definition
*
* Property Name: DUE
*
* Purpose: This property defines the date and time that a to-do is
* expected to be completed.
*
* Value Type: The default value type is DATE-TIME. The value type can
* be set to a DATE value type.
*
* Property Parameters: Non-standard, value data type, time zone
* identifier property parameters can be specified on this property.
*
* Conformance: The property can be specified once in a "VTODO" calendar
* component.
*
* Description: The value MUST be a date/time equal to or after the
* DTSTART value, if specified.
*
* Format Definition: The property is defined by the following notation:
*
* due = "DUE" dueparam":" dueval CRLF
*
* dueparam = *(
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
* (";" tzidparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* *(";" xparam)
*
* )
*
* dueval = date-time / date
* ;Value MUST match value type
*
* Example: The following is an example of this property:
*
* DUE:19980430T235959Z
*/
class qCal_Property_Due extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VTODO');
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Duration Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: DURATION
*
* Purpose: The property specifies a positive duration of time.
*
* Value Type: DURATION
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified in "VEVENT", "VTODO",
* "VFREEBUSY" or "VALARM" calendar components.
*
* Description: In a "VEVENT" calendar component the property may be
* used to specify a duration of the event, instead of an explicit end
* date/time. In a "VTODO" calendar component the property may be used
* to specify a duration for the to-do, instead of an explicit due
* date/time. In a "VFREEBUSY" calendar component the property may be
* used to specify the interval of free time being requested. In a
* "VALARM" calendar component the property may be used to specify the
* delay period prior to repeating an alarm.
*
* Format Definition: The property is defined by the following notation:
*
* duration = "DURATION" durparam ":" dur-value CRLF
* ;consisting of a positive duration of time.
*
* durparam = *(";" xparam)
*
* Example: The following is an example of this property that specifies
* an interval of time of 1 hour and zero minutes and zero seconds:
*
* DURATION:PT1H0M0S
*
* The following is an example of this property that specifies an
* interval of time of 15 minutes.
*
* DURATION:PT15M
*/
class qCal_Property_Duration extends qCal_Property {
protected $type = 'DURATION';
protected $allowedComponents = array('VEVENT','VTODO','VFREEBUSY','VALARM');
}

View File

@ -0,0 +1,85 @@
<?php
/**
* Exception Date/Times Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure allowedComponents is correct. The RFC isn't dead clear.
* Perhaps this means that it can be included in any component that
* includes an rdate or rrule property?
*
* RFC 2445 Definition
*
* Property Name: EXDATE
*
* Purpose: This property defines the list of date/time exceptions for a
* recurring calendar component.
*
* Value Type: The default value type for this property is DATE-TIME.
* The value type can be set to DATE.
*
* Property Parameters: Non-standard, value data type and time zone
* identifier property parameters can be specified on this property.
*
* Conformance: This property can be specified in an iCalendar object
* that includes a recurring calendar component.
*
* Description: The exception dates, if specified, are used in computing
* the recurrence set. The recurrence set is the complete set of
* recurrence instances for a calendar component. The recurrence set is
* generated by considering the initial "DTSTART" property along with
* the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
* within the iCalendar object. The "DTSTART" property defines the first
* instance in the recurrence set. Multiple instances of the "RRULE" and
* "EXRULE" properties can also be specified to define more
* sophisticated recurrence sets. The final recurrence set is generated
* by gathering all of the start date-times generated by any of the
* specified "RRULE" and "RDATE" properties, and then excluding any
* start date and times which fall within the union of start date and
* times generated by any specified "EXRULE" and "EXDATE" properties.
* This implies that start date and times within exclusion related
* properties (i.e., "EXDATE" and "EXRULE") take precedence over those
* specified by inclusion properties (i.e., "RDATE" and "RRULE"). Where
* duplicate instances are generated by the "RRULE" and "RDATE"
* properties, only one recurrence is considered. Duplicate instances
* are ignored.
*
* The "EXDATE" property can be used to exclude the value specified in
* "DTSTART". However, in such cases the original "DTSTART" date MUST
* still be maintained by the calendaring and scheduling system because
* the original "DTSTART" value has inherent usage dependencies by other
* properties such as the "RECURRENCE-ID".
*
* Format Definition: The property is defined by the following notation:
*
* exdate = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF
*
* exdtparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
* (";" tzidparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* exdtval = date-time / date
* ;Value MUST match value type
*
* Example: The following is an example of this property:
*
* EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z
*/
class qCal_Property_Exdate extends qCal_Property_MultiValue {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VTIMEZONE');
}

View File

@ -0,0 +1,78 @@
<?php
/**
* Exception Rule Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure allowedCompoents is correct. The RFC isn't dead clear
* See the todo for EXDATE
*
* RFC 2445 Definition
*
* Property Name: EXRULE
*
* Purpose: This property defines a rule or repeating pattern for an
* exception to a recurrence set.
*
* Value Type: RECUR
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in "VEVENT", "VTODO" or
* "VJOURNAL" calendar components.
*
* Description: The exception rule, if specified, is used in computing
* the recurrence set. The recurrence set is the complete set of
* recurrence instances for a calendar component. The recurrence set is
* generated by considering the initial "DTSTART" property along with
* the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
* within the iCalendar object. The "DTSTART" defines the first instance
* in the recurrence set. Multiple instances of the "RRULE" and "EXRULE"
* properties can also be specified to define more sophisticated
* recurrence sets. The final recurrence set is generated by gathering
* all of the start date-times generated by any of the specified "RRULE"
* and "RDATE" properties, and excluding any start date and times which
* fall within the union of start date and times generated by any
* specified "EXRULE" and "EXDATE" properties. This implies that start
* date and times within exclusion related properties (i.e., "EXDATE"
* and "EXRULE") take precedence over those specified by inclusion
*
*
* properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are
* generated by the "RRULE" and "RDATE" properties, only one recurrence
* is considered. Duplicate instances are ignored.
*
* The "EXRULE" property can be used to exclude the value specified in
* "DTSTART". However, in such cases the original "DTSTART" date MUST
* still be maintained by the calendaring and scheduling system because
* the original "DTSTART" value has inherent usage dependencies by other
* properties such as the "RECURRENCE-ID".
*
* Format Definition: The property is defined by the following notation:
*
* exrule = "EXRULE" exrparam ":" recur CRLF
*
* exrparam = *(";" xparam)
*
* Example: The following are examples of this property. Except every
* other week, on Tuesday and Thursday for 4 occurrences:
*
* EXRULE:FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH
*
* Except daily for 10 occurrences:
*
* EXRULE:FREQ=DAILY;COUNT=10
*
* Except yearly in June and July for 8 occurrences:
*
* EXRULE:FREQ=YEARLY;COUNT=8;BYMONTH=6,7
*/
class qCal_Property_Exrule extends qCal_Property {
protected $type = 'RECUR';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,78 @@
<?php
/**
* Free/Busy Time Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that values in the property are sorted as described below
*
* RFC 2445 Definition
*
* Property Name: FREEBUSY
*
* Purpose: The property defines one or more free or busy time
* intervals.
*
* Value Type: PERIOD. The date and time values MUST be in an UTC time
* format.
*
* Property Parameters: Non-standard or free/busy time type property
* parameters can be specified on this property.
*
* Conformance: The property can be specified in a "VFREEBUSY" calendar
* component.
*
* Property Parameter: "FBTYPE" and non-standard parameters can be
* specified on this property.
*
* Description: These time periods can be specified as either a start
* and end date-time or a start date-time and duration. The date and
* time MUST be a UTC time format.
*
* "FREEBUSY" properties within the "VFREEBUSY" calendar component
* SHOULD be sorted in ascending order, based on start time and then end
* time, with the earliest periods first.
*
* The "FREEBUSY" property can specify more than one value, separated by
* the COMMA character (US-ASCII decimal 44). In such cases, the
* "FREEBUSY" property values SHOULD all be of the same "FBTYPE"
* property parameter type (e.g., all values of a particular "FBTYPE"
* listed together in a single property).
*
* Format Definition: The property is defined by the following notation:
*
* freebusy = "FREEBUSY" fbparam ":" fbvalue
* CRLF
*
* fbparam = *(
* ; the following is optional,
* ; but MUST NOT occur more than once
*
* (";" fbtypeparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* fbvalue = period *["," period]
* ;Time value MUST be in the UTC time format.
*
* Example: The following are some examples of this property:
*
* FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:19970308T160000Z/PT8H30M
*
* FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H
*
* FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H,
* 19970308T230000Z/19970309T000000Z
*/
class qCal_Property_Freebusy extends qCal_Property_MultiValue {
protected $type = 'PERIOD';
protected $allowedComponents = array('VFREEBUSY');
}

View File

@ -0,0 +1,93 @@
<?php
/**
* Geographic Position Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: GEO
*
* Purpose: This property specifies information related to the global
* position for the activity specified by a calendar component.
*
* Value Type: FLOAT. The value MUST be two SEMICOLON separated FLOAT
* values.
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in "VEVENT" or "VTODO"
* calendar components.
*
* Description: The property value specifies latitude and longitude, in
* that order (i.e., "LAT LON" ordering). The longitude represents the
* location east or west of the prime meridian as a positive or negative
* real number, respectively. The longitude and latitude values MAY be
* specified up to six decimal places, which will allow for accuracy to
* within one meter of geographical position. Receiving applications
* MUST accept values of this precision and MAY truncate values of
* greater precision.
*
* Values for latitude and longitude shall be expressed as decimal
* fractions of degrees. Whole degrees of latitude shall be represented
* by a two-digit decimal number ranging from 0 through 90. Whole
* degrees of longitude shall be represented by a decimal number ranging
* from 0 through 180. When a decimal fraction of a degree is specified,
* it shall be separated from the whole number of degrees by a decimal
* point.
*
* Latitudes north of the equator shall be specified by a plus sign (+),
* or by the absence of a minus sign (-), preceding the digits
* designating degrees. Latitudes south of the Equator shall be
* designated by a minus sign (-) preceding the digits designating
* degrees. A point on the Equator shall be assigned to the Northern
* Hemisphere.
*
* Longitudes east of the prime meridian shall be specified by a plus
* sign (+), or by the absence of a minus sign (-), preceding the digits
* designating degrees. Longitudes west of the meridian shall be
* designated by minus sign (-) preceding the digits designating
* degrees. A point on the prime meridian shall be assigned to the
* Eastern Hemisphere. A point on the 180th meridian shall be assigned
* to the Western Hemisphere. One exception to this last convention is
* permitted. For the special condition of describing a band of latitude
* around the earth, the East Bounding Coordinate data element shall be
* assigned the value +180 (180) degrees.
*
* Any spatial address with a latitude of +90 (90) or -90 degrees will
* specify the position at the North or South Pole, respectively. The
* component for longitude may have any legal value.
*
* With the exception of the special condition described above, this
* form is specified in Department of Commerce, 1986, Representation of
* geographic point locations for information interchange (Federal
* Information Processing Standard 70-1): Washington, Department of
* Commerce, National Institute of Standards and Technology.
*
* The simple formula for converting degrees-minutes-seconds into
* decimal degrees is:
*
* decimal = degrees + minutes/60 + seconds/3600.
*
* Format Definition: The property is defined by the following notation:
*
* geo = "GEO" geoparam ":" geovalue CRLF
*
* geoparam = *(";" xparam)
*
* geovalue = float ";" float
* ;Latitude and Longitude components
*
* Example: The following is an example of this property:
*
* GEO:37.386013;-122.082932
*/
class qCal_Property_Geo extends qCal_Property {
protected $type = 'FLOAT';
protected $allowedComponents = array('VEVENT', 'VTODO');
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Last Modified Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that the date is converted to UTC
*
* RFC 2445 Definition
*
* Property Name: LAST-MODIFIED
*
* Purpose: The property specifies the date and time that the
* information associated with the calendar component was last revised
* in the calendar store.
*
* Note: This is analogous to the modification date and time for a
* file in the file system.
*
* Value Type: DATE-TIME
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in the "EVENT", "VTODO",
* "VJOURNAL" or "VTIMEZONE" calendar components.
*
* Description: The property value MUST be specified in the UTC time
* format.
*
* Format Definition: The property is defined by the following notation:
*
* last-mod = "LAST-MODIFIED" lstparam ":" date-time CRLF
*
* lstparam = *(";" xparam)
*
* Example: The following is are examples of this property:
*
* LAST-MODIFIED:19960817T133000Z
*/
class qCal_Property_LastModified extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VTIMEZONE');
}

View File

@ -0,0 +1,62 @@
<?php
/**
* Location Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
* Property Name: LOCATION
*
* Purpose: The property defines the intended venue for the activity
* defined by a calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: This property can be specified in "VEVENT" or "VTODO"
* calendar component.
*
* Description: Specific venues such as conference or meeting rooms may
* be explicitly specified using this property. An alternate
* representation may be specified that is a URI that points to
* directory information with more structured specification of the
* location. For example, the alternate representation may specify
* either an LDAP URI pointing to an LDAP server entry or a CID URI
* pointing to a MIME body part containing a vCard [RFC 2426] for the
* location.
*
* Format Definition: The property is defined by the following notation:
*
* location = "LOCATION locparam ":" text CRLF
*
* locparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following are some examples of this property:
*
* LOCATION:Conference Room - F123, Bldg. 002
*
* LOCATION;ALTREP="http://xyzcorp.com/conf-rooms/f123.vcf":
* Conference Room - F123, Bldg. 002
*/
class qCal_Property_Location extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT', 'VTODO');
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Method Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: METHOD
*
* Purpose: This property defines the iCalendar object method associated
* with the calendar object.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified in an iCalendar object.
*
* Description: When used in a MIME message entity, the value of this
* property MUST be the same as the Content-Type "method" parameter
* value. This property can only appear once within the iCalendar
* object. If either the "METHOD" property or the Content-Type "method"
* parameter is specified, then the other MUST also be specified.
*
* No methods are defined by this specification. This is the subject of
* other specifications, such as the iCalendar Transport-independent
*
* Interoperability Protocol (iTIP) defined by [ITIP].
*
* If this property is not present in the iCalendar object, then a
* scheduling transaction MUST NOT be assumed. In such cases, the
* iCalendar object is merely being used to transport a snapshot of some
* calendar information; without the intention of conveying a scheduling
* semantic.
*
* Format Definition: The property is defined by the following notation:
*
* method = "METHOD" metparam ":" metvalue CRLF
*
* metparam = *(";" xparam)
*
* metvalue = iana-token
*
* Example: The following is a hypothetical example of this property to
* convey that the iCalendar object is a request for a meeting:
*
* METHOD:REQUEST
*/
class qCal_Property_Method extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VCALENDAR');
}

View File

@ -0,0 +1,57 @@
<?php
/**
* Categories Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Property_MultiValue extends qCal_Property {
/**
* Property value
* @var qCal_Value object
*/
protected $value = array();
/**
* MultiValue properties contain an array of values rather than one, so we
* store them in an array and return them comma-separated.
*/
public function getValue() {
$return = array();
foreach ($this->value as $value) {
$return[] = $value->__toString();
}
return implode(chr(44), $return);
}
/**
* Sets the value of this property. Overwrites any previous values. Use addValue to
* add rather than overwrite.
* @todo I'm not sure I like how this is done. Eventually I will come back to it.
*/
public function setValue($value) {
if (!is_array($value)) {
$value = array($value);
}
// parent::setValue($value);
$this->value = array();
foreach ($value as $val) {
$this->value[] = $this->convertValue($val);
}
return $this;
}
/**
* Add a value to the array of values (rather than overwrite)
*/
public function addValue($value) {
$this->value[] = $this->convertValue($value);
return $this;
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* Non-standard Property(s)
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo I am not sure exactly how I plan on dealing with non-standard
* properties, but for now, I'm representing them with this class
* @todo Should this be a MultiValue?
* @todo Should this allow multiple instances?
*
* RFC 2445 Definition
*
* Property Name: Any property name with a "X-" prefix
*
* Purpose: This class of property provides a framework for defining
* non-standard properties.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard and language property parameters
* can be specified on this property.
*
* Conformance: This property can be specified in any calendar
* component.
*
* Description: The MIME Calendaring and Scheduling Content Type
* provides a "standard mechanism for doing non-standard things". This
* extension support is provided for implementers to "push the envelope"
* on the existing version of the memo. Extension properties are
* specified by property and/or property parameter names that have the
* prefix text of "X-" (the two character sequence: LATIN CAPITAL LETTER
* X character followed by the HYPEN-MINUS character). It is recommended
* that vendors concatenate onto this sentinel another short prefix text
* to identify the vendor. This will facilitate readability of the
* extensions and minimize possible collision of names between different
* vendors. User agents that support this content type are expected to
* be able to parse the extension properties and property parameters but
* can ignore them.
*
* At present, there is no registration authority for names of extension
* properties and property parameters. The data type for this property
* is TEXT. Optionally, the data type can be any of the other valid data
* types.
*
* Format Definition: The property is defined by the following notation:
*
* x-prop = x-name *(";" xparam) [";" languageparam] ":" text CRLF
* ; Lines longer than 75 octets should be folded
*
* Example: The following might be the ABC vendor's extension for an
* audio-clip form of subject property:
*
* X-ABC-MMSUBJ;X-ABC-MMSUBJTYPE=wave:http://load.noise.org/mysubj.wav
*/
class qCal_Property_NonStandard extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL',
'VALARM','VTIMEZONE','VFREEBUSY','VCALENDAR');
protected $allowMultiple = true;
public function __construct($value, $params, $name) {
parent::__construct($value, $params);
$this->name = strtoupper($name);
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* Organizer Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: ORGANIZER
*
* Purpose: The property defines the organizer for a calendar component.
*
* Value Type: CAL-ADDRESS
*
* Property Parameters: Non-standard, language, common name, directory
* entry reference, sent by property parameters can be specified on this
* property.
*
* Conformance: This property MUST be specified in an iCalendar object
* that specifies a group scheduled calendar entity. This property MUST
* be specified in an iCalendar object that specifies the publication of
* a calendar user's busy time. This property MUST NOT be specified in
* an iCalendar object that specifies only a time zone definition or
* that defines calendar entities that are not group scheduled entities,
* but are entities only on a single user's calendar.
*
* Description: The property is specified within the "VEVENT", "VTODO",
* "VJOURNAL calendar components to specify the organizer of a group
* scheduled calendar entity. The property is specified within the
* "VFREEBUSY" calendar component to specify the calendar user
* requesting the free or busy time. When publishing a "VFREEBUSY"
* calendar component, the property is used to specify the calendar that
* the published busy time came from.
*
* The property has the property parameters CN, for specifying the
* common or display name associated with the "Organizer", DIR, for
* specifying a pointer to the directory information associated with the
* "Organizer", SENT-BY, for specifying another calendar user that is
* acting on behalf of the "Organizer". The non-standard parameters may
* also be specified on this property. If the LANGUAGE property
* parameter is specified, the identified language applies to the CN
* parameter value.
*
* Format Definition: The property is defined by the following notation:
*
* organizer = "ORGANIZER" orgparam ":"
* cal-address CRLF
*
* orgparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" cnparam) / (";" dirparam) / (";" sentbyparam) /
* (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following is an example of this property:
*
* ORGANIZER;CN=John Smith:MAILTO:jsmith@host1.com
*
* The following is an example of this property with a pointer to the
* directory information associated with the organizer:
*
* ORGANIZER;CN=JohnSmith;DIR="ldap://host.com:6666/o=3DDC%20Associ
* ates,c=3DUS??(cn=3DJohn%20Smith)":MAILTO:jsmith@host1.com
*
* The following is an example of this property used by another calendar
* user who is acting on behalf of the organizer, with responses
* intended to be sent back to the organizer, not the other calendar
* user:
*
* ORGANIZER;SENT-BY="MAILTO:jane_doe@host.com":
* MAILTO:jsmith@host1.com
*/
class qCal_Property_Organizer extends qCal_Property {
protected $type = 'CAL-ADDRESS';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,55 @@
<?php
/**
* Percent Complete Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Should this default to zero?
*
* RFC 2445 Definition
*
* Property Name: PERCENT-COMPLETE
*
* Purpose: This property is used by an assignee or delegatee of a to-do
* to convey the percent completion of a to-do to the Organizer.
*
* Value Type: INTEGER
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in a "VTODO" calendar
* component.
*
* Description: The property value is a positive integer between zero
* and one hundred. A value of "0" indicates the to-do has not yet been
* started. A value of "100" indicates that the to-do has been
* completed. Integer values in between indicate the percent partially
* complete.
*
* When a to-do is assigned to multiple individuals, the property value
* indicates the percent complete for that portion of the to-do assigned
* to the assignee or delegatee. For example, if a to-do is assigned to
* both individuals "A" and "B". A reply from "A" with a percent
* complete of "70" indicates that "A" has completed 70% of the to-do
* assigned to them. A reply from "B" with a percent complete of "50"
* indicates "B" has completed 50% of the to-do assigned to them.
*
* Format Definition: The property is defined by the following notation:
*
* percent = "PERCENT-COMPLETE" pctparam ":" integer CRLF
*
* pctparam = *(";" xparam)
*
* Example: The following is an example of this property to show 39%
* completion:
*
* PERCENT-COMPLETE:39
*/
class qCal_Property_PercentComplete extends qCal_Property {
protected $type = 'INTEGER';
protected $allowedComponents = array('VTODO');
}

View File

@ -0,0 +1,87 @@
<?php
/**
* Priority Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: PRIORITY
*
* Purpose: The property defines the relative priority for a calendar
* component.
*
* Value Type: INTEGER
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified in a "VEVENT" or "VTODO"
* calendar component.
*
* Description: The priority is specified as an integer in the range
* zero to nine. A value of zero (US-ASCII decimal 48) specifies an
* undefined priority. A value of one (US-ASCII decimal 49) is the
* highest priority. A value of two (US-ASCII decimal 50) is the second
* highest priority. Subsequent numbers specify a decreasing ordinal
* priority. A value of nine (US-ASCII decimal 58) is the lowest
* priority.
*
* A CUA with a three-level priority scheme of "HIGH", "MEDIUM" and
* "LOW" is mapped into this property such that a property value in the
* range of one (US-ASCII decimal 49) to four (US-ASCII decimal 52)
* specifies "HIGH" priority. A value of five (US-ASCII decimal 53) is
* the normal or "MEDIUM" priority. A value in the range of six (US-
* ASCII decimal 54) to nine (US-ASCII decimal 58) is "LOW" priority.
*
* A CUA with a priority schema of "A1", "A2", "A3", "B1", "B2", ...,
* "C3" is mapped into this property such that a property value of one
* (US-ASCII decimal 49) specifies "A1", a property value of two (US-
* ASCII decimal 50) specifies "A2", a property value of three (US-ASCII
* decimal 51) specifies "A3", and so forth up to a property value of 9
* (US-ASCII decimal 58) specifies "C3".
*
* Other integer values are reserved for future use.
*
* Within a "VEVENT" calendar component, this property specifies a
* priority for the event. This property may be useful when more than
* one event is scheduled for a given time period.
*
* Within a "VTODO" calendar component, this property specified a
* priority for the to-do. This property is useful in prioritizing
* multiple action items for a given time period.
*
* Format Definition: The property is specified by the following
* notation:
*
* priority = "PRIORITY" prioparam ":" privalue CRLF
* ;Default is zero
*
* prioparam = *(";" xparam)
*
* privalue = integer ;Must be in the range [0..9]
* ; All other values are reserved for future use
*
* The following is an example of a property with the highest priority:
*
* PRIORITY:1
*
* The following is an example of a property with a next highest
* priority:
*
* PRIORITY:2
*
* Example: The following is an example of a property with no priority.
* This is equivalent to not specifying the "PRIORITY" property:
*
* PRIORITY:0
*/
class qCal_Property_Priority extends qCal_Property {
protected $type = 'INTEGER';
protected $allowedComponents = array('VEVENT','VTODO');
protected $default = 0;
}

View File

@ -0,0 +1,57 @@
<?php
/**
* Product Identifier Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Find a way to make sure that this is a globally unique id
* @todo I don't want my name in the default for this. Actually, I'm not even
* sure I want this property to have a default.
*
* RFC 2445 Definition
*
* Property Name: PRODID
*
* Purpose: This property specifies the identifier for the product that
* created the iCalendar object.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property MUST be specified once in an iCalendar
* object.
*
* Description: The vendor of the implementation SHOULD assure that this
* is a globally unique identifier; using some technique such as an FPI
* value, as defined in [ISO 9070].
*
* This property SHOULD not be used to alter the interpretation of an
* iCalendar object beyond the semantics specified in this memo. For
* example, it is not to be used to further the understanding of non-
* standard properties.
*
* Format Definition: The property is defined by the following notation:
*
* prodid = "PRODID" pidparam ":" pidvalue CRLF
*
* pidparam = *(";" xparam)
*
* pidvalue = text
* ;Any text that describes the product and version
* ;and that is generally assured of being unique.
*
* Example: The following is an example of this property. It does not
* imply that English is the default language.
*
* PRODID:-//ABC Corporation//NONSGML My Product//EN
*/
class qCal_Property_Prodid extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VCALENDAR');
protected $default = "-//Luke Visinoni//qCal v0.1//EN";
}

View File

@ -0,0 +1,89 @@
<?php
/**
* Recurrence Date/Times Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure allowedCompoents is correct. The RFC isn't dead clear
*
* RFC 2445 Definition
*
* Property Name: RDATE
*
* Purpose: This property defines the list of date/times for a
* recurrence set.
*
* Value Type: The default value type for this property is DATE-TIME.
* The value type can be set to DATE or PERIOD.
*
* Property Parameters: Non-standard, value data type and time zone
* identifier property parameters can be specified on this property.
*
* Conformance: The property can be specified in "VEVENT", "VTODO",
* "VJOURNAL" or "VTIMEZONE" calendar components.
*
* Description: This property can appear along with the "RRULE" property
* to define an aggregate set of repeating occurrences. When they both
* appear in an iCalendar object, the recurring events are defined by
* the union of occurrences defined by both the "RDATE" and "RRULE".
*
* The recurrence dates, if specified, are used in computing the
* recurrence set. The recurrence set is the complete set of recurrence
* instances for a calendar component. The recurrence set is generated
* by considering the initial "DTSTART" property along with the "RRULE",
* "RDATE", "EXDATE" and "EXRULE" properties contained within the
* iCalendar object. The "DTSTART" property defines the first instance
* in the recurrence set. Multiple instances of the "RRULE" and "EXRULE"
* properties can also be specified to define more sophisticated
* recurrence sets. The final recurrence set is generated by gathering
* all of the start date/times generated by any of the specified "RRULE"
* and "RDATE" properties, and excluding any start date/times which fall
* within the union of start date/times generated by any specified
* "EXRULE" and "EXDATE" properties. This implies that start date/times
* within exclusion related properties (i.e., "EXDATE" and "EXRULE")
* take precedence over those specified by inclusion properties (i.e.,
* "RDATE" and "RRULE"). Where duplicate instances are generated by the
* "RRULE" and "RDATE" properties, only one recurrence is considered.
* Duplicate instances are ignored.
*
* Format Definition: The property is defined by the following notation:
*
* rdate = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF
*
* rdtparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE" / "PERIOD")) /
* (";" tzidparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* rdtval = date-time / date / period
* ;Value MUST match value type
*
* Example: The following are examples of this property:
*
* RDATE:19970714T123000Z
*
* RDATE;TZID=US-EASTERN:19970714T083000
*
* RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z,
* 19960404T010000Z/PT3H
*
* RDATE;VALUE=DATE:19970101,19970120,19970217,19970421
* 19970526,19970704,19970901,19971014,19971128,19971129,19971225
*/
class qCal_Property_Rdate extends qCal_Property_MultiValue {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VTIMEZONE');
}

View File

@ -0,0 +1,96 @@
<?php
/**
* Recurrence Id Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo This has some pretty specific rules as to how it is to be used.
* Make sure that all of them are considered.
*
* RFC 2445 Definition
*
* Property Name: RECURRENCE-ID
*
* Purpose: This property is used in conjunction with the "UID" and
* "SEQUENCE" property to identify a specific instance of a recurring
* "VEVENT", "VTODO" or "VJOURNAL" calendar component. The property
* value is the effective value of the "DTSTART" property of the
* recurrence instance.
*
* Value Type: The default value type for this property is DATE-TIME.
* The time format can be any of the valid forms defined for a DATE-TIME
* value type. See DATE-TIME value type definition for specific
* interpretations of the various forms. The value type can be set to
* DATE.
*
* Property Parameters: Non-standard property, value data type, time
* zone identifier and recurrence identifier range parameters can be
* specified on this property.
*
* Conformance: This property can be specified in an iCalendar object
* containing a recurring calendar component.
*
* Description: The full range of calendar components specified by a
* recurrence set is referenced by referring to just the "UID" property
* value corresponding to the calendar component. The "RECURRENCE-ID"
* property allows the reference to an individual instance within the
* recurrence set.
*
* If the value of the "DTSTART" property is a DATE type value, then the
* value MUST be the calendar date for the recurrence instance.
*
* The date/time value is set to the time when the original recurrence
* instance would occur; meaning that if the intent is to change a
* Friday meeting to Thursday, the date/time is still set to the
* original Friday meeting.
*
* The "RECURRENCE-ID" property is used in conjunction with the "UID"
* and "SEQUENCE" property to identify a particular instance of a
* recurring event, to-do or journal. For a given pair of "UID" and
* "SEQUENCE" property values, the "RECURRENCE-ID" value for a
* recurrence instance is fixed. When the definition of the recurrence
* set for a calendar component changes, and hence the "SEQUENCE"
* property value changes, the "RECURRENCE-ID" for a given recurrence
* instance might also change.The "RANGE" parameter is used to specify
* the effective range of recurrence instances from the instance
* specified by the "RECURRENCE-ID" property value. The default value
* for the range parameter is the single recurrence instance only. The
* value can also be "THISANDPRIOR" to indicate a range defined by the
* given recurrence instance and all prior instances or the value can be
* "THISANDFUTURE" to indicate a range defined by the given recurrence
* instance and all subsequent instances.
*
* Format Definition: The property is defined by the following notation:
*
* recurid = "RECURRENCE-ID" ridparam ":" ridval CRLF
*
* ridparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" ("DATE-TIME" / "DATE)) /
* (";" tzidparam) / (";" rangeparam) /
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* ridval = date-time / date
* ;Value MUST match value type
*
* Example: The following are examples of this property:
*
* RECURRENCE-ID;VALUE=DATE:19960401
*
* RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z
*/
class qCal_Property_RecurrenceId extends qCal_Property {
protected $type = 'DATE-TIME';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,82 @@
<?php
/**
* Related To Id Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: RELATED-TO
*
* Purpose: The property is used to represent a relationship or
* reference between one calendar component and another.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard and relationship type property
* parameters can be specified on this property.
*
* Conformance: The property can be specified one or more times in the
* "VEVENT", "VTODO" or "VJOURNAL" calendar components.
*
* Description: The property value consists of the persistent, globally
* unique identifier of another calendar component. This value would be
* represented in a calendar component by the "UID" property.
*
* By default, the property value points to another calendar component
* that has a PARENT relationship to the referencing object. The
* "RELTYPE" property parameter is used to either explicitly state the
* default PARENT relationship type to the referenced calendar component
* or to override the default PARENT relationship type and specify
* either a CHILD or SIBLING relationship. The PARENT relationship
* indicates that the calendar component is a subordinate of the
* referenced calendar component. The CHILD relationship indicates that
* the calendar component is a superior of the referenced calendar
* component. The SIBLING relationship indicates that the calendar
* component is a peer of the referenced calendar component.
*
*
* Changes to a calendar component referenced by this property can have
* an implicit impact on the related calendar component. For example, if
* a group event changes its start or end date or time, then the
* related, dependent events will need to have their start and end dates
* changed in a corresponding way. Similarly, if a PARENT calendar
* component is canceled or deleted, then there is an implied impact to
* the related CHILD calendar components. This property is intended only
* to provide information on the relationship of calendar components. It
* is up to the target calendar system to maintain any property
* implications of this relationship.
*
* Format Definition: The property is defined by the following notation:
*
* related = "RELATED-TO" [relparam] ":" text CRLF
*
* relparam = *(
*
* ; the following is optional,
* ; but MUST NOT occur more than once
*
* (";" reltypeparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparm)
*
* )
*
* The following is an example of this property:
*
* RELATED-TO:<jsmith.part7.19960817T083000.xyzMail@host3.com>
*
* RELATED-TO:<19960401-080045-4000F192713-0052@host1.com>
*/
class qCal_Property_RecurrenceId extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Repeat Count Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that if the alarm triggers more than once, that this
* specifies a duration property.
*
* RFC 2445 Definition
*
* Property Name: REPEAT
*
* Purpose: This property defines the number of time the alarm should be
* repeated, after the initial trigger.
* Value Type: INTEGER
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in a "VALARM" calendar
* component.
*
* Description: If the alarm triggers more than once, then this property
* MUST be specified along with the "DURATION" property.
*
* Format Definition: The property is defined by the following notation:
*
* repeatcnt = "REPEAT" repparam ":" integer CRLF
* ;Default is "0", zero.
*
* repparam = *(";" xparam)
*
* Example: The following is an example of this property for an alarm
* that repeats 4 additional times with a 5 minute delay after the
* initial triggering of the alarm:
*
* REPEAT:4
* DURATION:PT5M
*/
class qCal_Property_Repeat extends qCal_Property {
protected $type = 'INTEGER';
protected $allowedComponents = array('VALARM');
}

View File

@ -0,0 +1,124 @@
<?php
/**
* Request Status Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo This allows some strange stuff in its value. Make sure that it won't
* break the parser.
* @todo This allows the specification of "components" within the text. I will
* need to figure out how to deal with these.
*
* RFC 2445 Definition
*
* Property Name: REQUEST-STATUS
*
* Purpose: This property defines the status code returned for a
* scheduling request.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard and language property parameters
* can be specified on this property.
*
* Conformance: The property can be specified in "VEVENT", "VTODO",
* "VJOURNAL" or "VFREEBUSY" calendar component.
*
* Description: This property is used to return status code information
* related to the processing of an associated iCalendar object. The data
* type for this property is TEXT.
*
* The value consists of a short return status component, a longer
* return status description component, and optionally a status-specific
* data component. The components of the value are separated by the
* SEMICOLON character (US-ASCII decimal 59).
* The short return status is a PERIOD character (US-ASCII decimal 46)
* separated 3-tuple of integers. For example, "3.1.1". The successive
* levels of integers provide for a successive level of status code
* granularity.
*
* The following are initial classes for the return status code.
* Individual iCalendar object methods will define specific return
* status codes for these classes. In addition, other classes for the
* return status code may be defined using the registration process
* defined later in this memo.
*
* |==============+===============================================|
* | Short Return | Longer Return Status Description |
* | Status Code | |
* |==============+===============================================|
* | 1.xx | Preliminary success. This class of status |
* | | of status code indicates that the request has |
* | | request has been initially processed but that |
* | | completion is pending. |
* |==============+===============================================|
* | 2.xx | Successful. This class of status code |
* | | indicates that the request was completed |
* | | successfuly. However, the exact status code |
* | | can indicate that a fallback has been taken. |
* |==============+===============================================|
* | 3.xx | Client Error. This class of status code |
* | | indicates that the request was not successful.|
* | | The error is the result of either a syntax or |
* | | a semantic error in the client formatted |
* | | request. Request should not be retried until |
* | | the condition in the request is corrected. |
* |==============+===============================================|
* | 4.xx | Scheduling Error. This class of status code |
* | | indicates that the request was not successful.|
* | | Some sort of error occurred within the |
* | | calendaring and scheduling service, not |
* | | directly related to the request itself. |
* |==============+===============================================|
*
* Format Definition: The property is defined by the following notation:
*
* rstatus = "REQUEST-STATUS" rstatparam ":"
* statcode ";" statdesc [";" extdata]
*
* rstatparam = *(
*
* ; the following is optional,
* ; but MUST NOT occur more than once
* (";" languageparm) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* statcode = 1*DIGIT *("." 1*DIGIT)
* ;Hierarchical, numeric return status code
*
* statdesc = text
* ;Textual status description
*
* extdata = text
* ;Textual exception data. For example, the offending property
* ;name and value or complete property line.
*
* Example: The following are some possible examples of this property.
* The COMMA and SEMICOLON separator characters in the property value
* are BACKSLASH character escaped because they appear in a text value.
*
* REQUEST-STATUS:2.0;Success
*
* REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01
*
* REQUEST-STATUS:2.8; Success\, repeating event ignored. Scheduled
* as a single event.;RRULE:FREQ=WEEKLY\;INTERVAL=2
*
* REQUEST-STATUS:4.1;Event conflict. Date/time is busy.
*
* REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:
* MAILTO:jsmith@host.com
*/
class qCal_Property_Sequence extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VFREEBUSY');
}

View File

@ -0,0 +1,59 @@
<?php
/**
* Resources Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: RESOURCES
*
* Purpose: This property defines the equipment or resources anticipated
* for an activity specified by a calendar entity..
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: This property can be specified in "VEVENT" or "VTODO"
* calendar component.
*
* Description: The property value is an arbitrary text. More than one
* resource can be specified as a list of resources separated by the
* COMMA character (US-ASCII decimal 44).
*
* Format Definition: The property is defined by the following notation:
*
* resources = "RESOURCES" resrcparam ":" text *("," text) CRLF
*
* resrcparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
*
*
* (";" xparam)
*
* )
*
* Example: The following is an example of this property:
*
* RESOURCES:EASEL,PROJECTOR,VCR
*
* RESOURCES;LANGUAGE=fr:1 raton-laveur
*/
class qCal_Property_Resources extends qCal_Property_MultiValue {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO');
}

View File

@ -0,0 +1,442 @@
<?php
/**
* Recurrence Rule Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure allowedCompoents is correct. The RFC isn't dead clear
* @todo There are a lot of rules for this guy. Make sure you take them all
* into consideration and conform to the shit below.
* @todo This property doesn't require a value. Make sure it is possible to
* render the property without the colon that comes between name, params and value
*
* RFC 2445 Definition
*
* Property Name: RRULE
*
* Purpose: This property defines a rule or repeating pattern for
* recurring events, to-dos, or time zone definitions.
*
* Value Type: RECUR
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified one or more times in
* recurring "VEVENT", "VTODO" and "VJOURNAL" calendar components. It
* can also be specified once in each STANDARD or DAYLIGHT sub-component
* of the "VTIMEZONE" calendar component.
*
* Description: The recurrence rule, if specified, is used in computing
* the recurrence set. The recurrence set is the complete set of
* recurrence instances for a calendar component. The recurrence set is
* generated by considering the initial "DTSTART" property along with
* the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
* within the iCalendar object. The "DTSTART" property defines the first
* instance in the recurrence set. Multiple instances of the "RRULE" and
* "EXRULE" properties can also be specified to define more
* sophisticated recurrence sets. The final recurrence set is generated
* by gathering all of the start date/times generated by any of the
* specified "RRULE" and "RDATE" properties, and excluding any start
* date/times which fall within the union of start date/times generated
* by any specified "EXRULE" and "EXDATE" properties. This implies that
* start date/times within exclusion related properties (i.e., "EXDATE"
* and "EXRULE") take precedence over those specified by inclusion
* properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are
* generated by the "RRULE" and "RDATE" properties, only one recurrence
* is considered. Duplicate instances are ignored.
*
*
*
* The "DTSTART" and "DTEND" property pair or "DTSTART" and "DURATION"
* property pair, specified within the iCalendar object defines the
* first instance of the recurrence. When used with a recurrence rule,
* the "DTSTART" and "DTEND" properties MUST be specified in local time
* and the appropriate set of "VTIMEZONE" calendar components MUST be
* included. For detail on the usage of the "VTIMEZONE" calendar
* component, see the "VTIMEZONE" calendar component definition.
*
* Any duration associated with the iCalendar object applies to all
* members of the generated recurrence set. Any modified duration for
* specific recurrences MUST be explicitly specified using the "RDATE"
* property.
*
* Format Definition: This property is defined by the following
* notation:
*
* rrule = "RRULE" rrulparam ":" recur CRLF
*
* rrulparam = *(";" xparam)
*
* Example: All examples assume the Eastern United States time zone.
*
* Daily for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=DAILY;COUNT=10
*
* ==> (1997 9:00 AM EDT)September 2-11
*
* Daily until December 24, 1997:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=DAILY;UNTIL=19971224T000000Z
*
* ==> (1997 9:00 AM EDT)September 2-30;October 1-25
* (1997 9:00 AM EST)October 26-31;November 1-30;December 1-23
*
* Every other day - forever:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=DAILY;INTERVAL=2
* ==> (1997 9:00 AM EDT)September2,4,6,8...24,26,28,30;
* October 2,4,6...20,22,24
* (1997 9:00 AM EST)October 26,28,30;November 1,3,5,7...25,27,29;
* Dec 1,3,...
*
* Every 10 days, 5 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
*
* ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12
*
* Everyday in January, for 3 years:
*
* DTSTART;TZID=US-Eastern:19980101T090000
* RRULE:FREQ=YEARLY;UNTIL=20000131T090000Z;
* BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
* or
* RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1
*
* ==> (1998 9:00 AM EDT)January 1-31
* (1999 9:00 AM EDT)January 1-31
* (2000 9:00 AM EDT)January 1-31
*
* Weekly for 10 occurrences
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;COUNT=10
*
* ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
* (1997 9:00 AM EST)October 28;November 4
*
* Weekly until December 24, 1997
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
*
* ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
* (1997 9:00 AM EST)October 28;November 4,11,18,25;
* December 2,9,16,23
* Every other week - forever:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=SU
*
* ==> (1997 9:00 AM EDT)September 2,16,30;October 14
* (1997 9:00 AM EST)October 28;November 11,25;December 9,23
* (1998 9:00 AM EST)January 6,20;February
* ...
*
* Weekly on Tuesday and Thursday for 5 weeks:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH
* or
* RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH
*
* ==> (1997 9:00 AM EDT)September 2,4,9,11,16,18,23,25,30;October 2
*
* Every other week on Monday, Wednesday and Friday until December 24,
* 1997, but starting on Tuesday, September 2, 1997:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;
* BYDAY=MO,WE,FR
* ==> (1997 9:00 AM EDT)September 2,3,5,15,17,19,29;October
* 1,3,13,15,17
* (1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28;
* December 8,10,12,22
*
* Every other week on Tuesday and Thursday, for 8 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH
*
* ==> (1997 9:00 AM EDT)September 2,4,16,18,30;October 2,14,16
*
* Monthly on the 1st Friday for ten occurrences:
*
* DTSTART;TZID=US-Eastern:19970905T090000
* RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
*
* ==> (1997 9:00 AM EDT)September 5;October 3
* (1997 9:00 AM EST)November 7;Dec 5
* (1998 9:00 AM EST)January 2;February 6;March 6;April 3
* (1998 9:00 AM EDT)May 1;June 5
*
* Monthly on the 1st Friday until December 24, 1997:
*
* DTSTART;TZID=US-Eastern:19970905T090000
* RRULE:FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR
*
* ==> (1997 9:00 AM EDT)September 5;October 3
* (1997 9:00 AM EST)November 7;December 5
*
* Every other month on the 1st and last Sunday of the month for 10
* occurrences:
*
* DTSTART;TZID=US-Eastern:19970907T090000
* RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
*
* ==> (1997 9:00 AM EDT)September 7,28
* (1997 9:00 AM EST)November 2,30
* (1998 9:00 AM EST)January 4,25;March 1,29
* (1998 9:00 AM EDT)May 3,31
*
* Monthly on the second to last Monday of the month for 6 months:
*
* DTSTART;TZID=US-Eastern:19970922T090000
* RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO
*
* ==> (1997 9:00 AM EDT)September 22;October 20
* (1997 9:00 AM EST)November 17;December 22
* (1998 9:00 AM EST)January 19;February 16
*
* Monthly on the third to the last day of the month, forever:
*
* DTSTART;TZID=US-Eastern:19970928T090000
* RRULE:FREQ=MONTHLY;BYMONTHDAY=-3
*
* ==> (1997 9:00 AM EDT)September 28
* (1997 9:00 AM EST)October 29;November 28;December 29
* (1998 9:00 AM EST)January 29;February 26
* ...
*
* Monthly on the 2nd and 15th of the month for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
*
* ==> (1997 9:00 AM EDT)September 2,15;October 2,15
* (1997 9:00 AM EST)November 2,15;December 2,15
* (1998 9:00 AM EST)January 2,15
*
* Monthly on the first and last day of the month for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970930T090000
* RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1
*
* ==> (1997 9:00 AM EDT)September 30;October 1
* (1997 9:00 AM EST)October 31;November 1,30;December 1,31
* (1998 9:00 AM EST)January 1,31;February 1
*
* Every 18 months on the 10th thru 15th of the month for 10
* occurrences:
*
* DTSTART;TZID=US-Eastern:19970910T090000
* RRULE:FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,
* 15
*
* ==> (1997 9:00 AM EDT)September 10,11,12,13,14,15
* (1999 9:00 AM EST)March 10,11,12,13
*
* Every Tuesday, every other month:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=TU
*
* ==> (1997 9:00 AM EDT)September 2,9,16,23,30
* (1997 9:00 AM EST)November 4,11,18,25
* (1998 9:00 AM EST)January 6,13,20,27;March 3,10,17,24,31
* ...
*
* Yearly in June and July for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970610T090000
* RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=6,7
* ==> (1997 9:00 AM EDT)June 10;July 10
* (1998 9:00 AM EDT)June 10;July 10
* (1999 9:00 AM EDT)June 10;July 10
* (2000 9:00 AM EDT)June 10;July 10
* (2001 9:00 AM EDT)June 10;July 10
* Note: Since none of the BYDAY, BYMONTHDAY or BYYEARDAY components
* are specified, the day is gotten from DTSTART
*
* Every other year on January, February, and March for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970310T090000
* RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3
*
* ==> (1997 9:00 AM EST)March 10
* (1999 9:00 AM EST)January 10;February 10;March 10
* (2001 9:00 AM EST)January 10;February 10;March 10
* (2003 9:00 AM EST)January 10;February 10;March 10
*
* Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:
*
* DTSTART;TZID=US-Eastern:19970101T090000
* RRULE:FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200
*
* ==> (1997 9:00 AM EST)January 1
* (1997 9:00 AM EDT)April 10;July 19
* (2000 9:00 AM EST)January 1
* (2000 9:00 AM EDT)April 9;July 18
* (2003 9:00 AM EST)January 1
* (2003 9:00 AM EDT)April 10;July 19
* (2006 9:00 AM EST)January 1
*
* Every 20th Monday of the year, forever:
* DTSTART;TZID=US-Eastern:19970519T090000
* RRULE:FREQ=YEARLY;BYDAY=20MO
*
* ==> (1997 9:00 AM EDT)May 19
* (1998 9:00 AM EDT)May 18
* (1999 9:00 AM EDT)May 17
* ...
*
* Monday of week number 20 (where the default start of the week is
* Monday), forever:
*
* DTSTART;TZID=US-Eastern:19970512T090000
* RRULE:FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO
*
* ==> (1997 9:00 AM EDT)May 12
* (1998 9:00 AM EDT)May 11
* (1999 9:00 AM EDT)May 17
* ...
*
* Every Thursday in March, forever:
*
* DTSTART;TZID=US-Eastern:19970313T090000
* RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=TH
*
* ==> (1997 9:00 AM EST)March 13,20,27
* (1998 9:00 AM EST)March 5,12,19,26
* (1999 9:00 AM EST)March 4,11,18,25
* ...
*
* Every Thursday, but only during June, July, and August, forever:
*
* DTSTART;TZID=US-Eastern:19970605T090000
* RRULE:FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8
*
* ==> (1997 9:00 AM EDT)June 5,12,19,26;July 3,10,17,24,31;
* August 7,14,21,28
* (1998 9:00 AM EDT)June 4,11,18,25;July 2,9,16,23,30;
* August 6,13,20,27
* (1999 9:00 AM EDT)June 3,10,17,24;July 1,8,15,22,29;
* August 5,12,19,26
* ...
*
* Every Friday the 13th, forever:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* EXDATE;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
*
* ==> (1998 9:00 AM EST)February 13;March 13;November 13
* (1999 9:00 AM EDT)August 13
* (2000 9:00 AM EDT)October 13
* ...
*
* The first Saturday that follows the first Sunday of the month,
* forever:
*
* DTSTART;TZID=US-Eastern:19970913T090000
* RRULE:FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13
*
* ==> (1997 9:00 AM EDT)September 13;October 11
* (1997 9:00 AM EST)November 8;December 13
* (1998 9:00 AM EST)January 10;February 7;March 7
* (1998 9:00 AM EDT)April 11;May 9;June 13...
* ...
*
* Every four years, the first Tuesday after a Monday in November,
* forever (U.S. Presidential Election day):
*
* DTSTART;TZID=US-Eastern:19961105T090000
* RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,
* 5,6,7,8
*
* ==> (1996 9:00 AM EST)November 5
* (2000 9:00 AM EST)November 7
* (2004 9:00 AM EST)November 2
* ...
*
* The 3rd instance into the month of one of Tuesday, Wednesday or
* Thursday, for the next 3 months:
*
* DTSTART;TZID=US-Eastern:19970904T090000
* RRULE:FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3
*
* ==> (1997 9:00 AM EDT)September 4;October 7
* (1997 9:00 AM EST)November 6
*
* The 2nd to last weekday of the month:
*
* DTSTART;TZID=US-Eastern:19970929T090000
* RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2
*
* ==> (1997 9:00 AM EDT)September 29
* (1997 9:00 AM EST)October 30;November 27;December 30
* (1998 9:00 AM EST)January 29;February 26;March 30
* ...
*
* Every 3 hours from 9:00 AM to 5:00 PM on a specific day:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z
*
* ==> (September 2, 1997 EDT)09:00,12:00,15:00
*
* Every 15 minutes for 6 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=MINUTELY;INTERVAL=15;COUNT=6
*
* ==> (September 2, 1997 EDT)09:00,09:15,09:30,09:45,10:00,10:15
*
* Every hour and a half for 4 occurrences:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=MINUTELY;INTERVAL=90;COUNT=4
*
* ==> (September 2, 1997 EDT)09:00,10:30;12:00;13:30
*
* Every 20 minutes from 9:00 AM to 4:40 PM every day:
*
* DTSTART;TZID=US-Eastern:19970902T090000
* RRULE:FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40
* or
* RRULE:FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16
*
* ==> (September 2, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
* ... 16:00,16:20,16:40
* (September 3, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
* ...16:00,16:20,16:40
* ...
*
* An example where the days generated makes a difference because of
* WKST:
*
* DTSTART;TZID=US-Eastern:19970805T090000
* RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO
*
* ==> (1997 EDT)Aug 5,10,19,24
*
* changing only WKST from MO to SU, yields different results...
*
* DTSTART;TZID=US-Eastern:19970805T090000
* RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU
* ==> (1997 EDT)August 5,17,19,31
*/
class qCal_Property_Rrule extends qCal_Property {
protected $type = 'RECUR';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VTIMEZONE','DAYLIGHT','STANDARD');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,94 @@
<?php
/**
* Sequence Number Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo A lot of the conformance below relates more to the application making
* use of this library, but make sure to conform however possible.
*
* RFC 2445 Definition
*
* Property Name: SEQUENCE
*
* Purpose: This property defines the revision sequence number of the
* calendar component within a sequence of revisions.
* Value Type: integer
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property can be specified in "VEVENT", "VTODO" or
* "VJOURNAL" calendar component.
*
* Description: When a calendar component is created, its sequence
* number is zero (US-ASCII decimal 48). It is monotonically incremented
* by the "Organizer's" CUA each time the "Organizer" makes a
* significant revision to the calendar component. When the "Organizer"
* makes changes to one of the following properties, the sequence number
* MUST be incremented:
*
* . "DTSTART"
*
* . "DTEND"
*
* . "DUE"
*
* . "RDATE"
*
* . "RRULE"
*
* . "EXDATE"
*
* . "EXRULE"
*
* . "STATUS"
*
* In addition, changes made by the "Organizer" to other properties can
* also force the sequence number to be incremented. The "Organizer" CUA
* MUST increment the sequence number when ever it makes changes to
* properties in the calendar component that the "Organizer" deems will
* jeopardize the validity of the participation status of the
* "Attendees". For example, changing the location of a meeting from one
* locale to another distant locale could effectively impact the
* participation status of the "Attendees".
*
* The "Organizer" includes this property in an iCalendar object that it
* sends to an "Attendee" to specify the current version of the calendar
* component.
*
* The "Attendee" includes this property in an iCalendar object that it
* sends to the "Organizer" to specify the version of the calendar
* component that the "Attendee" is referring to.
*
* A change to the sequence number is not the mechanism that an
* "Organizer" uses to request a response from the "Attendees". The
* "RSVP" parameter on the "ATTENDEE" property is used by the
* "Organizer" to indicate that a response from the "Attendees" is
* requested.
*
* Format Definition: This property is defined by the following
* notation:
*
* seq = "SEQUENCE" seqparam ":" integer CRLF
* ; Default is "0"
*
* seqparam = *(";" xparam)
*
* Example: The following is an example of this property for a calendar
* component that was just created by the "Organizer".
*
* SEQUENCE:0
*
* The following is an example of this property for a calendar component
* that has been revised two different times by the "Organizer".
*
* SEQUENCE:2
*/
class qCal_Property_Sequence extends qCal_Property {
protected $type = 'INTEGER';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,81 @@
<?php
/**
* Status Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that if this doesn't allow arbitrary status values that
* the use can't specify arbitrary values.
*
* RFC 2445 Definition
*
* Property Name: STATUS
*
* Purpose: This property defines the overall status or confirmation for
* the calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in "VEVENT", "VTODO" or
* "VJOURNAL" calendar components.
*
* Description: In a group scheduled calendar component, the property is
* used by the "Organizer" to provide a confirmation of the event to the
* "Attendees". For example in a "VEVENT" calendar component, the
* "Organizer" can indicate that a meeting is tentative, confirmed or
* cancelled. In a "VTODO" calendar component, the "Organizer" can
* indicate that an action item needs action, is completed, is in
* process or being worked on, or has been cancelled. In a "VJOURNAL"
* calendar component, the "Organizer" can indicate that a journal entry
* is draft, final or has been cancelled or removed.
*
* Format Definition: The property is defined by the following notation:
*
* status = "STATUS" statparam] ":" statvalue CRLF
*
* statparam = *(";" xparam)
*
* statvalue = "TENTATIVE" ;Indicates event is
* ;tentative.
* / "CONFIRMED" ;Indicates event is
* ;definite.
* / "CANCELLED" ;Indicates event was
* ;cancelled.
* ;Status values for a "VEVENT"
*
* statvalue =/ "NEEDS-ACTION" ;Indicates to-do needs action.
* / "COMPLETED" ;Indicates to-do completed.
* / "IN-PROCESS" ;Indicates to-do in process of
* / "CANCELLED" ;Indicates to-do was cancelled.
* ;Status values for "VTODO".
*
* statvalue =/ "DRAFT" ;Indicates journal is draft.
* / "FINAL" ;Indicates journal is final.
* / "CANCELLED" ;Indicates journal is removed.
* ;Status values for "VJOURNAL".
*
* Example: The following is an example of this property for a "VEVENT"
* calendar component:
*
* STATUS:TENTATIVE
*
* The following is an example of this property for a "VTODO" calendar
* component:
*
* STATUS:NEEDS-ACTION
*
* The following is an example of this property for a "VJOURNAL"
* calendar component:
*
* STATUS:DRAFT
*/
class qCal_Property_Status extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL');
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Summary Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: SUMMARY
*
* Purpose: This property defines a short summary or subject for the
* calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard, alternate text representation and
* language property parameters can be specified on this property.
*
* Conformance: The property can be specified in "VEVENT", "VTODO",
* "VJOURNAL" or "VALARM" calendar components.
*
* Description: This property is used in the "VEVENT", "VTODO" and
* "VJOURNAL" calendar components to capture a short, one line summary
* about the activity or journal entry.
*
* This property is used in the "VALARM" calendar component to capture
* the subject of an EMAIL category of alarm.
*
* Format Definition: The property is defined by the following notation:
*
* summary = "SUMMARY" summparam ":" text CRLF
*
* summparam = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" altrepparam) / (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following is an example of this property:
*
* SUMMARY:Department Party
*/
class qCal_Property_Summary extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VALARM');
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Time Transparency Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Should this default to OPAQUE?
* @todo There needs to be a library-level method of finding "visible" free-busy time
*
* RFC 2445 Definition
*
* Property Name: TRANSP
*
* Purpose: This property defines whether an event is transparent or not
* to busy time searches.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified once in a "VEVENT"
* calendar component.
*
* Description: Time Transparency is the characteristic of an event that
* determines whether it appears to consume time on a calendar. Events
* that consume actual time for the individual or resource associated
* with the calendar SHOULD be recorded as OPAQUE, allowing them to be
* detected by free-busy time searches. Other events, which do not take
* up the individual's (or resource's) time SHOULD be recorded as
* TRANSPARENT, making them invisible to free-busy time searches.
*
* Format Definition: The property is specified by the following
* notation:
*
* transp = "TRANSP" tranparam ":" transvalue CRLF
*
* tranparam = *(";" xparam)
*
* transvalue = "OPAQUE" ;Blocks or opaque on busy time searches.
* / "TRANSPARENT" ;Transparent on busy time searches.
* ;Default value is OPAQUE
*
* Example: The following is an example of this property for an event
* that is transparent or does not block on free/busy time searches:
*
* TRANSP:TRANSPARENT
*
* The following is an example of this property for an event that is
* opaque or blocks on free/busy time searches:
*
* TRANSP:OPAQUE
*/
class qCal_Property_Transp extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT');
}

View File

@ -0,0 +1,119 @@
<?php
/**
* Trigger Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure this behaves as expected when various other properties are
* introduced.
*
* RFC 2445 Definition
*
* Property Name: TRIGGER
*
* Purpose: This property specifies when an alarm will trigger.
*
* Value Type: The default value type is DURATION. The value type can be
* set to a DATE-TIME value type, in which case the value MUST specify a
* UTC formatted DATE-TIME value.
*
* Property Parameters: Non-standard, value data type, time zone
* identifier or trigger relationship property parameters can be
* specified on this property. The trigger relationship property
* parameter MUST only be specified when the value type is DURATION.
*
* Conformance: This property MUST be specified in the "VALARM" calendar
* component.
*
* Description: Within the "VALARM" calendar component, this property
* defines when the alarm will trigger. The default value type is
* DURATION, specifying a relative time for the trigger of the alarm.
* The default duration is relative to the start of an event or to-do
* that the alarm is associated with. The duration can be explicitly set
* to trigger from either the end or the start of the associated event
* or to-do with the "RELATED" parameter. A value of START will set the
* alarm to trigger off the start of the associated event or to-do. A
* value of END will set the alarm to trigger off the end of the
* associated event or to-do.
*
* Either a positive or negative duration may be specified for the
* "TRIGGER" property. An alarm with a positive duration is triggered
* after the associated start or end of the event or to-do. An alarm
* with a negative duration is triggered before the associated start or
* end of the event or to-do.
*
* The "RELATED" property parameter is not valid if the value type of
* the property is set to DATE-TIME (i.e., for an absolute date and time
* alarm trigger). If a value type of DATE-TIME is specified, then the
* property value MUST be specified in the UTC time format. If an
* absolute trigger is specified on an alarm for a recurring event or
* to-do, then the alarm will only trigger for the specified absolute
* date/time, along with any specified repeating instances.
*
* If the trigger is set relative to START, then the "DTSTART" property
* MUST be present in the associated "VEVENT" or "VTODO" calendar
* component. If an alarm is specified for an event with the trigger set
* relative to the END, then the "DTEND" property or the "DSTART" and
* "DURATION' properties MUST be present in the associated "VEVENT"
* calendar component. If the alarm is specified for a to-do with a
* trigger set relative to the END, then either the "DUE" property or
* the "DSTART" and "DURATION' properties MUST be present in the
* associated "VTODO" calendar component.
*
* Alarms specified in an event or to-do which is defined in terms of a
* DATE value type will be triggered relative to 00:00:00 UTC on the
* specified date. For example, if "DTSTART:19980205, then the duration
* trigger will be relative to19980205T000000Z.
*
* Format Definition: The property is defined by the following notation:
*
* trigger = "TRIGGER" (trigrel / trigabs)
*
* trigrel = *(
*
* ; the following are optional,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" "DURATION") /
* (";" trigrelparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
* ) ":" dur-value
*
* trigabs = 1*(
*
* ; the following is REQUIRED,
* ; but MUST NOT occur more than once
*
* (";" "VALUE" "=" "DATE-TIME") /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* ) ":" date-time
*
* Example: A trigger set 15 minutes prior to the start of the event or
* to-do.
*
* TRIGGER:-P15M
*
* A trigger set 5 minutes after the end of the event or to-do.
*
* TRIGGER;RELATED=END:P5M
*
* A trigger set to an absolute date/time.
*
* TRIGGER;VALUE=DATE-TIME:19980101T050000Z
*/
class qCal_Property_Trigger extends qCal_Property {
protected $type = 'DURATION';
protected $allowedComponents = array('VALARM');
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Time Zone Identifier Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that this must be specified in vtimezone
*
* RFC 2445 Definition
*
* Property Name: TZID
*
* Purpose: This property specifies the text value that uniquely
* identifies the "VTIMEZONE" calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be specified in a "VTIMEZONE"
* calendar component.
*
* Description: This is the label by which a time zone calendar
* component is referenced by any iCalendar properties whose data type
* is either DATE-TIME or TIME and not intended to specify a UTC or a
* "floating" time. The presence of the SOLIDUS character (US-ASCII
* decimal 47) as a prefix, indicates that this TZID represents an
* unique ID in a globally defined time zone registry (when such
* registry is defined).
*
* Note: This document does not define a naming convention for time
* zone identifiers. Implementers may want to use the naming
* conventions defined in existing time zone specifications such as
* the public-domain Olson database [TZ]. The specification of
* globally unique time zone identifiers is not addressed by this
* document and is left for future study.
*
* Format Definition: This property is defined by the following
* notation:
*
* tzid = "TZID" tzidpropparam ":" [tzidprefix] text CRLF
*
* tzidpropparam = *(";" xparam)
*
* ;tzidprefix = "/"
* ; Defined previously. Just listed here for reader convenience.
*
* Example: The following are examples of non-globally unique time zone
* identifiers:
*
* TZID:US-Eastern
*
* TZID:California-Los_Angeles
*
* The following is an example of a fictitious globally unique time zone
* identifier:
*
* TZID:/US-New_York-New_York
*/
class qCal_Property_Tzid extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VTIMEZONE');
}

View File

@ -0,0 +1,62 @@
<?php
/**
* Time Zone Name Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: TZNAME
*
* Purpose: This property specifies the customary designation for a time
* zone description.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard and language property parameters
* can be specified on this property.
*
* Conformance: This property can be specified in a "VTIMEZONE" calendar
* component.
*
* Description: This property may be specified in multiple languages; in
* order to provide for different language requirements.
*
* Format Definition: This property is defined by the following
* notation:
*
* tzname = "TZNAME" tznparam ":" text CRLF
*
* tznparam = *(
*
* ; the following is optional,
* ; but MUST NOT occur more than once
*
* (";" languageparam) /
*
* ; the following is optional,
* ; and MAY occur more than once
*
* (";" xparam)
*
* )
*
* Example: The following are example of this property:
*
* TZNAME:EST
*
* The following is an example of this property when two different
* languages for the time zone name are specified:
*
* TZNAME;LANGUAGE=en:EST
* TZNAME;LANGUAGE=fr-CA:HNE
*/
class qCal_Property_Tzname extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VTIMEZONE','DAYLIGHT','STANDARD');
protected $allowMultiple = true;
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Time Zone Offset From Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that the various components that require this actually
* require it.
*
* RFC 2445 Definition
*
* Property Name: TZOFFSETFROM
*
* Purpose: This property specifies the offset which is in use prior to
* this time zone observance.
*
* Value Type: UTC-OFFSET
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be specified in a "VTIMEZONE"
* calendar component.
*
* Description: This property specifies the offset which is in use prior
* to this time observance. It is used to calculate the absolute time at
* which the transition to a given observance takes place. This property
* MUST only be specified in a "VTIMEZONE" calendar component. A
* "VTIMEZONE" calendar component MUST include this property. The
* property value is a signed numeric indicating the number of hours and
* possibly minutes from UTC. Positive numbers represent time zones east
* of the prime meridian, or ahead of UTC. Negative numbers represent
* time zones west of the prime meridian, or behind UTC.
*
* Format Definition: The property is defined by the following notation:
*
* tzoffsetfrom = "TZOFFSETFROM" frmparam ":" utc-offset
* CRLF
*
* frmparam = *(";" xparam)
*
* Example: The following are examples of this property:
*
* TZOFFSETFROM:-0500
*
* TZOFFSETFROM:+1345
*/
class qCal_Property_Tzoffsetfrom extends qCal_Property {
protected $type = 'UTC-OFFSET';
protected $allowedComponents = array('VTIMEZONE','DAYLIGHT','STANDARD');
}

View File

@ -0,0 +1,51 @@
<?php
/**
* Time Zone Offset To Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Make sure that the various components that require this actually
* require it.
*
* RFC 2445 Definition
*
* Property Name: TZOFFSETTO
*
* Purpose: This property specifies the offset which is in use in this
* time zone observance.
*
* Value Type: UTC-OFFSET
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be specified in a "VTIMEZONE"
* calendar component.
*
* Description: This property specifies the offset which is in use in
* this time zone observance. It is used to calculate the absolute time
* for the new observance. The property value is a signed numeric
* indicating the number of hours and possibly minutes from UTC.
* Positive numbers represent time zones east of the prime meridian, or
* ahead of UTC. Negative numbers represent time zones west of the prime
* meridian, or behind UTC.
*
* Format Definition: The property is defined by the following notation:
*
* tzoffsetto = "TZOFFSETTO" toparam ":" utc-offset CRLF
*
* toparam = *(";" xparam)
*
* Example: The following are examples of this property:
*
* TZOFFSETTO:-0400
*
* TZOFFSETTO:+1245
*/
class qCal_Property_Tzoffsetto extends qCal_Property {
protected $type = 'UTC-OFFSET';
protected $allowedComponents = array('VTIMEZONE','DAYLIGHT','STANDARD');
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Time Zone URL Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: TZURL
*
* Purpose: The TZURL provides a means for a VTIMEZONE component to
* point to a network location that can be used to retrieve an up-to-
* date version of itself.
*
* Value Type: URI
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property can be specified in a "VTIMEZONE" calendar
* component.
*
* Description: The TZURL provides a means for a VTIMEZONE component to
* point to a network location that can be used to retrieve an up-to-
* date version of itself. This provides a hook to handle changes
* government bodies impose upon time zone definitions. Retrieval of
* this resource results in an iCalendar object containing a single
* VTIMEZONE component and a METHOD property set to PUBLISH.
*
* Format Definition: The property is defined by the following notation:
*
* tzurl = "TZURL" tzurlparam ":" uri CRLF
*
* tzurlparam = *(";" xparam)
*
* Example: The following is an example of this property:
*
* TZURL:http://timezones.r.us.net/tz/US-California-Los_Angeles
*/
class qCal_Property_Tzurl extends qCal_Property {
protected $type = 'URI';
protected $allowedComponents = array('VTIMEZONE');
}

View File

@ -0,0 +1,84 @@
<?php
/**
* Unique Identifier Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo The default value of this could be generated (so that unless
* otherwise specified, the uid would be generated)
* @todo Look into the RFC 822 spec and implement it if possible.
* @todo Several properties make use of a domain. Maybe there should be a method
* of globally specifying a domain.
*
* RFC 2445 Definition
*
* Property Name: UID
*
* Purpose: This property defines the persistent, globally unique
* identifier for the calendar component.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: The property MUST be specified in the "VEVENT", "VTODO",
* "VJOURNAL" or "VFREEBUSY" calendar components.
*
* Description: The UID itself MUST be a globally unique identifier. The
* generator of the identifier MUST guarantee that the identifier is
* unique. There are several algorithms that can be used to accomplish
* this. The identifier is RECOMMENDED to be the identical syntax to the
* [RFC 822] addr-spec. A good method to assure uniqueness is to put the
* domain name or a domain literal IP address of the host on which the
* identifier was created on the right hand side of the "@", and on the
* left hand side, put a combination of the current calendar date and
* time of day (i.e., formatted in as a DATE-TIME value) along with some
* other currently unique (perhaps sequential) identifier available on
* the system (for example, a process id number). Using a date/time
* value on the left hand side and a domain name or domain literal on
* the right hand side makes it possible to guarantee uniqueness since
* no two hosts should be using the same domain name or IP address at
* the same time. Though other algorithms will work, it is RECOMMENDED
* that the right hand side contain some domain identifier (either of
* the host itself or otherwise) such that the generator of the message
* identifier can guarantee the uniqueness of the left hand side within
* the scope of that domain.
*
* This is the method for correlating scheduling messages with the
* referenced "VEVENT", "VTODO", or "VJOURNAL" calendar component.
*
* The full range of calendar components specified by a recurrence set
* is referenced by referring to just the "UID" property value
* corresponding to the calendar component. The "RECURRENCE-ID" property
* allows the reference to an individual instance within the recurrence
* set.
*
* This property is an important method for group scheduling
* applications to match requests with later replies, modifications or
* deletion requests. Calendaring and scheduling applications MUST
* generate this property in "VEVENT", "VTODO" and "VJOURNAL" calendar
* components to assure interoperability with other group scheduling
* applications. This identifier is created by the calendar system that
* generates an iCalendar object.
*
* Implementations MUST be able to receive and persist values of at
* least 255 characters for this property.
*
* Format Definition: The property is defined by the following notation:
*
* uid = "UID" uidparam ":" text CRLF
*
* uidparam = *(";" xparam)
*
* Example: The following is an example of this property:
*
* UID:19960401T080045Z-4000F192713-0052@host1.com
*/
class qCal_Property_Uid extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VFREEBUSY');
}

View File

@ -0,0 +1,48 @@
<?php
/**
* Uniform Resource Locator Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: URL
*
* Purpose: This property defines a Uniform Resource Locator (URL)
* associated with the iCalendar object.
*
* Value Type: URI
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
*
* Conformance: This property can be specified once in the "VEVENT",
* "VTODO", "VJOURNAL" or "VFREEBUSY" calendar components.
*
* Description: This property may be used in a calendar component to
* convey a location where a more dynamic rendition of the calendar
* information associated with the calendar component can be found. This
* memo does not attempt to standardize the form of the URI, nor the
* format of the resource pointed to by the property value. If the URL
* property and Content-Location MIME header are both specified, they
* MUST point to the same resource.
*
* Format Definition: The property is defined by the following notation:
*
* url = "URL" urlparam ":" uri CRLF
*
* urlparam = *(";" xparam)
*
* Example: The following is an example of this property:
*
* URL:http://abc.com/pub/calendars/jsmith/mytime.ics
*/
class qCal_Property_Url extends qCal_Property {
protected $type = 'URI';
protected $allowedComponents = array('VEVENT','VTODO','VJOURNAL','VFREEBUSY');
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Version Property
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Property Name: VERSION
*
* Purpose: This property specifies the identifier corresponding to the
* highest version number or the minimum and maximum range of the
* iCalendar specification that is required in order to interpret the
* iCalendar object.
*
* Value Type: TEXT
*
* Property Parameters: Non-standard property parameters can be
* specified on this property.
*
* Conformance: This property MUST be specified by an iCalendar object,
* but MUST only be specified once.
*
* Description: A value of "2.0" corresponds to this memo.
*
* Format Definition: The property is defined by the following notation:
*
* version = "VERSION" verparam ":" vervalue CRLF
*
* verparam = *(";" xparam)
*
* vervalue = "2.0" ;This memo
* / maxver
* / (minver ";" maxver)
*
* minver = <A IANA registered iCalendar version identifier>
* ;Minimum iCalendar version needed to parse the iCalendar object
*
* maxver = <A IANA registered iCalendar version identifier>
* ;Maximum iCalendar version needed to parse the iCalendar object
*
* Example: The following is an example of this property:
*
* VERSION:2.0
*/
class qCal_Property_Version extends qCal_Property {
protected $type = 'TEXT';
protected $allowedComponents = array('VCALENDAR');
protected $default = "2.0";
}

View File

@ -0,0 +1,6 @@
<?php
abstract class qCal_Renderer {
abstract public function render(qCal_Component $component);
}

View File

@ -0,0 +1,115 @@
<?php
/**
* Default icalendar renderer. Pass a component to the renderer, and it will render it in accordance with rfc 2445
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class qCal_Renderer_iCalendar extends qCal_Renderer {
const LINE_ENDING = "\r\n";
const FOLD_LENGTH = 75;
/**
* Render any component
*/
public function render(qCal_Component $component) {
$return = "BEGIN:" . $component->getName() . self::LINE_ENDING;
foreach ($component->getProperties() as $property) {
if (is_array($property)) {
foreach ($property as $prop) {
$return .= $this->renderProperty($prop);
}
} else {
$return .= $this->renderProperty($property);
}
}
foreach ($component->getChildren() as $children) {
if (is_array($children)) {
foreach ($children as $child) {
$return .= $this->render($child);
}
} else {
$return .= $this->render($children);
}
}
return $return . "END:" . $component->getName() . self::LINE_ENDING;
}
/**
* Renders a property in accordance with rfc 2445
* @todo $proptype is created below and never used... wtf?
*/
protected function renderProperty(qCal_Property $property) {
$propval = $property->getValue();
$params = $property->getParams();
$paramreturn = "";
foreach ($params as $paramname => $paramval) {
$paramreturn .= $this->renderParam($paramname, $paramval);
}
// if property has a "value" param, then use it as the type instead
$proptype = isset($params['VALUE']) ? $params['VALUE'] : $property->getType();
if ($property instanceof qCal_Property_MultiValue) {
$values = array();
foreach ($property->getValue() as $value) {
$values[] = $this->renderValue($property->getValue(), $proptype);
}
$value = implode(chr(44), $values);
} else {
$value = $this->renderValue($property->getValue(), $proptype);
}
$content = $property->getName() . $paramreturn . ":" . $value . self::LINE_ENDING;
return $this->fold($content);
}
/**
* Renders a value
*/
protected function renderValue($value, $type) {
switch(strtoupper($type)) {
case "TEXT":
$value = str_replace(",", "\,", $value);
break;
}
return $value;
}
/**
* Renders a parameter
* RFC 2445 says if paramval contains COLON (US-ASCII decimal
* 58), SEMICOLON (US-ASCII decimal 59) or COMMA (US-ASCII decimal 44)
* character separators MUST be specified as quoted-string text values
*/
protected function renderParam($name, $value) {
$invchars = array(chr(58),chr(59),chr(44));
$quote = false;
foreach ($invchars as $char) {
if (strstr($value, $char)) {
$quote = true;
break;
}
}
if ($quote) $value = '"' . $value . '"';
return ";" . $name . "=" . $value;
}
/**
* Text cannot exceed 75 octets. This method will "fold" long lines in accordance with RFC 2445
* @todo Make sure this is multi-byte safe
* @todo The file I downloaded from google used this same folding method (long lines went to 76)
* so until I see any different, I'm going to keep it at 76.
*/
protected function fold($data) {
if (strlen($data) == (self::FOLD_LENGTH + strlen(self::LINE_ENDING))) return $data;
$apart = str_split($data, self::FOLD_LENGTH);
return implode(self::LINE_ENDING . " ", $apart);
}
}

View File

@ -0,0 +1,198 @@
<?php
class qCal_Time {
/**
* Timestamp (represents time at GMT, so must have timezone's offest
* applied before it will be accurate for your specified timezone)
*/
protected $time;
/**
* The default format that time is output as
*/
protected $format = "H:i:s";
/**
* The timezone
*/
protected $timezone;
/**
* Time array (contains hour, minute, second, etc.)
*/
protected $timeArray = array();
/**
* Class constructor
* This component is immutable. It can only be created, not modified.
*/
public function __construct($hour = null, $minute = null, $second = null, $timezone = null, $rollover = null) {
$this->setTimezone($timezone)
->setTime($hour, $minute, $second, $rollover);
}
/**
* Set the time
* @access protected This class is immutable, so this is protected. Only the constructor calls it.
*/
protected function setTime($hour = null, $minute = null, $second = null, $rollover = null) {
if (is_null($hour)) {
$hour = gmdate("H");
}
if (is_null($minute)) {
$minute = gmdate("i");
}
if (is_null($second)) {
$second = gmdate("s");
}
if (is_null($rollover)) $rollover = false;
if (!$rollover) {
if ($hour > 23 || $minute > 59 || $second > 59) {
throw new qCal_DateTime_Exception_InvalidTime(sprintf("Invalid time specified for qCal_Time: \"%02d:%02d:%02d\"", $hour, $minute, $second));
}
}
// since PHP is incapable of storing a time without a date, we use the first day of
// the unix epoch so that we only have the amount of seconds since the zero of unix epoch
// we only use gm here because we don't want the server's timezone to interfere
$time = gmmktime($hour, $minute, $second, 1, 1, 1970);
$this->time = $time;
$formatString = "a|A|B|g|G|h|H|i|s|u";
$keys = explode("|", $formatString);
$vals = explode("|", gmdate($formatString, $this->getTimestamp(false)));
$this->timeArray = array_merge($this->timeArray, array_combine($keys, $vals));
return $this;
}
/**
* Set the timezone
*/
protected function setTimezone($timezone) {
if (is_null($timezone) || !($timezone instanceof qCal_Timezone)) {
$timezone = qCal_Timezone::factory($timezone);
}
$this->timezone = $timezone;
return $this;
}
/**
* Get the timezone
*/
public function getTimezone() {
return $this->timezone;
}
/**
* Generate a qCal_Time object via a string or a number of other methods
*/
public static function factory($time, $timezone = null) {
if (is_null($timezone) || !($timezone instanceof qCal_Timezone)) {
$timezone = qCal_Timezone::factory($timezone);
}
// get the default timezone so we can set it back to it later
$tz = date_default_timezone_get();
// set the timezone to GMT temporarily
date_default_timezone_set("GMT");
if (is_integer($time)) {
// @todo Handle timestamps
// @maybe not...
}
if (is_string($time)) {
if ($time == "now") {
$time = new qCal_Time(null, null, null, $timezone);
} else {
$tstring = "01/01/1970 $time";
if (!$timestamp = strtotime($tstring)) {
// if unix timestamp can't be created throw an exception
throw new qCal_DateTime_Exception_InvalidTime("Invalid or ambiguous time string passed to qCal_Time::factory()");
}
list($hour, $minute, $second) = explode(":", gmdate("H:i:s", $timestamp));
$time = new qCal_Time($hour, $minute, $second, $timezone);
}
}
// set the timezone back to what it was
date_default_timezone_set($tz);
return $time;
}
/**
* Get the hour
*/
public function getHour() {
return $this->timeArray['G'];
}
/**
* Get the minute
*/
public function getMinute() {
return $this->timeArray['i'];
}
/**
* Get the second
*/
public function getSecond() {
return $this->timeArray['s'];
}
/**
* Get the timestamp
*/
public function getTimestamp($useOffset = true) {
$time = ($useOffset) ?
$this->time - $this->getTimezone()->getOffsetSeconds() :
$this->time;
return $time;
}
/**
* Set the format to use when outputting as a string
*/
public function setFormat($format) {
$this->format = (string) $format;
return $this;
}
/**
* Output the object using PHP's date() function's meta-characters
*/
public function format($format) {
$escape = false;
$meta = str_split($format);
$output = array();
foreach($meta as $char) {
if ($char == '\\') {
$escape = true;
continue;
}
if (!$escape && array_key_exists($char, $this->timeArray)) {
$output[] = $this->timeArray[$char];
} else {
$output[] = $char;
}
// reset this to false after every iteration that wasn't "continued"
$escape = false;
}
return implode($output);
}
/**
* Output the object as a string
*/
public function __toString() {
return $this->format($this->format);
}
}

View File

@ -0,0 +1,224 @@
<?php
class qCal_Timezone {
protected $format = "e";
protected $name;
protected $offsetSeconds;
protected $abbreviation;
protected $isDaylightSavings;
protected $formatArray = array();
protected static $timezones = array();
/**
* Class constructor
* A timezone must have a name, offset (in seconds), and optionsally an abbreviation. Daylight savings defaults to false.
* @todo When $abbreviation isn't specified, and $name is a valid pre-defined PHP timezone identifier, use its
* corresponding abbreviation rather than the name itself
* @todo When $offset isn't provided and $name is a valid timezone, use its corresponding offset, but if $name is not
* a valid timezone identifier and no offset is provided, throw an exception
*/
public function __construct($name, $offset, $abbreviation = null, $daylightsavings = null) {
$this->setName($name);
$this->setOffsetSeconds($offset);
if (is_null($abbreviation)) $abbreviation = $name;
$this->setAbbreviation($abbreviation);
$this->setIsDaylightSavings($daylightsavings);
$this->formatArray = array(
'e' => $this->getName(),
'I' => (integer) $this->isDaylightSavings(),
'O' => $this->getOffsetHours(),
'P' => $this->getOffset(),
'T' => $this->getAbbreviation(),
'Z' => $this->getOffsetSeconds(),
);
}
public function setName($name) {
$this->name = (string) $name;
}
public function setOffsetSeconds($offset) {
$this->offsetSeconds = (integer) $offset;
}
public function setAbbreviation($abbreviation) {
$this->abbreviation = (string) $abbreviation;
}
public function setIsDaylightSavings($daylightSavings = null) {
$this->isDaylightSavings = (boolean) $daylightSavings;
}
/**
* Generate a timezone from either an array of parameters, or a timezone
* name such as "America/Los_Angeles".
* @link http://php.net/manual/en/timezones.php A directory of valid timezones
* @todo This method is FUGLY. Rewrite it and make it make sense. This is sort of nonsensical.
*/
public static function factory($timezone = null) {
if (is_array($timezone)) {
// remove anything irrelevant
$vals = array_intersect_key($timezone, array_flip(array('name','offsetSeconds','abbreviation','isDaylightSavings')));
if (!array_key_exists("name", $vals)) {
// @todo throw an exception or something
}
if (!array_key_exists("offsetSeconds", $vals)) {
// @todo throw an exception or something
}
$name = $vals['name'];
$offsetSeconds = $vals['offsetSeconds'];
$abbreviation = (array_key_exists('abbreviation', $vals)) ? $vals['abbreviation'] : null;
$isDaylightSavings = (array_key_exists('isDaylightSavings', $vals)) ? $vals['isDaylightSavings'] : null;
$timezone = new qCal_Timezone($name, $offsetSeconds, $abbreviation, $isDaylightSavings);
} else {
// get the timezone information out of the string
$defaultTz = date_default_timezone_get();
if (is_null($timezone)) $timezone = $defaultTz;
// if the timezone being set is invalid, we will get a PHP notice, so error is suppressed here
// @todo It would be more clean and probably more efficient to use php's error handling to throw an exception here...
if (is_string($timezone)) {
@date_default_timezone_set($timezone);
// if the function above didn't work, this will be true
if (date_default_timezone_get() != $timezone) {
// if the timezone requested is registered, use it
if (array_key_exists($timezone, self::$timezones)) {
$timezone = self::$timezones[$timezone];
} else {
// otherwise, throw an exception
throw new qCal_DateTime_Exception_InvalidTimezone("'$timezone' is not a valid timezone.");
}
} else {
// if the timezone specified was a valid (native php) timezone, use it
$name = date("e");
$offset = date("Z");
$abbr = date("T");
$ds = date("I");
$timezone = new qCal_Timezone($name, $offset, $abbr, $ds);
}
}
// now set it back to what it was...
date_default_timezone_set($defaultTz);
}
return $timezone;
}
public static function register(qCal_Timezone $timezone) {
self::$timezones[$timezone->getName()] = $timezone;
}
public static function unregister($timezone) {
unset(self::$timezones[(string) $timezone]);
}
public function getName() {
return $this->name;
}
public function getOffset() {
$seconds = $this->getOffsetSeconds();
$negpos = "+";
if ($seconds < 0) {
$negpos = "-";
}
$hours = (integer) ($seconds / 60 / 60);
$minutes = $hours * 60;
$minutes = ($seconds / 60) - $minutes;
return sprintf("%s%02d:%02d", $negpos, abs($hours), abs($minutes));
}
public function getOffsetHours() {
$seconds = $this->getOffsetSeconds();
$negpos = "+";
if ($seconds < 0) {
$negpos = "-";
}
$hours = (integer) ($seconds / 60 / 60);
$minutes = $hours * 60;
$minutes = ($seconds / 60) - $minutes;
return sprintf("%s%02d%02d", $negpos, abs($hours), abs($minutes));
}
public function getOffsetSeconds() {
return $this->offsetSeconds;
}
public function getAbbreviation() {
return $this->abbreviation;
}
public function isDaylightSavings() {
return $this->isDaylightSavings;
}
/**
* Set the format that should be used when calling either __toString() or format() without an argument.
* @param string $format
*/
public function setFormat($format) {
$this->format = (string) $format;
return $this;
}
public function format($format) {
$escape = false;
$meta = str_split($format);
$output = array();
foreach($meta as $char) {
if ($char == '\\') {
$escape = true;
continue;
}
if (!$escape && array_key_exists($char, $this->formatArray)) {
$output[] = $this->formatArray[$char];
} else {
$output[] = $char;
}
// reset this to false after every iteration that wasn't "continued"
$escape = false;
}
return implode($output);
}
public function __toString() {
return $this->format($this->format);
}
}

View File

@ -0,0 +1,98 @@
<?php
/**
* Base property value class. Every property value has a specific data
* type. Some of them are very simple, such as boolean. Others can be
* rather complex, such as recur (specifies a date pattern for recurring
* events and other components).
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* The properties in an iCalendar object are strongly typed. The
* definition of each property restricts the value to be one of the
* value data types, or simply value types, defined in this section. The
* value type for a property will either be specified implicitly as the
* default value type or will be explicitly specified with the "VALUE"
* parameter. If the value type of a property is one of the alternate
* valid types, then it MUST be explicitly specified with the "VALUE"
* parameter.
*/
abstract class qCal_Value {
protected $value;
public function __construct($value) {
$this->setValue($value);
}
/**
* A factory for data type objects. Pass in a type and a value, and it will return the value
* casted to the proper type
*/
public static function factory($type, $value) {
// remove dashes, capitalize properly
$parts = explode("-", $type);
$type = "";
foreach ($parts as $part) $type .= trim(ucfirst(strtolower($part)));
// get the class, and instantiate
$className = "qCal_Value_" . $type;
$class = new $className($value);
return $class;
}
/**
* Sets the value of this object. The beauty of using inheritence here is that I can store
* the value however I want for any value type, and then on __toString() I can return it how
* iCalendar specifies :)
*/
public function setValue($value) {
$this->value = $this->doCast($value);
return $this;
}
/**
* Returns raw value (as it is stored)
*/
public function getValue() {
return $this->value;
}
/**
* Casts $value to this data type
*/
public function cast($value) {
return $this->doCast($value);
}
/**
* Returns the value as a string
*/
public function __toString() {
return $this->toString($this->value);
}
/**
* Converts from native format to a string, __toString() calls this internally
*/
protected function toString($value) {
return (string) $value;
}
/**
* This is left to be implemented by children classes, basically they
* implement this method to cast any input into their data type (from a string)
* @todo Change the name of this to something more appropriate, maybe toNative or something
*/
abstract protected function doCast($value);
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Binary Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Should integer/float/boolean be related somehow? Inheritance?
*
* RFC 2445 Definition
*
* Value Name: BINARY
*
* Purpose: This value type is used to identify properties that contain
* a character encoding of inline binary data. For example, an inline
* attachment of an object code might be included in an iCalendar
* object.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* binary = *(4b-char) [b-end]
* ; A "BASE64" encoded character string, as defined by [RFC 2045].
*
* b-end = (2b-char "==") / (3b-char "=")
*
* b-char = ALPHA / DIGIT / "+" / "/"
*
* Description: Property values with this value type MUST also include
* the inline encoding parameter sequence of ";ENCODING=BASE64". That
* is, all inline binary data MUST first be character encoded using the
* "BASE64" encoding method defined in [RFC 2045]. No additional content
* value encoding (i.e., BACKSLASH character encoding) is defined for
* this value type.
*
* Example: The following is an abridged example of a "BASE64" encoded
* binary value data.
*
* ATTACH;VALUE=BINARY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQY
* JKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlI
* ENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZv
* <...remainder of "BASE64" encoded binary data...>
*
* qCal_DataType_Binary
* This object defines any binary object that may be attached to an
* icalendar file.
*/
class qCal_Value_Binary extends qCal_Value {
/**
* When the value of a binary property is requested, it will be returned as a base64 encoded string
* @todo Base64 is the only encoding supported by this standard, but the encoding=base64 parameter must be
* provided regardless.
*/
protected function toString($value) {
return base64_encode($value);
}
/**
* Binary can be store as-is I believe, so don't change it
*/
protected function doCast($value) {
return $value;
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Boolean Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* RFC 2445 Definition
*
* Value Name: BOOLEAN
*
* Purpose: This value type is used to identify properties that contain
* either a "TRUE" or "FALSE" Boolean value.
*
* Formal Definition: The value type is defined by the following
* notation:
*
*
* boolean = "TRUE" / "FALSE"
*
* Description: These values are case insensitive text. No additional
* content value encoding (i.e., BACKSLASH character encoding) is
* defined for this value type.
*
* Example: The following is an example of a hypothetical property that
* has a BOOLEAN value type:
*
* GIBBERISH:TRUE
*/
class qCal_Value_Boolean extends qCal_Value {
protected function toString($value) {
return ($value) ? "TRUE" : "FALSE";
}
/**
* Returns boolean of whatever you pass in (by PHP's rules)
*/
protected function doCast($value) {
return (boolean) $value;
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* Calendar User Address Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* Value Name: CAL-ADDRESS
*
* Purpose: This value type is used to identify properties that contain
* a calendar user address.
*
* Formal Definition: The value type is as defined by the following
* notation:
*
* cal-address = uri
*
* Description: The value is a URI as defined by [RFC 1738] or any other
* IANA registered form for a URI. When used to address an Internet
* email transport address for a calendar user, the value MUST be a
* MAILTO URI, as defined by [RFC 1738]. No additional content value
* encoding (i.e., BACKSLASH character encoding) is defined for this
* value type.
*
* Example:
*
* ATTENDEE:MAILTO:jane_doe@host.com
*/
class qCal_Value_CalAddress extends qCal_Value_Uri {
/**
* @todo: implement this
*/
protected function doCast($value) {
return $value;
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* Date Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* Value Name: DATE
*
* Purpose: This value type is used to identify values that contain a
* calendar date.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* date = date-value
* date-value = date-fullyear date-month date-mday
* date-fullyear = 4DIGIT
* date-month = 2DIGIT ;01-12
* date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31
* ;based on month/year
*
* Description: If the property permits, multiple "date" values are
* specified as a COMMA character (US-ASCII decimal 44) separated list
* of values. The format for the value type is expressed as the [ISO
* 8601] complete representation, basic format for a calendar date. The
* textual format specifies a four-digit year, two-digit month, and
* two-digit day of the month. There are no separator characters between
* the year, month and day component text.
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) is defined for this value type.
*
* Example: The following represents July 14, 1997:
*
* 19970714
*/
class qCal_Value_Date extends qCal_Value {
/**
* qCal_Date object
*/
protected $value;
/**
* Convert the internal date storage to a string
*/
protected function toString($value) {
return $value->format('Ymd');
}
/**
* This converts to a qCal_Date for internal storage
*/
protected function doCast($value) {
$date = qCal_Date::factory($value);
return $date;
}
}

View File

@ -0,0 +1,134 @@
<?php
/**
* Date-Time Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* Value Name: DATE-TIME
*
* Purpose: This value type is used to identify values that specify a
* precise calendar date and time of day.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* date-time = date "T" time ;As specified in the date and time
* ;value definitions
*
* Description: If the property permits, multiple "date-time" values are
* specified as a COMMA character (US-ASCII decimal 44) separated list
* of values. No additional content value encoding (i.e., BACKSLASH
* character encoding) is defined for this value type.
*
* The "DATE-TIME" data type is used to identify values that contain a
* precise calendar date and time of day. The format is based on the
* [ISO 8601] complete representation, basic format for a calendar date
* and time of day. The text format is a concatenation of the "date",
* followed by the LATIN CAPITAL LETTER T character (US-ASCII decimal
* 84) time designator, followed by the "time" format.
*
* The "DATE-TIME" data type expresses time values in three forms:
*
* The form of date and time with UTC offset MUST NOT be used. For
* example, the following is not valid for a date-time value:
*
* DTSTART:19980119T230000-0800 ;Invalid time format
*
* FORM #1: DATE WITH LOCAL TIME
*
* The date with local time form is simply a date-time value that does
* not contain the UTC designator nor does it reference a time zone. For
* example, the following represents Janurary 18, 1998, at 11 PM:
*
* DTSTART:19980118T230000
*
* Date-time values of this type are said to be "floating" and are not
* bound to any time zone in particular. They are used to represent the
* same hour, minute, and second value regardless of which time zone is
* currently being observed. For example, an event can be defined that
* indicates that an individual will be busy from 11:00 AM to 1:00 PM
* every day, no matter which time zone the person is in. In these
* cases, a local time can be specified. The recipient of an iCalendar
* object with a property value consisting of a local time, without any
* relative time zone information, SHOULD interpret the value as being
* fixed to whatever time zone the ATTENDEE is in at any given moment.
* This means that two ATTENDEEs, in different time zones, receiving the
* same event definition as a floating time, may be participating in the
* event at different actual times. Floating time SHOULD only be used
* where that is the reasonable behavior.
*
* In most cases, a fixed time is desired. To properly communicate a
* fixed time in a property value, either UTC time or local time with
* time zone reference MUST be specified.
*
* The use of local time in a DATE-TIME value without the TZID property
* parameter is to be interpreted as floating time, regardless of the
* existence of "VTIMEZONE" calendar components in the iCalendar object.
*
* FORM #2: DATE WITH UTC TIME
*
* The date with UTC time, or absolute time, is identified by a LATIN
* CAPITAL LETTER Z suffix character (US-ASCII decimal 90), the UTC
* designator, appended to the time value. For example, the following
* represents January 19, 1998, at 0700 UTC:
*
* DTSTART:19980119T070000Z
*
* The TZID property parameter MUST NOT be applied to DATE-TIME
* properties whose time values are specified in UTC.
*
* FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE
*
* The date and local time with reference to time zone information is
* identified by the use the TZID property parameter to reference the
* appropriate time zone definition. TZID is discussed in detail in the
* section on Time Zone. For example, the following represents 2 AM in
* New York on Janurary 19, 1998:
*
* DTSTART;TZID=US-Eastern:19980119T020000
*
* Example: The following represents July 14, 1997, at 1:30 PM in New
* York City in each of the three time formats, using the "DTSTART"
* property.
*
* DTSTART:19970714T133000 ;Local time
* DTSTART:19970714T173000Z ;UTC time
* DTSTART;TZID=US-Eastern:19970714T133000 ;Local time and time
* ; zone reference
*
* A time value MUST ONLY specify 60 seconds when specifying the
* periodic "leap second" in the time value. For example:
*
* COMPLETED:19970630T235960Z
*/
class qCal_Value_Datetime extends qCal_Value {
/**
* qCal_Date object
*/
protected $value;
/**
* Convert the internal date storage to a string
*/
protected function toString($value) {
return $value->format('Ymd\THis');
}
/**
* This converts to a qCal_Date for internal storage
*/
protected function doCast($value) {
// @todo This may be the wrong place to do this...
if ($value instanceof qCal_DateTime) {
return $value;
}
$date = qCal_DateTime::factory($value);
return $date;
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Duration (of time) Value
* This data type differs from "period" in that it does not specify start
* and end time, just the duration (5 weeks, 1 day, etc)
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo I'm wondering if maybe I should make a qCal_Date_Span class
*
* Value Name: DURATION
*
* Purpose: This value type is used to identify properties that contain
* a duration of time.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
*
* dur-date = dur-day [dur-time]
* dur-time = "T" (dur-hour / dur-minute / dur-second)
* dur-week = 1*DIGIT "W"
* dur-hour = 1*DIGIT "H" [dur-minute]
* dur-minute = 1*DIGIT "M" [dur-second]
* dur-second = 1*DIGIT "S"
* dur-day = 1*DIGIT "D"
*
* Description: If the property permits, multiple "duration" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values. The format is expressed as the [ISO 8601] basic format for
* the duration of time. The format can represent durations in terms of
* weeks, days, hours, minutes, and seconds.
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) are defined for this value type.
*
* Example: A duration of 15 days, 5 hours and 20 seconds would be:
*
* P15DT5H0M20S
*
* A duration of 7 weeks would be:
*
* P7W
*/
class qCal_Value_Duration extends qCal_Value {
/**
* Convert seconds to duration
* @todo Some type of caching? This probably doesn't need to be "calculated" every time if it hasnt changed
*/
protected function toString($value) {
return $value->toICal();
}
/**
* Convert to internal representation
*/
protected function doCast($value) {
return new qCal_DateTime_Duration($value);
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* Float Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Should integer/float/boolean be related somehow? Inheritance?
*
* Value Name: FLOAT
*
* Purpose: This value type is used to identify properties that contain
* a real number value.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]
*
* Description: If the property permits, multiple "float" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values.
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) is defined for this value type.
*
* Example:
*
* 1000000.0000001
* 1.333
* -3.14
*/
class qCal_Value_Float extends qCal_Value {
/**
* Casts $value to float and returns it
*/
protected function doCast($value) {
return (float) $value;
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Integer Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo Should integer/float/boolean be related somehow? Inheritance?
*
* Value Name:INTEGER
*
* Purpose: This value type is used to identify properties that contain
* a signed integer value.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* integer = (["+"] / "-") 1*DIGIT
*
* Description: If the property permits, multiple "integer" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values. The valid range for "integer" is -2147483648 to
* 2147483647. If the sign is not specified, then the value is assumed
* to be positive.
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) is defined for this value type.
*
* Example:
*
* 1234567890
* -1234567890
* +1234567890
* 432109876
*/
class qCal_Value_Integer extends qCal_Value {
/**
* Casts $value to integer and returns it
*/
protected function doCast($value) {
return (integer) $value;
}
}

View File

@ -0,0 +1,98 @@
<?php
/**
* Period (of time) Value
* This data type differs from the "duration" data type in that it
* specifies the exact start and end time, whereas duration only specifies
* the amount of time.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
* @todo I'm wondering if maybe I should make a qCal_Date_Span class
*
* Value Name: PERIOD
*
* Purpose: This value type is used to identify values that contain a
* precise period of time.
*
* Formal Definition: The data type is defined by the following
* notation:
*
* period = period-explicit / period-start
*
* period-explicit = date-time "/" date-time
* ; [ISO 8601] complete representation basic format for a period of
* ; time consisting of a start and end. The start MUST be before the
* ; end.
*
* period-start = date-time "/" dur-value
* ; [ISO 8601] complete representation basic format for a period of
* ; time consisting of a start and positive duration of time.
*
* Description: If the property permits, multiple "period" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values. There are two forms of a period of time. First, a period
* of time is identified by its start and its end. This format is
* expressed as the [ISO 8601] complete representation, basic format for
* "DATE-TIME" start of the period, followed by a SOLIDUS character
* (US-ASCII decimal 47), followed by the "DATE-TIME" of the end of the
* period. The start of the period MUST be before the end of the period.
* Second, a period of time can also be defined by a start and a
* positive duration of time. The format is expressed as the [ISO 8601]
* complete representation, basic format for the "DATE-TIME" start of
*
* the period, followed by a SOLIDUS character (US-ASCII decimal 47),
* followed by the [ISO 8601] basic format for "DURATION" of the period.
*
* Example: The period starting at 18:00:00 UTC, on January 1, 1997 and
* ending at 07:00:00 UTC on January 2, 1997 would be:
*
* 19970101T180000Z/19970102T070000Z
*
* The period start at 18:00:00 on January 1, 1997 and lasting 5 hours
* and 30 minutes would be:
*
* 19970101T180000Z/PT5H30M
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) is defined for this value type.
*/
class qCal_Value_Period extends qCal_Value {
protected $value;
/**
* Cast a string value into a qCal_DateTime_Period object
*/
protected function doCast($value) {
$parts = explode("/", $value);
if (count($parts) !== 2) {
throw new qCal_DateTime_Exception_InvalidPeriod("A period must contain a start date and either an end date, or a duration of time.");
}
$start = qCal_DateTime::factory($parts[0]);
try {
$end = qCal_DateTime::factory($parts[1]);
} catch (qCal_DateTime_Exception $e) { // @todo This should probably be a more specific exception
// invalid date, so try duration
// @todo: I might want to create a qCal_Date object to represent a duration (not tied to any points in time)
// using a qCal_Value object here is sort of inconsistent. Plus, I can see value in having that functionality
// within the qCal_Date subcomponent
// also, there is a difference in a period and a duration in that if you say start on feb 26 and end on march 2
// that will be a different "duration" depending on the year. that goes for months with alternate amounts of days too
$duration = new qCal_DateTime_Duration($parts[1]);
$end = qCal_DateTime::factory($start->getUnixTimestamp() + $duration->getSeconds()); // @todo This needs to be updated once qCal_DateTime accepts timestamps
}
return new qCal_DateTime_Period($start, $end);
}
/**
* Convert to string - this converts to string into the UTC/UTC format
*/
protected function toString($value) {
return $value->getStart()->getUtc() . "/"
. $value->getEnd()->getUtc();
}
}

View File

@ -0,0 +1,279 @@
<?php
/**
* Recur Value
* Specifies a pattern of dates, often for recurring events. This is an
* extremely versitile data type. It can represent a very wide range of
* recurring dates, as well as include and exclude dates.
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* Value Name: RECUR
*
* Purpose: This value type is used to identify properties that contain
* a recurrence rule specification.
*
* Formal Definition: The value type is defined by the following
* notation:
*
* recur = "FREQ"=freq *(
*
* ; either UNTIL or COUNT may appear in a 'recur',
* ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
*
* ( ";" "UNTIL" "=" enddate ) /
* ( ";" "COUNT" "=" 1*DIGIT ) /
*
* ; the rest of these keywords are optional,
* ; but MUST NOT occur more than once
*
* ( ";" "INTERVAL" "=" 1*DIGIT ) /
* ( ";" "BYSECOND" "=" byseclist ) /
* ( ";" "BYMINUTE" "=" byminlist ) /
* ( ";" "BYHOUR" "=" byhrlist ) /
* ( ";" "BYDAY" "=" bywdaylist ) /
* ( ";" "BYMONTHDAY" "=" bymodaylist ) /
* ( ";" "BYYEARDAY" "=" byyrdaylist ) /
* ( ";" "BYWEEKNO" "=" bywknolist ) /
* ( ";" "BYMONTH" "=" bymolist ) /
* ( ";" "BYSETPOS" "=" bysplist ) /
* ( ";" "WKST" "=" weekday ) /
* ( ";" x-name "=" text )
* )
*
* freq = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
* / "WEEKLY" / "MONTHLY" / "YEARLY"
*
* enddate = date
* enddate =/ date-time ;An UTC value
*
* byseclist = seconds / ( seconds *("," seconds) )
*
* seconds = 1DIGIT / 2DIGIT ;0 to 59
*
* byminlist = minutes / ( minutes *("," minutes) )
*
* minutes = 1DIGIT / 2DIGIT ;0 to 59
*
* byhrlist = hour / ( hour *("," hour) )
*
* hour = 1DIGIT / 2DIGIT ;0 to 23
*
* bywdaylist = weekdaynum / ( weekdaynum *("," weekdaynum) )
*
* weekdaynum = [([plus] ordwk / minus ordwk)] weekday
*
* plus = "+"
*
* minus = "-"
*
* ordwk = 1DIGIT / 2DIGIT ;1 to 53
*
* weekday = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
* ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
* ;FRIDAY, SATURDAY and SUNDAY days of the week.
*
* bymodaylist = monthdaynum / ( monthdaynum *("," monthdaynum) )
*
* monthdaynum = ([plus] ordmoday) / (minus ordmoday)
*
* ordmoday = 1DIGIT / 2DIGIT ;1 to 31
*
* byyrdaylist = yeardaynum / ( yeardaynum *("," yeardaynum) )
*
* yeardaynum = ([plus] ordyrday) / (minus ordyrday)
*
* ordyrday = 1DIGIT / 2DIGIT / 3DIGIT ;1 to 366
*
* bywknolist = weeknum / ( weeknum *("," weeknum) )
*
* weeknum = ([plus] ordwk) / (minus ordwk)
*
* bymolist = monthnum / ( monthnum *("," monthnum) )
*
* monthnum = 1DIGIT / 2DIGIT ;1 to 12
*
* bysplist = setposday / ( setposday *("," setposday) )
*
* setposday = yeardaynum
*
* Description: If the property permits, multiple "recur" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values. The value type is a structured value consisting of a list
* of one or more recurrence grammar parts. Each rule part is defined by
* a NAME=VALUE pair. The rule parts are separated from each other by
* the SEMICOLON character (US-ASCII decimal 59). The rule parts are not
* ordered in any particular sequence. Individual rule parts MUST only
* be specified once.
*
* The FREQ rule part identifies the type of recurrence rule. This rule
* part MUST be specified in the recurrence rule. Valid values include
* SECONDLY, to specify repeating events based on an interval of a
* second or more; MINUTELY, to specify repeating events based on an
* interval of a minute or more; HOURLY, to specify repeating events
* based on an interval of an hour or more; DAILY, to specify repeating
* events based on an interval of a day or more; WEEKLY, to specify
* repeating events based on an interval of a week or more; MONTHLY, to
* specify repeating events based on an interval of a month or more; and
* YEARLY, to specify repeating events based on an interval of a year or
* more.
*
* The INTERVAL rule part contains a positive integer representing how
* often the recurrence rule repeats. The default value is "1", meaning
* every second for a SECONDLY rule, or every minute for a MINUTELY
* rule, every hour for an HOURLY rule, every day for a DAILY rule,
* every week for a WEEKLY rule, every month for a MONTHLY rule and
* every year for a YEARLY rule.
*
* The UNTIL rule part defines a date-time value which bounds the
* recurrence rule in an inclusive manner. If the value specified by
* UNTIL is synchronized with the specified recurrence, this date or
* date-time becomes the last instance of the recurrence. If specified
* as a date-time value, then it MUST be specified in an UTC time
* format. If not present, and the COUNT rule part is also not present,
* the RRULE is considered to repeat forever.
*
* The COUNT rule part defines the number of occurrences at which to
* range-bound the recurrence. The "DTSTART" property value, if
* specified, counts as the first occurrence.
*
* The BYSECOND rule part specifies a COMMA character (US-ASCII decimal
* 44) separated list of seconds within a minute. Valid values are 0 to
* 59. The BYMINUTE rule part specifies a COMMA character (US-ASCII
* decimal 44) separated list of minutes within an hour. Valid values
* are 0 to 59. The BYHOUR rule part specifies a COMMA character (US-
* ASCII decimal 44) separated list of hours of the day. Valid values
* are 0 to 23.
*
* The BYDAY rule part specifies a COMMA character (US-ASCII decimal 44)
* separated list of days of the week; MO indicates Monday; TU indicates
* Tuesday; WE indicates Wednesday; TH indicates Thursday; FR indicates
* Friday; SA indicates Saturday; SU indicates Sunday.
*
* Each BYDAY value can also be preceded by a positive (+n) or negative
* (-n) integer. If present, this indicates the nth occurrence of the
* specific day within the MONTHLY or YEARLY RRULE. For example, within
* a MONTHLY rule, +1MO (or simply 1MO) represents the first Monday
* within the month, whereas -1MO represents the last Monday of the
* month. If an integer modifier is not present, it means all days of
* this type within the specified frequency. For example, within a
* MONTHLY rule, MO represents all Mondays within the month.
*
* The BYMONTHDAY rule part specifies a COMMA character (ASCII decimal
* 44) separated list of days of the month. Valid values are 1 to 31 or
* -31 to -1. For example, -10 represents the tenth to the last day of
* the month.
*
* The BYYEARDAY rule part specifies a COMMA character (US-ASCII decimal
* 44) separated list of days of the year. Valid values are 1 to 366 or
* -366 to -1. For example, -1 represents the last day of the year
* (December 31st) and -306 represents the 306th to the last day of the
* year (March 1st).
*
* The BYWEEKNO rule part specifies a COMMA character (US-ASCII decimal
* 44) separated list of ordinals specifying weeks of the year. Valid
* values are 1 to 53 or -53 to -1. This corresponds to weeks according
* to week numbering as defined in [ISO 8601]. A week is defined as a
* seven day period, starting on the day of the week defined to be the
* week start (see WKST). Week number one of the calendar year is the
* first week which contains at least four (4) days in that calendar
* year. This rule part is only valid for YEARLY rules. For example, 3
* represents the third week of the year.
*
* Note: Assuming a Monday week start, week 53 can only occur when
* Thursday is January 1 or if it is a leap year and Wednesday is
* January 1.
*
* The BYMONTH rule part specifies a COMMA character (US-ASCII decimal
* 44) separated list of months of the year. Valid values are 1 to 12.
*
* The WKST rule part specifies the day on which the workweek starts.
* Valid values are MO, TU, WE, TH, FR, SA and SU. This is significant
* when a WEEKLY RRULE has an interval greater than 1, and a BYDAY rule
* part is specified. This is also significant when in a YEARLY RRULE
* when a BYWEEKNO rule part is specified. The default value is MO.
*
* The BYSETPOS rule part specifies a COMMA character (US-ASCII decimal
* 44) separated list of values which corresponds to the nth occurrence
* within the set of events specified by the rule. Valid values are 1 to
* 366 or -366 to -1. It MUST only be used in conjunction with another
* BYxxx rule part. For example "the last work day of the month" could
* be represented as:
*
* RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
*
* Each BYSETPOS value can include a positive (+n) or negative (-n)
* integer. If present, this indicates the nth occurrence of the
* specific occurrence within the set of events specified by the rule.
*
* If BYxxx rule part values are found which are beyond the available
* scope (ie, BYMONTHDAY=30 in February), they are simply ignored.
*
* Information, not contained in the rule, necessary to determine the
* various recurrence instance start time and dates are derived from the
* Start Time (DTSTART) entry attribute. For example,
* "FREQ=YEARLY;BYMONTH=1" doesn't specify a specific day within the
* month or a time. This information would be the same as what is
* specified for DTSTART.
*
* BYxxx rule parts modify the recurrence in some manner. BYxxx rule
* parts for a period of time which is the same or greater than the
* frequency generally reduce or limit the number of occurrences of the
* recurrence generated. For example, "FREQ=DAILY;BYMONTH=1" reduces the
* number of recurrence instances from all days (if BYMONTH tag is not
* present) to all days in January. BYxxx rule parts for a period of
* time less than the frequency generally increase or expand the number
* of occurrences of the recurrence. For example,
* "FREQ=YEARLY;BYMONTH=1,2" increases the number of days within the
* yearly recurrence set from 1 (if BYMONTH tag is not present) to 2.
*
* If multiple BYxxx rule parts are specified, then after evaluating the
* specified FREQ and INTERVAL rule parts, the BYxxx rule parts are
* applied to the current set of evaluated occurrences in the following
* order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR,
* BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated.
*
* Here is an example of evaluating multiple BYxxx rule parts.
*
* DTSTART;TZID=US-Eastern:19970105T083000
* RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;
* BYMINUTE=30
*
* First, the "INTERVAL=2" would be applied to "FREQ=YEARLY" to arrive
* at "every other year". Then, "BYMONTH=1" would be applied to arrive
* at "every January, every other year". Then, "BYDAY=SU" would be
* applied to arrive at "every Sunday in January, every other year".
* Then, "BYHOUR=8,9" would be applied to arrive at "every Sunday in
* January at 8 AM and 9 AM, every other year". Then, "BYMINUTE=30"
* would be applied to arrive at "every Sunday in January at 8:30 AM and
* 9:30 AM, every other year". Then, lacking information from RRULE, the
* second is derived from DTSTART, to end up in "every Sunday in January
* at 8:30:00 AM and 9:30:00 AM, every other year". Similarly, if the
* BYMINUTE, BYHOUR, BYDAY, BYMONTHDAY or BYMONTH rule part were
* missing, the appropriate minute, hour, day or month would have been
* retrieved from the "DTSTART" property.
*
* No additional content value encoding (i.e., BACKSLASH character
* encoding) is defined for this value type.
*
* Example: The following is a rule which specifies 10 meetings which
* occur every other day:
*
* FREQ=DAILY;COUNT=10;INTERVAL=2
*
* There are other examples specified in the "RRULE" specification.
*/
class qCal_Value_Recur extends qCal_Value {
/**
* @todo: implement this - this one's gonna be a doozy
*/
protected function doCast($value) {
// return new qCal_Date_Recur();
return $value;
}
}

View File

@ -0,0 +1,80 @@
<?php
/**
* Text Value
* @package qCal
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*
* Value Name: TEXT
*
* Purpose This value type is used to identify values that contain human
* readable text.
*
* Formal Definition: The character sets supported by this revision of
* iCalendar are UTF-8 and US ASCII thereof. The applicability to other
* character sets is for future work. The value type is defined by the
* following notation.
*
* text = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR)
* ; Folded according to description above
*
* ESCAPED-CHAR = "\\" / "\;" / "\," / "\N" / "\n")
* ; \\ encodes \, \N or \n encodes newline
* ; \; encodes ;, \, encodes ,
*
* TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B
* %x5D-7E / NON-US-ASCII
* ; Any character except CTLs not needed by the current
* ; character set, DQUOTE, ";", ":", "\", ","
*
* Note: Certain other character sets may require modification of the
* above definitions, but this is beyond the scope of this document.
*
* Description: If the property permits, multiple "text" values are
* specified by a COMMA character (US-ASCII decimal 44) separated list
* of values.
*
* The language in which the text is represented can be controlled by
* the "LANGUAGE" property parameter.
*
* An intentional formatted text line break MUST only be included in a
* "TEXT" property value by representing the line break with the
* character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
* LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
* N (US-ASCII decimal 78), that is "\n" or "\N".
*
* The "TEXT" property values may also contain special characters that
* are used to signify delimiters, such as a COMMA character for lists
* of values or a SEMICOLON character for structured values. In order to
* support the inclusion of these special characters in "TEXT" property
* values, they MUST be escaped with a BACKSLASH character. A BACKSLASH
* character (US-ASCII decimal 92) in a "TEXT" property value MUST be
* escaped with another BACKSLASH character. A COMMA character in a
* "TEXT" property value MUST be escaped with a BACKSLASH character
* (US-ASCII decimal 92). A SEMICOLON character in a "TEXT" property
* value MUST be escaped with a BACKSLASH character (US-ASCII decimal
* 92). However, a COLON character in a "TEXT" property value SHALL NOT
* be escaped with a BACKSLASH character.Example: A multiple line value
* of:
*
* Project XYZ Final Review
* Conference Room - 3B
* Come Prepared.
*
* would be represented as:
*
* Project XYZ Final Review\nConference Room - 3B\nCome Prepared.
*/
class qCal_Value_Text extends qCal_Value {
/**
* @todo: implement this
*/
protected function doCast($value) {
return $value;
}
}

Some files were not shown because too many files have changed in this diff Show More