4 class vcard_source_data_email
8 function __construct($type, $email)
10 $this->email = $email;
15 class vcard_source_data_homepage
17 public $homepage, $type;
19 function __construct($type, $homepage)
21 $this->homepage = $homepage;
26 class vcard_source_data_telephone
28 public $telephone, $type;
30 function __construct($type, $telephone)
32 $this->telephone = $telephone;
37 class vcard_source_data_socialnetwork
39 public $nick, $type, $url;
41 function __construct($type, $nick, $url)
49 class vcard_source_data_address
51 public $street, $street2, $zip, $city, $country, $type;
54 class vcard_source_data_photo
57 public $width, $height;
61 class vcard_source_data
63 function __construct($name_first, $name_middle, $name_last)
65 $this->name_first = $name_first;
66 $this->name_middle = $name_middle;
67 $this->name_last = $name_last;
70 public $name_first, $name_middle, $name_last;
74 /** @var array|vcard_source_data_telephone[] $telephones */
77 /** @var array|vcard_source_data_homepage[] $homepages */
80 /** @var array|vcard_source_data_socialnetwork[] $socialnetworks */
81 public $socialnetworks;
83 /** @var array|vcard_source_data_email[] $email */
86 /** @var array|vcard_source_data_addresses[] $addresses */
89 /** @var vcard_source_data_photo */
97 * @param vcard_source_data $vcardsource
100 function vcard_source_compile($vcardsource)
102 $str = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Friendica//DAV-Plugin//EN\r\n";
103 $str .= "N:" . str_replace(";", ",", $vcardsource->name_last) . ";" . str_replace(";", ",", $vcardsource->name_first) . ";" . str_replace(";", ",", $vcardsource->name_middle) . ";;\r\n";
104 $str .= "FN:" . str_replace(";", ",", $vcardsource->name_first) . " " . str_replace(";", ",", $vcardsource->name_middle) . " " . str_replace(";", ",", $vcardsource->name_last) . "\r\n";
105 $str .= "REV:" . str_replace(" ", "T", $vcardsource->last_update) . "Z\r\n";
108 for ($i = 0; $i < count($vcardsource->homepages); $i++) {
109 if ($i == 0) $str .= "URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
112 $str .= "item$c.URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n";
113 $str .= "item$c.X-ABLabel:_\$!<HomePage>!\$_\r\n";
117 if (is_object($vcardsource->photo)) {
118 $data = base64_encode($vcardsource->photo->binarydata);
119 $str .= "PHOTO;ENCODING=BASE64;TYPE=" . $vcardsource->photo->type . ":" . $data . "\r\n";
122 if (isset($vcardsource->socialnetworks) && is_array($vcardsource->socialnetworks)) foreach ($vcardsource->socialnetworks as $netw) switch ($netw->type) {
124 $str .= "X-SOCIALPROFILE;type=dfrn;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
127 $str .= "X-SOCIALPROFILE;type=facebook;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
130 $str .= "X-SOCIALPROFILE;type=twitter;x-user=" . $netw->nick . ":" . $netw->url . "\r\n";
134 $str .= "END:VCARD\r\n";
140 * @param array $start
142 * @param bool $allday
145 function dav_create_vevent($start, $end, $allday)
147 if ($end["year"] < $start["year"] ||
148 ($end["year"] == $start["year"] && $end["month"] < $start["month"]) ||
149 ($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] < $start["day"]) ||
150 ($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] < $start["hour"]) ||
151 ($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] < $start["minute"]) ||
152 ($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] == $start["minute"] && $end["second"] < $start["second"])
155 } // DTEND muss <= DTSTART
157 $vevent = new vevent();
159 $vevent->setDtstart($start["year"], $start["month"], $start["day"], FALSE, FALSE, FALSE, FALSE, array("VALUE"=> "DATE"));
160 $end = IntVal(mktime(0, 0, 0, $end["month"], $end["day"], $end["year"]) + 3600 * 24);
162 // If a DST change occurs on the current day
163 $end += IntVal(date("Z", ($end - 3600 * 24)) - date("Z", $end));
165 $vevent->setDtend(date("Y", $end), date("m", $end), date("d", $end), FALSE, FALSE, FALSE, FALSE, array("VALUE"=> "DATE"));
167 $vevent->setDtstart($start["year"], $start["month"], $start["day"], $start["hour"], $start["minute"], $start["second"], FALSE, array("VALUE"=> "DATE-TIME"));
168 $vevent->setDtend($end["year"], $end["month"], $end["day"], $end["hour"], $end["minute"], $end["second"], FALSE, array("VALUE"=> "DATE-TIME"));
175 * @param int $phpDate (UTC)
176 * @return string (Lokalzeit)
178 function wdcal_php2MySqlTime($phpDate)
180 return date("Y-m-d H:i:s", $phpDate);
184 * @param string $sqlDate
187 function wdcal_mySql2PhpTime($sqlDate)
189 $ts = DateTime::createFromFormat("Y-m-d H:i:s", $sqlDate);
190 return $ts->format("U");
194 * @param string $myqlDate
197 function wdcal_mySql2icalTime($myqlDate)
199 $x = explode(" ", $myqlDate);
200 $y = explode("-", $x[0]);
201 $ret = array("year"=> $y[0], "month"=> $y[1], "day"=> $y[2]);
202 $y = explode(":", $x[1]);
203 $ret["hour"] = $y[0];
204 $ret["minute"] = $y[1];
205 $ret["second"] = $y[2];
214 function icalendar_sanitize_string($str = "")
216 $str = str_replace("\r\n", "\n", $str);
217 $str = str_replace("\n\r", "\n", $str);
218 $str = str_replace("\r", "\n", $str);
224 * @param DBClass_friendica_calendars $calendar
225 * @param DBClass_friendica_calendarobjects $calendarobject
227 function renderCalDavEntry_data(&$calendar, &$calendarobject)
231 $v = new vcalendar();
232 $v->setConfig('unique_id', $a->get_hostname());
233 $v->parse($calendarobject->calendardata);
236 $eventArray = $v->selectComponents(2009, 1, 1, date("Y") + 2, 12, 30);
238 $start_min = $end_max = "";
240 $allday = $summary = $vevent = $rrule = $color = $start = $end = null;
241 $location = $description = "";
243 foreach ($eventArray as $yearArray) {
244 foreach ($yearArray as $monthArray) {
245 foreach ($monthArray as $day => $dailyEventsArray) {
246 foreach ($dailyEventsArray as $vevent) {
247 /** @var $vevent vevent */
252 $dtstart = $vevent->getProperty('X-CURRENT-DTSTART');
253 if (is_array($dtstart)) {
254 $start = "'" . $dtstart[1] . "'";
255 if (strpos($dtstart[1], ":") === false) $allday = 1;
257 $dtstart = $vevent->getProperty('dtstart');
258 if (isset($dtstart["day"]) && $dtstart["day"] == $day) { // Mehrtägige Events nur einmal rein
259 if (isset($dtstart["hour"])) $start = "'" . $dtstart["year"] . "-" . $dtstart["month"] . "-" . $dtstart["day"] . " " . $dtstart["hour"] . ":" . $dtstart["minute"] . ":" . $dtstart["secont"] . "'";
261 $start = "'" . $dtstart["year"] . "-" . $dtstart["month"] . "-" . $dtstart["day"] . " 00:00:00'";
267 $dtend = $vevent->getProperty('X-CURRENT-DTEND');
268 if (is_array($dtend)) {
269 $end = "'" . $dtend[1] . "'";
270 if (strpos($dtend[1], ":") === false) $allday = 1;
272 $dtend = $vevent->getProperty('dtend');
273 if (isset($dtend["hour"])) $end = "'" . $dtend["year"] . "-" . $dtend["month"] . "-" . $dtend["day"] . " " . $dtend["hour"] . ":" . $dtend["minute"] . ":" . $dtend["second"] . "'";
275 $end = "'" . $dtend["year"] . "-" . $dtend["month"] . "-" . $dtend["day"] . " 00:00:00' - INTERVAL 1 SECOND";
279 $summary = $vevent->getProperty('summary');
280 $description = $vevent->getProperty('description');
281 $location = $vevent->getProperty('location');
282 $rrule_prob = $vevent->getProperty('rrule');
283 if ($rrule_prob != null) {
284 $rrule = $vevent->createRrule();
285 $rrule = "'" . dbesc($rrule) . "'";
287 $color_ = $vevent->getProperty("X-ANIMEXX-COLOR");
288 $color = (is_array($color_) ? $color_[1] : "NULL");
290 if ($start_min == "" || preg_replace("/[^0-9]/", "", $start) < preg_replace("/[^0-9]/", "", $start_min)) $start_min = $start;
291 if ($end_max == "" || preg_replace("/[^0-9]/", "", $end) > preg_replace("/[^0-9]/", "", $start_min)) $end_max = $end;
297 if ($start_min != "") {
299 if ($allday && mb_strlen($end_max) == 12) {
300 $x = explode("-", str_replace("'", "", $end_max));
301 $time = mktime(0, 0, 0, IntVal($x[1]), IntVal($x[2]), IntVal($x[0]));
302 $end_max = date("'Y-m-d H:i:s'", ($time - 1));
305 q("INSERT INTO %s%sjqcalendar (`uid`, `namespace`, `namespace_id`, `ical_uri`, `Subject`, `Location`, `Description`, `StartTime`, `EndTime`, `IsAllDayEvent`, `RecurringRule`, `Color`)
306 VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', %s, %s, %d, '%s', '%s')",
307 CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
308 IntVal($calendar->uid), IntVal($calendarobject->namespace), IntVal($calendarobject->namespace_id), dbesc($calendarobject->uri), dbesc($summary),
309 dbesc($location), dbesc(str_replace("\\n", "\n", $description)), $start_min, $end_max, IntVal($allday), dbesc($rrule), dbesc($color)
312 foreach ($vevent->components as $comp) {
313 /** @var $comp calendarComponent */
314 $trigger = $comp->getProperty("TRIGGER");
315 $sql_field = ($trigger["relatedStart"] ? $start : $end);
316 $sql_op = ($trigger["before"] ? "DATE_SUB" : "DATE_ADD");
320 if (isset($trigger["second"])) {
321 $num = IntVal($trigger["second"]) . " SECOND";
322 $rel_type = "second";
323 $rel_value = IntVal($trigger["second"]);
325 if (isset($trigger["minute"])) {
326 $num = IntVal($trigger["minute"]) . " MINUTE";
327 $rel_type = "minute";
328 $rel_value = IntVal($trigger["minute"]);
330 if (isset($trigger["hour"])) {
331 $num = IntVal($trigger["hour"]) . " HOUR";
333 $rel_value = IntVal($trigger["hour"]);
335 if (isset($trigger["day"])) {
336 $num = IntVal($trigger["day"]) . " DAY";
338 $rel_value = IntVal($trigger["day"]);
340 if (isset($trigger["week"])) {
341 $num = IntVal($trigger["week"]) . " WEEK";
343 $rel_value = IntVal($trigger["week"]);
345 if (isset($trigger["month"])) {
346 $num = IntVal($trigger["month"]) . " MONTH";
348 $rel_value = IntVal($trigger["month"]);
350 if (isset($trigger["year"])) {
351 $num = IntVal($trigger["year"]) . " YEAR";
353 $rel_value = IntVal($trigger["year"]);
355 if ($trigger["before"]) $rel_value *= -1;
357 if ($rel_type != "") {
358 $not_date = "$sql_op($sql_field, INTERVAL $num)";
359 q("INSERT INTO %s%snotifications (`uid`, `ical_uri`, `rel_type`, `rel_value`, `alert_date`, `notified`) VALUES ('%s', '%s', '%s', '%s', %s, IF(%s < NOW(), 1, 0))",
360 CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
361 IntVal($calendar->uid), dbesc($calendarobject->uri), dbesc($rel_type), IntVal($rel_value), $not_date, $not_date);
371 function renderAllCalDavEntries()
373 q("DELETE FROM %s%sjqcalendar", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
374 q("DELETE FROM %s%snotifications", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
375 $calendars = q("SELECT * FROM %s%scalendars", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
376 $anz = count($calendars);
378 foreach ($calendars as $calendar) {
379 $cal = new DBClass_friendica_calendars($calendar);
381 if (($i % 100) == 0) echo "$i / $anz\n";
382 $calobjs = q("SELECT * FROM %s%scalendarobjects WHERE `namespace` = %d AND `namespace_id` = %d",
383 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendar["namespace"]), IntVal($calendar["namespace_id"]));
384 foreach ($calobjs as $calobj) {
385 $obj = new DBClass_friendica_calendarobjects($calobj);
386 renderCalDavEntry_data($cal, $obj);
396 function renderCalDavEntry_uri($uri)
398 q("DELETE FROM %s%sjqcalendar WHERE `ical_uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
399 q("DELETE FROM %s%snotifications WHERE `ical_uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
401 $calobj = q("SELECT * FROM %s%scalendarobjects WHERE `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
402 if (count($calobj) == 0) return false;
403 $cal = new DBClass_friendica_calendarobjects($calobj[0]);
404 $calendars = q("SELECT * FROM %s%scalendars WHERE `namespace`=%d AND `namespace_id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($cal->namespace), IntVal($cal->namespace_id));
405 $calendar = new DBClass_friendica_calendars($calendars[0]);
406 renderCalDavEntry_data($calendar, $cal);
413 * @return array|DBClass_friendica_calendars[]
415 function dav_getMyCals($user_id)
417 $d = q("SELECT * FROM %s%scalendars WHERE `uid` = %d ORDER BY `calendarorder` ASC",
418 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($user_id), CALDAV_NAMESPACE_PRIVATE
421 foreach ($d as $e) $cals[] = new DBClass_friendica_calendars($e);
430 function wdcal_jsonp_encode($obj)
432 $str = json_encode($obj);
433 if (isset($_REQUEST["callback"])) {
434 $str = $_REQUEST["callback"] . "(" . $str . ")";
442 * @param int $weekstartday
443 * @param int $num_days
444 * @param string $type
447 function wdcal_get_list_range_params($day, $weekstartday, $num_days, $type)
449 $phpTime = IntVal($day);
452 $st = mktime(0, 0, 0, date("m", $phpTime), 1, date("Y", $phpTime));
453 $et = mktime(0, 0, -1, date("m", $phpTime) + 1, 1, date("Y", $phpTime));
456 //suppose first day of a week is monday
457 $monday = date("d", $phpTime) - date('N', $phpTime) + 1;
458 //echo date('N', $phpTime);
459 $st = mktime(0, 0, 0, date("m", $phpTime), $monday, date("Y", $phpTime));
460 $et = mktime(0, 0, -1, date("m", $phpTime), $monday + 7, date("Y", $phpTime));
463 //suppose first day of a week is monday
464 $monday = date("d", $phpTime) - date('N', $phpTime) + $weekstartday;
465 //echo date('N', $phpTime);
466 $st = mktime(0, 0, 0, date("m", $phpTime), $monday, date("Y", $phpTime));
467 $et = mktime(0, 0, -1, date("m", $phpTime), $monday + $num_days, date("Y", $phpTime));
470 $st = mktime(0, 0, 0, date("m", $phpTime), date("d", $phpTime), date("Y", $phpTime));
471 $et = mktime(0, 0, -1, date("m", $phpTime), date("d", $phpTime) + 1, date("Y", $phpTime));
476 return array($st, $et);
485 * @param string $recurr_uri
487 * @param string $timezone
488 * @param string $goaway_url
491 function wdcal_postEditPage($uri, $recurr_uri = "", $uid = 0, $timezone = "", $goaway_url = "")
494 $localization = wdcal_local::getInstanceByUser($uid);
496 if (isset($_REQUEST["allday"])) {
497 $start = $localization->date_parseLocal($_REQUEST["start_date"] . " 00:00");
498 $end = $localization->date_parseLocal($_REQUEST["end_date"] . " 20:00");
501 $start = $localization->date_parseLocal($_REQUEST["start_date"] . " " . $_REQUEST["start_time"]);
502 $end = $localization->date_parseLocal($_REQUEST["end_date"] . " " . $_REQUEST["end_time"]);
507 $cals = dav_getMyCals($uid);
508 foreach ($cals as $c) {
509 $cs = wdcal_calendar_factory($uid, $c->namespace, $c->namespace_id);
510 $p = $cs->getPermissionsCalendar($uid);
512 if ($p["write"]) try {
513 $cs->addItem($start, $end, dav_compat_getRequestVar("subject"), $isallday, dav_compat_parse_text_serverside("wdcal_desc"),
514 dav_compat_getRequestVar("location"), dav_compat_getRequestVar("color"), $timezone,
515 isset($_REQUEST["notification"]), $_REQUEST["notification_type"], $_REQUEST["notification_value"]);
516 } catch (Exception $e) {
517 notification(t("Error") . ": " . $e);
519 dav_compat_redirect($goaway_url);
523 $cals = dav_getMyCals($uid);
524 foreach ($cals as $c) {
525 $cs = wdcal_calendar_factory($uid, $c->namespace, $c->namespace_id);
526 $p = $cs->getPermissionsItem($uid, $uri, $recurr_uri);
527 if ($p["write"]) try {
528 $cs->updateItem($uri, $start, $end,
529 dav_compat_getRequestVar("subject"), $isallday, dav_compat_parse_text_serverside("wdcal_desc"),
530 dav_compat_getRequestVar("location"), dav_compat_getRequestVar("color"), $timezone,
531 isset($_REQUEST["notification"]), $_REQUEST["notification_type"], $_REQUEST["notification_value"]);
532 } catch (Exception $e) {
533 notification(t("Error") . ": " . $e);
535 dav_compat_redirect($goaway_url);
544 function wdcal_print_feed($base_path = "")
546 $user_id = dav_compat_get_curr_user_id();
548 if (isset($_REQUEST["cal"])) foreach ($_REQUEST["cal"] as $c) {
549 $x = explode("-", $c);
550 $calendarSource = wdcal_calendar_factory($user_id, $x[0], $x[1]);
551 $calp = $calendarSource->getPermissionsCalendar($user_id);
552 if ($calp["read"]) $cals[] = $calendarSource;
556 /** @var $cals array|AnimexxCalSource[] */
558 $method = $_GET["method"];
562 foreach ($cals as $c) if ($cs == null) {
563 $x = $c->getPermissionsCalendar($user_id);
564 if ($x["read"]) $cs = $c;
567 echo wdcal_jsonp_encode(array('IsSuccess' => false,
568 'Msg' => t('No access')));
572 $start = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarStartTime"]));
573 $end = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarEndTime"]));
574 $newuri = $cs->addItem($start, $end, $_REQUEST["CalendarTitle"], $_REQUEST["IsAllDayEvent"]);
577 'Msg' => 'add success',
581 } catch (Exception $e) {
583 'IsSuccess' => false,
584 'Msg' => $e->__toString(),
589 $weekstartday = (isset($_REQUEST["weekstartday"]) ? IntVal($_REQUEST["weekstartday"]) : 1); // 1 = Monday
590 $num_days = (isset($_REQUEST["num_days"]) ? IntVal($_REQUEST["num_days"]) : 7);
593 $date = wdcal_get_list_range_params($_REQUEST["showdate"], $weekstartday, $num_days, $_REQUEST["viewtype"]);
595 $ret['events'] = array();
596 $ret["issort"] = true;
597 $ret["start"] = $date[0];
598 $ret["end"] = $date[1];
599 $ret['error'] = null;
601 foreach ($cals as $c) {
602 $events = $c->listItemsByRange($date[0], $date[1], $base_path);
603 $ret["events"] = array_merge($ret["events"], $events);
607 foreach ($ret["events"] as $e) {
608 if (!isset($tmpev[$e["start"]])) $tmpev[$e["start"]] = array();
609 $tmpev[$e["start"]][] = $e;
612 $ret["events"] = array();
613 foreach ($tmpev as $e) foreach ($e as $f) $ret["events"][] = $f;
618 $start = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarStartTime"]));
619 $end = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarEndTime"]));
620 foreach ($cals as $c) try {
621 $permissions_item = $c->getPermissionsItem($user_id, $_REQUEST["calendarId"], "");
622 if ($permissions_item["write"]) {
623 $c->updateItem($_REQUEST["calendarId"], $start, $end);
626 } catch (Exception $e) {
633 'Msg' => 'Succefully',
636 echo wdcal_jsonp_encode(array('IsSuccess' => false,
637 'Msg' => t('No access')));
642 } catch (Exception $e) {
644 'IsSuccess' => false,
645 'Msg' => $e->__toString(),
651 foreach ($cals as $c) try {
652 $permissions_item = $c->getPermissionsItem($user_id, $_REQUEST["calendarId"], "");
653 if ($permissions_item["write"]) $c->removeItem($_REQUEST["calendarId"]);
654 } catch (Exception $e) {
660 'Msg' => 'Succefully',
663 echo wdcal_jsonp_encode(array('IsSuccess' => false,
664 'Msg' => t('No access')));
669 echo wdcal_jsonp_encode($ret);