Mercurial > hg > rc1
comparison plugins/calendar/lib/calendar_itip.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 require_once realpath(__DIR__ . '/../../libcalendaring/lib/libcalendaring_itip.php'); | |
4 | |
5 /** | |
6 * iTIP functions for the Calendar plugin | |
7 * | |
8 * Class providing functionality to manage iTIP invitations | |
9 * | |
10 * @version @package_version@ | |
11 * @author Thomas Bruederli <bruederli@kolabsys.com> | |
12 * @package @package_name@ | |
13 * | |
14 * Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com> | |
15 * | |
16 * This program is free software: you can redistribute it and/or modify | |
17 * it under the terms of the GNU Affero General Public License as | |
18 * published by the Free Software Foundation, either version 3 of the | |
19 * License, or (at your option) any later version. | |
20 * | |
21 * This program is distributed in the hope that it will be useful, | |
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 * GNU Affero General Public License for more details. | |
25 * | |
26 * You should have received a copy of the GNU Affero General Public License | |
27 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
28 */ | |
29 class calendar_itip extends libcalendaring_itip | |
30 { | |
31 /** | |
32 * Constructor to set text domain to calendar | |
33 */ | |
34 function __construct($plugin, $domain = 'calendar') | |
35 { | |
36 parent::__construct($plugin, $domain); | |
37 | |
38 $this->db_itipinvitations = $this->rc->db->table_name('itipinvitations', true); | |
39 } | |
40 | |
41 /** | |
42 * Handler for calendar/itip-status requests | |
43 */ | |
44 public function get_itip_status($event, $existing = null) | |
45 { | |
46 $status = parent::get_itip_status($event, $existing); | |
47 | |
48 // don't ask for deleting events when declining | |
49 if ($this->rc->config->get('kolab_invitation_calendars')) | |
50 $status['saved'] = false; | |
51 | |
52 return $status; | |
53 } | |
54 | |
55 /** | |
56 * Find invitation record by token | |
57 * | |
58 * @param string Invitation token | |
59 * @return mixed Invitation record as hash array or False if not found | |
60 */ | |
61 public function get_invitation($token) | |
62 { | |
63 if ($parts = $this->decode_token($token)) { | |
64 $result = $this->rc->db->query("SELECT * FROM $this->db_itipinvitations WHERE `token` = ?", $parts['base']); | |
65 if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { | |
66 $rec['event'] = unserialize($rec['event']); | |
67 $rec['attendee'] = $parts['attendee']; | |
68 return $rec; | |
69 } | |
70 } | |
71 | |
72 return false; | |
73 } | |
74 | |
75 /** | |
76 * Update the attendee status of the given invitation record | |
77 * | |
78 * @param array Invitation record as fetched with calendar_itip::get_invitation() | |
79 * @param string Attendee email address | |
80 * @param string New attendee status | |
81 */ | |
82 public function update_invitation($invitation, $email, $newstatus) | |
83 { | |
84 if (is_string($invitation)) | |
85 $invitation = $this->get_invitation($invitation); | |
86 | |
87 if ($invitation['token'] && $invitation['event']) { | |
88 // update attendee record in event data | |
89 foreach ($invitation['event']['attendees'] as $i => $attendee) { | |
90 if ($attendee['role'] == 'ORGANIZER') { | |
91 $organizer = $attendee; | |
92 } | |
93 else if ($attendee['email'] == $email) { | |
94 // nothing to be done here | |
95 if ($attendee['status'] == $newstatus) | |
96 return true; | |
97 | |
98 $invitation['event']['attendees'][$i]['status'] = $newstatus; | |
99 $this->sender = $attendee; | |
100 } | |
101 } | |
102 $invitation['event']['changed'] = new DateTime(); | |
103 | |
104 // send iTIP REPLY message to organizer | |
105 if ($organizer) { | |
106 $status = strtolower($newstatus); | |
107 if ($this->send_itip_message($invitation['event'], 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) | |
108 $this->rc->output->command('display_message', $this->plugin->gettext(array('name' => 'sentresponseto', 'vars' => array('mailto' => $organizer['name'] ? $organizer['name'] : $organizer['email']))), 'confirmation'); | |
109 else | |
110 $this->rc->output->command('display_message', $this->plugin->gettext('itipresponseerror'), 'error'); | |
111 } | |
112 | |
113 // update record in DB | |
114 $query = $this->rc->db->query( | |
115 "UPDATE $this->db_itipinvitations | |
116 SET `event` = ? | |
117 WHERE `token` = ?", | |
118 self::serialize_event($invitation['event']), | |
119 $invitation['token'] | |
120 ); | |
121 | |
122 if ($this->rc->db->affected_rows($query)) | |
123 return true; | |
124 } | |
125 | |
126 return false; | |
127 } | |
128 | |
129 | |
130 /** | |
131 * Create iTIP invitation token for later replies via URL | |
132 * | |
133 * @param array Hash array with event properties | |
134 * @param string Attendee email address | |
135 * @return string Invitation token | |
136 */ | |
137 public function store_invitation($event, $attendee) | |
138 { | |
139 static $stored = array(); | |
140 | |
141 if (!$event['uid'] || !$attendee) | |
142 return false; | |
143 | |
144 // generate token for this invitation | |
145 $token = $this->generate_token($event, $attendee); | |
146 $base = substr($token, 0, 40); | |
147 | |
148 // already stored this | |
149 if ($stored[$base]) | |
150 return $token; | |
151 | |
152 // delete old entry | |
153 $this->rc->db->query("DELETE FROM $this->db_itipinvitations WHERE `token` = ?", $base); | |
154 | |
155 $event_uid = $event['uid'] . ($event['_instance'] ? '-' . $event['_instance'] : ''); | |
156 | |
157 $query = $this->rc->db->query( | |
158 "INSERT INTO $this->db_itipinvitations | |
159 (`token`, `event_uid`, `user_id`, `event`, `expires`) | |
160 VALUES(?, ?, ?, ?, ?)", | |
161 $base, | |
162 $event_uid, | |
163 $this->rc->user->ID, | |
164 self::serialize_event($event), | |
165 date('Y-m-d H:i:s', $event['end']->format('U') + 86400 * 2) | |
166 ); | |
167 | |
168 if ($this->rc->db->affected_rows($query)) { | |
169 $stored[$base] = 1; | |
170 return $token; | |
171 } | |
172 | |
173 return false; | |
174 } | |
175 | |
176 /** | |
177 * Mark invitations for the given event as cancelled | |
178 * | |
179 * @param array Hash array with event properties | |
180 */ | |
181 public function cancel_itip_invitation($event) | |
182 { | |
183 $event_uid = $event['uid'] . ($event['_instance'] ? '-' . $event['_instance'] : ''); | |
184 | |
185 // flag invitation record as cancelled | |
186 $this->rc->db->query( | |
187 "UPDATE $this->db_itipinvitations | |
188 SET `cancelled` = 1 | |
189 WHERE `event_uid` = ? AND `user_id` = ?", | |
190 $event_uid, | |
191 $this->rc->user->ID | |
192 ); | |
193 } | |
194 | |
195 /** | |
196 * Generate an invitation request token for the given event and attendee | |
197 * | |
198 * @param array Event hash array | |
199 * @param string Attendee email address | |
200 */ | |
201 public function generate_token($event, $attendee) | |
202 { | |
203 $event_uid = $event['uid'] . ($event['_instance'] ? '-' . $event['_instance'] : ''); | |
204 $base = sha1($event_uid . ';' . $this->rc->user->ID); | |
205 $mail = base64_encode($attendee); | |
206 $hash = substr(md5($base . $mail . $this->rc->config->get('des_key')), 0, 6); | |
207 | |
208 return "$base.$mail.$hash"; | |
209 } | |
210 | |
211 /** | |
212 * Decode the given iTIP request token and return its parts | |
213 * | |
214 * @param string Request token to decode | |
215 * @return mixed Hash array with parts or False if invalid | |
216 */ | |
217 public function decode_token($token) | |
218 { | |
219 list($base, $mail, $hash) = explode('.', $token); | |
220 | |
221 // validate and return parts | |
222 if ($mail && $hash && $hash == substr(md5($base . $mail . $this->rc->config->get('des_key')), 0, 6)) { | |
223 return array('base' => $base, 'attendee' => base64_decode($mail)); | |
224 } | |
225 | |
226 return false; | |
227 } | |
228 | |
229 /** | |
230 * Helper method to serialize the given event for storing in invitations table | |
231 */ | |
232 private static function serialize_event($event) | |
233 { | |
234 $ev = $event; | |
235 $ev['description'] = abbreviate_string($ev['description'], 100); | |
236 unset($ev['attachments']); | |
237 return serialize($ev); | |
238 } | |
239 | |
240 } |