f0af57c91727ef5924067805b739b9602ea20c31
[friendica-addons.git/.git] / dav / friendica / main.php
1 <?php
2
3 use Friendica\Module\Login;
4 use Friendica\Util\Emailer;
5
6 require_once('include/security.php');
7
8 function dav_install()
9 {
10         register_hook('event_created', 'addon/dav/dav.php', 'dav_event_created_hook');
11         register_hook('event_updated', 'addon/dav/dav.php', 'dav_event_updated_hook');
12         register_hook('profile_tabs', 'addon/dav/dav.php', 'dav_profile_tabs_hook');
13         register_hook('cron', 'addon/dav/dav.php', 'dav_cron');
14 }
15
16
17 function dav_uninstall()
18 {
19         unregister_hook('event_created', 'addon/dav/dav.php', 'dav_event_created_hook');
20         unregister_hook('event_updated', 'addon/dav/dav.php', 'dav_event_updated_hook');
21         unregister_hook('profile_tabs', 'addon/dav/dav.php', 'dav_profile_tabs_hook');
22         unregister_hook('cron', 'addon/dav/dav.php', 'dav_cron');
23 }
24
25
26 function dav_module()
27 {
28 }
29
30 function dav_include_files()
31 {
32         require_once (__DIR__ . "/../SabreDAV/lib/Sabre/autoload.php");
33
34         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Node.php");
35         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Element.php");
36         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component.php");
37         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/DateTimeParser.php");
38         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/ElementList.php");
39         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/FreeBusyGenerator.php");
40         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Parameter.php");
41         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/ParseException.php");
42         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property.php");
43         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Reader.php");
44         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/RecurrenceIterator.php");
45         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/TimeZoneUtil.php");
46         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Version.php");
47         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property/DateTime.php");
48         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property/MultiDateTime.php");
49         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VAlarm.php");
50         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VCalendar.php");
51         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VEvent.php");
52         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VJournal.php");
53         require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VTodo.php");
54
55         require_once (__DIR__ . "/../common/calendar.fnk.php");
56         require_once (__DIR__ . "/../common/calendar_rendering.fnk.php");
57
58         require_once (__DIR__ . "/../common/dav_caldav_backend_common.inc.php");
59         require_once (__DIR__ . "/../common/dav_caldav_backend_private.inc.php");
60         require_once (__DIR__ . "/../common/dav_caldav_backend_virtual.inc.php");
61         require_once (__DIR__ . "/../common/dav_caldav_root.inc.php");
62         require_once (__DIR__ . "/../common/dav_user_calendars.inc.php");
63         require_once (__DIR__ . "/../common/dav_caldav_calendar_virtual.inc.php");
64         require_once (__DIR__ . "/../common/dav_caldav_calendar_private.inc.php");
65
66         require_once (__DIR__ . "/../common/dav_carddav_root.inc.php");
67         require_once (__DIR__ . "/../common/dav_carddav_backend_common.inc.php");
68         require_once (__DIR__ . "/../common/dav_carddav_backend_virtual.inc.php");
69         require_once (__DIR__ . "/../common/dav_carddav_backend_private.inc.php");
70         require_once (__DIR__ . "/../common/dav_user_addressbooks.inc.php");
71
72         require_once (__DIR__ . "/../common/wdcal_configuration.php");
73         require_once (__DIR__ . "/../common/wdcal_backend.inc.php");
74
75         require_once (__DIR__ . "/dav_friendica_principal.inc.php");
76         require_once (__DIR__ . "/dav_friendica_auth.inc.php");
77         require_once (__DIR__ . "/dav_carddav_backend_virtual_friendica.inc.php");
78         require_once (__DIR__ . "/dav_caldav_backend_virtual_friendica.inc.php");
79         require_once (__DIR__ . "/FriendicaACLPlugin.inc.php");
80
81         require_once (__DIR__ . "/../common/wdcal_edit.inc.php");
82         require_once (__DIR__ . "/calendar.friendica.fnk.php");
83         require_once (__DIR__ . "/layout.fnk.php");
84 }
85
86
87 /**
88  * @param App $a
89  */
90 function dav_init(&$a)
91 {
92
93         /*
94          * Recommended settings:
95          * ALTER TABLE `photo` ADD INDEX ( `contact-id` )
96          */
97
98         ini_set("display_errors", 1);
99         error_reporting(E_ALL);
100
101         dav_include_files();
102
103         if (false) {
104                 dbg(true);
105                 error_reporting(E_ALL);
106                 ini_set("display_errors", 1);
107         }
108
109         wdcal_create_std_calendars();
110         wdcal_create_std_addressbooks();
111         wdcal_addRequiredHeaders();
112
113         if ($a->argc >= 2 && $a->argv[1] == "wdcal") {
114
115                 if ($a->argc >= 3 && $a->argv[2] == "feed") {
116                         wdcal_print_feed($a->get_baseurl() . "/dav/wdcal/");
117                         killme();
118                 }
119                 return;
120         }
121         if ($a->argc >= 2 && $a->argv[1] == "getExceptionDates") {
122                 echo wdcal_getEditPage_exception_selector();
123                 killme();
124         }
125
126         if ($a->argc >= 2 && $a->argv[1] == "settings") {
127                 return;
128         }
129
130
131         if (isset($_REQUEST["test"])) {
132                 renderAllCalDavEntries();
133         }
134
135
136         $server = dav_create_server();
137
138         $browser = new Sabre_DAV_Browser_Plugin();
139         $server->addPlugin($browser);
140
141         $server->exec();
142
143         killme();
144 }
145
146 /**
147  * @return string
148  */
149 function dav_content()
150 {
151         $a = get_app();
152         if (!isset($a->user["uid"]) || $a->user["uid"] == 0) {
153                 return Login::form();
154         }
155
156         $x = "";
157         try {
158                 if ($a->argv[1] == "settings") {
159                         return wdcal_getSettingsPage($a);
160                 } elseif ($a->argv[1] == "wdcal") {
161                         if (isset($a->argv[2]) && strlen($a->argv[2]) > 0) {
162                                 if ($a->argv[2] == "new") {
163                                         $o = "";
164                                         if (isset($_REQUEST["save"])) {
165                                                 check_form_security_token_redirectOnErr("/dav/wdcal/", "caledit");
166                                                 $ret = wdcal_postEditPage("new", "", $a->user["uid"], $a->timezone, $a->get_baseurl() . "/dav/wdcal/");
167                                                 if ($ret["ok"]) notice($ret["msg"]);
168                                                 else info($ret["msg"]);
169                                                 goaway('dav/wdcal/');
170                                         }
171                                         $o .= wdcal_getNewPage();
172                                         return $o;
173                                 } else {
174                                         $calendar_id = IntVal($a->argv[2]);
175                                         if (isset($a->argv[3]) && $a->argv[3] == "ics-export") {
176                                                 wdcal_print_user_ics($calendar_id);
177                                         } elseif (isset($a->argv[3]) && $a->argv[3] == "ics-import") {
178                                                 return wdcal_import_user_ics($calendar_id);
179                                         } elseif (isset($a->argv[3]) && $a->argv[3] > 0) {
180                                                 if (isset($a->argv[4]) && $a->argv[4] == "edit") {
181                                                         $o = "";
182                                                         if (isset($_REQUEST["save"])) {
183                                                                 check_form_security_token_redirectOnErr("/dav/wdcal/", "caledit");
184                                                                 $ret = wdcal_postEditPage($a->argv[3], $a->user["uid"], $a->timezone, $a->get_baseurl() . "/dav/wdcal/");
185                                                                 if ($ret["ok"]) notice($ret["msg"]);
186                                                                 else info($ret["msg"]);
187                                                                 goaway('dav/wdcal/');
188                                                         }
189                                                         $o .= wdcal_getEditPage($calendar_id, $a->argv[3]);
190                                                         return $o;
191                                                 } else {
192                                                         return wdcal_getDetailPage($calendar_id, $a->argv[3]);
193                                                 }
194                                         } else {
195                                                 // @TODO Edit Calendar
196                                         }
197                                 }
198                         } else {
199                                 $server = dav_create_server(true, true, false);
200                                 $cals   = dav_get_current_user_calendars($server, DAV_ACL_READ);
201                                 $x      = wdcal_printCalendar($cals, array(), $a->get_baseurl() . "/dav/wdcal/feed/", "week", 0, 200);
202                         }
203                 }
204         } catch (DAVVersionMismatchException $e) {
205                 $x = t("The current version of this plugin has not been set up correctly. Please contact the system administrator of your installation of friendica to fix this.");
206         }
207         return $x;
208 }
209
210
211 /**
212  * @param App $a
213  * @param object $b
214  */
215 function dav_event_created_hook(&$a, &$b)
216 {
217         dav_include_files();
218         // @TODO Updating the cache instead of completely invalidating and rebuilding it
219         Sabre_CalDAV_Backend_Friendica::invalidateCache($a->user["uid"], CALDAV_FRIENDICA_CONTACTS);
220         Sabre_CalDAV_Backend_Friendica::invalidateCache($a->user["uid"], CALDAV_FRIENDICA_MINE);
221 }
222
223 /**
224  * @param App $a
225  * @param object $b
226  */
227 function dav_event_updated_hook(&$a, &$b)
228 {
229         dav_include_files();
230         // @TODO Updating the cache instead of completely invalidating and rebuilding it
231         Sabre_CalDAV_Backend_Friendica::invalidateCache($a->user["uid"], CALDAV_FRIENDICA_CONTACTS);
232         Sabre_CalDAV_Backend_Friendica::invalidateCache($a->user["uid"], CALDAV_FRIENDICA_MINE);
233 }
234
235 /**
236  * @param App $a
237  * @param object $b
238  */
239 function dav_profile_tabs_hook(&$a, &$b)
240 {
241         $b["tabs"][] = array(
242                 "label" => t('Calendar'),
243                 "url"   => $a->get_baseurl() . "/dav/wdcal/",
244                 "sel"   => "",
245                 "title" => t('Extended calendar with CalDAV-support'),
246         );
247 }
248
249
250 /**
251  * @param App $a
252  * @param object $b
253  */
254 function dav_cron(&$a, &$b)
255 {
256         dav_include_files();
257
258         $r = q("SELECT * FROM %s%snotifications WHERE `notified` = 0 AND `alert_date` <= NOW()", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
259     if (is_array($r)) {
260         foreach ($r as $not) {
261                 q("UPDATE %s%snotifications SET `notified` = 1 WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $not["id"]);
262                 $event    = q("SELECT * FROM %s%sjqcalendar WHERE `calendarobject_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $not["calendarobject_id"]);
263                 $calendar = q("SELECT * FROM %s%scalendars WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $not["calendar_id"]);
264                 $users    = array();
265                 if (count($calendar) != 1 || count($event) == 0) continue;
266                 switch ($calendar[0]["namespace"]) {
267                         case CALDAV_NAMESPACE_PRIVATE:
268                                 $user = q("SELECT * FROM user WHERE `uid` = %d AND `blocked` = 0", $calendar[0]["namespace_id"]);
269                                 if (count($user) != 1) continue;
270                                 $users[] = $user[0];
271                                 break;
272                 }
273                 switch ($not["action"]) {
274                         case "email":
275                         case "display": // @TODO implement "Display"
276                                 foreach ($users as $user) {
277                                         $find      = array("%to%", "%event%", "%url%");
278                                         $repl      = array($user["username"], $event[0]["Summary"], $a->get_baseurl() . "/dav/wdcal/" . $calendar[0]["id"] . "/" . $not["calendarobject_id"] . "/");
279                                         $text_text = str_replace($find, $repl, "Hi %to%!\n\nThe event \"%event%\" is about to begin:\n%url%");
280                                         $text_html = str_replace($find, $repl, "Hi %to%!<br>\n<br>\nThe event \"%event%\" is about to begin:<br>\n<a href='" . "%url%" . "'>%url%</a>");
281                                         $params    = array(
282                                                 'fromName'             => FRIENDICA_PLATFORM,
283                                                 'fromEmail'            => t('noreply') . '@' . $a->get_hostname(),
284                                                 'replyTo'              => t('noreply') . '@' . $a->get_hostname(),
285                                                 'toEmail'              => $user["email"],
286                                                 'messageSubject'       => t("Notification: " . $event[0]["Summary"]),
287                                                 'htmlVersion'          => $text_html,
288                                                 'textVersion'          => $text_text,
289                                                 'additionalMailHeader' => "",
290                                         );
291                                         Emailer::send($params);
292                                 }
293                                 break;
294                 }
295         }
296     }
297 }
298
299
300 /**
301  * @param App $a
302  * @param null|object $o
303  */
304 function dav_plugin_admin_post(&$a = null, &$o = null)
305 {
306         check_form_security_token_redirectOnErr('/admin/plugins/dav', 'dav_admin_save');
307
308         dav_include_files();
309         require_once(__DIR__ . "/database-init.inc.php");
310
311         if (isset($_REQUEST["install"])) {
312                 $errs = dav_create_tables();
313                 if (count($errs) == 0) info(t('The database tables have been installed.') . EOL);
314                 else notice(t("An error occurred during the installation.") . EOL);
315         }
316         if (isset($_REQUEST["upgrade"])) {
317                 $errs = dav_upgrade_tables();
318                 if (count($errs) == 0) {
319                         renderAllCalDavEntries();
320                         info(t('The database tables have been updated.') . EOL);
321                 } else notice(t("An error occurred during the update.") . EOL);
322         }
323 }
324
325 /**
326  * @param App $a
327  * @param string $o
328  */
329 function dav_plugin_admin(&$a, &$o)
330 {
331         dav_include_files();
332         require_once(__DIR__ . "/database-init.inc.php");
333
334         $dbstatus = dav_check_tables();
335
336         $o = '<input type="hidden" name="form_security_token" value="' . get_form_security_token("dav_admin_save") . '">';
337         $o .= '<i>' . t("No system-wide settings yet.") . '</i><br><br>';
338
339
340         $o .= '<h3>' . t('Database status') . '</h3>';
341         switch ($dbstatus) {
342                 case 0:
343                         $o .= t('Installed');
344                         break;
345                 case 1:
346                 case 2:
347                         $o .= "<strong>" . t('Upgrade needed') . "</strong><br>" . t("Please back up all calendar data (the tables beginning with dav_*) before proceeding. While all calendar events <i>should</i> be converted to the new database structure, it's always safe to have a backup. Below, you can have a look at the database-queries that will be made when pressing the 'update'-button.") . "<br><br><input type='submit' name='upgrade' value='" . t('Upgrade') . "'>";
348                         break;
349                 case -1:
350                         $o .= t('Not installed') . "<br><br><input type='submit' name='install' value='" . t('Install') . "'>";
351                         break;
352                 case -2:
353                 default:
354                         $o .= t('Unknown') . "<br><br>" . t("Something really went wrong. I cannot recover from this state automatically, sorry. Please go to the database backend, back up the data, and delete all tables beginning with 'dav_' manually. Afterwards, this installation routine should be able to reinitialize the tables automatically.");
355                         break;
356         }
357         $o .= "<br><br>";
358
359         $o .= "<h3>" . t("Troubleshooting") . "</h3>";
360         $o .= "<h4>" . t("Manual creation of the database tables:") . "</h4>";
361         $o .= "<a href='#' onClick='\$(\"#sqlstatements\").show(); return false;'>" . t("Show SQL-statements") . "</a><blockquote style='display: none;' id='sqlstatements'><pre>";
362         switch ($dbstatus) {
363                 case 1: case 2:
364                         $tables = dav_get_update_statements($dbstatus);
365                         foreach ($tables as $t) $o .= escape_tags($t . ";\n\n");
366                         break;
367                 default:
368                         $tables = dav_get_create_statements();
369                         foreach ($tables as $t) $o .= escape_tags($t . ";\n\n");
370                         break;
371         }
372         $o .= "</pre></blockquote>";
373 }