comparison plugins/calendar/drivers/kolab/kolab_invitation_calendar.php @ 3:f6fe4b6ae66a

calendar plugin nearly as distributed
author Charlie Root
date Sat, 13 Jan 2018 08:56:12 -0500
parents
children
comparison
equal deleted inserted replaced
2:c828b0fd4a6e 3:f6fe4b6ae66a
1 <?php
2
3 /**
4 * Kolab calendar storage class simulating a virtual calendar listing pedning/declined invitations
5 *
6 * @author Thomas Bruederli <bruederli@kolabsys.com>
7 *
8 * Copyright (C) 2014-2015, Kolab Systems AG <contact@kolabsys.com>
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as
12 * published by the Free Software Foundation, either version 3 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 class kolab_invitation_calendar
25 {
26 public $id = '__invitation__';
27 public $ready = true;
28 public $alarms = false;
29 public $rights = 'lrsv';
30 public $editable = false;
31 public $attachments = false;
32 public $subscriptions = false;
33 public $partstats = array('unknown');
34 public $categories = array();
35 public $name = 'Invitations';
36
37
38 /**
39 * Default constructor
40 */
41 public function __construct($id, $calendar)
42 {
43 $this->cal = $calendar;
44 $this->id = $id;
45
46 switch ($this->id) {
47 case kolab_driver::INVITATIONS_CALENDAR_PENDING:
48 $this->partstats = array('NEEDS-ACTION');
49 $this->name = $this->cal->gettext('invitationspending');
50 if (!empty($_REQUEST['_quickview']))
51 $this->partstats[] = 'TENTATIVE';
52 break;
53
54 case kolab_driver::INVITATIONS_CALENDAR_DECLINED:
55 $this->partstats = array('DECLINED');
56 $this->name = $this->cal->gettext('invitationsdeclined');
57 break;
58 }
59
60 // user-specific alarms settings win
61 $prefs = $this->cal->rc->config->get('kolab_calendars', array());
62 if (isset($prefs[$this->id]['showalarms']))
63 $this->alarms = $prefs[$this->id]['showalarms'];
64 }
65
66 /**
67 * Getter for a nice and human readable name for this calendar
68 *
69 * @return string Name of this calendar
70 */
71 public function get_name()
72 {
73 return $this->name;
74 }
75
76 /**
77 * Getter for the IMAP folder owner
78 *
79 * @return string Name of the folder owner
80 */
81 public function get_owner()
82 {
83 return $this->cal->rc->get_user_name();
84 }
85
86 /**
87 *
88 */
89 public function get_title()
90 {
91 return $this->get_name();
92 }
93
94 /**
95 * Getter for the name of the namespace to which the IMAP folder belongs
96 *
97 * @return string Name of the namespace (personal, other, shared)
98 */
99 public function get_namespace()
100 {
101 return 'x-special';
102 }
103
104 /**
105 * Getter for the top-end calendar folder name (not the entire path)
106 *
107 * @return string Name of this calendar
108 */
109 public function get_foldername()
110 {
111 return $this->get_name();
112 }
113
114 /**
115 * Getter for the Cyrus mailbox identifier corresponding to this folder
116 *
117 * @return string Mailbox ID
118 */
119 public function get_mailbox_id()
120 {
121 // this is a virtual collection and has no concrete mailbox ID
122 return null;
123 }
124
125 /**
126 * Return color to display this calendar
127 */
128 public function get_color()
129 {
130 // calendar color is stored in local user prefs
131 $prefs = $this->cal->rc->config->get('kolab_calendars', array());
132
133 if (!empty($prefs[$this->id]) && !empty($prefs[$this->id]['color']))
134 return $prefs[$this->id]['color'];
135
136 return 'ffffff';
137 }
138
139 /**
140 * Compose an URL for CalDAV access to this calendar (if configured)
141 */
142 public function get_caldav_url()
143 {
144 return false;
145 }
146
147 /**
148 * Check activation status of this folder
149 *
150 * @return boolean True if enabled, false if not
151 */
152 public function is_active()
153 {
154 $prefs = $this->cal->rc->config->get('kolab_calendars', array()); // read local prefs
155 return (bool)$prefs[$this->id]['active'];
156 }
157
158 /**
159 * Update properties of this calendar folder
160 *
161 * @see calendar_driver::edit_calendar()
162 */
163 public function update(&$prop)
164 {
165 // don't change anything.
166 // let kolab_driver save props in local prefs
167 return $prop['id'];
168 }
169
170 /**
171 * Getter for a single event object
172 */
173 public function get_event($id)
174 {
175 // redirect call to kolab_driver::get_event()
176 $event = $this->cal->driver->get_event($id, calendar_driver::FILTER_WRITEABLE);
177
178 if (is_array($event)) {
179 // add pointer to original calendar folder
180 $event['_folder_id'] = $event['calendar'];
181 $event = $this->_mod_event($event);
182 }
183
184 return $event;
185 }
186
187 /**
188 * Get attachment body
189 * @see calendar_driver::get_attachment_body()
190 */
191 public function get_attachment_body($id, $event)
192 {
193 // find the actual folder this event resides in
194 if (!empty($event['_folder_id'])) {
195 $cal = $this->cal->driver->get_calendar($event['_folder_id']);
196 }
197 else {
198 $cal = null;
199 foreach (kolab_storage::list_folders('', '*', 'event', null) as $foldername) {
200 $cal = $this->_get_calendar($foldername);
201 if ($cal->ready && $cal->storage && $cal->get_event($event['id'])) {
202 break;
203 }
204 }
205 }
206
207 if ($cal && $cal->storage) {
208 return $cal->get_attachment_body($id, $event);
209 }
210
211 return false;
212 }
213
214 /**
215 * @param integer Event's new start (unix timestamp)
216 * @param integer Event's new end (unix timestamp)
217 * @param string Search query (optional)
218 * @param boolean Include virtual events (optional)
219 * @param array Additional parameters to query storage
220 * @return array A list of event records
221 */
222 public function list_events($start, $end, $search = null, $virtual = 1, $query = array())
223 {
224 // get email addresses of the current user
225 $user_emails = $this->cal->get_user_emails();
226 $subquery = array();
227 foreach ($user_emails as $email) {
228 foreach ($this->partstats as $partstat) {
229 $subquery[] = array('tags', '=', 'x-partstat:' . $email . ':' . strtolower($partstat));
230 }
231 }
232
233 // aggregate events from all calendar folders
234 $events = array();
235 foreach (kolab_storage::list_folders('', '*', 'event', null) as $foldername) {
236 $cal = $this->_get_calendar($foldername);
237 if ($cal->get_namespace() == 'other')
238 continue;
239
240 foreach ($cal->list_events($start, $end, $search, 1, $query, array(array($subquery, 'OR'))) as $event) {
241 $match = false;
242
243 // post-filter events to match out partstats
244 if (is_array($event['attendees'])) {
245 foreach ($event['attendees'] as $attendee) {
246 if (in_array($attendee['email'], $user_emails) && in_array($attendee['status'], $this->partstats)) {
247 $match = true;
248 break;
249 }
250 }
251 }
252
253 if ($match) {
254 $events[$event['id'] ?: $event['uid']] = $this->_mod_event($event);
255 }
256 }
257
258 // merge list of event categories (really?)
259 $this->categories += $cal->categories;
260 }
261
262 return $events;
263 }
264
265 /**
266 *
267 * @param integer Date range start (unix timestamp)
268 * @param integer Date range end (unix timestamp)
269 * @return integer Count
270 */
271 public function count_events($start, $end = null)
272 {
273 // get email addresses of the current user
274 $user_emails = $this->cal->get_user_emails();
275 $subquery = array();
276 foreach ($user_emails as $email) {
277 foreach ($this->partstats as $partstat) {
278 $subquery[] = array('tags', '=', 'x-partstat:' . $email . ':' . strtolower($partstat));
279 }
280 }
281
282 $filter = array(
283 array('tags','!=','x-status:cancelled'),
284 array($subquery, 'OR')
285 );
286
287 // aggregate counts from all calendar folders
288 $count = 0;
289 foreach (kolab_storage::list_folders('', '*', 'event', null) as $foldername) {
290 $cal = $this->_get_calendar($foldername);
291 if ($cal->get_namespace() == 'other')
292 continue;
293
294 $count += $cal->count_events($start, $end, $filter);
295 }
296
297 return $count;
298 }
299
300 /**
301 * Get calendar object instance (that maybe already initialized)
302 */
303 private function _get_calendar($folder_name)
304 {
305 $id = kolab_storage::folder_id($folder_name, true);
306 return $this->cal->driver->get_calendar($id);
307 }
308
309 /**
310 * Helper method to modify some event properties
311 */
312 private function _mod_event($event)
313 {
314 // set classes according to PARTSTAT
315 $event = kolab_driver::add_partstat_class($event, $this->partstats);
316
317 if (strpos($event['className'], 'fc-invitation-') !== false) {
318 $event['calendar'] = $this->id;
319 }
320
321 return $event;
322 }
323
324 /**
325 * Create a new event record
326 *
327 * @see calendar_driver::new_event()
328 *
329 * @return mixed The created record ID on success, False on error
330 */
331 public function insert_event($event)
332 {
333 return false;
334 }
335
336 /**
337 * Update a specific event record
338 *
339 * @see calendar_driver::new_event()
340 * @return boolean True on success, False on error
341 */
342 public function update_event($event, $exception_id = null)
343 {
344 // forward call to the actual storage folder
345 if ($event['_folder_id']) {
346 $cal = $this->cal->driver->get_calendar($event['_folder_id']);
347 if ($cal && $cal->ready) {
348 return $cal->update_event($event, $exception_id);
349 }
350 }
351
352 return false;
353 }
354
355 /**
356 * Delete an event record
357 *
358 * @see calendar_driver::remove_event()
359 * @return boolean True on success, False on error
360 */
361 public function delete_event($event, $force = true)
362 {
363 return false;
364 }
365
366 /**
367 * Restore deleted event record
368 *
369 * @see calendar_driver::undelete_event()
370 * @return boolean True on success, False on error
371 */
372 public function restore_event($event)
373 {
374 return false;
375 }
376 }