[vCalendar] Developing this to be useful for scheduling.
[awl.git] / inc / vCalendar.php
blob7f3d8cbbd8e96f9be0c5d3cc6af7319786ae87d3
1 <?php
2 /**
3 * A Class for handling vCalendar data.
5 * When parsed the underlying structure is roughly as follows:
7 * vCalendar( array(vComponent), array(vProperty), array(vTimezone) )
9 * with the TIMEZONE data still currently included in the component array (likely
10 * to change in the future) and the timezone array only containing vComponent objects
11 * (which is also likely to change).
13 * @package awl
14 * @subpackage vCalendar
15 * @author Andrew McMillan <andrew@mcmillan.net.nz>
16 * @copyright Morphoss Ltd <http://www.morphoss.com/>
17 * @license http://gnu.org/copyleft/lgpl.html GNU LGPL v3 or later
21 require_once('vComponent.php');
23 class VCalendar extends vComponent {
25 /**
26 * These variables are mostly used to improve efficiency by caching values as they are
27 * retrieved to speed any subsequent access.
28 * @var string $contained_type
29 * @var array $timezones
30 * @var string $organizer
31 * @var array $attendees
33 private $contained_type;
34 private $timezones;
35 private $organizer;
36 private $attendees;
38 /**
39 * Constructor. If a string is passed it will be parsed as if it was an iCalendar object,
40 * otherwise a new vCalendar will be initialised with basic content. If an array of key value
41 * pairs is provided they will also be used as top-level properties.
43 * Typically this will be used to set a METHOD property on the VCALENDAR as something like:
44 * $shinyCalendar = new vCalendar( array('METHOD' => 'REQUEST' ) );
46 * @param mixed $content Can be a string to be parsed, or an array of key value pairs.
48 function __construct($content=null) {
49 $this->contained_type = null;
50 $this->timezones = array();
51 if ( empty($content) || is_array($content) ) {
52 parent::__construct();
53 $this->SetType('VCALENDAR');
54 $this->AddProperty('PRODID', '-//davical.org//NONSGML AWL Calendar//EN');
55 $this->AddProperty('VERSION', '2.0');
56 $this->AddProperty('CALSCALE', 'GREGORIAN');
57 if ( !empty($content) ) {
58 foreach( $content AS $k => $v ) {
59 $this->AddProperty($k,$v);
63 else {
64 parent::__construct($content);
65 foreach( $this->components AS $k => $comp ) {
66 if ( $comp->GetType() == 'VTIMEZONE' ) {
67 $this->AddTimeZone($comp, true);
69 else if ( empty($this->contained_type) ) {
70 $this->contained_type = $comp->GetType();
77 /**
78 * Add a timezone component to this vCalendar.
80 function AddTimeZone(vComponent $vtz, $in_components=false) {
81 $tzid = $vtz->GetPValue('TZID');
82 if ( empty($tzid) ) {
83 dbg_error_log('ERROR','Ignoring invalid VTIMEZONE with no TZID parameter!');
84 return;
86 $this->timezones[$tzid] = $vtz;
87 if ( !$in_components ) $this->AddComponent($vtz);
91 /**
92 * Get a timezone component for a specific TZID in this calendar.
94 function GetTimeZone( $tzid ) {
95 if ( empty($this->timezones[$tzid]) ) return null;
96 return $this->timezones[$tzid];
101 * Get the organizer of this VEVENT/VTODO
103 function GetOrganizer() {
104 if ( !isset($this->organizer) ) {
105 $organizers = $this->GetPropertiesByPath('/VCALENDAR/*/ORGANIZER');
106 $organizer = (count($organizers) > 0 ? $organizers[0]->Value() : false);
107 $this->organizer = (empty($organizer) ? false : $organizer );
109 return $this->organizer;
114 * Get the attendees of this VEVENT/VTODO
116 function GetAttendees() {
117 if ( !isset($this->attendees) ) {
118 $attendees = $this->GetPropertiesByPath('/VCALENDAR/*/ATTENDEE');
119 $wr_attendees = $this->GetPropertiesByPath('/VCALENDAR/*/X-WR-ATTENDEE');
120 if ( count ( $wr_attendees ) > 0 ) {
121 dbg_error_log( 'PUT', 'Non-compliant iCal request. Using X-WR-ATTENDEE property' );
122 foreach( $wr_attendees AS $k => $v ) {
123 $attendees[] = $v;
126 $this->attendees = $attendees;
128 return $this->attendees;