]> git.mxchange.org Git - friendica-addons.git/blob - dav/common/calendar.fnk.php
Bug fix for Twitter
[friendica-addons.git] / dav / common / calendar.fnk.php
1 <?php
2
3
4 define("DAV_ACL_READ", "{DAV:}read");
5 define("DAV_ACL_WRITE", "{DAV:}write");
6 define("DAV_DISPLAYNAME", "{DAV:}displayname");
7 define("DAV_CALENDARCOLOR", "{http://apple.com/ns/ical/}calendar-color");
8
9
10 class DAVVersionMismatchException extends Exception
11 {
12 }
13
14
15 class vcard_source_data_email
16 {
17         public $email, $type;
18
19         function __construct($type, $email)
20         {
21                 $this->email = $email;
22                 $this->type  = $type;
23         }
24 }
25
26 class vcard_source_data_homepage
27 {
28         public $homepage, $type;
29
30         function __construct($type, $homepage)
31         {
32                 $this->homepage = $homepage;
33                 $this->type     = $type;
34         }
35 }
36
37 class vcard_source_data_telephone
38 {
39         public $telephone, $type;
40
41         function __construct($type, $telephone)
42         {
43                 $this->telephone = $telephone;
44                 $this->type      = $type;
45         }
46 }
47
48 class vcard_source_data_socialnetwork
49 {
50         public $nick, $type, $url;
51
52         function __construct($type, $nick, $url)
53         {
54                 $this->nick = $nick;
55                 $this->type = $type;
56                 $this->url  = $url;
57         }
58 }
59
60 class vcard_source_data_address
61 {
62         public $street, $street2, $zip, $city, $country, $type;
63 }
64
65 class vcard_source_data_photo
66 {
67         public $binarydata;
68         public $width, $height;
69         public $type;
70 }
71
72 class vcard_source_data
73 {
74         function __construct($name_first, $name_middle, $name_last)
75         {
76                 $this->name_first  = $name_first;
77                 $this->name_middle = $name_middle;
78                 $this->name_last   = $name_last;
79         }
80
81         public $name_first, $name_middle, $name_last;
82         public $last_update;
83         public $picture_data;
84
85         /** @var array|vcard_source_data_telephone[] $telephones */
86         public $telephones;
87
88         /** @var array|vcard_source_data_homepage[] $homepages */
89         public $homepages;
90
91         /** @var array|vcard_source_data_socialnetwork[] $socialnetworks */
92         public $socialnetworks;
93
94         /** @var array|vcard_source_data_email[] $email */
95         public $emails;
96
97         /** @var array|vcard_source_data_address[] $addresses */
98         public $addresses;
99
100         /** @var vcard_source_data_photo */
101         public $photo;
102 }
103
104 /**
105  * @param vcard_source_data $vcardsource
106  * @return string
107  */
108 function vcard_source_compile($vcardsource)
109 {
110         $str = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Friendica//DAV-Plugin//EN\r\n";
111         $str .= "N:" . str_replace(";", ",", $vcardsource->name_last) . ";" . str_replace(";", ",", $vcardsource->name_first) . ";" . str_replace(";", ",", $vcardsource->name_middle) . ";;\r\n";
112         $str .= "FN:" . str_replace(";", ",", $vcardsource->name_first) . " " . str_replace(";", ",", $vcardsource->name_middle) . " " . str_replace(";", ",", $vcardsource->name_last) . "\r\n";
113         $str .= "REV:" . str_replace(" ", "T", $vcardsource->last_update) . "Z\r\n";
114
115         $item_count = 0;
116         for ($i = 0; $i < count($vcardsource->homepages); $i++) {
117                 if ($i == 0) $str .= "URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
118                 else {
119                         $c = ++$item_count;
120                         $str .= "item$c.URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
121                         $str .= "item$c.X-ABLabel:_\$!<HomePage>!\$_\r\n";
122                 }
123         }
124
125         if (is_object($vcardsource->photo)) {
126                 $data = base64_encode($vcardsource->photo->binarydata);
127                 $str .= "PHOTO;ENCODING=BASE64;TYPE=" . $vcardsource->photo->type . ":" . $data . "\r\n";
128         }
129
130         if (isset($vcardsource->socialnetworks) && is_array($vcardsource->socialnetworks)) foreach ($vcardsource->socialnetworks as $netw) switch ($netw->type) {
131                 case "dfrn":
132                         $str .= "X-SOCIALPROFILE;type=dfrn;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
133                         break;
134                 case "facebook":
135                         $str .= "X-SOCIALPROFILE;type=facebook;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
136                         break;
137                 case "twitter":
138                         $str .= "X-SOCIALPROFILE;type=twitter;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
139                         break;
140         }
141
142         $str .= "END:VCARD\r\n";
143         return $str;
144 }
145
146
147 /**
148  * @param int $phpDate (UTC)
149  * @return string (Lokalzeit)
150  */
151 function wdcal_php2MySqlTime($phpDate)
152 {
153         return date("Y-m-d H:i:s", $phpDate);
154 }
155
156 /**
157  * @param string $sqlDate
158  * @return int
159  */
160 function wdcal_mySql2PhpTime($sqlDate)
161 {
162         $ts = DateTime::createFromFormat("Y-m-d H:i:s", $sqlDate);
163         return $ts->format("U");
164 }
165
166 /**
167  * @param string $myqlDate
168  * @return array
169  */
170 function wdcal_mySql2icalTime($myqlDate)
171 {
172         $x             = explode(" ", $myqlDate);
173         $y             = explode("-", $x[0]);
174         $ret           = array("year"=> $y[0], "month"=> $y[1], "day"=> $y[2]);
175         $y             = explode(":", $x[1]);
176         $ret["hour"]   = $y[0];
177         $ret["minute"] = $y[1];
178         $ret["second"] = $y[2];
179         return $ret;
180 }
181
182
183 /**
184  * @param string $str
185  * @return string
186  */
187 function icalendar_sanitize_string($str = "")
188 {
189         return preg_replace("/[\\r\\n]+/siu", "\r\n", $str);
190 }
191
192
193 /**
194  * @return Sabre_CalDAV_AnimexxCalendarRootNode
195  */
196 function dav_createRootCalendarNode()
197 {
198         $backends = array(Sabre_CalDAV_Backend_Private::getInstance());
199         foreach ($GLOBALS["CALDAV_PRIVATE_SYSTEM_BACKENDS"] as $backendclass) $backends[] = $backendclass::getInstance();
200         return new Sabre_CalDAV_AnimexxCalendarRootNode(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), $backends);
201 }
202
203 /**
204  * @return Sabre_CardDAV_AddressBookRootFriendica
205  */
206 function dav_createRootContactsNode()
207 {
208         $backends = array(Sabre_CardDAV_Backend_Std::getInstance());
209         foreach ($GLOBALS["CARDDAV_PRIVATE_SYSTEM_BACKENDS"] as $backendclass) $backends[] = $backendclass::getInstance();
210
211         return new Sabre_CardDAV_AddressBookRootFriendica(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), $backends);
212 }
213
214
215 /**
216  * @param bool $force_authentication
217  * @param bool $needs_caldav
218  * @param bool $needs_carddav
219  * @return Sabre_DAV_Server
220  */
221 function dav_create_server($force_authentication = false, $needs_caldav = true, $needs_carddav = true)
222 {
223         $arr = array(
224                 new Sabre_DAV_SimpleCollection('principals', array(
225                         new Sabre_CalDAV_Principal_Collection(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), "principals/users"),
226                 )),
227         );
228         if ($needs_caldav) $arr[] = dav_createRootCalendarNode();
229         if ($needs_carddav) $arr[] = dav_createRootContactsNode();
230
231
232         $tree = new Sabre_DAV_SimpleCollection('root', $arr);
233
234 // The object tree needs in turn to be passed to the server class
235         $server = new Sabre_DAV_Server($tree);
236
237         if (CALDAV_URL_PREFIX != "") $server->setBaseUri(CALDAV_URL_PREFIX);
238
239         $authPlugin = new Sabre_DAV_Auth_Plugin(Sabre_DAV_Auth_Backend_Std::getInstance(), DAV_APPNAME);
240         $server->addPlugin($authPlugin);
241
242         if ($needs_caldav) {
243                 $caldavPlugin = new Sabre_CalDAV_Plugin();
244                 $server->addPlugin($caldavPlugin);
245         }
246         if ($needs_carddav) {
247                 $carddavPlugin = new Sabre_CardDAV_Plugin();
248                 $server->addPlugin($carddavPlugin);
249         }
250
251         if ($GLOBALS["CALDAV_ACL_PLUGIN_CLASS"] != "") {
252                 $aclPlugin                      = new $GLOBALS["CALDAV_ACL_PLUGIN_CLASS"]();
253                 $aclPlugin->defaultUsernamePath = "principals/users";
254                 $server->addPlugin($aclPlugin);
255         } else {
256                 $aclPlugin                      = new Sabre_DAVACL_Plugin();
257                 $aclPlugin->defaultUsernamePath = "principals/users";
258                 $server->addPlugin($aclPlugin);
259         }
260
261         if ($force_authentication) $server->broadcastEvent('beforeMethod', array("GET", "/")); // Make it authenticate
262
263         return $server;
264 }
265
266
267 /**
268  * @param Sabre_DAV_Server $server
269  * @param string $with_privilege
270  * @return array|Sabre_CalDAV_Calendar[]
271  */
272 function dav_get_current_user_calendars(&$server, $with_privilege = "")
273 {
274         if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
275
276         $a             = get_app();
277         $calendar_path = "/calendars/" . strtolower($a->user["nickname"]) . "/";
278
279         /** @var Sabre_CalDAV_AnimexxUserCalendars $tree  */
280         $tree = $server->tree->getNodeForPath($calendar_path);
281         /** @var array|Sabre_CalDAV_Calendar[] $calendars  */
282         $children = $tree->getChildren();
283
284         $calendars = array();
285         /** @var Sabre_DAVACL_Plugin $aclplugin  */
286         $aclplugin = $server->getPlugin("acl");
287         foreach ($children as $child) if (is_a($child, "Sabre_CalDAV_Calendar") || is_subclass_of($child, "Sabre_CalDAV_Calendar")) {
288                 if ($with_privilege != "") {
289                         $caluri = $calendar_path . $child->getName();
290                         if ($aclplugin->checkPrivileges($caluri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) $calendars[] = $child;
291                 } else {
292                         $calendars[] = $child;
293                 }
294         }
295         return $calendars;
296 }
297
298
299 /**
300  * @param Sabre_DAV_Server $server
301  * @param Sabre_CalDAV_Calendar $calendar
302  * @param string $calendarobject_uri
303  * @param string $with_privilege
304  * @return null|Sabre\VObject\Component\VCalendar
305  */
306 function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
307 {
308         $obj = $calendar->getChild($calendarobject_uri);
309
310         if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
311
312         $a   = get_app();
313         $uri = "/calendars/" . strtolower($a->user["nickname"]) . "/" . $calendar->getName() . "/" . $calendarobject_uri;
314
315         /** @var Sabre_DAVACL_Plugin $aclplugin  */
316         $aclplugin = $server->getPlugin("acl");
317         if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) return null;
318
319         $data    = $obj->get();
320         $vObject = Sabre\VObject\Reader::read($data);
321
322         return $vObject;
323 }
324
325
326 /**
327  * @param Sabre_DAV_Server $server
328  * @param int $id
329  * @param string $with_privilege
330  * @return null|Sabre_CalDAV_Calendar
331  */
332 function dav_get_current_user_calendar_by_id(&$server, $id, $with_privilege = "")
333 {
334         $calendars = dav_get_current_user_calendars($server, $with_privilege);
335
336         $calendar = null;
337         foreach ($calendars as $cal) {
338                 $prop = $cal->getProperties(array("id"));
339                 if (isset($prop["id"]) && $prop["id"] == $id) $calendar = $cal;
340         }
341
342         return $calendar;
343 }
344
345
346 /**
347  * @param string $uid
348  * @return Sabre\VObject\Component\VCalendar $vObject
349  */
350 function dav_create_empty_vevent($uid = "")
351 {
352         if ($uid == "") $uid = uniqid();
353         return Sabre\VObject\Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . dav_compat_get_hostname() .
354                 "\r\nDTSTAMP:" . date("Ymd") . "T" . date("His") . "Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
355 }
356
357
358 /**
359  * @param Sabre\VObject\Component\VCalendar $vObject
360  * @return Sabre\VObject\Component\VEvent|null
361  */
362 function dav_get_eventComponent(&$vObject)
363 {
364         $component     = null;
365         $componentType = "";
366         foreach ($vObject->getComponents() as $component) {
367                 if ($component->name !== 'VTIMEZONE') {
368                         $componentType = $component->name;
369                         break;
370                 }
371         }
372         if ($componentType != "VEVENT") return null;
373
374         return $component;
375 }