1: <?php
2: /**
3: * A reduced event representation derived from the Kronolith event
4: * representation.
5: *
6: * PHP version 5
7: *
8: * @category Kolab
9: * @package Kolab_FreeBusy
10: * @author Chuck Hagenbuch <chuck@horde.org>
11: * @author Jan Schneider <jan@horde.org>
12: * @author Gunnar Wrobel <wrobel@pardus.de>
13: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
14: * @link http://pear.horde.org/index.php?package=Kolab_FreeBusy
15: */
16:
17: /**
18: * A reduced event representation derived from the Kronolith event
19: * representation.
20: *
21: * Copyright 1999-2012 Horde LLC (http://www.horde.org/)
22: * Copyright 2004-2008 Klarälvdalens Datakonsult AB
23: * Copyright 2011 Kolab Systems AG
24: *
25: * See the enclosed file COPYING for license information (LGPL). If you
26: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
27: *
28: * @category Kolab
29: * @package Kolab_FreeBusy
30: * @author Chuck Hagenbuch <chuck@horde.org>
31: * @author Jan Schneider <jan@horde.org>
32: * @author Gunnar Wrobel <wrobel@pardus.de>
33: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
34: * @link http://pear.horde.org/index.php?package=Kolab_FreeBusy
35: */
36: class Horde_Kolab_FreeBusy_Object_Event {
37:
38: /** Event status */
39: const STATUS_NONE = 'none';
40: const STATUS_UNKNOWN = 'unknown';
41: const STATUS_BUSY = 'busy';
42: const STATUS_TENTATIVE = 'tentative';
43: const STATUS_OUTOFOFFICE = 'outofoffice';
44: const STATUS_FREE = 'free';
45: const STATUS_CONFIRMED = 'confirmed';
46: const STATUS_CANCELLED = 'cancelled';
47:
48: /**
49: * The driver unique identifier for this event.
50: *
51: * @var string
52: */
53: private $_event_id;
54:
55: /**
56: * The start time of the event.
57: *
58: * @var Horde_Date
59: */
60: private $_start;
61:
62: /**
63: * The end time of the event.
64: *
65: * @var Horde_Date
66: */
67: private $_end;
68:
69: /**
70: * The title of this event.
71: *
72: * @var string
73: */
74: private $_title = '';
75:
76: /**
77: * The location this event occurs at.
78: *
79: * @var string
80: */
81: private $_location = '';
82:
83: /**
84: * Whether the event is private.
85: *
86: * @var boolean
87: */
88: private $_private = false;
89:
90: /**
91: * Recurrence information.
92: *
93: * @var Horde_Date_Recurrence
94: */
95: private $_recurrence;
96:
97: /**
98: * Constructor.
99: *
100: * @param array $event The event data.
101: */
102: public function __construct(array $event)
103: {
104: if (isset($event['uid'])) {
105: $this->_event_id = $event['uid'];
106: }
107:
108: if (!($event['start-date'] instanceOf Horde_Date)) {
109: $this->_start = new Horde_Date($event['start-date']);
110: } else {
111: $this->_start = $event['start-date'];
112: }
113:
114: if (!($event['end-date'] instanceOf Horde_Date)) {
115: $this->_end = new Horde_Date($event['end-date']);
116: } else {
117: $this->_end = $event['end-date'];
118: }
119:
120: if (isset($event['summary'])) {
121: $this->_title = $event['summary'];
122: }
123:
124: if (isset($event['location'])) {
125: $this->_location = $event['location'];
126: }
127:
128: if (isset($event['sensitivity']) &&
129: ($event['sensitivity'] == 'private' ||
130: $event['sensitivity'] == 'confidential')) {
131: $this->_private = true;
132: }
133:
134: if (isset($event['show-time-as'])) {
135: $this->_status = $event['show-time-as'];
136: } else {
137: $this->_status = self::STATUS_NONE;
138: }
139:
140: // Recurrence
141: if (isset($event['recurrence'])) {
142: $this->_recurrence = new Horde_Date_Recurrence($this->_start);
143: $this->_recurrence->fromHash($event['recurrence']);
144: }
145: }
146:
147: /**
148: * Determines if the event recurs in the given time span.
149: *
150: * @param Horde_Date $startDate Start of the time span.
151: * @param Horde_Date $endDate End of the time span.
152: *
153: * @return boolean True if the event recurs in this time span.
154: */
155: public function recursIn(Horde_Date $startDate, Horde_Date $endDate)
156: {
157: $next = $this->_recurrence->nextRecurrence($startDate);
158: while ($next !== false &&
159: $this->_recurrence->hasException($next->year, $next->month, $next->mday)) {
160: $next->mday++;
161: $next = $this->_recurrence->nextRecurrence($next);
162: }
163:
164: if ($next !== false) {
165: $duration = $next->timestamp() - $this->_start->timestamp();
166: $next_end = new Horde_Date($this->_end->timestamp() + $duration);
167:
168: if ((!(($endDate->compareDateTime($next) < 0) ||
169: ($startDate->compareDateTime($next_end) > 0)))) {
170: return true;
171: }
172: }
173: return false;
174: }
175:
176: /**
177: * Returns whether this event is a recurring event.
178: *
179: * @return boolean True if this is a recurring event.
180: */
181: public function recurs()
182: {
183: return isset($this->_recurrence) &&
184: !$this->_recurrence->hasRecurType(Horde_Date_Recurrence::RECUR_NONE);
185: }
186:
187: /**
188: * Return the event status (one of the event status codes defined in this
189: * class).
190: *
191: * @return string The status of this event.
192: */
193: public function getStatus()
194: {
195: return $this->_status;
196: }
197:
198: /**
199: * Return the duration of the event.
200: *
201: * @return int The duration (in seconds) of the event.
202: */
203: public function duration()
204: {
205: return $this->_end->timestamp() - $this->_start->timestamp();
206: }
207:
208: /**
209: * Return event details encoded for integration into the free/busy output.
210: *
211: * @return array The encoded free/busy information.
212: */
213: public function getEncodedInformation()
214: {
215: return array(
216: 'X-UID' => base64_encode($this->_event_id),
217: 'X-SUMMARY' => base64_encode($this->_private ? '' : $this->_title),
218: 'X-LOCATION' => base64_encode($this->_private ? '' : $this->_location)
219: );
220: }
221:
222: /**
223: * Retrieve the busy times from this event within the given timeframe. This
224: * is trivial for non-recurring events but recurring events need to be
225: * expanded.
226: *
227: * @param Horde_Date $startDate The start point.
228: * @param Horde_Date $endDate The end point.
229: *
230: * @return array The list of busy times (only the start times of the event).
231: */
232: public function getBusyTimes(Horde_Date $startDate, Horde_Date $endDate)
233: {
234: if (!$this->recurs()) {
235: if ($startDate->compareDateTime($this->_start) > 0 ||
236: $endDate->compareDateTime($this->_start) < 0) {
237: return array();
238: }
239: return array($this->_start->timestamp());
240: } else {
241: $result = array();
242: $next = $this->_recurrence->nextRecurrence($startDate);
243: while ($next) {
244: if ($endDate->compareDateTime($next) < 0) {
245: break;
246: }
247: if (!$this->_recurrence->hasException($next->year, $next->month, $next->mday)) {
248: $result[] = $next->timestamp();
249: }
250: $next->mday++;
251: $next = $this->_recurrence->nextRecurrence($next);
252: }
253: return $result;
254: }
255: }
256: }
257: