]> git.mxchange.org Git - friendica-addons.git/blob - dav/dav_caldav_backend_virtual_friendica.inc.php
Heavily refactored, including multiple calendars per user and recurring events. Not...
[friendica-addons.git] / dav / dav_caldav_backend_virtual_friendica.inc.php
1 <?php
2
3 class Sabre_CalDAV_Backend_Friendica extends Sabre_CalDAV_Backend_Virtual
4 {
5
6         /**
7          * @var null|Sabre_CalDAV_Backend_Friendica
8          */
9         private static $instance = null;
10
11         /**
12          * @static
13          * @return Sabre_CalDAV_Backend_Friendica
14          */
15         public static function getInstance()
16         {
17                 if (self::$instance == null) {
18                         self::$instance = new Sabre_CalDAV_Backend_Friendica();
19                 }
20                 return self::$instance;
21         }
22
23         /**
24          * @return int
25          */
26         public function getNamespace()
27         {
28                 return CALDAV_NAMESPACE_PRIVATE;
29         }
30
31
32         /**
33          * @static
34          * @param int $calendarId
35          * @throws Sabre_DAV_Exception_NotFound
36          * @return void
37          */
38         protected static function createCache_internal($calendarId)
39         {
40                 $calendar = Sabre_CalDAV_Backend_Common::loadCalendarById($calendarId);
41
42                 switch ($calendar["uri"]) {
43                         case CALDAV_FRIENDICA_MINE:
44                                 $sql_where = " AND cid = 0";
45                                 break;
46                         case CALDAV_FRIENDICA_CONTACTS:
47                                 $sql_where = " AND cid > 0";
48                                 break;
49                         default:
50                                 throw new Sabre_DAV_Exception_NotFound();
51                 }
52
53                 $r = q("SELECT * FROM `event` WHERE `uid` = %d " . $sql_where . " ORDER BY `start`", IntVal($calendar["namespace_id"]));
54
55                 foreach ($r as $row) {
56                         $uid       = $calendar["uri"] . "-" . $row["id"];
57                         $vevent    = dav_create_empty_vevent($uid);
58                         $component = dav_get_eventComponent($vevent);
59
60                         if ($row["adjust"]) {
61                                 $start  = datetime_convert('UTC', date_default_timezone_get(), $row["start"]);
62                                 $finish = datetime_convert('UTC', date_default_timezone_get(), $row["finish"]);
63                         } else {
64                                 $start  = $row["start"];
65                                 $finish = $row["finish"];
66                         }
67
68                         $summary = ($row["summary"] != "" ? $row["summary"] : $row["desc"]);
69                         $desc    = ($row["summary"] != "" ? $row["desc"] : "");
70                         $component->add("SUMMARY", icalendar_sanitize_string($summary));
71                         $component->add("LOCATION", icalendar_sanitize_string($row["location"]));
72                         $component->add("DESCRIPTION", icalendar_sanitize_string($desc));
73
74                         $ts_start = wdcal_mySql2PhpTime($start);
75                         $ts_end   = wdcal_mySql2PhpTime($start);
76
77                         $allday = (strpos($start, "00:00:00") !== false && strpos($finish, "00:00:00") !== false);
78                         $type           = ($allday ? Sabre_VObject_Property_DateTime::DATE : Sabre_VObject_Property_DateTime::LOCALTZ);
79
80                         $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
81                         $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_start)), $type);
82                         $datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
83                         $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_end)), $type);
84
85                         $component->add($datetime_start);
86                         $component->add($datetime_end);
87
88                         $data = $vevent->serialize();
89
90                         q("INSERT INTO %s%scal_virtual_object_cache (`calendar_id`, `data_uri`, `data_summary`, `data_location`, `data_start`, `data_end`, `data_allday`, `data_type`,
91                                 `calendardata`, `size`, `etag`) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', %d, '%s')",
92                                 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calendarId, dbesc($uid), dbesc($summary), dbesc($row["location"]), dbesc($row["start"]), dbesc($row["finish"]),
93                                         ($allday ? 1 : 0), dbesc(($row["type"] == "birthday" ? "birthday" : "")), dbesc($data), strlen($data), md5($data));
94
95                 }
96
97         }
98
99
100         /**
101          * @param array $row
102          * @param array $calendar
103          * @param string $base_path
104          * @return array
105          */
106         private function jqcal2wdcal($row, $calendar, $base_path)
107         {
108                 if ($row["adjust"]) {
109                         $start  = datetime_convert('UTC', date_default_timezone_get(), $row["start"]);
110                         $finish = datetime_convert('UTC', date_default_timezone_get(), $row["finish"]);
111                 } else {
112                         $start  = $row["start"];
113                         $finish = $row["finish"];
114                 }
115
116                 $allday = (strpos($start, "00:00:00") !== false && strpos($finish, "00:00:00") !== false);
117
118                 $summary = (($row["summary"]) ? $row["summary"] : substr(preg_replace("/\[[^\]]*\]/", "", $row["desc"]), 0, 100));
119
120                 return array(
121                         "jq_id"             => $row["id"],
122                         "ev_id"             => $row["id"],
123                         "summary"           => escape_tags($summary),
124                         "start"             => wdcal_mySql2PhpTime($start),
125                         "end"               => wdcal_mySql2PhpTime($finish),
126                         "is_allday"         => ($allday ? 1 : 0),
127                         "is_moredays"       => (substr($start, 0, 10) != substr($finish, 0, 10)),
128                         "is_recurring"      => ($row["type"] == "birthday"),
129                         "color"             => "#f8f8ff",
130                         "is_editable"       => 0,
131                         "is_editable_quick" => 0,
132                         "location"          => $row["location"],
133                         "attendees"         => '',
134                         "has_notification"  => 0,
135                         "url_detail"        => $base_path . "/events/event/" . $row["id"],
136                         "url_edit"          => "",
137                         "special_type"      => ($row["type"] == "birthday" ? "birthday" : ""),
138                 );
139         }
140
141
142         /**
143          * @param int $calendarId
144          * @param string $date_from
145          * @param string $date_to
146          * @param string $base_path
147          * @throws Sabre_DAV_Exception_NotFound
148          * @return array
149          */
150         public function listItemsByRange($calendarId, $date_from, $date_to, $base_path)
151         {
152                 $calendar = Sabre_CalDAV_Backend_Common::loadCalendarById($calendarId);
153
154                 if ($calendar["namespace"] != CALDAV_NAMESPACE_PRIVATE) throw new Sabre_DAV_Exception_NotFound();
155
156                 switch ($calendar["uri"]) {
157                         case CALDAV_FRIENDICA_MINE:
158                                 $sql_where = " AND cid = 0";
159                                 break;
160                         case CALDAV_FRIENDICA_CONTACTS:
161                                 $sql_where = " AND cid > 0";
162                                 break;
163                         default:
164                                 throw new Sabre_DAV_Exception_NotFound();
165                 }
166
167                 if ($date_from != "") {
168                         if (is_numeric($date_from)) $sql_where .= " AND `finish` >= '" . date("Y-m-d H:i:s", $date_from) . "'";
169                         else $sql_where .= " AND `finish` >= '" . dbesc($date_from) . "'";
170                 }
171                 if ($date_to != "") {
172                         if (is_numeric($date_to)) $sql_where .= " AND `start` <= '" . date("Y-m-d H:i:s", $date_to) . "'";
173                         else $sql_where .= " AND `start` <= '" . dbesc($date_to) . "'";
174                 }
175                 $ret = array();
176
177                 $r = q("SELECT * FROM `event` WHERE `uid` = %d " . $sql_where . " ORDER BY `start`", IntVal($calendar["namespace_id"]));
178
179                 $a = get_app();
180                 foreach ($r as $row) {
181                         $r                = $this->jqcal2wdcal($row, $calendar, $a->get_baseurl());
182                         $r["calendar_id"] = $calendar["id"];
183                         $ret[]            = $r;
184                 }
185
186                 return $ret;
187         }
188
189
190         /**
191          * Returns a list of calendars for a principal.
192          *
193          * Every project is an array with the following keys:
194          *  * id, a unique id that will be used by other functions to modify the
195          *    calendar. This can be the same as the uri or a database key.
196          *  * uri, which the basename of the uri with which the calendar is
197          *    accessed.
198          *  * principaluri. The owner of the calendar. Almost always the same as
199          *    principalUri passed to this method.
200          *
201          * Furthermore it can contain webdav properties in clark notation. A very
202          * common one is '{DAV:}displayname'.
203          *
204          * @param string $principalUri
205          * @return array
206          */
207         public function getCalendarsForUser($principalUri)
208         {
209                 $n = dav_compat_principal2namespace($principalUri);
210                 if ($n["namespace"] != $this->getNamespace()) return array();
211
212                 $cals = q("SELECT * FROM %s%scalendars WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->getNamespace(), IntVal($n["namespace_id"]));
213                 $ret  = array();
214                 foreach ($cals as $cal) {
215                         if (!in_array($cal["uri"], $GLOBALS["CALDAV_PRIVATE_SYSTEM_CALENDARS"])) continue;
216
217                         $dat = array(
218                                 "id"                                                      => $cal["id"],
219                                 "uri"                                                     => $cal["uri"],
220                                 "principaluri"                                            => $principalUri,
221                                 '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}getctag' => $cal['ctag'] ? $cal['ctag'] : '0',
222                                 "calendar_class"                                          => "Sabre_CalDAV_Calendar_Virtual",
223                         );
224                         foreach ($this->propertyMap as $key=> $field) $dat[$key] = $cal[$field];
225
226                         $ret[] = $dat;
227                 }
228
229                 return $ret;
230         }
231
232         /**
233          * @param int $calendar_id
234          * @param int $calendarobject_id
235          * @return string
236          */
237         function getItemDetailRedirect($calendar_id, $calendarobject_id)
238         {
239                 $a    = get_app();
240                 $item = q("SELECT `id` FROM `item` WHERE `event-id` = %d AND `uid` = %d AND deleted = 0", IntVal($calendarobject_id), $a->user["uid"]);
241                 if (count($item) == 0) return "/events/";
242                 return "/display/" . $a->user["nickname"] . "/" . IntVal($item[0]["id"]);
243
244         }
245 }