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");
11 class vcard_source_data_email
15 function __construct($type, $email)
17 $this->email = $email;
22 class vcard_source_data_homepage
24 public $homepage, $type;
26 function __construct($type, $homepage)
28 $this->homepage = $homepage;
33 class vcard_source_data_telephone
35 public $telephone, $type;
37 function __construct($type, $telephone)
39 $this->telephone = $telephone;
44 class vcard_source_data_socialnetwork
46 public $nick, $type, $url;
48 function __construct($type, $nick, $url)
56 class vcard_source_data_address
58 public $street, $street2, $zip, $city, $country, $type;
61 class vcard_source_data_photo
64 public $width, $height;
68 class vcard_source_data
70 function __construct($name_first, $name_middle, $name_last)
72 $this->name_first = $name_first;
73 $this->name_middle = $name_middle;
74 $this->name_last = $name_last;
77 public $name_first, $name_middle, $name_last;
81 /** @var array|vcard_source_data_telephone[] $telephones */
84 /** @var array|vcard_source_data_homepage[] $homepages */
87 /** @var array|vcard_source_data_socialnetwork[] $socialnetworks */
88 public $socialnetworks;
90 /** @var array|vcard_source_data_email[] $email */
93 /** @var array|vcard_source_data_address[] $addresses */
96 /** @var vcard_source_data_photo */
104 * @param vcard_source_data $vcardsource
107 function vcard_source_compile($vcardsource)
109 $str = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Friendica//DAV-Plugin//EN\r\n";
110 $str .= "N:" . str_replace(";", ",", $vcardsource->name_last) . ";" . str_replace(";", ",", $vcardsource->name_first) . ";" . str_replace(";", ",", $vcardsource->name_middle) . ";;\r\n";
111 $str .= "FN:" . str_replace(";", ",", $vcardsource->name_first) . " " . str_replace(";", ",", $vcardsource->name_middle) . " " . str_replace(";", ",", $vcardsource->name_last) . "\r\n";
112 $str .= "REV:" . str_replace(" ", "T", $vcardsource->last_update) . "Z\r\n";
115 for ($i = 0; $i < count($vcardsource->homepages); $i++) {
116 if ($i == 0) $str .= "URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
119 $str .= "item$c.URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
120 $str .= "item$c.X-ABLabel:_\$!<HomePage>!\$_\r\n";
124 if (is_object($vcardsource->photo)) {
125 $data = base64_encode($vcardsource->photo->binarydata);
126 $str .= "PHOTO;ENCODING=BASE64;TYPE=" . $vcardsource->photo->type . ":" . $data . "\r\n";
129 if (isset($vcardsource->socialnetworks) && is_array($vcardsource->socialnetworks)) foreach ($vcardsource->socialnetworks as $netw) switch ($netw->type) {
131 $str .= "X-SOCIALPROFILE;type=dfrn;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
134 $str .= "X-SOCIALPROFILE;type=facebook;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
137 $str .= "X-SOCIALPROFILE;type=twitter;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
141 $str .= "END:VCARD\r\n";
147 * @param int $phpDate (UTC)
148 * @return string (Lokalzeit)
150 function wdcal_php2MySqlTime($phpDate)
152 return date("Y-m-d H:i:s", $phpDate);
156 * @param string $sqlDate
159 function wdcal_mySql2PhpTime($sqlDate)
161 $ts = DateTime::createFromFormat("Y-m-d H:i:s", $sqlDate);
162 return $ts->format("U");
166 * @param string $myqlDate
169 function wdcal_mySql2icalTime($myqlDate)
171 $x = explode(" ", $myqlDate);
172 $y = explode("-", $x[0]);
173 $ret = array("year"=> $y[0], "month"=> $y[1], "day"=> $y[2]);
174 $y = explode(":", $x[1]);
175 $ret["hour"] = $y[0];
176 $ret["minute"] = $y[1];
177 $ret["second"] = $y[2];
186 function icalendar_sanitize_string($str = "")
188 $str = str_replace("\r\n", "\n", $str);
189 $str = str_replace("\n\r", "\n", $str);
190 $str = str_replace("\r", "\n", $str);
191 $str = str_replace("\n\n", "\n", $str);
192 $str = str_replace("\n\n", "\n", $str);
198 * @return Sabre_CalDAV_AnimexxCalendarRootNode
200 function dav_createRootCalendarNode()
202 $caldavBackend_std = Sabre_CalDAV_Backend_Private::getInstance();
203 $caldavBackend_community = Sabre_CalDAV_Backend_Friendica::getInstance();
205 return new Sabre_CalDAV_AnimexxCalendarRootNode(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), array(
207 $caldavBackend_community,
212 * @return Sabre_CardDAV_AddressBookRootFriendica
214 function dav_createRootContactsNode()
216 $carddavBackend_std = Sabre_CardDAV_Backend_Std::getInstance();
217 $carddavBackend_community = Sabre_CardDAV_Backend_FriendicaCommunity::getInstance();
219 return new Sabre_CardDAV_AddressBookRootFriendica(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), array(
221 $carddavBackend_community,
227 * @param bool $force_authentication
228 * @param bool $needs_caldav
229 * @param bool $needs_carddav
230 * @return Sabre_DAV_Server
232 function dav_create_server($force_authentication = false, $needs_caldav = true, $needs_carddav = true)
235 new Sabre_DAV_SimpleCollection('principals', array(
236 new Sabre_CalDAV_Principal_Collection(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), "principals/users"),
239 if ($needs_caldav) $arr[] = dav_createRootCalendarNode();
240 if ($needs_carddav) $arr[] = dav_createRootContactsNode();
243 $tree = new Sabre_DAV_SimpleCollection('root', $arr);
245 // The object tree needs in turn to be passed to the server class
246 $server = new Sabre_DAV_Server($tree);
248 $server->setBaseUri(CALDAV_URL_PREFIX);
250 $authPlugin = new Sabre_DAV_Auth_Plugin(Sabre_DAV_Auth_Backend_Std::getInstance(), 'SabreDAV');
251 $server->addPlugin($authPlugin);
253 $aclPlugin = new Sabre_DAVACL_Plugin_Friendica();
254 $aclPlugin->defaultUsernamePath = "principals/users";
255 $server->addPlugin($aclPlugin);
258 $caldavPlugin = new Sabre_CalDAV_Plugin();
259 $server->addPlugin($caldavPlugin);
261 if ($needs_carddav) {
262 $carddavPlugin = new Sabre_CardDAV_Plugin();
263 $server->addPlugin($carddavPlugin);
266 if ($force_authentication) $server->broadcastEvent('beforeMethod', array("GET", "/")); // Make it authenticate
273 * @param Sabre_DAV_Server $server
274 * @param string $with_privilege
275 * @return array|Sabre_CalDAV_Calendar[]
277 function dav_get_current_user_calendars(&$server, $with_privilege = "")
279 if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
282 $calendar_path = "/calendars/" . strtolower($a->user["nickname"]) . "/";
284 /** @var Sabre_CalDAV_AnimexxUserCalendars $tree */
285 $tree = $server->tree->getNodeForPath($calendar_path);
286 /** @var array|Sabre_CalDAV_Calendar[] $calendars */
287 $children = $tree->getChildren();
289 $calendars = array();
290 /** @var Sabre_DAVACL_Plugin $aclplugin */
291 $aclplugin = $server->getPlugin("acl");
292 foreach ($children as $child) if (is_a($child, "Sabre_CalDAV_Calendar")) {
293 if ($with_privilege != "") {
294 $caluri = $calendar_path . $child->getName();
295 if ($aclplugin->checkPrivileges($caluri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) $calendars[] = $child;
297 $calendars[] = $child;
305 * @param Sabre_DAV_Server $server
306 * @param Sabre_CalDAV_Calendar $calendar
307 * @param string $calendarobject_uri
308 * @param string $with_privilege
309 * @return null|Sabre_VObject_Component_VEvent
311 function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
313 $obj = $calendar->getChild($calendarobject_uri);
315 if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
318 $uri = "/calendars/" . strtolower($a->user["nickname"]) . "/" . $calendar->getName() . "/" . $calendarobject_uri;
320 /** @var Sabre_DAVACL_Plugin $aclplugin */
321 $aclplugin = $server->getPlugin("acl");
322 if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) return null;
325 $vObject = Sabre_VObject_Reader::read($data);
332 * @param Sabre_DAV_Server $server
334 * @param string $with_privilege
335 * @return null|Sabre_CalDAV_Calendar
337 function dav_get_current_user_calendar_by_id(&$server, $id, $with_privilege = "")
339 $calendars = dav_get_current_user_calendars($server, $with_privilege);
342 foreach ($calendars as $cal) {
343 $prop = $cal->getProperties(array("id"));
344 if (isset($prop["id"]) && $prop["id"] == $id) $calendar = $cal;
353 * @return Sabre_VObject_Component_VEvent $vObject
355 function dav_create_empty_vevent($uid = "")
358 if ($uid == "") $uid = uniqid();
359 return Sabre_VObject_Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Friendica//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . $a->get_hostname() .
360 "\r\nDTSTAMP:" . date("Ymd") . "T" . date("His") . "Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
367 * @param Sabre_VObject_Component_VEvent $vObject
368 * @return Sabre_VObject_Component_VEvent|null
370 function dav_get_eventComponent(&$vObject)
374 foreach ($vObject->getComponents() as $component) {
375 if ($component->name !== 'VTIMEZONE') {
376 $componentType = $component->name;
380 if ($componentType != "VEVENT") return null;