]> git.mxchange.org Git - friendica-addons.git/blob - dav/SabreDAV/lib/Sabre/CalDAV/ICSExportPlugin.php
Second part of refactoring; should be runnable again, yet not thoroughly tested
[friendica-addons.git] / dav / SabreDAV / lib / Sabre / CalDAV / ICSExportPlugin.php
1 <?php
2
3 use Sabre\VObject;
4
5 /**
6  * ICS Exporter
7  *
8  * This plugin adds the ability to export entire calendars as .ics files.
9  * This is useful for clients that don't support CalDAV yet. They often do
10  * support ics files.
11  *
12  * @package Sabre
13  * @subpackage CalDAV
14  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
15  * @author Evert Pot (http://www.rooftopsolutions.nl/)
16  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
17  */
18 class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
19
20     /**
21      * Reference to Server class
22      *
23      * @var Sabre_DAV_Server
24      */
25     private $server;
26
27     /**
28      * Initializes the plugin and registers event handlers
29      *
30      * @param Sabre_DAV_Server $server
31      * @return void
32      */
33     public function initialize(Sabre_DAV_Server $server) {
34
35         $this->server = $server;
36         $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90);
37
38     }
39
40     /**
41      * 'beforeMethod' event handles. This event handles intercepts GET requests ending
42      * with ?export
43      *
44      * @param string $method
45      * @param string $uri
46      * @return bool
47      */
48     public function beforeMethod($method, $uri) {
49
50         if ($method!='GET') return;
51         if ($this->server->httpRequest->getQueryString()!='export') return;
52
53         // splitting uri
54         list($uri) = explode('?',$uri,2);
55
56         $node = $this->server->tree->getNodeForPath($uri);
57
58         if (!($node instanceof Sabre_CalDAV_Calendar)) return;
59
60         // Checking ACL, if available.
61         if ($aclPlugin = $this->server->getPlugin('acl')) {
62             $aclPlugin->checkPrivileges($uri, '{DAV:}read');
63         }
64
65         $this->server->httpResponse->setHeader('Content-Type','text/calendar');
66         $this->server->httpResponse->sendStatus(200);
67
68         $nodes = $this->server->getPropertiesForPath($uri, array(
69             '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data',
70         ),1);
71
72         $this->server->httpResponse->sendBody($this->generateICS($nodes));
73
74         // Returning false to break the event chain
75         return false;
76
77     }
78
79     /**
80      * Merges all calendar objects, and builds one big ics export
81      *
82      * @param array $nodes
83      * @return string
84      */
85     public function generateICS(array $nodes) {
86
87         $calendar = new VObject\Component('vcalendar');
88         $calendar->version = '2.0';
89         if (Sabre_DAV_Server::$exposeVersion) {
90             $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
91         } else {
92             $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
93         }
94         $calendar->calscale = 'GREGORIAN';
95
96         $collectedTimezones = array();
97
98         $timezones = array();
99         $objects = array();
100
101         foreach($nodes as $node) {
102
103             if (!isset($node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'])) {
104                 continue;
105             }
106             $nodeData = $node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'];
107
108             $nodeComp = VObject\Reader::read($nodeData);
109
110             foreach($nodeComp->children() as $child) {
111
112                 switch($child->name) {
113                     case 'VEVENT' :
114                     case 'VTODO' :
115                     case 'VJOURNAL' :
116                         $objects[] = $child;
117                         break;
118
119                     // VTIMEZONE is special, because we need to filter out the duplicates
120                     case 'VTIMEZONE' :
121                         // Naively just checking tzid.
122                         if (in_array((string)$child->TZID, $collectedTimezones)) continue;
123
124                         $timezones[] = $child;
125                         $collectedTimezones[] = $child->TZID;
126                         break;
127
128                 }
129
130             }
131
132         }
133
134         foreach($timezones as $tz) $calendar->add($tz);
135         foreach($objects as $obj) $calendar->add($obj);
136
137         return $calendar->serialize();
138
139     }
140
141 }