0byt3m1n1
Path:
/
data
/
applications
/
aps
/
tikiwiki
/
7.0-0
/
standard
/
htdocs
/
lib
/
ical
/
iCal
/
[
Home
]
File: Component.php
<?php /* PHP iCal Interface Library Copyright (C) 2005 Gregory Szorc <gregory.szorc@case.edu> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** * iCal (RFC 2245) class definition * * PHP version 5 * * @package iCal * @subpackage Parser * @author Gregory Szorc <gregory.szorc@case.edu> * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 */ /** * iCal components when put together form an iCalendar. * * File_iCal_Components are the representation of iCal components. The base class is abstract * and provides methods common to all types of components. * * @author Gregory Szorc <gregory.szorc@case.edu> * @package iCal * @abstract */ abstract class File_iCal_Component { /** * The name for this component * * @access protected * @var string */ protected $_name; /** * The properties associated with this component * * @access protected * @var array */ protected $_properties = array(); /** * Array of possible properties for this component * * @access protected * @var array */ protected $_properties_possible = array(); /** * Array of possible properties for this component that can only occur once * * @access protected * @var array */ protected $_properties_single = array(); /** * Array of possible properties for this component which can occur more than once * * @access protected * @var array */ protected $_properties_multiple = array(); /** * Array of arrays of properties which are exclusive to each other * * @access protected * @var array */ protected $_properties_exclusive = array(); /** * Creates a component * * @access public * @param array Array of properties */ public function __construct($s) { $this->_properties_possible = array_merge($this->_properties_single, $this->_properties_multiple); if (is_array($s)) { //verify integrity of the array foreach ($s as $v) { if (!is_a($v, "File_iCal_ContentLine")) { trigger_error("Component constructor passed array does not contain all ContentLines", E_USER_ERROR); } } //all elements are ConentLines //verify first and last lines are BEGIN and END, respectively if (($s[0]->name() == "BEGIN") && ($s[count($s)-1]->name() == "END")) { $this->_name = $s[0]->value(); //go through and create the properties for ($i = 1, $icount_s = count($s); $i < $icount_s - 1; $i++) { $name = strtoupper($s[$i]->name()); if (in_array($name, $this->_properties_possible)) { //now we know we have a good property //easiest case is to add it to an array if (in_array($name, $this->_properties_multiple)) { $prop = $s[$i]->getProperty(); self::addProperty($prop, true); } else if (in_array($name, $this->_properties_single)) { $check_conflict = false; foreach ($this->_properties_exclusive as $pe) { if (is_array($pe) && in_array($name, $pe)) $check_conflict = true; } if ($check_conflict) { $is_conflict = false; foreach ($this->_properties_exclusive as $pe) { foreach ($pe as $name_conflict) { if (array_key_exists($name_conflict, $this->_properties)) { trigger_error("A property conflicts with another! The iCal file is not valid", E_USER_WARNING); $is_conflict = true; } } } if (!$is_conflict) { self::addProperty($s[$i]->getProperty(), false); } } else { $prop = $s[$i]->getProperty(); self::addProperty($prop, false); } } else { trigger_error("Not sure what to do with property", E_USER_WARNING); } } /* else { //trigger_error("Unexpected property in component. Found $name", E_USER_WARNING); } */ } } else { trigger_error("Component array must start and end with BEGIN and END tags", E_USER_ERROR); } } /* else { //trigger_error("Component constructor expects an array", E_USER_ERROR); } */ } /** * Add a property to the current component * * @access protected * @param File_iCal_Property $property The property to add to this component * @param bool $multiple Whether this is a multiple property */ protected function addProperty($property, $multiple = false) { //File_iCal_Property $name = $property->getName(); if (!array_key_exists($name, $this->_properties)) { if ($multiple) { $this->_properties[$name] = array(); $this->_properties[$name][] = $property; return; } else { $this->_properties[$name] = $property; return; } } else if ($multiple) { $this->_properties[$name][] = $property; return; } else { //the logic before addProperty should have prevented this from happening... trigger_error("Trying to insert a property (".$name.") that already exists. This function should never have been called", E_USER_ERROR); } } /** * Get all of the properties associated with this component * * @access public * @return array An array of File_iCal_Property objects */ public function getPropertyArray() { $r = array(); require_once 'Property.php'; $r[] = File_iCal_Property::getProperty("BEGIN", array(), $this->_name); foreach ($this->_properties as $prop) { if (is_array($prop)) { foreach ($prop as $propv) { $r[] = $propv; } } else { $r[] = $prop; } } $r[] = File_iCal_Property::getProperty("END", array(), $this->_name); return $r; } /** * get an array of contentLines for this component * * @access public * @return array Array of File_iCal_ContentLine objects */ public function getCalendar() { $r = array(); require_once 'ContentLine.php'; $r[] = new File_iCal_ContentLine("BEGIN:".$this->_name); foreach ($this->_properties as $prop) { if (is_array($prop)) { foreach ($prop as $propv) { if (is_a($propv, "File_iCal_Property")) { //$r[] = $propv->getName().':'.$propv->getValue(); $r[] = new File_iCal_ContentLine($propv); } } } else { if (is_a($prop, "File_iCal_Property")) { //$r[] = $prop->getName().':'.$prop->getValue(); $r[] = new File_iCal_ContentLine($prop); } } } $r[] = new File_iCal_ContentLine("END:".$this->_name); return $r; } /** * See if a property exists * * @access protected * @return int The number of occurences * @param string $name The name of the property * @param int $key By Reference: will be set to an integer or array of intergers. * The values represent the internal array keys for properties of this type. */ protected function propertyExists($name, &$key = null) { require_once 'Property.php'; $pn = File_iCal_Property::getClassName($name); $count = 0; $keys = array(); foreach ($this->_properties as $k=>$p) { if (is_a($p, $pn)) { $count++; $keys[] = $k; } } if (count($keys) == 1) { $key = $keys[0]; } else { $key = $keys; } return $count; } /** * Add a property value to an existing property if it exists * * @access protected * @param string $name The name of the property to which to add the value * @param string $value The value to add to the property * @param bool $match_param If multiple properties with the name are present, we don't know for sure to which to add the new value * If set to true, the function will check for matching parameters when selecting the property to which to add */ protected function addPropertyValue($name, $value, $match_param = null) { require_once 'Property.php'; if (in_array($name, $this->_properties_possible)) { $pn = File_iCal_Property::getClassName($name); if (in_array($name, $this->_properties_single)) { foreach ($this->_properties as $p) { if (is_a($p, $pn)) { return $p->addValue($value); } } } else if (in_array($name, $this->_properties_multiple)) { foreach ($this->_properties as $p) { if (is_a($p, $pn)) { //match the $match_param here //ignore for now return $p->addValue($value); } } } } else { trigger_error("The property $name is not allowed for component ".$this->_name, E_USER_WARNING); } } /** * Returns a new component for a passed File_iCal_{Event, Alarm, FreeBusy, TimeZone, ToDo} * * @access public * @static * @param object $e The event for which you wish to return a component object * @return File_iCal_Component_Event The new component object */ public static function getComponent($e) { //ideally we call the component constructor with an array of contentlines $props = array(); $component_name = ""; //print_r($e); switch (get_class($e)) { case "File_iCal_Alarm": $component_name = "VALARM"; break; case "File_iCal_Event": $component_name = "VEVENT"; break; case "File_iCal_FreeBusy": $component_name = "VFREEBUSY"; break; case "File_iCal_TimeZone": $component_name = "VTIMEZONE"; break; case "File_iCal_ToDo": $component_name = "VTODO"; break; case "File_iCal_Journal": $component_name = "VJOURNAL"; break; default: trigger_error("Passed object not valid type (is a ".get_class($e).")", E_USER_WARNING); } require_once 'Property.php'; $props[] = File_iCal_Property::getProperty("BEGIN", array(), $component_name); //attachment is defined in the basecomponent class, so method_exists is always true /* if (is_subclass_of($e, "File_iCal_BaseComponent_EJT") || is_a($e, "File_iCal_Alarm")) { } //needs to be finished if (is_subclass_of($e, "File_iCal_BaseComponent_EFJT") || is_a($e, "File_iCal_TimeZone")) { foreach ($e->getComments() as $c) { } } */ //this method is defined in the BaseComponent class, so it always exists //method should only be public for AEJT if (is_subclass_of($e, "File_iCal_BaseComponent_EJT") || is_a($e, "File_iCal_Alarm")) { if ($description = $e->getDescription()) { $props[] = File_iCal_Property::getProperty("DESCRIPTION", array(), $description); } } if (is_subclass_of($e, "File_iCal_BaseComponent_EJT") || is_a($e, "File_iCal_Alarm")) { if ($summary = $e->getSummary()) { $props[] = File_iCal_Property::getProperty("SUMMARY", array(), $summary); } } if (is_a($e, "File_iCal_Event") || is_a($e, "File_iCal_FreeBusy")) { if (($de = $e->getDateEnd()) > 0) { $props[] = File_iCal_Property::getProperty("DTEND", array(), $de); } } if (is_subclass_of($e, "File_iCal_BaseComponent_EFJT")) { if (($ds = $e->getDateStart()) > 0) { $props[] = File_iCal_Property::getProperty("DTSTART", array(), $ds); } } if (is_subclass_of($e, "File_iCal_BaseComponent_ET") || is_a($e, "File_iCal_Alarm") || is_a($e, "File_iCal_FreeBusy")) { if (($dur = $e->getDuration()) > 0) { $props[] = File_iCal_Property::getProperty("DURATION", array(), $dur); } } //should be changed /* if (method_exists($e, "getAttendees")) { } if (is_subclass_of($e, "File_iCal_BaseComponent_EJT") || is_a($e, "File_iCal_TimeZone")) { } if (method_exists($e, "getContacts")) { } */ if (method_exists($e, "getOrganizer")) { if ($o = $e->getOrganizer()) { $props[] = File_iCal_Property::getProperty("ORGANIZER", array(), $o); } } if (method_exists($e, "getURL")) { if ($url = $e->getURL()) { $props[] = File_iCal_Property::getProperty("URL", array(), $url); } } if (method_exists($e, "getUID")) { if ($uid = $e->getUID()) { $props[] = File_iCal_Property::getProperty("UID", array(), $uid); } } if (method_exists($e, "getDateStamp")) { if ($ds = $e->getDateStamp()) { $props[] = File_iCal_Property::getProperty("DTSTAMP", array(), $uid); } } /* if (method_exists($e, "getRequestStatus")) { } if (method_exists($e, "getCategories")) { } if (method_exists($e, "getClassification")) { } if (method_exists($e, "getStatus")) { } if (method_exists($e, "getRecurrenceId")) { } if (method_exists($e, "getRelatedTo")) { } if (method_exists($e, "getCreated")) { } */ if (method_exists($e, "getSequence")) { if ($sequence = $e->getSequence()) { $props[] = File_iCal_Property::getProperty("SEQUENCE", array(), $sequence); } } /* if (method_exists($e, "getLatitude")) { } if (method_exists($e, "getLongitude")) { } */ if (method_exists($e, "getLocation")) { if ($location = $e->getLocation()) { $props[] = File_iCal_Property::getLocation("LOCATION", array(), $location); } } /* if (method_exists($e, "getPriority")) { } if (method_exists($e, "getResources")) { } if (method_exists($e, "getTransparency")) { } */ $props[] = File_iCal_Property::getProperty("END", array(), $component_name); //convert these properties to contentlines require_once 'ContentLine.php'; foreach ($props as $k=>$p) { $props[$k] = new File_iCal_ContentLine($p); } switch ($component_name) { case "VEVENT": return new File_iCal_Component_Event($props); break; case "VTODO": return new File_iCal_Component_Todo($props); break; case "VTIMEZONE": return new File_iCal_Component_Timezone($props); break; case "VALARM": return new File_iCal_Component_Alarm($props); break; case "VFREEBUSY": return new File_iCal_Component_FreeBusy($props); break; case "VJOURNAL": return new File_iCal_Component_Journal($props); break; default: trigger_error("Cannot yet retrieve component"); } } /** * Returns the user-equivalent object for a parsed component * * Depending on the component type, this function could return one of the following: * File_iCal_Event, File_iCalAlarm, File_iCal_FreeBusy, File_iCal_TimeZone, File_iCal_TodDo * * @access public * @return object */ public function getUserComponent() { $component_name = ""; $c = null; switch (get_class($this)) { case "File_iCal_Component_Event": $component_name = "VEVENT"; require_once 'Event.php'; $c = new File_iCal_Event(); break; case "File_iCal_Component_ToDo": $component_name = "VTODO"; $c = new File_iCal_ToDo(); break; case "File_iCal_Component_Journal": $component_name = "VJOURNAL"; $c = new File_iCal_Journal(); break; case "File_iCal_Component_Alarm": $component_name = "VALARM"; $c = new File_iCal_Alarm(); break; case "File_iCal_Component_FreeBusy": $component_name = "VFREEBUSY"; $c = new File_iCal_FreeBusy(); break; case "File_iCal_Component_Timezone": $component_name = "VTIMEZONE"; $c = new File_iCal_TimeZone(); break; default: trigger_error("Component not yet supported (". get_class($this).")", E_USER_WARNING); } foreach ($this->_properties as $p) { if (is_array($p)) { foreach ($p as $p2) { self::addPropertyToUserComponent($c, $p2); } } else { self::addPropertyToUserComponent($c, $p); } } return $c; } protected static function addPropertyToUserComponent(&$component, $property) { switch (get_class($property)) { case "File_iCal_Property_Attachment": case "File_iCal_Property_Category": case "File_iCal_Property_Classification": case "File_iCal_Property_Comment": break; case "File_iCal_Property_Description": $component->setDescription($property->getValue()->getValue()); break; case "File_iCal_Property_GeographicPosition": break; case "File_iCal_Property_Location": $component->setLocation($property->getValue()->getValue()); break; case "File_iCal_Property_PercentComplete": case "File_iCal_Property_Priority": case "File_iCal_Property_Resources": case "File_iCal_Property_Status": break; case "File_iCal_Property_Summary": $component->setSummary($property->getValue()->getValue()); break; case "File_iCal_Property_DateTimeCompleted": case "File_iCal_Property_DateTimeEnd": case "File_iCal_Property_DateTimeDue": break; case "File_iCal_Property_DateTimeStart": $component->setDateStart($property->getValue()->getIntegerValue()); break; case "File_iCal_Property_Duration": case "File_iCal_Property_FreeBusyTime": case "File_iCal_Property_TimeTransparency": case "File_iCal_Property_TimeZoneIdentifier": case "File_iCal_Property_TimeZoneName": case "File_iCal_Property_TimeZoneOffsetFrom": case "File_iCal_Property_TimeZoneOffsetTo": case "File_iCal_Property_TimeZoneURL": case "File_iCal_Property_Attendee": case "File_iCal_Property_Contact": case "File_iCal_Property_Organizer": case "File_iCal_Property_RecurrenceID": case "File_iCal_Property_RelatedTo": case "File_iCal_Property_URL": break; case "File_iCal_Property_UID": $component->setUID($property->getValue()->getValue()); break; case "File_iCal_Property_ExceptionDateTimes": case "File_iCal_Property_ExceptionRule": case "File_iCal_Property_RecurrenceDateTimes": case "File_iCal_Property_RecurrenceRule": case "File_iCal_Property_Action": case "File_iCal_Property_RepeatCount": case "File_iCal_Property_Trigger": case "File_iCal_Property_DateTimeCreated": case "File_iCal_Property_DateTimeStamp": case "File_iCal_Property_LastModified": case "File_iCal_Property_SequenceNumber": case "File_iCal_Property_RequestStatus": break; default: trigger_error("Uknown property ".get_class($property), E_USER_WARNING); } } } /** * Implements the VALARM component * * @package iCal */ class File_iCal_Component_Alarm extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "ACTION", "TRIGGER", "DURATION", "REPEAT", "ATTACH" ); /** * Defines the properties that may occur more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "X-*" ); /** * Create a new VALARM component * * @access public * @param array $a An array of File_iCal_Property objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VALARM"; } } /** * Implements the VEVENT component * * @package iCal */ class File_iCal_Component_Event extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "CLASS", "CREATED", "DESCRIPTION", "DTSTART", "GEO", "LAST-MODIFIED", "LOCATION", "ORGANIZER", "PRIORITY", "DTSTAMP", "SEQUENCE", "STATUS", "SUMMARY", "TRANSP", "UID", "URL", "RECURRENCE-ID", "DTEND", "DURATION" ); /** * Defines the properties that are exclusive * * @access protected * @var array Array of property names */ protected $_properties_exclusive = array( array("DTEND","DURATION") ); /** * Defines the properties that may more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "ATTACH", "ATTENDEE", "CATEGORIES", "COMMENT", "CONTACT", "EXDATE", "EXRULE", "REQUEST-STATUS", "RELATED-TO", "RESOURCES", "RDATE", "RRULE", "X-*" ); /** * Create a new VEVENT component * * @access public * @param array $s An array of File_iCal_Property objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VEVENT"; } } /** * Implements the FREEBUSY component * * @package iCal */ class File_iCal_Component_FreeBusy extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "CONTACT", "DTSTART", "DTEND", "DURATION", "DTSTAMP", "ORGANIZER", "UID", "URL" ); /** * Defines the properties that may occur more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "ATTENDEE", "COMMENT", "FREEBUSY", "RSTATUS", "X-*" ); /** * Create a new Freebusy component * * @access public * @param array $s Array of File_iCal_Property objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VFREEBUSY"; } } /** * Implements the VJOURNAL component * * @package iCal */ class File_iCal_Component_Journal extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "CLASS", "CREATED", "DESCRIPTION", "DTSTART", "DTSTAMP", "LAST-MODIFIED", "ORGANIZER", "RECURRENCE-ID", "SEQUENCE", "STATUS", "SUMMARY", "UID", "URL" ); /** * Defines the properties that may occur more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "ATTACH", "ATTENDEE", "CATEGORIES", "COMMENT", "CONTACT", "EXDATE", "EXRULE", "RELATED-TO", "RESOURCES", "RDATE", "RRULE", "RSTATUS", "X-*" ); /** * Create a new VJOURNAL component * * @access public * @param array $s Array of File_iCal_Property objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VJOURNAL"; } } /** * Implements the VTIMEZONE component * * @package iCal */ class File_iCal_Component_Timezone extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "TZID", "LAST-MODIFIED", "TZURL" ); /** * Defines the properties that may more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "STANDARDC", "DAYLIGHTC", "X-*" ); /** * Create a new VTIMEZONE component * * @access public * @param array $s array of File_iCal_Proeperty objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VTIMEZONE"; } } /** * Implements the VTODO component * * @package iCal */ class File_iCal_Component_ToDo extends File_iCal_Component { /** * Defines the properties that may only occur once * * @access protected * @var array Array of property names */ protected $_properties_single = array( "CLASS", "COMPLETED", "CREATED", "DESCRIPTION", "DTSTAMP", "DTSTART", "GEO", "LAST-MODIFIED", "LOCATION", "ORGANIZER", "PERCENT-COMPLETE", "PRIORITY", "RECURRENCE-ID", "SEQUENCE", "STATUS", "SUMMARY", "UID", "URL", "DUE", "DURATION" ); /** * Defines the properties that are exclusive to one another * * @access protected * @var array Array of property names */ protected $_properties_exclusive = array( array("DUE","DURATION") ); /** * Defines the properties that may occur more than once * * @access protected * @var array Array of property names */ protected $_properties_multiple = array( "ATTACH", "ATTENDEE", "CATEGORIES", "COMMENT", "CONTACT", "EXDATE", "EXRULE", "REQUEST-STATUS", "RELATED-TO", "RESOURCES", "RDATE", "RRULE", "X-*" ); /** * Create a new VTODO component * * @access public * @param array $s Array of File_iCal_Property objects */ public function __construct($s) { parent::__construct($s); $this->_name = "VTODO"; } }