更新到 5.2 后第一次 SVN 提交。
yuchenghu@hawebs.net git-svn-id: https://svn.code.sf.net/p/hawebs/svn@543 a2543c7e-f6e9-4f8a-8bff-1ffc34733512
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
Changelog for qCal, since Version 0.0.2
|
||||
---------------------------------------------
|
||||
|
||||
January 14, 2010: v0.0.2
|
||||
--------------------
|
||||
|
||||
* Integrated qCal_DateTime sub-components into the library.
|
||||
* Removed old qCal_Date component (replaced by qCal_DateTime, qCal_DateV2,
|
||||
which has been renamed qCal_Date, and qCal_Time)
|
||||
* Added full documentation for the library at http://qcal.lukevisinoni.com/ as
|
||||
well as inside the "docs" sub-folder.
|
||||
* Added this changelog.
|
||||
* Added README and VERSION files.
|
||||
|
||||
-- End of Changes --
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,33 @@
|
||||
qCal iCalendar Library for PHP5, by Luke Visinoni
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
qCal is an object-oriented, open-source iCalendar library for PHP5.
|
||||
It is released under the LGPL license.
|
||||
|
||||
Homepage: http://qcal.lukevisinoni.com/
|
||||
Documentation: http://qcal.lukevisinoni.com/doku.php?id=start
|
||||
Mailing List: http://groups.google.com/group/qcal
|
||||
Bugs: http://code.google.com/p/qcal/issues/list
|
||||
Repository: https://qcal.googlecode.com/svn/
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
This library requires no installation. At least not in the traditional sense.
|
||||
Simply upload to a path within PHP's include path and include
|
||||
"lib/autoload.php".
|
||||
|
||||
For more info, visit http://qcal.lukevisinoni.com/doku.php?id=installation
|
||||
|
||||
Show your support!
|
||||
------------------
|
||||
|
||||
If you use the library and would like to show your support, feel free to make a
|
||||
donation. I accept donations via PayPal. You can send me money at the following
|
||||
e-mail address.
|
||||
|
||||
luke.visinoni@gmail.com
|
||||
|
||||
I didn't write this library to make money, but I do appreciate donations. In
|
||||
fact, those users who donate to the project are by far cooler than those who
|
||||
don't. I like donors better than non-donors. LOL!
|
||||
@@ -0,0 +1 @@
|
||||
qCal-v0.0.2
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Include this file if you want to use the __autoload feature rather than including
|
||||
* all of the files manually. It will automatically register its autoload function
|
||||
* with spl's autoload mechanism.
|
||||
*/
|
||||
|
||||
require_once 'qCal/Loader.php';
|
||||
function qCal_Autoloader($name) {
|
||||
|
||||
qCal_Loader::loadClass($name);
|
||||
|
||||
}
|
||||
|
||||
spl_autoload_register("qCal_Autoloader");
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
class qCal extends qCal_Component_Vcalendar {
|
||||
// this is simply a facade to qCal_Component_Calendar, a shortcut
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,523 @@
|
||||
<?php
|
||||
/**
|
||||
* Base calendar component class. Events, Todos, and Calendars are
|
||||
* examples of components in qCal
|
||||
* @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 body of the iCalendar object consists of a sequence of calendar
|
||||
* properties and one or more calendar components. The calendar
|
||||
* properties are attributes that apply to the calendar as a whole. The
|
||||
* calendar components are collections of properties that express a
|
||||
* particular calendar semantic. For example, the calendar component can
|
||||
* specify an event, a to-do, a journal entry, time zone information, or
|
||||
* free/busy time information, or an alarm.
|
||||
*
|
||||
* The body of the iCalendar object is defined by the following
|
||||
* notation:
|
||||
*
|
||||
* icalbody = calprops component
|
||||
*
|
||||
* calprops = 2*(
|
||||
*
|
||||
* ; 'prodid' and 'version' are both REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* prodid /version /
|
||||
*
|
||||
* ; 'calscale' and 'method' are optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* calscale /
|
||||
* method /
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* component = 1*(eventc / todoc / journalc / freebusyc /
|
||||
* / timezonec / iana-comp / x-comp)
|
||||
*
|
||||
* iana-comp = "BEGIN" ":" iana-token CRLF
|
||||
*
|
||||
* 1*contentline
|
||||
*
|
||||
* "END" ":" iana-token CRLF
|
||||
*
|
||||
* x-comp = "BEGIN" ":" x-name CRLF
|
||||
*
|
||||
* 1*contentline
|
||||
*
|
||||
* "END" ":" x-name CRLF
|
||||
*
|
||||
* An iCalendar object MUST include the "PRODID" and "VERSION" calendar
|
||||
* properties. In addition, it MUST include at least one calendar
|
||||
* component. Special forms of iCalendar objects are possible to publish
|
||||
* just busy time (i.e., only a "VFREEBUSY" calendar component) or time
|
||||
* zone (i.e., only a "VTIMEZONE" calendar component) information. In
|
||||
* addition, a complex iCalendar object is possible that is used to
|
||||
* capture a complete snapshot of the contents of a calendar (e.g.,
|
||||
* composite of many different calendar components). More commonly, an
|
||||
* iCalendar object will consist of just a single "VEVENT", "VTODO" or
|
||||
* "VJOURNAL" calendar component.
|
||||
*/
|
||||
abstract class qCal_Component {
|
||||
|
||||
/**
|
||||
* The name of this component
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
/**
|
||||
* Contains a list of allowed parent components.
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedComponents = array();
|
||||
/**
|
||||
* Contains an array of this component's child components (if any). It uses
|
||||
* @var array
|
||||
*/
|
||||
protected $children = array();
|
||||
/**
|
||||
* Contains an array of this component's properties. Properties provide
|
||||
* information about their respective components. This array is associative.
|
||||
* It uses property name as key and property object as value (or array of them
|
||||
* if said property can be set multiple times). This is so that I can quickly
|
||||
* look up any certain property.
|
||||
* @var array
|
||||
*/
|
||||
protected $properties = array();
|
||||
/**
|
||||
* Contains an array of this component's required properties
|
||||
*/
|
||||
protected $requiredProperties = array();
|
||||
/**
|
||||
* Parent component (all components but vcalendar should have one once attached)
|
||||
*/
|
||||
protected $parent;
|
||||
/**
|
||||
* Class constructor
|
||||
* Accepts an array of properties, which can be simple values or actual property objects
|
||||
* Pass in a null value to use a property's default value (some dont have defaults, so beware)
|
||||
* Example:
|
||||
* $cal = new qCal_Component_Calendar(array(
|
||||
* 'prodid' => '-// Some Property Id//',
|
||||
* 'someotherproperty' => null,
|
||||
* qCal_Property_Version(2.0),
|
||||
* ), array(
|
||||
* qCal_Component_Daylight(),
|
||||
* ));
|
||||
*/
|
||||
public function __construct($properties = array(), $components = array()) {
|
||||
|
||||
foreach ($components as $component) {
|
||||
// if value is an array, then each value inside of it will be a component
|
||||
if ($component instanceof qCal_Component) {
|
||||
$this->attach($component);
|
||||
}
|
||||
else throw new qCal_Exception_InvalidComponent('The second argument is optional, but if provided, must be an array of components');
|
||||
}
|
||||
foreach ($properties as $name => $value) {
|
||||
// if value is an array, then each value inside of it will be a property
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $val) {
|
||||
if ($val instanceof qCal_Property) {
|
||||
$this->addProperty($val);
|
||||
} else {
|
||||
$this->addProperty($name, $val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($value instanceof qCal_Property) {
|
||||
$this->addProperty($value);
|
||||
} else {
|
||||
$this->addProperty($name, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
// I think it would make more sense to do validation at render time. That way you don't have
|
||||
// to have all of the required components and properties when you instantiate. Also, that way
|
||||
// components don't need to be aware of eachother until render time (or until validate() is called
|
||||
// explicitly). @todo
|
||||
// $this->validate();
|
||||
|
||||
}
|
||||
/**
|
||||
* @todo (lazy load functionality) Check that this is a valid component. This method is sort of lazy-loaded. It only gets called
|
||||
* if the user has requested data that requires validation and the component has not been validated already.
|
||||
* @todo Shouldn't this loop over children and validate them too? Maybe optionally?
|
||||
*/
|
||||
public function validate() {
|
||||
|
||||
// if we're missing any required properties and they have no default, throw an exception
|
||||
$properties = array();
|
||||
foreach ($this->getProperties() as $property) {
|
||||
if (is_array($property)) {
|
||||
foreach ($property as $prop) {
|
||||
$properties[] = $prop->getName();
|
||||
}
|
||||
} else {
|
||||
$properties[] = $property->getName();
|
||||
}
|
||||
}
|
||||
$missing = array_diff($this->requiredProperties, array_unique($properties));
|
||||
foreach ($missing as $propertyname) {
|
||||
// the property factory will throw an exception if it's passed a null value for a property with no default
|
||||
try {
|
||||
$property = qCal_Property::factory($propertyname, null);
|
||||
$this->addProperty($property);
|
||||
} catch (qCal_Exception_InvalidPropertyValue $e) {
|
||||
// if that's the case, catch the exception and throw a missing property exception
|
||||
throw new qCal_Exception_MissingProperty($this->getName() . " component requires " . $propertyname . " property");
|
||||
}
|
||||
}
|
||||
// this allows per-component validation :)
|
||||
$this->doValidation();
|
||||
|
||||
}
|
||||
/**
|
||||
* Returns the component name
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
return $this->name;
|
||||
|
||||
}
|
||||
/**
|
||||
* Returns true if this component can be attached to $component
|
||||
* I'm sure there's a better way to do this, but this works for now
|
||||
*/
|
||||
public function canAttachTo(qCal_Component $component) {
|
||||
|
||||
if (in_array($component->getName(), $this->allowedComponents)) return true;
|
||||
|
||||
}
|
||||
/**
|
||||
* Attach a component to this component (alarm inside event for example)
|
||||
* @todo There may be an issue with the way this is done. When parsing a file, if a component
|
||||
* or property with a tzid comes before its corresponding vtimezone component, an exception
|
||||
* will be thrown. I'm don't think the RFC specifies that requirement (that timezone components
|
||||
* must come before their corresponding tzids)
|
||||
* @todo Sub-components such as Vevent need to be able to access the main vcalendar object
|
||||
* for several reasons.
|
||||
* - If a vtodo has a tzid, it needs to be able to determine that the corresponding
|
||||
* vtimezone component is available.
|
||||
* - If components need to relate to eachother, they can only find eachother through
|
||||
* the main vcalendar object.
|
||||
* - Freebusy time can only be determined by polling all components in the main vcalendar
|
||||
* object.
|
||||
* - More to come probably
|
||||
*/
|
||||
public function attach(qCal_Component $component) {
|
||||
|
||||
if (!$component->canAttachTo($this)) {
|
||||
throw new qCal_Exception_InvalidComponent($component->getName() . ' cannot be attached to ' . $this->getName());
|
||||
}
|
||||
$component->setParent($this);
|
||||
// make sure if a timezone is requested that it is available...
|
||||
$timezones = $this->getTimezones();
|
||||
$tzids = array_keys($timezones);
|
||||
// we only need to check if tzid exists if we are attaching something other than a timezone...
|
||||
if (!($component instanceof qCal_Component_Vtimezone)) {
|
||||
foreach ($component->getProperties() as $pname => $properties) {
|
||||
$pname = strtoupper($pname); // probably redundant...
|
||||
foreach ($properties as $property) {
|
||||
switch ($pname) {
|
||||
case "TZID":
|
||||
$tzid = $property->getValue();
|
||||
if (!array_key_exists($tzid, $tzids)) {
|
||||
throw new qCal_Exception_MissingComponent('TZID "' . $tzid . '" not defined');
|
||||
}
|
||||
break;
|
||||
}
|
||||
$params = $property->getParams();
|
||||
foreach ($params as $param => $val) {
|
||||
$param = strtoupper($param); // probably redundant...
|
||||
switch ($param) {
|
||||
case "TZID":
|
||||
$tzid = $val;
|
||||
if (!array_key_exists($tzid, $tzids)) {
|
||||
throw new qCal_Exception_MissingComponent('TZID "' . $tzid . '" not defined');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->children[$component->getName()][] = $component;
|
||||
|
||||
}
|
||||
/**
|
||||
* Set the parent of this component
|
||||
* @todo I'm not sure this will suffice. See the attach method for reasoning behind this.
|
||||
*/
|
||||
public function setParent(qCal_Component $component) {
|
||||
|
||||
$this->parent = $component;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the parent of this component (if there is one)
|
||||
*/
|
||||
public function getParent() {
|
||||
|
||||
return $this->parent;
|
||||
|
||||
}
|
||||
/**
|
||||
* The only thing I need this for so far is the parser, but it may come in handy for the facade as well
|
||||
*/
|
||||
static public function factory($name, $properties = array()) {
|
||||
|
||||
if (empty($name)) return false;
|
||||
// capitalize
|
||||
$component = ucfirst(strtolower($name));
|
||||
$className = "qCal_Component_" . $component;
|
||||
$fileName = str_replace("_", DIRECTORY_SEPARATOR, $className) . ".php";
|
||||
qCal_Loader::loadFile($fileName);
|
||||
$class = new $className($properties);
|
||||
return $class;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* I'm not sure how this should work. Not sure if it should be setProperty,
|
||||
* addProperty, both? Because properties on some components can be set multiple
|
||||
* times, while some properties have multiple values. :( I am trying to consider
|
||||
* a case where somebody needs to open a calendar, change a few properties on a
|
||||
* component (change event time for instance). I think the way I'll handle properties
|
||||
* that can be set multiple times is I'll create a method do delete properties based
|
||||
* on values, parameters, etc. since they don't really have IDs. So I tihnk I'll go
|
||||
* with addProperty :)
|
||||
*/
|
||||
public function addProperty($property, $value = null, $params = array()) {
|
||||
|
||||
if (!($property instanceof qCal_Property)) {
|
||||
$property = qCal_Property::factory($property, $value, $params);
|
||||
}
|
||||
if (!$property->of($this)) {
|
||||
throw new qCal_Exception_InvalidProperty($this->getName() . " component does not allow " . $property->getName() . " property");
|
||||
}
|
||||
if (!$property->allowMultiple()) {
|
||||
unset($this->properties[$property->getName()]);
|
||||
}
|
||||
$this->properties[$property->getName()][] = $property;
|
||||
|
||||
}
|
||||
/**
|
||||
* Returns property of this component by name
|
||||
*
|
||||
* @todo Since the same property can appear in a component more than once, this method
|
||||
* doesn't make that much sense unless it returns all of the instances of the property
|
||||
* @return array of qCal_Property
|
||||
*/
|
||||
public function getProperty($name) {
|
||||
|
||||
$name = strtoupper($name);
|
||||
if ($this->hasProperty($name)) {
|
||||
return $this->properties[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this component contains a property of $name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasProperty($name) {
|
||||
|
||||
$name = strtoupper($name);
|
||||
return isset($this->properties[$name]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this component contains a property of $name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasComponent($name) {
|
||||
|
||||
$name = strtoupper($name);
|
||||
return isset($this->children[$name]);
|
||||
|
||||
}
|
||||
/**
|
||||
* Returns the child component requested
|
||||
*/
|
||||
public function getComponent($name) {
|
||||
|
||||
$name = strtoupper($name);
|
||||
if ($this->hasComponent($name)) {
|
||||
return $this->children[$name];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
public function clearProperties() {
|
||||
|
||||
$this->properties = array();
|
||||
|
||||
}
|
||||
|
||||
public function clearChildren() {
|
||||
|
||||
$this->children = array();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
public function getProperties() {
|
||||
|
||||
return $this->properties;
|
||||
|
||||
}
|
||||
|
||||
public function getChildren() {
|
||||
|
||||
return $this->children;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent-most component in the tree. I would really like to come up
|
||||
* with a cleaner way to access other components from within a component, but oh well.
|
||||
*/
|
||||
public function getRootComponent() {
|
||||
|
||||
$parent = $this;
|
||||
while (!($parent instanceof qCal_Component_Vcalendar)) {
|
||||
if (!$parent->getParent()) break;
|
||||
$parent = $parent->getParent();
|
||||
}
|
||||
return $parent;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the calendar, by default in icalendar format. If you pass
|
||||
* in a renderer, it will use that instead
|
||||
*
|
||||
* @return mixed Depends on the renderer
|
||||
* @todo Would it make more sense to pass the component to the renderer, or the renderer
|
||||
* to the component? I'm not sure components should know about rendering.
|
||||
*/
|
||||
public function render(qCal_Renderer $renderer = null) {
|
||||
|
||||
$this->validate();
|
||||
if (is_null($renderer)) $renderer = new qCal_Renderer_iCalendar();
|
||||
return $renderer->render($this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the icalendar component as a string (render it)
|
||||
*/
|
||||
public function __toString() {
|
||||
|
||||
return $this->render();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* getFreeBusyTime
|
||||
* Looks through all of the data in the calendar and returns a qCal_Component_Vfreebusy object
|
||||
* with free/busy time from $startdate to $enddate. The component will contain all components, but some
|
||||
* may have their transparency set to "transparent".
|
||||
* @todo This cannot be finished until recurring events are finished, since free/busy does not allow
|
||||
* recurrence rules, each instance of a recurrence would need to be calculated out and passed into the free/busy
|
||||
* component, so that the component would contain concrete instances of each event recurrence.
|
||||
*/
|
||||
public function getFreeBusyTime() {
|
||||
|
||||
$root = $this->getRootComponent();
|
||||
foreach ($root->getChildren() as $children) {
|
||||
foreach ($children as $child) {
|
||||
// now get the object's free/busy time
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* getTimeZones
|
||||
*/
|
||||
public function getTimezones() {
|
||||
|
||||
$tzs = array();
|
||||
$root = $this->getRootComponent();
|
||||
foreach ($root->getChildren() as $children) {
|
||||
foreach ($children as $child) {
|
||||
// if the child is a vtimezone, add it to the results
|
||||
// @todo make sure that tzid is available, throw exception otherwise
|
||||
if ($child instanceof qCal_Component_Vtimezone) {
|
||||
$tzid = $child->getTzid();
|
||||
$tzid = strtoupper($tzid);
|
||||
$tzs[$tzid] = $child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tzs;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get a specific timezone by tzid
|
||||
* @param string The timezone identifier
|
||||
*/
|
||||
public function getTimezone($tzid) {
|
||||
|
||||
$tzid = strtoupper($tzid);
|
||||
$root = $this->getRootComponent();
|
||||
$timezones = $root->getTimezones();
|
||||
if (array_key_exists($tzid, $timezones)) {
|
||||
return $timezones[$tzid];
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
/**
|
||||
* Allows for components to get and set property values by calling
|
||||
* qCal_Component::getPropertyName() and qCal_Component::setPropertyName('2.0') where propertyName is the property name
|
||||
* to be set and $val is the property value.
|
||||
* This is just a convenience facade, it isn't going to be used within the library as much as by end-users
|
||||
* @todo I can't decided whether to maybe get rid of the facade methods at least for now since some properties
|
||||
* can potentially return multiple values and that makes the interface inconsistent
|
||||
*/
|
||||
public function __call($method, $params) {
|
||||
|
||||
$firstthree = substr($method, 0, 3);
|
||||
$name = substr($method, 3);
|
||||
if ($firstthree == "get") {
|
||||
// if property is allowed multiple times, an array is returned, otherwise just the one component
|
||||
if ($this->hasProperty($name)) {
|
||||
$property = $this->getProperty($name);
|
||||
if (!$property[0]->allowMultiple()) {
|
||||
return $property[0];
|
||||
} else {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
} elseif ($firstthree == "set") {
|
||||
$value = isset($params[0]) ? $params[0] : null;
|
||||
$params = isset($params[1]) ? $params[1] : array();
|
||||
$property = qCal_Property::factory($name, $value, $params);
|
||||
$this->addProperty($property);
|
||||
} elseif ($firstthree == "add") {
|
||||
// add property type
|
||||
$property = qCal_Property::factory($name, $params);
|
||||
$this->addProperty($property);
|
||||
return $this;
|
||||
}
|
||||
// throw exception here?
|
||||
// throw new qCal_Exception();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
<?php
|
||||
/**
|
||||
* Timezone Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VTIMEZONE
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that defines a
|
||||
* time zone.
|
||||
*
|
||||
* Formal Definition: A "VTIMEZONE" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* timezonec = "BEGIN" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* 2*(
|
||||
*
|
||||
* ; 'tzid' is required, but MUST NOT occur more
|
||||
* ; than once
|
||||
*
|
||||
* tzid /
|
||||
*
|
||||
* ; 'last-mod' and 'tzurl' are optional,
|
||||
* but MUST NOT occur more than once
|
||||
*
|
||||
* last-mod / tzurl /
|
||||
*
|
||||
* ; one of 'standardc' or 'daylightc' MUST occur
|
||||
* ..; and each MAY occur more than once.
|
||||
*
|
||||
* standardc / daylightc /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* "END" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* standardc = "BEGIN" ":" "STANDARD" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "STANDARD" CRLF
|
||||
*
|
||||
* daylightc = "BEGIN" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop = 3*(
|
||||
*
|
||||
* ; the following are each REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* dtstart / tzoffsetto / tzoffsetfrom /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* comment / rdate / rrule / tzname / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A time zone is unambiguously defined by the set of time
|
||||
* measurement rules determined by the governing body for a given
|
||||
* geographic area. These rules describe at a minimum the base offset
|
||||
* from UTC for the time zone, often referred to as the Standard Time
|
||||
* offset. Many locations adjust their Standard Time forward or backward
|
||||
* by one hour, in order to accommodate seasonal changes in number of
|
||||
* daylight hours, often referred to as Daylight Saving Time. Some
|
||||
* locations adjust their time by a fraction of an hour. Standard Time
|
||||
* is also known as Winter Time. Daylight Saving Time is also known as
|
||||
* Advanced Time, Summer Time, or Legal Time in certain countries. The
|
||||
* following table shows the changes in time zone rules in effect for
|
||||
* New York City starting from 1967. Each line represents a description
|
||||
* or rule for a particular observance.
|
||||
*
|
||||
* Effective Observance Rule
|
||||
*
|
||||
* Date (Date/Time) Offset Abbreviation
|
||||
*
|
||||
* 1967-* last Sun in Oct, 02:00 -0500 EST
|
||||
*
|
||||
* 1967-1973 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1974-1974 Jan 6, 02:00 -0400 EDT
|
||||
*
|
||||
* 1975-1975 Feb 23, 02:00 -0400 EDT
|
||||
*
|
||||
* 1976-1986 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1987-* first Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* Note: The specification of a global time zone registry is not
|
||||
* addressed by this document and is left for future study.
|
||||
* However, implementers may find the Olson time zone database [TZ]
|
||||
* a useful reference. It is an informal, public-domain collection
|
||||
* of time zone information, which is currently being maintained by
|
||||
* volunteer Internet participants, and is used in several
|
||||
* operating systems. This database contains current and historical
|
||||
* time zone information for a wide variety of locations around the
|
||||
* globe; it provides a time zone identifier for every unique time
|
||||
* zone rule set in actual use since 1970, with historical data
|
||||
* going back to the introduction of standard time.
|
||||
*
|
||||
* Interoperability between two calendaring and scheduling applications,
|
||||
* especially for recurring events, to-dos or journal entries, is
|
||||
* dependent on the ability to capture and convey date and time
|
||||
* information in an unambiguous format. The specification of current
|
||||
* time zone information is integral to this behavior.
|
||||
*
|
||||
* If present, the "VTIMEZONE" calendar component defines the set of
|
||||
* Standard Time and Daylight Saving Time observances (or rules) for a
|
||||
* particular time zone for a given interval of time. The "VTIMEZONE"
|
||||
* calendar component cannot be nested within other calendar components.
|
||||
* Multiple "VTIMEZONE" calendar components can exist in an iCalendar
|
||||
* object. In this situation, each "VTIMEZONE" MUST represent a unique
|
||||
*
|
||||
* time zone definition. This is necessary for some classes of events,
|
||||
* such as airline flights, that start in one time zone and end in
|
||||
* another.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST be present if the iCalendar
|
||||
* object contains an RRULE that generates dates on both sides of a time
|
||||
* zone shift (e.g. both in Standard Time and Daylight Saving Time)
|
||||
* unless the iCalendar object intends to convey a floating time (See
|
||||
* the section "4.1.10.11 Time" for proper interpretation of floating
|
||||
* time). It can be present if the iCalendar object does not contain
|
||||
* such a RRULE. In addition, if a RRULE is present, there MUST be valid
|
||||
* time zone information for all recurrence instances.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST include the "TZID" property
|
||||
* and at least one definition of a standard or daylight component. The
|
||||
* standard or daylight component MUST include the "DTSTART",
|
||||
* "TZOFFSETFROM" and "TZOFFSETTO" properties.
|
||||
*
|
||||
* An individual "VTIMEZONE" calendar component MUST be specified for
|
||||
* each unique "TZID" parameter value specified in the iCalendar object.
|
||||
*
|
||||
* Each "VTIMEZONE" calendar component consists of a collection of one
|
||||
* or more sub-components that describe the rule for a particular
|
||||
* observance (either a Standard Time or a Daylight Saving Time
|
||||
* observance). The "STANDARD" sub-component consists of a collection of
|
||||
* properties that describe Standard Time. The "DAYLIGHT" sub-component
|
||||
* consists of a collection of properties that describe Daylight Saving
|
||||
* Time. In general this collection of properties consists of:
|
||||
*
|
||||
* - the first onset date-time for the observance
|
||||
*
|
||||
* - the last onset date-time for the observance, if a last onset
|
||||
* is known.
|
||||
*
|
||||
* - the offset to be applied for the observance
|
||||
*
|
||||
* - a rule that describes the day and time when the observance
|
||||
* takes effect
|
||||
*
|
||||
* - an optional name for the observance
|
||||
*
|
||||
* For a given time zone, there may be multiple unique definitions of
|
||||
* the observances over a period of time. Each observance is described
|
||||
* using either a "STANDARD" or "DAYLIGHT" sub-component. The collection
|
||||
* of these sub-components is used to describe the time zone for a given
|
||||
* period of time. The offset to apply at any given time is found by
|
||||
* locating the observance that has the last onset date and time before
|
||||
* the time in question, and using the offset value from that
|
||||
* observance.
|
||||
*
|
||||
* The top-level properties in a "VTIMEZONE" calendar component are:
|
||||
*
|
||||
* The mandatory "TZID" property is a text value that uniquely
|
||||
* identifies the VTIMZONE calendar component within the scope of an
|
||||
* iCalendar object.
|
||||
*
|
||||
* The optional "LAST-MODIFIED" property is a UTC value that specifies
|
||||
* the date and time that this time zone definition was last updated.
|
||||
*
|
||||
* The optional "TZURL" property is url value that points to a published
|
||||
* VTIMEZONE definition. TZURL SHOULD refer to a resource that is
|
||||
* accessible by anyone who might need to interpret the object. This
|
||||
* SHOULD NOT normally be a file: URL or other URL that is not widely-
|
||||
* accessible.
|
||||
*
|
||||
* The collection of properties that are used to define the STANDARD and
|
||||
* DAYLIGHT sub-components include:
|
||||
*
|
||||
* The mandatory "DTSTART" property gives the effective onset date and
|
||||
* local time for the time zone sub-component definition. "DTSTART" in
|
||||
* this usage MUST be specified as a local DATE-TIME value.
|
||||
*
|
||||
* The mandatory "TZOFFSETFROM" property gives the UTC offset which is
|
||||
* in use when the onset of this time zone observance begins.
|
||||
* "TZOFFSETFROM" is combined with "DTSTART" to define the effective
|
||||
* onset for the time zone sub-component definition. For example, the
|
||||
* following represents the time at which the observance of Standard
|
||||
* Time took effect in Fall 1967 for New York City:
|
||||
*
|
||||
* DTSTART:19671029T020000
|
||||
*
|
||||
* TZOFFSETFROM:-0400
|
||||
*
|
||||
* The mandatory "TZOFFSETTO " property gives the UTC offset for the
|
||||
* time zone sub-component (Standard Time or Daylight Saving Time) when
|
||||
* this observance is in use.
|
||||
*
|
||||
* The optional "TZNAME" property is the customary name for the time
|
||||
* zone. It may be specified multiple times, to allow for specifying
|
||||
* multiple language variants of the time zone names. This could be used
|
||||
* for displaying dates.
|
||||
*
|
||||
* If specified, the onset for the observance defined by the time zone
|
||||
* sub-component is defined by either the "RRULE" or "RDATE" property.
|
||||
* If neither is specified, only one sub-component can be specified in
|
||||
* the "VTIMEZONE" calendar component and it is assumed that the single
|
||||
* observance specified is always in effect.
|
||||
*
|
||||
* The "RRULE" property defines the recurrence rule for the onset of the
|
||||
* observance defined by this time zone sub-component. Some specific
|
||||
* requirements for the usage of RRULE for this purpose include:
|
||||
*
|
||||
* - If observance is known to have an effective end date, the
|
||||
* "UNTIL" recurrence rule parameter MUST be used to specify the
|
||||
* last valid onset of this observance (i.e., the UNTIL date-time
|
||||
* will be equal to the last instance generated by the recurrence
|
||||
* pattern). It MUST be specified in UTC time.
|
||||
*
|
||||
* - The "DTSTART" and the "TZOFFSETTO" properties MUST be used
|
||||
* when generating the onset date-time values (instances) from the
|
||||
* RRULE.
|
||||
*
|
||||
* Alternatively, the "RDATE" property can be used to define the onset
|
||||
* of the observance by giving the individual onset date and times.
|
||||
* "RDATE" in this usage MUST be specified as a local DATE-TIME value in
|
||||
* UTC time.
|
||||
*
|
||||
* The optional "COMMENT" property is also allowed for descriptive
|
||||
* explanatory text.
|
||||
*
|
||||
* Example: The following are examples of the "VTIMEZONE" calendar
|
||||
* component:
|
||||
*
|
||||
* This is an example showing time zone information for the Eastern
|
||||
* United States using "RDATE" property. Note that this is only suitable
|
||||
* for a recurring event that starts on or later than April 6, 1997 at
|
||||
* 03:00:00 EDT (i.e., the earliest effective transition date and time)
|
||||
* and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid
|
||||
* date and time for EST in this scenario). For example, this can be
|
||||
* used for a recurring event that occurs every Friday, 8am-9:00 AM,
|
||||
* starting June 1, 1997, ending December 31, 1997.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19971026T020000
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19970406T020000
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is a simple example showing the current time zone rules for the
|
||||
* Eastern United States using a RRULE recurrence pattern. Note that
|
||||
* there is no effective end date to either of the Standard Time or
|
||||
* Daylight Time rules. This information would be valid for a recurring
|
||||
* event starting today and continuing indefinitely.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* TZURL:http://zones.stds_r_us.net/tz/US-Eastern
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the Daylight Time rule has an effective end date
|
||||
* (i.e., after that date, Daylight Time is no longer observed).
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
*
|
||||
*
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the first Daylight Time rule has an effective
|
||||
* end date. There is a second Daylight Time rule that picks up where
|
||||
* the other left off.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19990424T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*/
|
||||
class qCal_Component_Daylight extends qCal_Component {
|
||||
|
||||
protected $name = "DAYLIGHT";
|
||||
protected $allowedComponents = array('VTIMEZONE');
|
||||
protected $requiredProperties = array('DTSTART','TZOFFSETFROM','TZOFFSETTO');
|
||||
|
||||
}
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
<?php
|
||||
/**
|
||||
* Timezone Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VTIMEZONE
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that defines a
|
||||
* time zone.
|
||||
*
|
||||
* Formal Definition: A "VTIMEZONE" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* timezonec = "BEGIN" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* 2*(
|
||||
*
|
||||
* ; 'tzid' is required, but MUST NOT occur more
|
||||
* ; than once
|
||||
*
|
||||
* tzid /
|
||||
*
|
||||
* ; 'last-mod' and 'tzurl' are optional,
|
||||
* but MUST NOT occur more than once
|
||||
*
|
||||
* last-mod / tzurl /
|
||||
*
|
||||
* ; one of 'standardc' or 'daylightc' MUST occur
|
||||
* ..; and each MAY occur more than once.
|
||||
*
|
||||
* standardc / daylightc /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* "END" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* standardc = "BEGIN" ":" "STANDARD" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "STANDARD" CRLF
|
||||
*
|
||||
* daylightc = "BEGIN" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop = 3*(
|
||||
*
|
||||
* ; the following are each REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* dtstart / tzoffsetto / tzoffsetfrom /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* comment / rdate / rrule / tzname / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A time zone is unambiguously defined by the set of time
|
||||
* measurement rules determined by the governing body for a given
|
||||
* geographic area. These rules describe at a minimum the base offset
|
||||
* from UTC for the time zone, often referred to as the Standard Time
|
||||
* offset. Many locations adjust their Standard Time forward or backward
|
||||
* by one hour, in order to accommodate seasonal changes in number of
|
||||
* daylight hours, often referred to as Daylight Saving Time. Some
|
||||
* locations adjust their time by a fraction of an hour. Standard Time
|
||||
* is also known as Winter Time. Daylight Saving Time is also known as
|
||||
* Advanced Time, Summer Time, or Legal Time in certain countries. The
|
||||
* following table shows the changes in time zone rules in effect for
|
||||
* New York City starting from 1967. Each line represents a description
|
||||
* or rule for a particular observance.
|
||||
*
|
||||
* Effective Observance Rule
|
||||
*
|
||||
* Date (Date/Time) Offset Abbreviation
|
||||
*
|
||||
* 1967-* last Sun in Oct, 02:00 -0500 EST
|
||||
*
|
||||
* 1967-1973 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1974-1974 Jan 6, 02:00 -0400 EDT
|
||||
*
|
||||
* 1975-1975 Feb 23, 02:00 -0400 EDT
|
||||
*
|
||||
* 1976-1986 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1987-* first Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* Note: The specification of a global time zone registry is not
|
||||
* addressed by this document and is left for future study.
|
||||
* However, implementers may find the Olson time zone database [TZ]
|
||||
* a useful reference. It is an informal, public-domain collection
|
||||
* of time zone information, which is currently being maintained by
|
||||
* volunteer Internet participants, and is used in several
|
||||
* operating systems. This database contains current and historical
|
||||
* time zone information for a wide variety of locations around the
|
||||
* globe; it provides a time zone identifier for every unique time
|
||||
* zone rule set in actual use since 1970, with historical data
|
||||
* going back to the introduction of standard time.
|
||||
*
|
||||
* Interoperability between two calendaring and scheduling applications,
|
||||
* especially for recurring events, to-dos or journal entries, is
|
||||
* dependent on the ability to capture and convey date and time
|
||||
* information in an unambiguous format. The specification of current
|
||||
* time zone information is integral to this behavior.
|
||||
*
|
||||
* If present, the "VTIMEZONE" calendar component defines the set of
|
||||
* Standard Time and Daylight Saving Time observances (or rules) for a
|
||||
* particular time zone for a given interval of time. The "VTIMEZONE"
|
||||
* calendar component cannot be nested within other calendar components.
|
||||
* Multiple "VTIMEZONE" calendar components can exist in an iCalendar
|
||||
* object. In this situation, each "VTIMEZONE" MUST represent a unique
|
||||
*
|
||||
* time zone definition. This is necessary for some classes of events,
|
||||
* such as airline flights, that start in one time zone and end in
|
||||
* another.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST be present if the iCalendar
|
||||
* object contains an RRULE that generates dates on both sides of a time
|
||||
* zone shift (e.g. both in Standard Time and Daylight Saving Time)
|
||||
* unless the iCalendar object intends to convey a floating time (See
|
||||
* the section "4.1.10.11 Time" for proper interpretation of floating
|
||||
* time). It can be present if the iCalendar object does not contain
|
||||
* such a RRULE. In addition, if a RRULE is present, there MUST be valid
|
||||
* time zone information for all recurrence instances.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST include the "TZID" property
|
||||
* and at least one definition of a standard or daylight component. The
|
||||
* standard or daylight component MUST include the "DTSTART",
|
||||
* "TZOFFSETFROM" and "TZOFFSETTO" properties.
|
||||
*
|
||||
* An individual "VTIMEZONE" calendar component MUST be specified for
|
||||
* each unique "TZID" parameter value specified in the iCalendar object.
|
||||
*
|
||||
* Each "VTIMEZONE" calendar component consists of a collection of one
|
||||
* or more sub-components that describe the rule for a particular
|
||||
* observance (either a Standard Time or a Daylight Saving Time
|
||||
* observance). The "STANDARD" sub-component consists of a collection of
|
||||
* properties that describe Standard Time. The "DAYLIGHT" sub-component
|
||||
* consists of a collection of properties that describe Daylight Saving
|
||||
* Time. In general this collection of properties consists of:
|
||||
*
|
||||
* - the first onset date-time for the observance
|
||||
*
|
||||
* - the last onset date-time for the observance, if a last onset
|
||||
* is known.
|
||||
*
|
||||
* - the offset to be applied for the observance
|
||||
*
|
||||
* - a rule that describes the day and time when the observance
|
||||
* takes effect
|
||||
*
|
||||
* - an optional name for the observance
|
||||
*
|
||||
* For a given time zone, there may be multiple unique definitions of
|
||||
* the observances over a period of time. Each observance is described
|
||||
* using either a "STANDARD" or "DAYLIGHT" sub-component. The collection
|
||||
* of these sub-components is used to describe the time zone for a given
|
||||
* period of time. The offset to apply at any given time is found by
|
||||
* locating the observance that has the last onset date and time before
|
||||
* the time in question, and using the offset value from that
|
||||
* observance.
|
||||
*
|
||||
* The top-level properties in a "VTIMEZONE" calendar component are:
|
||||
*
|
||||
* The mandatory "TZID" property is a text value that uniquely
|
||||
* identifies the VTIMZONE calendar component within the scope of an
|
||||
* iCalendar object.
|
||||
*
|
||||
* The optional "LAST-MODIFIED" property is a UTC value that specifies
|
||||
* the date and time that this time zone definition was last updated.
|
||||
*
|
||||
* The optional "TZURL" property is url value that points to a published
|
||||
* VTIMEZONE definition. TZURL SHOULD refer to a resource that is
|
||||
* accessible by anyone who might need to interpret the object. This
|
||||
* SHOULD NOT normally be a file: URL or other URL that is not widely-
|
||||
* accessible.
|
||||
*
|
||||
* The collection of properties that are used to define the STANDARD and
|
||||
* DAYLIGHT sub-components include:
|
||||
*
|
||||
* The mandatory "DTSTART" property gives the effective onset date and
|
||||
* local time for the time zone sub-component definition. "DTSTART" in
|
||||
* this usage MUST be specified as a local DATE-TIME value.
|
||||
*
|
||||
* The mandatory "TZOFFSETFROM" property gives the UTC offset which is
|
||||
* in use when the onset of this time zone observance begins.
|
||||
* "TZOFFSETFROM" is combined with "DTSTART" to define the effective
|
||||
* onset for the time zone sub-component definition. For example, the
|
||||
* following represents the time at which the observance of Standard
|
||||
* Time took effect in Fall 1967 for New York City:
|
||||
*
|
||||
* DTSTART:19671029T020000
|
||||
*
|
||||
* TZOFFSETFROM:-0400
|
||||
*
|
||||
* The mandatory "TZOFFSETTO " property gives the UTC offset for the
|
||||
* time zone sub-component (Standard Time or Daylight Saving Time) when
|
||||
* this observance is in use.
|
||||
*
|
||||
* The optional "TZNAME" property is the customary name for the time
|
||||
* zone. It may be specified multiple times, to allow for specifying
|
||||
* multiple language variants of the time zone names. This could be used
|
||||
* for displaying dates.
|
||||
*
|
||||
* If specified, the onset for the observance defined by the time zone
|
||||
* sub-component is defined by either the "RRULE" or "RDATE" property.
|
||||
* If neither is specified, only one sub-component can be specified in
|
||||
* the "VTIMEZONE" calendar component and it is assumed that the single
|
||||
* observance specified is always in effect.
|
||||
*
|
||||
* The "RRULE" property defines the recurrence rule for the onset of the
|
||||
* observance defined by this time zone sub-component. Some specific
|
||||
* requirements for the usage of RRULE for this purpose include:
|
||||
*
|
||||
* - If observance is known to have an effective end date, the
|
||||
* "UNTIL" recurrence rule parameter MUST be used to specify the
|
||||
* last valid onset of this observance (i.e., the UNTIL date-time
|
||||
* will be equal to the last instance generated by the recurrence
|
||||
* pattern). It MUST be specified in UTC time.
|
||||
*
|
||||
* - The "DTSTART" and the "TZOFFSETTO" properties MUST be used
|
||||
* when generating the onset date-time values (instances) from the
|
||||
* RRULE.
|
||||
*
|
||||
* Alternatively, the "RDATE" property can be used to define the onset
|
||||
* of the observance by giving the individual onset date and times.
|
||||
* "RDATE" in this usage MUST be specified as a local DATE-TIME value in
|
||||
* UTC time.
|
||||
*
|
||||
* The optional "COMMENT" property is also allowed for descriptive
|
||||
* explanatory text.
|
||||
*
|
||||
* Example: The following are examples of the "VTIMEZONE" calendar
|
||||
* component:
|
||||
*
|
||||
* This is an example showing time zone information for the Eastern
|
||||
* United States using "RDATE" property. Note that this is only suitable
|
||||
* for a recurring event that starts on or later than April 6, 1997 at
|
||||
* 03:00:00 EDT (i.e., the earliest effective transition date and time)
|
||||
* and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid
|
||||
* date and time for EST in this scenario). For example, this can be
|
||||
* used for a recurring event that occurs every Friday, 8am-9:00 AM,
|
||||
* starting June 1, 1997, ending December 31, 1997.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19971026T020000
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19970406T020000
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is a simple example showing the current time zone rules for the
|
||||
* Eastern United States using a RRULE recurrence pattern. Note that
|
||||
* there is no effective end date to either of the Standard Time or
|
||||
* Daylight Time rules. This information would be valid for a recurring
|
||||
* event starting today and continuing indefinitely.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* TZURL:http://zones.stds_r_us.net/tz/US-Eastern
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the Daylight Time rule has an effective end date
|
||||
* (i.e., after that date, Daylight Time is no longer observed).
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
*
|
||||
*
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the first Daylight Time rule has an effective
|
||||
* end date. There is a second Daylight Time rule that picks up where
|
||||
* the other left off.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19990424T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*/
|
||||
class qCal_Component_Standard extends qCal_Component {
|
||||
|
||||
protected $name = "STANDARD";
|
||||
protected $allowedComponents = array('VTIMEZONE');
|
||||
protected $requiredProperties = array('DTSTART','TZOFFSETFROM','TZOFFSETTO');
|
||||
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
<?php
|
||||
/**
|
||||
* Alarm Component
|
||||
* @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: Provide a grouping of component properties that define an
|
||||
* alarm.
|
||||
*
|
||||
* Formal Definition: A "VALARM" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* alarmc = "BEGIN" ":" "VALARM" CRLF
|
||||
* (audioprop / dispprop / emailprop / procprop)
|
||||
* "END" ":" "VALARM" CRLF
|
||||
*
|
||||
* audioprop = 2*(
|
||||
*
|
||||
* ; 'action' and 'trigger' are both REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* action / trigger /
|
||||
*
|
||||
* ; 'duration' and 'repeat' are both optional,
|
||||
* ; and MUST NOT occur more than once each,
|
||||
* ; but if one occurs, so MUST the other
|
||||
*
|
||||
* duration / repeat /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* attach /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* dispprop = 3*(
|
||||
*
|
||||
* ; the following are all REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* action / description / trigger /
|
||||
*
|
||||
* ; 'duration' and 'repeat' are both optional,
|
||||
* ; and MUST NOT occur more than once each,
|
||||
* ; but if one occurs, so MUST the other
|
||||
*
|
||||
* duration / repeat /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* *x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* emailprop = 5*(
|
||||
*
|
||||
* ; the following are all REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* action / description / trigger / summary
|
||||
*
|
||||
* ; the following is REQUIRED,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* attendee /
|
||||
*
|
||||
* ; 'duration' and 'repeat' are both optional,
|
||||
* ; and MUST NOT occur more than once each,
|
||||
* ; but if one occurs, so MUST the other
|
||||
*
|
||||
* duration / repeat /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* attach / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* procprop = 3*(
|
||||
*
|
||||
* ; the following are all REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* action / attach / trigger /
|
||||
*
|
||||
* ; 'duration' and 'repeat' are both optional,
|
||||
* ; and MUST NOT occur more than once each,
|
||||
* ; but if one occurs, so MUST the other
|
||||
*
|
||||
* duration / repeat /
|
||||
*
|
||||
* ; 'description' is optional,
|
||||
* ; and MUST NOT occur more than once
|
||||
*
|
||||
* description /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A "VALARM" calendar component is a grouping of component
|
||||
* properties that is a reminder or alarm for an event or a to-do. For
|
||||
* example, it may be used to define a reminder for a pending event or
|
||||
* an overdue to-do.
|
||||
*
|
||||
* The "VALARM" calendar component MUST include the "ACTION" and
|
||||
* "TRIGGER" properties. The "ACTION" property further constrains the
|
||||
* "VALARM" calendar component in the following ways:
|
||||
*
|
||||
* When the action is "AUDIO", the alarm can also include one and only
|
||||
* one "ATTACH" property, which MUST point to a sound resource, which is
|
||||
* rendered when the alarm is triggered.
|
||||
*
|
||||
* When the action is "DISPLAY", the alarm MUST also include a
|
||||
* "DESCRIPTION" property, which contains the text to be displayed when
|
||||
* the alarm is triggered.
|
||||
*
|
||||
* When the action is "EMAIL", the alarm MUST include a "DESCRIPTION"
|
||||
* property, which contains the text to be used as the message body, a
|
||||
* "SUMMARY" property, which contains the text to be used as the message
|
||||
* subject, and one or more "ATTENDEE" properties, which contain the
|
||||
* email address of attendees to receive the message. It can also
|
||||
* include one or more "ATTACH" properties, which are intended to be
|
||||
* sent as message attachments. When the alarm is triggered, the email
|
||||
* message is sent.
|
||||
*
|
||||
* When the action is "PROCEDURE", the alarm MUST include one and only
|
||||
* one "ATTACH" property, which MUST point to a procedure resource,
|
||||
* which is invoked when the alarm is triggered.
|
||||
*
|
||||
* The "VALARM" calendar component MUST only appear within either a
|
||||
* "VEVENT" or "VTODO" calendar component. "VALARM" calendar components
|
||||
* cannot be nested. Multiple mutually independent "VALARM" calendar
|
||||
* components can be specified for a single "VEVENT" or "VTODO" calendar
|
||||
* component.
|
||||
*
|
||||
* The "TRIGGER" property specifies when the alarm will be triggered.
|
||||
* The "TRIGGER" property specifies a duration prior to the start of an
|
||||
* event or a to-do. The "TRIGGER" edge may be explicitly set to be
|
||||
* relative to the "START" or "END" of the event or to-do with the
|
||||
* "RELATED" parameter of the "TRIGGER" property. The "TRIGGER" property
|
||||
* value type can alternatively be set to an absolute calendar date and
|
||||
* time of day value.
|
||||
*
|
||||
* In an alarm set to trigger on the "START" of an event or to-do, the
|
||||
* "DTSTART" property MUST be present in the associated event or to-do.
|
||||
* In an alarm in a "VEVENT" calendar component set to trigger on the
|
||||
* "END" of the event, either the "DTEND" property MUST be present, or
|
||||
* the "DTSTART" and "DURATION" properties MUST both be present. In an
|
||||
* alarm in a "VTODO" calendar component set to trigger on the "END" of
|
||||
* the to-do, either the "DUE" property MUST be present, or the
|
||||
* "DTSTART" and "DURATION" properties MUST both be present.
|
||||
*
|
||||
* The alarm can be defined such that it triggers repeatedly. A
|
||||
* definition of an alarm with a repeating trigger MUST include both the
|
||||
* "DURATION" and "REPEAT" properties. The "DURATION" property specifies
|
||||
* the delay period, after which the alarm will repeat. The "REPEAT"
|
||||
* property specifies the number of additional repetitions that the
|
||||
* alarm will triggered. This repitition count is in addition to the
|
||||
* initial triggering of the alarm. Both of these properties MUST be
|
||||
* present in order to specify a repeating alarm. If one of these two
|
||||
* properties is absent, then the alarm will not repeat beyond the
|
||||
* initial trigger.
|
||||
*
|
||||
* The "ACTION" property is used within the "VALARM" calendar component
|
||||
* to specify the type of action invoked when the alarm is triggered.
|
||||
* The "VALARM" properties provide enough information for a specific
|
||||
* action to be invoked. It is typically the responsibility of a
|
||||
* "Calendar User Agent" (CUA) to deliver the alarm in the specified
|
||||
* fashion. An "ACTION" property value of AUDIO specifies an alarm that
|
||||
* causes a sound to be played to alert the user; DISPLAY specifies an
|
||||
* alarm that causes a text message to be displayed to the user; EMAIL
|
||||
* specifies an alarm that causes an electronic email message to be
|
||||
* delivered to one or more email addresses; and PROCEDURE specifies an
|
||||
* alarm that causes a procedure to be executed. The "ACTION" property
|
||||
* MUST specify one and only one of these values.
|
||||
*
|
||||
* In an AUDIO alarm, if the optional "ATTACH" property is included, it
|
||||
* MUST specify an audio sound resource. The intention is that the sound
|
||||
* will be played as the alarm effect. If an "ATTACH" property is
|
||||
* specified that does not refer to a sound resource, or if the
|
||||
* specified sound resource cannot be rendered (because its format is
|
||||
* unsupported, or because it cannot be retrieved), then the CUA or
|
||||
* other entity responsible for playing the sound may choose a fallback
|
||||
* action, such as playing a built-in default sound, or playing no sound
|
||||
* at all.
|
||||
*
|
||||
* In a DISPLAY alarm, the intended alarm effect is for the text value
|
||||
* of the "DESCRIPTION" property to be displayed to the user.
|
||||
*
|
||||
* In an EMAIL alarm, the intended alarm effect is for an email message
|
||||
* to be composed and delivered to all the addresses specified by the
|
||||
* "ATTENDEE" properties in the "VALARM" calendar component. The
|
||||
* "DESCRIPTION" property of the "VALARM" calendar component MUST be
|
||||
* used as the body text of the message, and the "SUMMARY" property MUST
|
||||
* be used as the subject text. Any "ATTACH" properties in the "VALARM"
|
||||
* calendar component SHOULD be sent as attachments to the message.
|
||||
*
|
||||
* In a PROCEDURE alarm, the "ATTACH" property in the "VALARM" calendar
|
||||
* component MUST specify a procedure or program that is intended to be
|
||||
* invoked as the alarm effect. If the procedure or program is in a
|
||||
* format that cannot be rendered, then no procedure alarm will be
|
||||
* invoked. If the "DESCRIPTION" property is present, its value
|
||||
* specifies the argument string to be passed to the procedure or
|
||||
* program. "Calendar User Agents" that receive an iCalendar object with
|
||||
* this category of alarm, can disable or allow the "Calendar User" to
|
||||
* disable, or otherwise ignore this type of alarm. While a very useful
|
||||
* alarm capability, the PROCEDURE type of alarm SHOULD be treated by
|
||||
* the "Calendar User Agent" as a potential security risk.
|
||||
*
|
||||
* Example: The following example is for a "VALARM" calendar component
|
||||
* that specifies an audio alarm that will sound at a precise time and
|
||||
* repeat 4 more times at 15 minute intervals:
|
||||
*
|
||||
* BEGIN:VALARM
|
||||
* TRIGGER;VALUE=DATE-TIME:19970317T133000Z
|
||||
* REPEAT:4
|
||||
* DURATION:PT15M
|
||||
* ACTION:AUDIO
|
||||
* ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
|
||||
* END:VALARM
|
||||
*
|
||||
* The following example is for a "VALARM" calendar component that
|
||||
* specifies a display alarm that will trigger 30 minutes before the
|
||||
* scheduled start of the event or the due date/time of the to-do it is
|
||||
* associated with and will repeat 2 more times at 15 minute intervals:
|
||||
*
|
||||
* BEGIN:VALARM
|
||||
* TRIGGER:-PT30M
|
||||
* REPEAT:2
|
||||
* DURATION:PT15M
|
||||
* ACTION:DISPLAY
|
||||
* DESCRIPTION:Breakfast meeting with executive\n
|
||||
* team at 8:30 AM EST.
|
||||
* END:VALARM
|
||||
*
|
||||
* The following example is for a "VALARM" calendar component that
|
||||
* specifies an email alarm that will trigger 2 days before the
|
||||
* scheduled due date/time of a to-do it is associated with. It does not
|
||||
* repeat. The email has a subject, body and attachment link.
|
||||
*
|
||||
* BEGIN:VALARM
|
||||
* TRIGGER:-P2D
|
||||
* ACTION:EMAIL
|
||||
* ATTENDEE:MAILTO:john_doe@host.com
|
||||
* SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
|
||||
* DESCRIPTION:A draft agenda needs to be sent out to the attendees
|
||||
* to the weekly managers meeting (MGR-LIST). Attached is a
|
||||
* pointer the document template for the agenda file.
|
||||
* ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen
|
||||
* da.doc
|
||||
* END:VALARM
|
||||
*
|
||||
* The following example is for a "VALARM" calendar component that
|
||||
* specifies a procedural alarm that will trigger at a precise date/time
|
||||
* and will repeat 23 more times at one hour intervals. The alarm will
|
||||
* invoke a procedure file.
|
||||
*
|
||||
* BEGIN:VALARM
|
||||
* TRIGGER;VALUE=DATE-TIME:19980101T050000Z
|
||||
* REPEAT:23
|
||||
* DURATION:PT1H
|
||||
* ACTION:PROCEDURE
|
||||
* ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-
|
||||
* procs/felizano.exe
|
||||
* END:VALARM
|
||||
*/
|
||||
class qCal_Component_Valarm extends qCal_Component {
|
||||
|
||||
protected $name = "VALARM";
|
||||
protected $allowedComponents = array('VEVENT','VTODO');
|
||||
protected $requiredProperties = array('ACTION', 'TRIGGER');
|
||||
protected function doValidation() {
|
||||
|
||||
$action = $this->getAction();
|
||||
switch(strtoupper($action->getValue())) {
|
||||
case "AUDIO":
|
||||
// action, trigger (already covered by parent constructor)
|
||||
// attach can only occur once
|
||||
$attach = $this->getProperty('ATTACH');
|
||||
if (count($attach) > 1) {
|
||||
throw new qCal_Exception_InvalidProperty('VALARM audio component can contain one and only one ATTACH property');
|
||||
}
|
||||
break;
|
||||
case "DISPLAY":
|
||||
// action, trigger, description
|
||||
if (!$this->hasProperty('DESCRIPTION')) {
|
||||
throw new qCal_Exception_MissingProperty("DISPLAY VALARM component requires DESCRIPTION property");
|
||||
}
|
||||
break;
|
||||
case "EMAIL":
|
||||
// action, description, trigger, summary
|
||||
if (!$this->hasProperty('DESCRIPTION')) {
|
||||
throw new qCal_Exception_MissingProperty("EMAIL VALARM component requires DESCRIPTION property");
|
||||
}
|
||||
if (!$this->hasProperty('SUMMARY')) {
|
||||
throw new qCal_Exception_MissingProperty("EMAIL VALARM component requires SUMMARY property");
|
||||
}
|
||||
break;
|
||||
case "PROCEDURE":
|
||||
// action, attach, trigger
|
||||
$attach = $this->getProperty('ATTACH');
|
||||
if (count($attach) > 1) {
|
||||
throw new qCal_Exception_InvalidProperty('VALARM procedure component can contain one and only one ATTACH property');
|
||||
}
|
||||
if (count($attach) < 1) {
|
||||
throw new qCal_Exception_MissingProperty("PROCEDURE VALARM component requires ATTACH property");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($this->hasProperty('DURATION')) {
|
||||
if (!$this->hasProperty('REPEAT')) {
|
||||
throw new qCal_Exception_MissingProperty("VALARM component with a DURATION property requires a REPEAT property");
|
||||
}
|
||||
}
|
||||
if ($this->hasProperty('REPEAT')) {
|
||||
if (!$this->hasProperty('DURATION')) {
|
||||
throw new qCal_Exception_MissingProperty("VALARM component with a REPEAT property requires a DURATION property");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Calendar Component
|
||||
* This is the outer-most object in an icalendar file that represents
|
||||
* the calendar as a whole. All other components must be nested within
|
||||
* this component.
|
||||
* @package qCal
|
||||
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
|
||||
* @author Luke Visinoni (luke.visinoni@gmail.com)
|
||||
* @license GNU Lesser General Public License
|
||||
* @todo Implement a method of NOT allowing more than one of properties
|
||||
* such as METHOD to be set.
|
||||
*
|
||||
* RFC 2445 Definition
|
||||
*
|
||||
* The Calendaring and Scheduling Core Object is a collection of
|
||||
* calendaring and scheduling information. Typically, this information
|
||||
* will consist of a single iCalendar object. However, multiple
|
||||
* iCalendar objects can be sequentially grouped together. The first
|
||||
* line and last line of the iCalendar object MUST contain a pair of
|
||||
* iCalendar object delimiter strings. The syntax for an iCalendar
|
||||
* object is as follows:
|
||||
*
|
||||
* icalobject = 1*("BEGIN" ":" "VCALENDAR" CRLF
|
||||
* icalbody
|
||||
* "END" ":" "VCALENDAR" CRLF)
|
||||
*
|
||||
* The following is a simple example of an iCalendar object:
|
||||
*
|
||||
* BEGIN:VCALENDAR
|
||||
* VERSION:2.0
|
||||
* PRODID:-//hacksw/handcal//NONSGML v1.0//EN
|
||||
* BEGIN:VEVENT
|
||||
* DTSTART:19970714T170000Z
|
||||
* DTEND:19970715T035959Z
|
||||
* SUMMARY:Bastille Day Party
|
||||
* END:VEVENT
|
||||
* END:VCALENDAR
|
||||
*/
|
||||
class qCal_Component_Vcalendar extends qCal_Component {
|
||||
|
||||
protected $name = "VCALENDAR";
|
||||
protected $requiredProperties = array('PRODID','VERSION');
|
||||
/**
|
||||
* vcalendar objects have a number of requirements defined in the RFC just as most other
|
||||
* components do. Each has a global set of validation rules as well as their own set. This
|
||||
* is the set of rules defined by the vcalendar object.
|
||||
*/
|
||||
public function doValidation() {
|
||||
|
||||
// @todo make sure that all tzids that are specified have a corresponding vtimezone
|
||||
// look for tzids and make sure there are corresponding vtimezone components for each tzid
|
||||
// In order to be sure I find all tzids, I need to search through the entire tree, so either
|
||||
// I need a recursive getProperties() or I need to use a stack to find all of them.
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* Event Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: "VEVENT"
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that describe an
|
||||
* event.
|
||||
*
|
||||
* Format Definition: A "VEVENT" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* eventc = "BEGIN" ":" "VEVENT" CRLF
|
||||
* eventprop *alarmc
|
||||
* "END" ":" "VEVENT" CRLF
|
||||
*
|
||||
* eventprop = *(
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* class / created / description / dtstart / geo /
|
||||
* last-mod / location / organizer / priority /
|
||||
* dtstamp / seq / status / summary / transp /
|
||||
* uid / url / recurid /
|
||||
*
|
||||
* ; either 'dtend' or 'duration' may appear in
|
||||
* ; a 'eventprop', but 'dtend' and 'duration'
|
||||
* ; MUST NOT occur in the same 'eventprop'
|
||||
*
|
||||
* dtend / duration /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* attach / attendee / categories / comment /
|
||||
* contact / exdate / exrule / rstatus / related /
|
||||
* resources / rdate / rrule / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A "VEVENT" calendar component is a grouping of component
|
||||
* properties, and possibly including "VALARM" calendar components, that
|
||||
* represents a scheduled amount of time on a calendar. For example, it
|
||||
* can be an activity; such as a one-hour long, department meeting from
|
||||
* 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
|
||||
* on an individual calendar. Hence, the event will appear as an opaque
|
||||
* interval in a search for busy time. Alternately, the event can have
|
||||
* its Time Transparency set to "TRANSPARENT" in order to prevent
|
||||
* blocking of the event in searches for busy time.
|
||||
*
|
||||
* The "VEVENT" is also the calendar component used to specify an
|
||||
* anniversary or daily reminder within a calendar. These events have a
|
||||
* DATE value type for the "DTSTART" property instead of the default
|
||||
* data type of DATE-TIME. If such a "VEVENT" has a "DTEND" property, it
|
||||
* MUST be specified as a DATE value also. The anniversary type of
|
||||
* "VEVENT" can span more than one date (i.e, "DTEND" property value is
|
||||
* set to a calendar date after the "DTSTART" property value).
|
||||
*
|
||||
* The "DTSTART" property for a "VEVENT" specifies the inclusive start
|
||||
* of the event. For recurring events, it also specifies the very first
|
||||
* instance in the recurrence set. The "DTEND" property for a "VEVENT"
|
||||
* calendar component specifies the non-inclusive end of the event. For
|
||||
* cases where a "VEVENT" calendar component specifies a "DTSTART"
|
||||
* property with a DATE data type but no "DTEND" property, the events
|
||||
* non-inclusive end is the end of the calendar date specified by the
|
||||
* "DTSTART" property. For cases where a "VEVENT" calendar component
|
||||
* specifies a "DTSTART" property with a DATE-TIME data type but no
|
||||
* "DTEND" property, the event ends on the same calendar date and time
|
||||
* of day specified by the "DTSTART" property.
|
||||
*
|
||||
* The "VEVENT" calendar component cannot be nested within another
|
||||
* calendar component. However, "VEVENT" calendar components can be
|
||||
* related to each other or to a "VTODO" or to a "VJOURNAL" calendar
|
||||
* component with the "RELATED-TO" property.
|
||||
*
|
||||
* Example: The following is an example of the "VEVENT" calendar
|
||||
* component used to represent a meeting that will also be opaque to
|
||||
* searches for busy time:
|
||||
*
|
||||
* BEGIN:VEVENT
|
||||
* UID:19970901T130000Z-123401@host.com
|
||||
* DTSTAMP:19970901T1300Z
|
||||
* DTSTART:19970903T163000Z
|
||||
* DTEND:19970903T190000Z
|
||||
* SUMMARY:Annual Employee Review
|
||||
* CLASS:PRIVATE
|
||||
* CATEGORIES:BUSINESS,HUMAN RESOURCES
|
||||
* END:VEVENT
|
||||
*
|
||||
* The following is an example of the "VEVENT" calendar component used
|
||||
* to represent a reminder that will not be opaque, but rather
|
||||
* transparent, to searches for busy time:
|
||||
*
|
||||
* BEGIN:VEVENT
|
||||
* UID:19970901T130000Z-123402@host.com
|
||||
* DTSTAMP:19970901T1300Z
|
||||
* DTSTART:19970401T163000Z
|
||||
* DTEND:19970402T010000Z
|
||||
* SUMMARY:Laurel is in sensitivity awareness class.
|
||||
* CLASS:PUBLIC
|
||||
* CATEGORIES:BUSINESS,HUMAN RESOURCES
|
||||
* TRANSP:TRANSPARENT
|
||||
* END:VEVENT
|
||||
*
|
||||
* The following is an example of the "VEVENT" calendar component used
|
||||
* to represent an anniversary that will occur annually. Since it takes
|
||||
* up no time, it will not appear as opaque in a search for busy time;
|
||||
* no matter what the value of the "TRANSP" property indicates:
|
||||
*
|
||||
* BEGIN:VEVENT
|
||||
* UID:19970901T130000Z-123403@host.com
|
||||
* DTSTAMP:19970901T1300Z
|
||||
* DTSTART:19971102
|
||||
* SUMMARY:Our Blissful Anniversary
|
||||
* CLASS:CONFIDENTIAL
|
||||
* CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
|
||||
* RRULE:FREQ=YEARLY
|
||||
* END:VEVENT
|
||||
*/
|
||||
class qCal_Component_Vevent extends qCal_Component {
|
||||
|
||||
protected $name = "VEVENT";
|
||||
protected $allowedComponents = array('VCALENDAR');
|
||||
protected function doValidation() {
|
||||
|
||||
$properties = $this->getProperties();
|
||||
$propnames = array_keys($properties);
|
||||
if (in_array('DTEND', $propnames) && in_array('DURATION', $propnames)) {
|
||||
throw new qCal_Exception_InvalidProperty('DTEND and DURATION cannot both occur in the same VEVENT component');
|
||||
}
|
||||
if (in_array('DTSTART', $propnames)) {
|
||||
$dtstart = $this->getProperty('dtstart');
|
||||
$dtstart = $dtstart[0];
|
||||
// check that if dtstart is a DATE that dtend is a DATE
|
||||
if ($dtstart->getType() == 'DATE') {
|
||||
if (in_array('DTEND', $propnames)) {
|
||||
$dtend = $this->getProperty('dtend');
|
||||
$dtend = $dtend[0];
|
||||
if ($dtend->getType() != 'DATE') {
|
||||
throw new qCal_Exception_InvalidProperty('If DTSTART property is specified as a DATE property, so must DTEND');
|
||||
}
|
||||
}
|
||||
}
|
||||
// check that dtstart comes before dtend
|
||||
if (in_array('DTEND', $propnames)) {
|
||||
$dtend = $this->getProperty('dtend');
|
||||
$dtend = $dtend[0];
|
||||
$startdate = strtotime($dtstart->getValue());
|
||||
$enddate = strtotime($dtend->getValue());
|
||||
if ($startdate > $enddate) {
|
||||
throw new qCal_Exception_InvalidProperty('DTSTART property must come before DTEND');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Freebusy Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VFREEBUSY
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that describe
|
||||
* either a request for free/busy time, describe a response to a request
|
||||
* for free/busy time or describe a published set of busy time.
|
||||
*
|
||||
* Formal Definition: A "VFREEBUSY" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* freebusyc = "BEGIN" ":" "VFREEBUSY" CRLF
|
||||
* fbprop
|
||||
* "END" ":" "VFREEBUSY" CRLF
|
||||
*
|
||||
* fbprop = *(
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* contact / dtstart / dtend / duration / dtstamp /
|
||||
* organizer / uid / url /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* attendee / comment / freebusy / rstatus / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A "VFREEBUSY" calendar component is a grouping of
|
||||
* component properties that represents either a request for, a reply to
|
||||
* a request for free or busy time information or a published set of
|
||||
* busy time information.
|
||||
*
|
||||
* When used to request free/busy time information, the "ATTENDEE"
|
||||
* property specifies the calendar users whose free/busy time is being
|
||||
* requested; the "ORGANIZER" property specifies the calendar user who
|
||||
* is requesting the free/busy time; the "DTSTART" and "DTEND"
|
||||
* properties specify the window of time for which the free/busy time is
|
||||
* being requested; the "UID" and "DTSTAMP" properties are specified to
|
||||
* assist in proper sequencing of multiple free/busy time requests.
|
||||
*
|
||||
* When used to reply to a request for free/busy time, the "ATTENDEE"
|
||||
* property specifies the calendar user responding to the free/busy time
|
||||
* request; the "ORGANIZER" property specifies the calendar user that
|
||||
* originally requested the free/busy time; the "FREEBUSY" property
|
||||
* specifies the free/busy time information (if it exists); and the
|
||||
*
|
||||
* "UID" and "DTSTAMP" properties are specified to assist in proper
|
||||
* sequencing of multiple free/busy time replies.
|
||||
*
|
||||
* When used to publish busy time, the "ORGANIZER" property specifies
|
||||
* the calendar user associated with the published busy time; the
|
||||
* "DTSTART" and "DTEND" properties specify an inclusive time window
|
||||
* that surrounds the busy time information; the "FREEBUSY" property
|
||||
* specifies the published busy time information; and the "DTSTAMP"
|
||||
* property specifies the date/time that iCalendar object was created.
|
||||
*
|
||||
* The "VFREEBUSY" calendar component cannot be nested within another
|
||||
* calendar component. Multiple "VFREEBUSY" calendar components can be
|
||||
* specified within an iCalendar object. This permits the grouping of
|
||||
* Free/Busy information into logical collections, such as monthly
|
||||
* groups of busy time information.
|
||||
*
|
||||
* The "VFREEBUSY" calendar component is intended for use in iCalendar
|
||||
* object methods involving requests for free time, requests for busy
|
||||
* time, requests for both free and busy, and the associated replies.
|
||||
*
|
||||
* Free/Busy information is represented with the "FREEBUSY" property.
|
||||
* This property provides a terse representation of time periods. One or
|
||||
* more "FREEBUSY" properties can be specified in the "VFREEBUSY"
|
||||
* calendar component.
|
||||
*
|
||||
* When present in a "VFREEBUSY" calendar component, the "DTSTART" and
|
||||
* "DTEND" properties SHOULD be specified prior to any "FREEBUSY"
|
||||
* properties. In a free time request, these properties can be used in
|
||||
* combination with the "DURATION" property to represent a request for a
|
||||
* duration of free time within a specified window of time.
|
||||
*
|
||||
* The recurrence properties ("RRULE", "EXRULE", "RDATE", "EXDATE") are
|
||||
* not permitted within a "VFREEBUSY" calendar component. Any recurring
|
||||
* events are resolved into their individual busy time periods using the
|
||||
* "FREEBUSY" property.
|
||||
*
|
||||
* Example: The following is an example of a "VFREEBUSY" calendar
|
||||
* component used to request free or busy time information:
|
||||
*
|
||||
* BEGIN:VFREEBUSY
|
||||
* ORGANIZER:MAILTO:jane_doe@host1.com
|
||||
* ATTENDEE:MAILTO:john_public@host2.com
|
||||
* DTSTART:19971015T050000Z
|
||||
* DTEND:19971016T050000Z
|
||||
* DTSTAMP:19970901T083000Z
|
||||
* END:VFREEBUSY
|
||||
*
|
||||
* The following is an example of a "VFREEBUSY" calendar component used
|
||||
* to reply to the request with busy time information:
|
||||
*
|
||||
* BEGIN:VFREEBUSY
|
||||
* ORGANIZER:MAILTO:jane_doe@host1.com
|
||||
* ATTENDEE:MAILTO:john_public@host2.com
|
||||
* DTSTAMP:19970901T100000Z
|
||||
* FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M,
|
||||
* 19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M
|
||||
* URL:http://host2.com/pub/busy/jpublic-01.ifb
|
||||
* COMMENT:This iCalendar file contains busy time information for
|
||||
* the next three months.
|
||||
* END:VFREEBUSY
|
||||
*
|
||||
* The following is an example of a "VFREEBUSY" calendar component used
|
||||
* to publish busy time information.
|
||||
*
|
||||
* BEGIN:VFREEBUSY
|
||||
* ORGANIZER:jsmith@host.com
|
||||
* DTSTART:19980313T141711Z
|
||||
* DTEND:19980410T141711Z
|
||||
* FREEBUSY:19980314T233000Z/19980315T003000Z
|
||||
* FREEBUSY:19980316T153000Z/19980316T163000Z
|
||||
* FREEBUSY:19980318T030000Z/19980318T040000Z
|
||||
* URL:http://www.host.com/calendar/busytime/jsmith.ifb
|
||||
* END:VFREEBUSY
|
||||
*/
|
||||
class qCal_Component_Vfreebusy extends qCal_Component {
|
||||
|
||||
protected $name = "VFREEBUSY";
|
||||
protected $allowedComponents = array('VCALENDAR');
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Journal Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VJOURNAL
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that describe a
|
||||
* journal entry.
|
||||
*
|
||||
* Formal Definition: A "VJOURNAL" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* journalc = "BEGIN" ":" "VJOURNAL" CRLF
|
||||
* jourprop
|
||||
* "END" ":" "VJOURNAL" CRLF
|
||||
*
|
||||
* jourprop = *(
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* class / created / description / dtstart / dtstamp /
|
||||
* last-mod / organizer / recurid / seq / status /
|
||||
* summary / uid / url /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* attach / attendee / categories / comment /
|
||||
* contact / exdate / exrule / related / rdate /
|
||||
* rrule / rstatus / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A "VJOURNAL" calendar component is a grouping of
|
||||
* component properties that represent one or more descriptive text
|
||||
* notes associated with a particular calendar date. The "DTSTART"
|
||||
* property is used to specify the calendar date that the journal entry
|
||||
* is associated with. Generally, it will have a DATE value data type,
|
||||
* but it can also be used to specify a DATE-TIME value data type.
|
||||
* Examples of a journal entry include a daily record of a legislative
|
||||
* body or a journal entry of individual telephone contacts for the day
|
||||
* or an ordered list of accomplishments for the day. The "VJOURNAL"
|
||||
* calendar component can also be used to associate a document with a
|
||||
* calendar date.
|
||||
*
|
||||
* The "VJOURNAL" calendar component does not take up time on a
|
||||
* calendar. Hence, it does not play a role in free or busy time
|
||||
* searches - - it is as though it has a time transparency value of
|
||||
* TRANSPARENT. It is transparent to any such searches.
|
||||
*
|
||||
* The "VJOURNAL" calendar component cannot be nested within another
|
||||
* calendar component. However, "VJOURNAL" calendar components can be
|
||||
* related to each other or to a "VEVENT" or to a "VTODO" calendar
|
||||
* component, with the "RELATED-TO" property.
|
||||
*
|
||||
* Example: The following is an example of the "VJOURNAL" calendar
|
||||
* component:
|
||||
*
|
||||
* BEGIN:VJOURNAL
|
||||
* UID:19970901T130000Z-123405@host.com
|
||||
* DTSTAMP:19970901T1300Z
|
||||
* DTSTART;VALUE=DATE:19970317
|
||||
* SUMMARY:Staff meeting minutes
|
||||
* DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa
|
||||
* and Bob. Aurora project plans were reviewed. There is currently
|
||||
* no budget reserves for this project. Lisa will escalate to
|
||||
* management. Next meeting on Tuesday.\n
|
||||
* 2. Telephone Conference: ABC Corp. sales representative called
|
||||
* to discuss new printer. Promised to get us a demo by Friday.\n
|
||||
* 3. Henry Miller (Handsoff Insurance): Car was totaled by tree.
|
||||
* Is looking into a loaner car. 654-2323 (tel).
|
||||
* END:VJOURNAL
|
||||
*/
|
||||
class qCal_Component_Vjournal extends qCal_Component {
|
||||
|
||||
protected $name = "VJOURNAL";
|
||||
protected $allowedComponents = array('VCALENDAR');
|
||||
|
||||
}
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/**
|
||||
* Timezone Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VTIMEZONE
|
||||
*
|
||||
* Purpose: Provide a grouping of component properties that defines a
|
||||
* time zone.
|
||||
*
|
||||
* Formal Definition: A "VTIMEZONE" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* timezonec = "BEGIN" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* 2*(
|
||||
*
|
||||
* ; 'tzid' is required, but MUST NOT occur more
|
||||
* ; than once
|
||||
*
|
||||
* tzid /
|
||||
*
|
||||
* ; 'last-mod' and 'tzurl' are optional,
|
||||
* but MUST NOT occur more than once
|
||||
*
|
||||
* last-mod / tzurl /
|
||||
*
|
||||
* ; one of 'standardc' or 'daylightc' MUST occur
|
||||
* ..; and each MAY occur more than once.
|
||||
*
|
||||
* standardc / daylightc /
|
||||
*
|
||||
* ; the following is optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* "END" ":" "VTIMEZONE" CRLF
|
||||
*
|
||||
* standardc = "BEGIN" ":" "STANDARD" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "STANDARD" CRLF
|
||||
*
|
||||
* daylightc = "BEGIN" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop
|
||||
*
|
||||
* "END" ":" "DAYLIGHT" CRLF
|
||||
*
|
||||
* tzprop = 3*(
|
||||
*
|
||||
* ; the following are each REQUIRED,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* dtstart / tzoffsetto / tzoffsetfrom /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
*
|
||||
* comment / rdate / rrule / tzname / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A time zone is unambiguously defined by the set of time
|
||||
* measurement rules determined by the governing body for a given
|
||||
* geographic area. These rules describe at a minimum the base offset
|
||||
* from UTC for the time zone, often referred to as the Standard Time
|
||||
* offset. Many locations adjust their Standard Time forward or backward
|
||||
* by one hour, in order to accommodate seasonal changes in number of
|
||||
* daylight hours, often referred to as Daylight Saving Time. Some
|
||||
* locations adjust their time by a fraction of an hour. Standard Time
|
||||
* is also known as Winter Time. Daylight Saving Time is also known as
|
||||
* Advanced Time, Summer Time, or Legal Time in certain countries. The
|
||||
* following table shows the changes in time zone rules in effect for
|
||||
* New York City starting from 1967. Each line represents a description
|
||||
* or rule for a particular observance.
|
||||
*
|
||||
* Effective Observance Rule
|
||||
*
|
||||
* Date (Date/Time) Offset Abbreviation
|
||||
*
|
||||
* 1967-* last Sun in Oct, 02:00 -0500 EST
|
||||
*
|
||||
* 1967-1973 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1974-1974 Jan 6, 02:00 -0400 EDT
|
||||
*
|
||||
* 1975-1975 Feb 23, 02:00 -0400 EDT
|
||||
*
|
||||
* 1976-1986 last Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* 1987-* first Sun in Apr, 02:00 -0400 EDT
|
||||
*
|
||||
* Note: The specification of a global time zone registry is not
|
||||
* addressed by this document and is left for future study.
|
||||
* However, implementers may find the Olson time zone database [TZ]
|
||||
* a useful reference. It is an informal, public-domain collection
|
||||
* of time zone information, which is currently being maintained by
|
||||
* volunteer Internet participants, and is used in several
|
||||
* operating systems. This database contains current and historical
|
||||
* time zone information for a wide variety of locations around the
|
||||
* globe; it provides a time zone identifier for every unique time
|
||||
* zone rule set in actual use since 1970, with historical data
|
||||
* going back to the introduction of standard time.
|
||||
*
|
||||
* Interoperability between two calendaring and scheduling applications,
|
||||
* especially for recurring events, to-dos or journal entries, is
|
||||
* dependent on the ability to capture and convey date and time
|
||||
* information in an unambiguous format. The specification of current
|
||||
* time zone information is integral to this behavior.
|
||||
*
|
||||
* If present, the "VTIMEZONE" calendar component defines the set of
|
||||
* Standard Time and Daylight Saving Time observances (or rules) for a
|
||||
* particular time zone for a given interval of time. The "VTIMEZONE"
|
||||
* calendar component cannot be nested within other calendar components.
|
||||
* Multiple "VTIMEZONE" calendar components can exist in an iCalendar
|
||||
* object. In this situation, each "VTIMEZONE" MUST represent a unique
|
||||
* time zone definition. This is necessary for some classes of events,
|
||||
* such as airline flights, that start in one time zone and end in
|
||||
* another.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST be present if the iCalendar
|
||||
* object contains an RRULE that generates dates on both sides of a time
|
||||
* zone shift (e.g. both in Standard Time and Daylight Saving Time)
|
||||
* unless the iCalendar object intends to convey a floating time (See
|
||||
* the section "4.1.10.11 Time" for proper interpretation of floating
|
||||
* time). It can be present if the iCalendar object does not contain
|
||||
* such a RRULE. In addition, if a RRULE is present, there MUST be valid
|
||||
* time zone information for all recurrence instances.
|
||||
*
|
||||
* The "VTIMEZONE" calendar component MUST include the "TZID" property
|
||||
* and at least one definition of a standard or daylight component. The
|
||||
* standard or daylight component MUST include the "DTSTART",
|
||||
* "TZOFFSETFROM" and "TZOFFSETTO" properties.
|
||||
*
|
||||
* An individual "VTIMEZONE" calendar component MUST be specified for
|
||||
* each unique "TZID" parameter value specified in the iCalendar object.
|
||||
*
|
||||
* Each "VTIMEZONE" calendar component consists of a collection of one
|
||||
* or more sub-components that describe the rule for a particular
|
||||
* observance (either a Standard Time or a Daylight Saving Time
|
||||
* observance). The "STANDARD" sub-component consists of a collection of
|
||||
* properties that describe Standard Time. The "DAYLIGHT" sub-component
|
||||
* consists of a collection of properties that describe Daylight Saving
|
||||
* Time. In general this collection of properties consists of:
|
||||
*
|
||||
* - the first onset date-time for the observance
|
||||
*
|
||||
* - the last onset date-time for the observance, if a last onset
|
||||
* is known.
|
||||
*
|
||||
* - the offset to be applied for the observance
|
||||
*
|
||||
* - a rule that describes the day and time when the observance
|
||||
* takes effect
|
||||
*
|
||||
* - an optional name for the observance
|
||||
*
|
||||
* For a given time zone, there may be multiple unique definitions of
|
||||
* the observances over a period of time. Each observance is described
|
||||
* using either a "STANDARD" or "DAYLIGHT" sub-component. The collection
|
||||
* of these sub-components is used to describe the time zone for a given
|
||||
* period of time. The offset to apply at any given time is found by
|
||||
* locating the observance that has the last onset date and time before
|
||||
* the time in question, and using the offset value from that
|
||||
* observance.
|
||||
*
|
||||
* The top-level properties in a "VTIMEZONE" calendar component are:
|
||||
*
|
||||
* The mandatory "TZID" property is a text value that uniquely
|
||||
* identifies the VTIMZONE calendar component within the scope of an
|
||||
* iCalendar object.
|
||||
*
|
||||
* The optional "LAST-MODIFIED" property is a UTC value that specifies
|
||||
* the date and time that this time zone definition was last updated.
|
||||
*
|
||||
* The optional "TZURL" property is url value that points to a published
|
||||
* VTIMEZONE definition. TZURL SHOULD refer to a resource that is
|
||||
* accessible by anyone who might need to interpret the object. This
|
||||
* SHOULD NOT normally be a file: URL or other URL that is not widely-
|
||||
* accessible.
|
||||
*
|
||||
* The collection of properties that are used to define the STANDARD and
|
||||
* DAYLIGHT sub-components include:
|
||||
*
|
||||
* The mandatory "DTSTART" property gives the effective onset date and
|
||||
* local time for the time zone sub-component definition. "DTSTART" in
|
||||
* this usage MUST be specified as a local DATE-TIME value.
|
||||
*
|
||||
* The mandatory "TZOFFSETFROM" property gives the UTC offset which is
|
||||
* in use when the onset of this time zone observance begins.
|
||||
* "TZOFFSETFROM" is combined with "DTSTART" to define the effective
|
||||
* onset for the time zone sub-component definition. For example, the
|
||||
* following represents the time at which the observance of Standard
|
||||
* Time took effect in Fall 1967 for New York City:
|
||||
*
|
||||
* DTSTART:19671029T020000
|
||||
*
|
||||
* TZOFFSETFROM:-0400
|
||||
*
|
||||
* The mandatory "TZOFFSETTO " property gives the UTC offset for the
|
||||
* time zone sub-component (Standard Time or Daylight Saving Time) when
|
||||
* this observance is in use.
|
||||
*
|
||||
* The optional "TZNAME" property is the customary name for the time
|
||||
* zone. It may be specified multiple times, to allow for specifying
|
||||
* multiple language variants of the time zone names. This could be used
|
||||
* for displaying dates.
|
||||
*
|
||||
* If specified, the onset for the observance defined by the time zone
|
||||
* sub-component is defined by either the "RRULE" or "RDATE" property.
|
||||
* If neither is specified, only one sub-component can be specified in
|
||||
* the "VTIMEZONE" calendar component and it is assumed that the single
|
||||
* observance specified is always in effect.
|
||||
*
|
||||
* The "RRULE" property defines the recurrence rule for the onset of the
|
||||
* observance defined by this time zone sub-component. Some specific
|
||||
* requirements for the usage of RRULE for this purpose include:
|
||||
*
|
||||
* - If observance is known to have an effective end date, the
|
||||
* "UNTIL" recurrence rule parameter MUST be used to specify the
|
||||
* last valid onset of this observance (i.e., the UNTIL date-time
|
||||
* will be equal to the last instance generated by the recurrence
|
||||
* pattern). It MUST be specified in UTC time.
|
||||
*
|
||||
* - The "DTSTART" and the "TZOFFSETTO" properties MUST be used
|
||||
* when generating the onset date-time values (instances) from the
|
||||
* RRULE.
|
||||
*
|
||||
* Alternatively, the "RDATE" property can be used to define the onset
|
||||
* of the observance by giving the individual onset date and times.
|
||||
* "RDATE" in this usage MUST be specified as a local DATE-TIME value in
|
||||
* UTC time.
|
||||
*
|
||||
* The optional "COMMENT" property is also allowed for descriptive
|
||||
* explanatory text.
|
||||
*
|
||||
* Example: The following are examples of the "VTIMEZONE" calendar
|
||||
* component:
|
||||
*
|
||||
* This is an example showing time zone information for the Eastern
|
||||
* United States using "RDATE" property. Note that this is only suitable
|
||||
* for a recurring event that starts on or later than April 6, 1997 at
|
||||
* 03:00:00 EDT (i.e., the earliest effective transition date and time)
|
||||
* and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid
|
||||
* date and time for EST in this scenario). For example, this can be
|
||||
* used for a recurring event that occurs every Friday, 8am-9:00 AM,
|
||||
* starting June 1, 1997, ending December 31, 1997.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19971026T020000
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19971026T020000
|
||||
* RDATE:19970406T020000
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is a simple example showing the current time zone rules for the
|
||||
* Eastern United States using a RRULE recurrence pattern. Note that
|
||||
* there is no effective end date to either of the Standard Time or
|
||||
* Daylight Time rules. This information would be valid for a recurring
|
||||
* event starting today and continuing indefinitely.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* TZURL:http://zones.stds_r_us.net/tz/US-Eastern
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the Daylight Time rule has an effective end date
|
||||
* (i.e., after that date, Daylight Time is no longer observed).
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*
|
||||
* This is an example showing a fictitious set of rules for the Eastern
|
||||
* United States, where the first Daylight Time rule has an effective
|
||||
* end date. There is a second Daylight Time rule that picks up where
|
||||
* the other left off.
|
||||
*
|
||||
* BEGIN:VTIMEZONE
|
||||
* TZID:US--Fictitious-Eastern
|
||||
* LAST-MODIFIED:19870101T000000Z
|
||||
* BEGIN:STANDARD
|
||||
* DTSTART:19671029T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
* TZOFFSETFROM:-0400
|
||||
* TZOFFSETTO:-0500
|
||||
* TZNAME:EST
|
||||
* END:STANDARD
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19870405T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* BEGIN:DAYLIGHT
|
||||
* DTSTART:19990424T020000
|
||||
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
|
||||
* TZOFFSETFROM:-0500
|
||||
* TZOFFSETTO:-0400
|
||||
* TZNAME:EDT
|
||||
* END:DAYLIGHT
|
||||
* END:VTIMEZONE
|
||||
*/
|
||||
class qCal_Component_Vtimezone extends qCal_Component {
|
||||
|
||||
protected $name = "VTIMEZONE";
|
||||
protected $allowedComponents = array('VCALENDAR');
|
||||
protected $requiredProperties = array('TZID');
|
||||
/**
|
||||
* Make sure that all of the rules specified above are followed
|
||||
*/
|
||||
protected function doValidation() {
|
||||
|
||||
$children = $this->getChildren();
|
||||
if (!array_key_exists('DAYLIGHT', $children) && !array_key_exists('STANDARD', $children)) {
|
||||
throw new qCal_Exception_MissingComponent('Either a STANDARD or DAYLIGHT component is required within a VTIMEZONE component');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Todo Component
|
||||
* @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
|
||||
*
|
||||
* Component Name: VTODO
|
||||
*
|
||||
* Purpose: Provide a grouping of calendar properties that describe a
|
||||
* to-do.
|
||||
*
|
||||
* Formal Definition: A "VTODO" calendar component is defined by the
|
||||
* following notation:
|
||||
*
|
||||
* todoc = "BEGIN" ":" "VTODO" CRLF
|
||||
* todoprop *alarmc
|
||||
* "END" ":" "VTODO" CRLF
|
||||
*
|
||||
* todoprop = *(
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; but MUST NOT occur more than once
|
||||
*
|
||||
* class / completed / created / description / dtstamp /
|
||||
* dtstart / geo / last-mod / location / organizer /
|
||||
* percent / priority / recurid / seq / status /
|
||||
* summary / uid / url /
|
||||
*
|
||||
* ; either 'due' or 'duration' may appear in
|
||||
* ; a 'todoprop', but 'due' and 'duration'
|
||||
* ; MUST NOT occur in the same 'todoprop'
|
||||
*
|
||||
* due / duration /
|
||||
*
|
||||
* ; the following are optional,
|
||||
* ; and MAY occur more than once
|
||||
* attach / attendee / categories / comment / contact /
|
||||
* exdate / exrule / rstatus / related / resources /
|
||||
* rdate / rrule / x-prop
|
||||
*
|
||||
* )
|
||||
*
|
||||
* Description: A "VTODO" calendar component is a grouping of component
|
||||
* properties and possibly "VALARM" calendar components that represent
|
||||
* an action-item or assignment. For example, it can be used to
|
||||
* represent an item of work assigned to an individual; such as "turn in
|
||||
* travel expense today".
|
||||
*
|
||||
* The "VTODO" calendar component cannot be nested within another
|
||||
* calendar component. However, "VTODO" calendar components can be
|
||||
* related to each other or to a "VTODO" or to a "VJOURNAL" calendar
|
||||
* component with the "RELATED-TO" property.
|
||||
*
|
||||
* A "VTODO" calendar component without the "DTSTART" and "DUE" (or
|
||||
* "DURATION") properties specifies a to-do that will be associated with
|
||||
* each successive calendar date, until it is completed.
|
||||
*
|
||||
* Example: The following is an example of a "VTODO" calendar component:
|
||||
*
|
||||
* BEGIN:VTODO
|
||||
* UID:19970901T130000Z-123404@host.com
|
||||
* DTSTAMP:19970901T1300Z
|
||||
* DTSTART:19970415T133000Z
|
||||
* DUE:19970416T045959Z
|
||||
* SUMMARY:1996 Income Tax Preparation
|
||||
* CLASS:CONFIDENTIAL
|
||||
* CATEGORIES:FAMILY,FINANCE
|
||||
* PRIORITY:1
|
||||
* STATUS:NEEDS-ACTION
|
||||
* END:VTODO
|
||||
*/
|
||||
class qCal_Component_Vtodo extends qCal_Component {
|
||||
|
||||
protected $name = "VTODO";
|
||||
protected $allowedComponents = array('VCALENDAR');
|
||||
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
<?php
|
||||
/**
|
||||
* Base date object. Stores date information only (without a time). Internally the date is stored as a
|
||||
* unix timestamp, but the time portion of it is not used. If you need a date with a time, use qCal_DateTime
|
||||
* @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_Date {
|
||||
|
||||
/**
|
||||
* @var unix timestamp
|
||||
*/
|
||||
protected $date;
|
||||
/**
|
||||
* @var int The start day of the week (defaults to Monday)
|
||||
*/
|
||||
protected $wkst = 1;
|
||||
/**
|
||||
* @var array The results of a getdate() call
|
||||
*/
|
||||
protected $dateArray = array();
|
||||
/**
|
||||
* @var string The date format that is used when outputting via __toString()
|
||||
*/
|
||||
protected $format = "m/d/Y";
|
||||
/**
|
||||
* @var array This is just a mapping of weekdays to 0 (for Sunday) through 6 (for Saturday)
|
||||
* which is a direct correlation with PHP's date function's "w" metacharacter
|
||||
*/
|
||||
protected $weekdays = array(
|
||||
"sunday",
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
);
|
||||
/**
|
||||
* @var array This is an array of months starting at 1 and ending on 12
|
||||
*/
|
||||
protected $months = array(
|
||||
1 => "january",
|
||||
2 => "february",
|
||||
3 => "march",
|
||||
4 => "april",
|
||||
5 => "may",
|
||||
6 => "june",
|
||||
7 => "july",
|
||||
8 => "august",
|
||||
9 => "september",
|
||||
10 => "october",
|
||||
11 => "november",
|
||||
12 => "december",
|
||||
);
|
||||
/**
|
||||
* @var array The month in a two-dimensional array (picture a calendar)
|
||||
*/
|
||||
protected $monthMap = array();
|
||||
/**
|
||||
* Class constructor
|
||||
* @param int The year of this date
|
||||
* @param int The month of this date
|
||||
* @param int The day of this date
|
||||
*/
|
||||
public function __construct($year = null, $month = null, $day = null, $rollover = false) {
|
||||
|
||||
$this->setDate($year, $month, $day, $rollover);
|
||||
|
||||
}
|
||||
/**
|
||||
* Set the date of this class
|
||||
* The date defaults to now. If any part of the date is missing, it will default to whatever "now"'s
|
||||
* date portion is. For instance, if the year provided is 2006 and no other portion is given, it will
|
||||
* default to today's month and day, but in the year 2006. If, for any reason the date defaults to a
|
||||
* nonsensical date, an exception will be thrown. For instance, if you specify the year as 2006, and
|
||||
* the current date is february 29th, an exception will be thrown because the 29th of February does not
|
||||
* exist in 2006.
|
||||
* @param int The year of this date
|
||||
* @param int The month of this date
|
||||
* @param int The day of this date
|
||||
* @throws qCal_Date_Exception_InvalidDate
|
||||
*/
|
||||
protected function setDate($year = null, $month = null, $day = null, $rollover = false) {
|
||||
|
||||
$now = getdate();
|
||||
if (is_null($year)) {
|
||||
$year = $now['year'];
|
||||
}
|
||||
if (is_null($month)) {
|
||||
$month = $now['mon'];
|
||||
}
|
||||
if (is_null($day)) {
|
||||
$day = $now['mday'];
|
||||
}
|
||||
|
||||
$this->date = gmmktime(0, 0, 0, $month, $day, $year);
|
||||
$this->dateArray = self::gmgetdate($this->date);
|
||||
if (!$rollover) {
|
||||
if ($this->dateArray["mday"] != $day || $this->dateArray["mon"] != $month || $this->dateArray["year"] != $year) {
|
||||
throw new qCal_DateTime_Exception_InvalidDate("Invalid date specified for qCal_Date: \"{$month}/{$day}/{$year}\"");
|
||||
}
|
||||
}
|
||||
|
||||
// @todo Look into how much more efficient it might be to call date() only once and then break apart the result...
|
||||
$formatString = "d|D|j|l|N|S|w|z|W|F|m|M|n|t|L|o|y|Y|c|r|U";
|
||||
$keys = explode("|", $formatString);
|
||||
$vals = explode("|", gmdate($formatString, $this->date));
|
||||
$this->dateArray = array_merge($this->dateArray, array_combine($keys, $vals));
|
||||
return $this;
|
||||
|
||||
}
|
||||
/**
|
||||
* This is a factory method. It allows you to create a date by string or by another date object (to make a copy)
|
||||
*/
|
||||
public static function factory($date) {
|
||||
|
||||
if (is_integer($date)) {
|
||||
// @todo Handle timestamps
|
||||
}
|
||||
if (is_string($date)) {
|
||||
if (!$timestamp = strtotime($date)) {
|
||||
// if unix timestamp can't be created throw an exception
|
||||
throw new qCal_Date_Exception_InvalidDate("Invalid or ambiguous date string passed to qCal_Date::factory()");
|
||||
}
|
||||
}
|
||||
|
||||
$date = self::gmgetdate($timestamp);
|
||||
$newdate = gmmktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']);
|
||||
$newdate = self::gmgetdate($newdate);
|
||||
return new qCal_Date($newdate['year'], $newdate['mon'], $newdate['mday']);
|
||||
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
||||
/**
|
||||
* Formats the date according to either the existing $this->format, or if the $format arg is passed
|
||||
* in, it uses that.
|
||||
* @param string The format that is to be used (according to php's date function). Only date-related metacharacters work.
|
||||
*/
|
||||
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->dateArray)) {
|
||||
$output[] = $this->dateArray[$char];
|
||||
} else {
|
||||
$output[] = $char;
|
||||
}
|
||||
// reset this to false after every iteration that wasn't "continued"
|
||||
$escape = false;
|
||||
}
|
||||
return implode($output);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Getters
|
||||
* The next dozen or so methods are just your standard getters for things such as month, day, year, week day, etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the month (number) of this date
|
||||
* @return integer A number between 1 and 12 inclusively
|
||||
*/
|
||||
public function getMonth() {
|
||||
|
||||
return $this->dateArray["mon"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the month of this date
|
||||
* @return string The actual name of the month, capitalized
|
||||
*/
|
||||
public function getMonthName() {
|
||||
|
||||
return $this->dateArray["month"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the day of the month
|
||||
* @return integer A number between 1 and 31 inclusively
|
||||
*/
|
||||
public function getDay() {
|
||||
|
||||
return $this->dateArray["mday"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the day of the year
|
||||
* @return integer A number between 0 and 365 inclusively
|
||||
*/
|
||||
public function getYearDay($startFromOne = false) {
|
||||
|
||||
$yearDay = $this->dateArray["yday"] + (integer) $startFromOne;
|
||||
return $yearDay;
|
||||
|
||||
}
|
||||
/**
|
||||
* Find how many days until the end of the year.
|
||||
* For instance, if the date is December 25th, there are 6 days until the end of the year
|
||||
*/
|
||||
public function getNumDaysUntilEndOfYear() {
|
||||
|
||||
$yearday = $this->getYearDay(true);
|
||||
return $this->getNumDaysInYear() - $yearday;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get how many months until the end of the year
|
||||
* @todo This is really rudimentary. There is more to this, but this works for now...
|
||||
*/
|
||||
public function getNumMonthsUntilEndOfYear() {
|
||||
|
||||
return 12 - $this->getMonth();
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the amount of days in the year (365 unless it is a leap-year, then it's 366)
|
||||
*/
|
||||
public function getNumDaysInYear() {
|
||||
|
||||
return ($this->isLeapYear()) ? 366 : 365;
|
||||
|
||||
}
|
||||
/**
|
||||
* Return the first day of the month as a qCal_Date object
|
||||
* @return qCal_Date The first day of the month
|
||||
*/
|
||||
public function getFirstDayOfMonth() {
|
||||
|
||||
return new qCal_Date($this->getYear(), $this->getMonth(), 1);
|
||||
|
||||
}
|
||||
/**
|
||||
* Return the last day of the month as a qCal_Date object
|
||||
* @return qCal_Date The last day of the month
|
||||
*/
|
||||
public function getLastDayOfMonth() {
|
||||
|
||||
$lastday = $this->format("t");
|
||||
return new qCal_Date($this->getYear(), $this->getMonth(), $lastday);
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the number of days until the end of the month
|
||||
*/
|
||||
public function getNumDaysUntilEndOfMonth() {
|
||||
|
||||
return $this->getNumDaysInMonth() - $this->getDay();
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the year
|
||||
* @return integer The year of this date, for example 1999
|
||||
*/
|
||||
public function getYear() {
|
||||
|
||||
return $this->dateArray["year"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the day of the week
|
||||
* @return integer A number between 0 (for Sunday) and 6 (for Saturday).
|
||||
*/
|
||||
public function getWeekDay() {
|
||||
|
||||
return $this->dateArray["wday"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the day of the week
|
||||
* @return string The actual name of the day of the week, capitalized
|
||||
*/
|
||||
public function getWeekDayName() {
|
||||
|
||||
return $this->dateArray["weekday"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the amount of days in the current month of this year
|
||||
* @return integer The number of days in the month
|
||||
*/
|
||||
public function getNumDaysInMonth() {
|
||||
|
||||
return $this->dateArray["t"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get the week of the year
|
||||
* @return integer The week of the year (0-51 I think)
|
||||
* @todo This is not accurate if the week start isn't monday. I need to adjust for that
|
||||
*/
|
||||
public function getWeekOfYear() {
|
||||
|
||||
return $this->dateArray["W"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get how many weeks until the end of the year
|
||||
* @todo This is really rudimentary. There is more to this, but this works for now...
|
||||
*/
|
||||
public function getWeeksUntilEndOfYear() {
|
||||
|
||||
return 52 - $this->getWeekOfYear();
|
||||
|
||||
}
|
||||
/**
|
||||
* Determine if this is a leap year
|
||||
*/
|
||||
public function isLeapYear() {
|
||||
|
||||
return (boolean) $this->dateArray["L"];
|
||||
|
||||
}
|
||||
/**
|
||||
* Get a unix timestamp for the date
|
||||
* @return integer The amount of seconds since unix epoch (January 1, 1970 UTC)
|
||||
*/
|
||||
public function getUnixTimestamp() {
|
||||
|
||||
return $this->dateArray[0];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Date magic
|
||||
* This component is capable of doing some really convenient things with dates.
|
||||
* It is capable of determining things such as how many days until the end of the year,
|
||||
* which monday of the month it is (ie: third monday in february), etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine the number or Tuesdays (or whatever day of the week this date is) since the
|
||||
* beginning or end of the month.
|
||||
* @param integer $xth A positive or negative number that determines which weekday of the month we want
|
||||
* @param string|integer $weekday Either Sunday-Saturday or 0-6 to specify the weekday we want
|
||||
* @param string|integer $month Either January-December or 1-12 to specify the month we want
|
||||
* @param integer $year A valid year to specify which year we want
|
||||
*/
|
||||
public function getXthWeekdayOfMonth($xth, $weekday = null, $month = null, $year = null) {
|
||||
|
||||
$negpos = substr($xth, 0, 1);
|
||||
if ($negpos == "+" || $negpos == "-") {
|
||||
$xth = (integer) substr($xth, 1);
|
||||
} else {
|
||||
$negpos = "+";
|
||||
}
|
||||
|
||||
if (is_null($weekday)) {
|
||||
$weekday = $this->getWeekday();
|
||||
}
|
||||
|
||||
if (ctype_digit((string) $weekday)) {
|
||||
if (!array_key_exists($weekday, $this->weekdays)) {
|
||||
throw new qCal_Date_Exception_InvalidWeekday("\"$weekday\" is not a valid weekday.");
|
||||
}
|
||||
} else {
|
||||
$weekday = strtolower($weekday);
|
||||
if (!in_array($weekday, $this->weekdays)) {
|
||||
throw new qCal_Date_Exception_InvalidWeekday("\"$weekday\" is not a valid weekday.");
|
||||
}
|
||||
$wdays = array_flip($this->weekdays);
|
||||
$weekday = $wdays[$weekday];
|
||||
}
|
||||
|
||||
if (is_null($month)) {
|
||||
$month = $this->getMonth();
|
||||
}
|
||||
|
||||
if (ctype_digit((string) $month)) {
|
||||
if (!array_key_exists($month, $this->months)) {
|
||||
throw new qCal_Date_Exception_InvalidMonth("\"$month\" is not a valid month.");
|
||||
}
|
||||
} else {
|
||||
$month = strtolower($month);
|
||||
if (!in_array($month, $this->months)) {
|
||||
throw new qCal_Date_Exception_InvalidMonth("\"$month\" is not a valid month.");
|
||||
}
|
||||
$mons = array_flip($this->months);
|
||||
$month = $mons[$month];
|
||||
}
|
||||
|
||||
if (is_null($year)) {
|
||||
$year = $this->getYear();
|
||||
}
|
||||
|
||||
if (!ctype_digit((string) $year) || strlen($year) != 4) {
|
||||
throw new qCal_Date_Exception_InvalidYear("\"$year\" is not a valid year.");
|
||||
}
|
||||
|
||||
// now, using the year, month and numbered weekday, we need to find the actual day of the month...
|
||||
$firstofmonth = new qCal_Date($year, $month, 1);
|
||||
$numdaysinmonth = $firstofmonth->getNumDaysInMonth();
|
||||
$numweekdays = 0; // the number of weekdays that have occurred (in the loop)
|
||||
$foundday = false;
|
||||
if ($negpos == "+") {
|
||||
$day = 1;
|
||||
$wday = $firstofmonth->getWeekday();
|
||||
// while we are in the current month, loop
|
||||
while ($day <= $numdaysinmonth) {
|
||||
// if the specified weekday == the current week day in the loop
|
||||
if ($weekday == $wday) {
|
||||
$numweekdays++;
|
||||
if ($numweekdays == $xth) {
|
||||
// break out of the loop, we've found the right day! yay!
|
||||
$foundday = $day;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($wday == 6) $wday = 0; // reset to Sunday after Saturday
|
||||
else $wday++;
|
||||
$day++;
|
||||
}
|
||||
} else {
|
||||
$day = $numdaysinmonth;
|
||||
$lastofmonth = $firstofmonth->getLastDayOfMonth();
|
||||
$wday = $lastofmonth->getWeekday();
|
||||
while ($day >= 1) {
|
||||
if ($weekday == $wday) {
|
||||
$numweekdays++;
|
||||
if ($numweekdays == $xth) {
|
||||
// break out of the loop, we've found the right day! yay!
|
||||
$foundday = $day;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($wday == 0) $wday = 6; // reset to Saturday after Sunday
|
||||
else $wday--;
|
||||
$day--;
|
||||
}
|
||||
}
|
||||
|
||||
if ($foundday && checkdate($month, $day, $year)) {
|
||||
$date = new qCal_Date($year, $month, $day);
|
||||
} else {
|
||||
if ($day == 32) {
|
||||
throw new qCal_DateTime_Exception_InvalidDate("You have specified an incorrect number of days for qCal_Date::getXthWeekdayOfMonth()");
|
||||
} else {
|
||||
throw new qCal_DateTime_Exception_InvalidDate("You have entered an invalid date.");
|
||||
}
|
||||
}
|
||||
|
||||
return $date;
|
||||
|
||||
}
|
||||
/**
|
||||
* Determine the number or Tuesdays (or whatever day of the week this date is) since the
|
||||
* beginning or end of the year.
|
||||
*/
|
||||
public function getXthWeekdayOfYear($xth, $weekday = null, $year = null) {
|
||||
|
||||
$negpos = substr($xth, 0, 1);
|
||||
if ($negpos == "+" || $negpos == "-") {
|
||||
$xth = (integer) substr($xth, 1);
|
||||
} else {
|
||||
$negpos = "+";
|
||||
}
|
||||
|
||||
if (is_null($weekday)) {
|
||||
$weekday = $this->getWeekday();
|
||||
}
|
||||
|
||||
if (ctype_digit((string) $weekday)) {
|
||||
if (!array_key_exists($weekday, $this->weekdays)) {
|
||||
throw new qCal_Date_Exception_InvalidWeekday("\"$weekday\" is not a valid weekday.");
|
||||
}
|
||||
} else {
|
||||
$weekday = strtolower($weekday);
|
||||
if (!in_array($weekday, $this->weekdays)) {
|
||||
throw new qCal_Date_Exception_InvalidWeekday("\"$weekday\" is not a valid weekday.");
|
||||
}
|
||||
$wdays = array_flip($this->weekdays);
|
||||
$weekday = $wdays[$weekday];
|
||||
}
|
||||
|
||||
if (is_null($year)) {
|
||||
$year = $this->getYear();
|
||||
}
|
||||
|
||||
if (!ctype_digit((string) $year) || strlen($year) != 4) {
|
||||
throw new qCal_Date_Exception_InvalidYear("\"$year\" is not a valid year.");
|
||||
}
|
||||
|
||||
// now find the specified day by counting either forwards or backwards to the day in question
|
||||
$firstofyear = new qCal_Date($year, 1, 1);
|
||||
$numdaysinyear = ($firstofyear->isLeapYear()) ? 366 : 365;
|
||||
$numweekdays = 0; // the number of weekdays that have occurred within the loop
|
||||
$found = false; // whether or not the specified day has been found
|
||||
if ($negpos == "+") {
|
||||
// count forward
|
||||
// loop over every day of every month looking for the right one
|
||||
$day = 1;
|
||||
$wday = $firstofyear->getWeekDay();
|
||||
while ($day <= $numdaysinyear) {
|
||||
// if the specified weekday == the current week day in the loop
|
||||
if ($weekday == $wday) {
|
||||
$numweekdays++;
|
||||
if ($numweekdays == $xth) {
|
||||
// break out of the loop, we've found the right day! yay!
|
||||
$found = $day;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($wday == 6) $wday = 0; // reset to Sunday after Saturday
|
||||
else $wday++;
|
||||
$day++;
|
||||
}
|
||||
} else {
|
||||
// count backward
|
||||
$lastofyear = new qCal_Date($year, 12, 31);
|
||||
// count forward
|
||||
// loop over every day of every month looking for the right one
|
||||
$day = $numdaysinyear;
|
||||
$wday = $lastofyear->getWeekDay();
|
||||
while ($day >= 1) {
|
||||
// if the specified weekday == the current week day in the loop
|
||||
if ($weekday == $wday) {
|
||||
$numweekdays++;
|
||||
if ($numweekdays == $xth) {
|
||||
// break out of the loop, we've found the right day! yay!
|
||||
$found = $day;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($wday == 0) $wday = 6; // reset to Saturday after Sunday
|
||||
else $wday--;
|
||||
$day--;
|
||||
}
|
||||
}
|
||||
|
||||
// @todo: Can't use checkdate here, so find another validation method...
|
||||
if ($found) {
|
||||
$date = new qCal_Date($year, 1, $found, true); // takes advantage of the rollover feature :)
|
||||
} else {
|
||||
throw new qCal_DateTime_Exception_InvalidDate("You have specified an incorrect number of days for qCal_Date::getXthWeekdayOfYear()");
|
||||
}
|
||||
|
||||
return $date;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output the date as a string. Options are as follows:
|
||||
* @return string The formatted date
|
||||
*/
|
||||
public function __toString() {
|
||||
|
||||
return $this->format($this->format);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Static methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Because PHP does not provide a gmgetdate() function, I borrowed this one from the
|
||||
* comments on the getdate() function page on php.net
|
||||
* @param integer The timestamp to use to create the date
|
||||
*/
|
||||
public static function gmgetdate($timestamp = null) {
|
||||
|
||||
$k = array('seconds','minutes','hours','mday','wday','mon','year','yday','weekday','month',0);
|
||||
return(array_combine($k, split(":", gmdate('s:i:G:j:w:n:Y:z:l:F:U', is_null($timestamp) ? time() : $timestamp))));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* qCal_DateTime
|
||||
*
|
||||
* In order to perform all the complex date/time based math and logic required to
|
||||
* implement the iCalendar spec, we need a complex date/time class. This class represents
|
||||
* a specific point in time, including the time. Internally it makes use of qCal_Date and
|
||||
* qCal_Time. If only a date or only a time needs to be represented, then one of those
|
||||
* classes should be used.
|
||||
*
|
||||
* @package qCal_Date
|
||||
* @
|
||||
*/
|
||||
class qCal_DateTime {
|
||||
|
||||
/**
|
||||
* @var qCal_Date An object that represents the date
|
||||
*/
|
||||
protected $date;
|
||||
/**
|
||||
* @var qCal_Time An object that represents the time
|
||||
*/
|
||||
protected $time;
|
||||
/**
|
||||
* @var string The default string representation of datetime is a direct
|
||||
* correlation to the date function's "c" metacharacter
|
||||
*/
|
||||
protected $format = "Y-m-d\TH:i:sP";
|
||||
/**
|
||||
* Class constructor
|
||||
* @todo Make this default to "now"
|
||||
* @todo It is possible that the timezone could put the date back (or forward?) a day. This does not account for that
|
||||
*/
|
||||
public function __construct($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null, $rollover = null) {
|
||||
|
||||
$date = new qCal_Date($year, $month, $day, $rollover);
|
||||
$time = new qCal_Time($hour, $minute, $second, $timezone, $rollover);
|
||||
$this->setDate($date);
|
||||
$this->setTime($time);
|
||||
|
||||
}
|
||||
/**
|
||||
* Generate a datetime object via string
|
||||
* @todo Should this accept qCal_Date and qCal_DateTime objects?
|
||||
*/
|
||||
public static function factory($datetime, $timezone = null) {
|
||||
|
||||
if (is_null($timezone) || !($timezone instanceof qCal_Timezone)) {
|
||||
// @todo Make sure this doesn't cause any issues
|
||||
// detect if we're working with a UTC string like "19970101T180000Z", where the Z means use UTC time
|
||||
if (strtolower(substr($datetime, -1)) == "z") {
|
||||
$timezone = "UTC";
|
||||
}
|
||||
$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");
|
||||
|
||||
// handles unix timestamp
|
||||
if (is_integer($datetime) || ctype_digit((string) $datetime)) {
|
||||
$timestamp = $datetime;
|
||||
} else {
|
||||
// handles just about any string representation of date/time (strtotime)
|
||||
if (is_string($datetime) || empty($datetime)) {
|
||||
if (!$timestamp = strtotime($datetime)) {
|
||||
// if unix timestamp can't be created throw an exception
|
||||
throw new qCal_DateTime_Exception("Invalid or ambiguous date/time string passed to qCal_DateTime::factory()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($timestamp)) {
|
||||
throw new qCal_DateTime_Exception("Could not generate a qCal_DateTime object.");
|
||||
}
|
||||
|
||||
list($year, $month, $day, $hour, $minute, $second) = explode("|", gmdate("Y|m|d|H|i|s", $timestamp));
|
||||
|
||||
// set the timezone back to what it was
|
||||
date_default_timezone_set($tz);
|
||||
|
||||
return new qCal_DateTime($year, $month, $day, $hour, $minute, $second, $timezone);
|
||||
|
||||
}
|
||||
/**
|
||||
* Set the date component
|
||||
*/
|
||||
protected function setDate(qCal_Date $date) {
|
||||
|
||||
$this->date = $date;
|
||||
|
||||
}
|
||||
/**
|
||||
* Set the time component
|
||||
*/
|
||||
protected function setTime(qCal_Time $time) {
|
||||
|
||||
$this->time = $time;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get time portion as object
|
||||
*/
|
||||
public function getTime() {
|
||||
|
||||
return $this->time;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get date portion as object
|
||||
*/
|
||||
public function getDate() {
|
||||
|
||||
return $this->date;
|
||||
|
||||
}
|
||||
/**
|
||||
* Get unix timestamp
|
||||
*/
|
||||
public function getUnixTimestamp($useOffset = true) {
|
||||
|
||||
return $this->date->getUnixTimestamp() + $this->time->getTimestamp($useOffset);
|
||||
|
||||
}
|
||||
/**
|
||||
* Set the format to use when outputting as a string
|
||||
*/
|
||||
public function setFormat($format) {
|
||||
|
||||
$this->format = (string) $format;
|
||||
return $this;
|
||||
|
||||
}
|
||||
/**
|
||||
* Format the date/time using PHP's date() function's meta-characters
|
||||
* @todo It's obvious I need to find a better solution to formatting since I have repeated this method
|
||||
* in three classes now...
|
||||
*/
|
||||
public function format($format) {
|
||||
|
||||
$escape = false;
|
||||
$meta = str_split($format);
|
||||
$output = array();
|
||||
foreach($meta as $char) {
|
||||
if ($char == '\\') {
|
||||
$escape = true;
|
||||
continue;
|
||||
}
|
||||
if (!$escape && $this->convertChar($char) != $char) {
|
||||
$output[] = $this->convertChar($char);
|
||||
} else {
|
||||
$output[] = $char;
|
||||
}
|
||||
// reset this to false after every iteration that wasn't "continued"
|
||||
$escape = false;
|
||||
}
|
||||
return implode($output);
|
||||
|
||||
}
|
||||
/**
|
||||
* convert character
|
||||
*/
|
||||
protected function convertChar($char) {
|
||||
|
||||
$char = $this->date->format($char);
|
||||
$char = $this->time->format($char);
|
||||
$char = $this->time->getTimezone()->format($char);
|
||||
return $char;
|
||||
|
||||
}
|
||||
/**
|
||||
* Output date/time as string
|
||||
*/
|
||||
public function __toString() {
|
||||
|
||||
return $this->format($this->format);
|
||||
|
||||
}
|
||||
/**
|
||||
* Get date/time as UTC
|
||||
*/
|
||||
public function getUtc($humanReadable = false) {
|
||||
|
||||
if ($humanReadable) return gmdate('Y-m-d', $this->date->getUnixTimestamp()) . gmdate('\TH:i:s\Z', $this->time->getTimestamp());
|
||||
else return gmdate('Ymd', $this->date->getUnixTimestamp()) . gmdate('\THis\Z', $this->time->getTimestamp());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Date duration
|
||||
*
|
||||
* @package qCal
|
||||
* @subpackage qCal_DateTime
|
||||
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
|
||||
* @author Luke Visinoni (luke.visinoni@gmail.com)
|
||||
* @license GNU Lesser General Public License
|
||||
*/
|
||||
class qCal_DateTime_Duration {
|
||||
|
||||
// an array of how manys seconds are in a minute, hour, day, etc.
|
||||
// IMPORTANT - don't change the order of these
|
||||
protected $durations = array ('W' => 604800, 'D' => 86400, 'H' => 3600, 'M' => 60, 'S' => 1);
|
||||
/**
|
||||
* Duration in seconds
|
||||
*/
|
||||
protected $duration;
|
||||
/**
|
||||
* If this is negative, this will be a minus symbol. Positive doesn't need a sign, so it is just null
|
||||
*/
|
||||
protected $sign;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($duration = null) {
|
||||
|
||||
$this->setDuration($duration);
|
||||
|
||||
}
|
||||
/**
|
||||
* Set duration - accepts an integer (amount of seconds) or an icalendar-formatted duration string
|
||||
*/
|
||||
public function setDuration($duration) {
|
||||
|
||||
$duration = strtoupper($duration);
|
||||
// if plus or minus precedes number, remove it set in class
|
||||
if (preg_match("/^[+-]/", (string) $duration, $matches)) {
|
||||
if ($matches[0] == "-") $this->sign = "-";
|
||||
$duration = str_split($duration);
|
||||
array_shift($duration);
|
||||
$duration = implode("", $duration);
|
||||
}
|
||||
if (ctype_digit($duration)) {
|
||||
$this->duration = $duration;
|
||||
} else {
|
||||
// convert value to duration in seconds
|
||||
preg_match('/^P([0-9]+[W])?([0-9]+[D])?T?([0-9]+[H])?([0-9]+[M])?([0-9]+[S])?$/i', $duration, $matches);
|
||||
// remove first element (which is just entire the matched string)
|
||||
array_shift($matches);
|
||||
$seconds = 0;
|
||||
foreach ($matches as $duration) {
|
||||
if (empty($duration)) continue;
|
||||
$seconds += $this->calculateSeconds($duration);
|
||||
}
|
||||
$this->duration = $seconds;
|
||||
}
|
||||
return $this;
|
||||
|
||||
}
|
||||
/**
|
||||
* Pass in a string like "15W" or "1D" and this will return how many seconds are in it
|
||||
*/
|
||||
protected function calculateSeconds($duration) {
|
||||
|
||||
$amnt = preg_replace("/[^0-9]/i", "", $duration);
|
||||
$inc = preg_replace("/[^A-Z]/i", "", $duration);
|
||||
return $this->durations[$inc] * $amnt;
|
||||
|
||||
}
|
||||
/**
|
||||
* Converts seconds to an icalendar-formatted duration string
|
||||
*/
|
||||
public function toICal() {
|
||||
|
||||
$total = $this->duration;
|
||||
$return = "P";
|
||||
// this is why order is important when defining $this->durations
|
||||
foreach ($this->durations as $dur => $amnt) {
|
||||
// how many "weeks" are in the value?
|
||||
$quotient = (int) ($total / $amnt);
|
||||
// get the remainder of the division
|
||||
$remainder = $total - ($quotient*$amnt);
|
||||
// now if we got a whole number as quotient, add this duration to the return string
|
||||
if ($quotient) {
|
||||
// if this is the first "time" duration, add the required T char
|
||||
if ($dur == "H" || $dur == "M" || $dur == "S") {
|
||||
if (!strpos($return, "T")) $return .= "T";
|
||||
}
|
||||
$return .= $quotient . $dur;
|
||||
}
|
||||
$total = $remainder;
|
||||
}
|
||||
return $this->sign . $return;
|
||||
|
||||
}
|
||||
/**
|
||||
* @todo Should this be the string representation? I dont really know.
|
||||
*/
|
||||
public function __toString() {
|
||||
|
||||
return $this->toICal();
|
||||
|
||||
}
|
||||
/**
|
||||
* Get duration in seconds
|
||||
*/
|
||||
public function getSeconds() {
|
||||
|
||||
return (integer) $this->sign . $this->duration;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* qCal_Date is a sub-package of qCal, so it has its own exceptions.
|
||||
*/
|
||||
class qCal_DateTime_Exception extends qCal_Exception {
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Invalid Date Exception - thrown when an invalid or ambiguous date is passed to qCal_Date::setDate()
|
||||
* @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_Exception_InvalidDate extends qCal_DateTime_Exception {
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Invalid Date Span Exception - thrown when somebody attempts to make a start date come after an end date
|
||||
* @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_Exception_InvalidPeriod extends qCal_DateTime_Exception {
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Invalid Date Recurrence Exception - thrown when somebody attempts to create an invalid recurrence
|
||||
* @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_Exception_InvalidRecur extends qCal_DateTime_Exception {
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Invalid Time Exception - thrown when an invalid or ambiguous time string is passed to qCal_Time::setTime()
|
||||
* @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_Exception_InvalidTime extends qCal_DateTime_Exception {
|
||||
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
class qCal_DateTime_Exception_InvalidTimezone extends qCal_DateTime_Exception {}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
class qCal_DateTime_Exception_InvalidWeekday extends qCal_DateTime_Exception {
|
||||
|
||||
// w00t!
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Daily extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Hourly extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Minutely extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Monthly extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -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();
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByDay extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByHour extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByMinute extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByMonthDay extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_BySecond extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_BySetPos extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByWeekNo extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Rule_ByYearDay extends qCal_DateTime_Recur_Rule {
|
||||
|
||||
public function getRecurrences() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Secondly extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
class qCal_DateTime_Recur_Weekly extends qCal_DateTime_Recur {
|
||||
|
||||
protected function doGetRecurrences($rules, $start, $end) {
|
||||
|
||||
// do stuff!
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+143
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
class qCal_Exception_FileNotFound extends qCal_Exception {
|
||||
|
||||
// hooty
|
||||
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
class qCal_Exception_InvalidFile extends qCal_Exception {}
|
||||
+12
@@ -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 {
|
||||
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
}
|
||||
+6
@@ -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
|
||||
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
+120
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
+61
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+72
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+47
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+57
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+70
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+55
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+96
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
+124
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user