xref: /plugin/davcal/helper.php (revision ed76489033608e6ba6d26aced43cf2e3c68b1a1f)
1a1a3b679SAndreas Boehler<?php
2a1a3b679SAndreas Boehler/**
3cb71a62aSAndreas Boehler  * Helper Class for the DAVCal plugin
4a1a3b679SAndreas Boehler  * This helper does the actual work.
5a1a3b679SAndreas Boehler  *
6a1a3b679SAndreas Boehler  */
7a1a3b679SAndreas Boehler
8a1a3b679SAndreas Boehler// must be run within Dokuwiki
9a1a3b679SAndreas Boehlerif(!defined('DOKU_INC')) die();
10a1a3b679SAndreas Boehler
11a1a3b679SAndreas Boehlerclass helper_plugin_davcal extends DokuWiki_Plugin {
12a1a3b679SAndreas Boehler
13a1a3b679SAndreas Boehler  protected $sqlite = null;
14185e2535SAndreas Boehler  protected $cachedValues = array();
15a1a3b679SAndreas Boehler
16a1a3b679SAndreas Boehler  /**
17cb71a62aSAndreas Boehler    * Constructor to load the configuration and the SQLite plugin
18a1a3b679SAndreas Boehler    */
19a1a3b679SAndreas Boehler  public function helper_plugin_davcal() {
20a1a3b679SAndreas Boehler    $this->sqlite =& plugin_load('helper', 'sqlite');
2121d04f73SAndreas Boehler    global $conf;
2221d04f73SAndreas Boehler    if($conf['allowdebug'])
2321d04f73SAndreas Boehler        dbglog('---- DAVCAL helper.php init');
24a1a3b679SAndreas Boehler    if(!$this->sqlite)
25a1a3b679SAndreas Boehler    {
2621d04f73SAndreas Boehler        if($conf['allowdebug'])
2721d04f73SAndreas Boehler            dbglog('This plugin requires the sqlite plugin. Please install it.');
28a1a3b679SAndreas Boehler        msg('This plugin requires the sqlite plugin. Please install it.');
29a1a3b679SAndreas Boehler        return;
30a1a3b679SAndreas Boehler    }
31a1a3b679SAndreas Boehler
32a1a3b679SAndreas Boehler    if(!$this->sqlite->init('davcal', DOKU_PLUGIN.'davcal/db/'))
33a1a3b679SAndreas Boehler    {
3421d04f73SAndreas Boehler        if($conf['allowdebug'])
3521d04f73SAndreas Boehler            dbglog('Error initialising the SQLite DB for DAVCal');
36a1a3b679SAndreas Boehler        return;
37a1a3b679SAndreas Boehler    }
38a1a3b679SAndreas Boehler  }
39a1a3b679SAndreas Boehler
40cb71a62aSAndreas Boehler  /**
41185e2535SAndreas Boehler   * Retrieve meta data for a given page
42185e2535SAndreas Boehler   *
43185e2535SAndreas Boehler   * @param string $id optional The page ID
44185e2535SAndreas Boehler   * @return array The metadata
45185e2535SAndreas Boehler   */
46185e2535SAndreas Boehler  private function getMeta($id = null) {
47185e2535SAndreas Boehler    global $ID;
48185e2535SAndreas Boehler    global $INFO;
49185e2535SAndreas Boehler
50185e2535SAndreas Boehler    if ($id === null) $id = $ID;
51185e2535SAndreas Boehler
52185e2535SAndreas Boehler    if($ID === $id && $INFO['meta']) {
53185e2535SAndreas Boehler        $meta = $INFO['meta'];
54185e2535SAndreas Boehler    } else {
55185e2535SAndreas Boehler        $meta = p_get_metadata($id);
56185e2535SAndreas Boehler    }
57185e2535SAndreas Boehler
58185e2535SAndreas Boehler    return $meta;
59185e2535SAndreas Boehler  }
60185e2535SAndreas Boehler
61185e2535SAndreas Boehler  /**
62185e2535SAndreas Boehler   * Retrieve the meta data for a given page
63185e2535SAndreas Boehler   *
64185e2535SAndreas Boehler   * @param string $id optional The page ID
65185e2535SAndreas Boehler   * @return array with meta data
66185e2535SAndreas Boehler   */
67185e2535SAndreas Boehler  public function getCalendarMetaForPage($id = null)
68185e2535SAndreas Boehler  {
69185e2535SAndreas Boehler      if(is_null($id))
70185e2535SAndreas Boehler      {
71185e2535SAndreas Boehler          global $ID;
72185e2535SAndreas Boehler          $id = $ID;
73185e2535SAndreas Boehler      }
74185e2535SAndreas Boehler
75185e2535SAndreas Boehler      $meta = $this->getMeta($id);
76185e2535SAndreas Boehler      if(isset($meta['plugin_davcal']))
77185e2535SAndreas Boehler        return $meta['plugin_davcal'];
78185e2535SAndreas Boehler      else
79185e2535SAndreas Boehler        return array();
80185e2535SAndreas Boehler  }
81185e2535SAndreas Boehler
82185e2535SAndreas Boehler  /**
83185e2535SAndreas Boehler   * Get all calendar pages used by a given page
84185e2535SAndreas Boehler   * based on the stored metadata
85185e2535SAndreas Boehler   *
86185e2535SAndreas Boehler   * @param string $id optional The page id
87185e2535SAndreas Boehler   * @return mixed The pages as array or false
88185e2535SAndreas Boehler   */
89185e2535SAndreas Boehler  public function getCalendarPagesByMeta($id = null)
90185e2535SAndreas Boehler  {
91185e2535SAndreas Boehler      if(is_null($id))
92185e2535SAndreas Boehler      {
93185e2535SAndreas Boehler          global $ID;
94185e2535SAndreas Boehler          $id = $ID;
95185e2535SAndreas Boehler      }
96185e2535SAndreas Boehler
97185e2535SAndreas Boehler      $meta = $this->getCalendarMetaForPage($id);
98185e2535SAndreas Boehler      if(isset($meta['id']))
99*ed764890SAndreas Boehler      {
100*ed764890SAndreas Boehler          // Filter the list of pages by permission
101*ed764890SAndreas Boehler          $pages = array_keys($meta['id']);
102*ed764890SAndreas Boehler          $retList = array();
103*ed764890SAndreas Boehler          foreach($pages as $page)
104*ed764890SAndreas Boehler          {
105*ed764890SAndreas Boehler            if(auth_quickaclcheck($page) >= AUTH_READ)
106*ed764890SAndreas Boehler            {
107*ed764890SAndreas Boehler                $retList[] = $page;
108*ed764890SAndreas Boehler            }
109*ed764890SAndreas Boehler          }
110*ed764890SAndreas Boehler          if(empty($retList))
111*ed764890SAndreas Boehler            return false;
112*ed764890SAndreas Boehler          return $retList;
113*ed764890SAndreas Boehler      }
114185e2535SAndreas Boehler      return false;
115185e2535SAndreas Boehler  }
116185e2535SAndreas Boehler
117185e2535SAndreas Boehler  /**
118185e2535SAndreas Boehler   * Get a list of calendar names/pages/ids/colors
119185e2535SAndreas Boehler   * for an array of page ids
120185e2535SAndreas Boehler   *
121185e2535SAndreas Boehler   * @param array $calendarPages The calendar pages to retrieve
122185e2535SAndreas Boehler   * @return array The list
123185e2535SAndreas Boehler   */
124185e2535SAndreas Boehler  public function getCalendarMapForIDs($calendarPages)
125185e2535SAndreas Boehler  {
126185e2535SAndreas Boehler      $data = array();
127185e2535SAndreas Boehler      foreach($calendarPages as $page)
128185e2535SAndreas Boehler      {
129185e2535SAndreas Boehler          $calid = $this->getCalendarIdForPage($page);
130185e2535SAndreas Boehler          if($calid !== false)
131185e2535SAndreas Boehler          {
132185e2535SAndreas Boehler            $settings = $this->getCalendarSettings($calid);
133185e2535SAndreas Boehler            $name = $settings['displayname'];
134185e2535SAndreas Boehler            $color = $settings['calendarcolor'];
135*ed764890SAndreas Boehler            $write = (auth_quickaclcheck($page) > AUTH_READ);
136185e2535SAndreas Boehler            $data[] = array('name' => $name, 'page' => $page, 'calid' => $calid,
137*ed764890SAndreas Boehler                            'color' => $color, 'write' => $write);
138185e2535SAndreas Boehler          }
139185e2535SAndreas Boehler      }
140185e2535SAndreas Boehler      return $data;
141185e2535SAndreas Boehler  }
142185e2535SAndreas Boehler
143185e2535SAndreas Boehler  /**
144185e2535SAndreas Boehler   * Get the saved calendar color for a given page.
145185e2535SAndreas Boehler   *
146185e2535SAndreas Boehler   * @param string $id optional The page ID
147185e2535SAndreas Boehler   * @return mixed The color on success, otherwise false
148185e2535SAndreas Boehler   */
149185e2535SAndreas Boehler  public function getCalendarColorForPage($id = null)
150185e2535SAndreas Boehler  {
151185e2535SAndreas Boehler      if(is_null($id))
152185e2535SAndreas Boehler      {
153185e2535SAndreas Boehler          global $ID;
154185e2535SAndreas Boehler          $id = $ID;
155185e2535SAndreas Boehler      }
156185e2535SAndreas Boehler
157185e2535SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
158185e2535SAndreas Boehler      if($calid === false)
159185e2535SAndreas Boehler        return false;
160185e2535SAndreas Boehler
161185e2535SAndreas Boehler      return $this->getCalendarColorForCalendar($calid);
162185e2535SAndreas Boehler  }
163185e2535SAndreas Boehler
164185e2535SAndreas Boehler  /**
165185e2535SAndreas Boehler   * Get the saved calendar color for a given calendar ID.
166185e2535SAndreas Boehler   *
167185e2535SAndreas Boehler   * @param string $id optional The calendar ID
168185e2535SAndreas Boehler   * @return mixed The color on success, otherwise false
169185e2535SAndreas Boehler   */
170185e2535SAndreas Boehler  public function getCalendarColorForCalendar($calid)
171185e2535SAndreas Boehler  {
172185e2535SAndreas Boehler      if(isset($this->cachedValues['calendarcolor'][$calid]))
173185e2535SAndreas Boehler        return $this->cachedValues['calendarcolor'][$calid];
174185e2535SAndreas Boehler
175185e2535SAndreas Boehler      $row = $this->getCalendarSettings($calid);
176185e2535SAndreas Boehler
177185e2535SAndreas Boehler      if(!isset($row['calendarcolor']))
178185e2535SAndreas Boehler        return false;
179185e2535SAndreas Boehler
180185e2535SAndreas Boehler      $color = $row['calendarcolor'];
181185e2535SAndreas Boehler      $this->cachedValues['calendarcolor'][$calid] = $color;
182185e2535SAndreas Boehler      return $color;
183185e2535SAndreas Boehler  }
184185e2535SAndreas Boehler
185185e2535SAndreas Boehler  /**
186e86c8dd3SAndreas Boehler   * Get the user's principal URL for iOS sync
187e86c8dd3SAndreas Boehler   * @param string $user the user name
188e86c8dd3SAndreas Boehler   * @return the URL to the principal sync
189e86c8dd3SAndreas Boehler   */
190e86c8dd3SAndreas Boehler  public function getPrincipalUrlForUser($user)
191e86c8dd3SAndreas Boehler  {
192e86c8dd3SAndreas Boehler      if(is_null($user))
193e86c8dd3SAndreas Boehler        return false;
194e86c8dd3SAndreas Boehler      $url = DOKU_URL.'lib/plugins/davcal/calendarserver.php/principals/'.$user;
195e86c8dd3SAndreas Boehler      return $url;
196e86c8dd3SAndreas Boehler  }
197e86c8dd3SAndreas Boehler
198e86c8dd3SAndreas Boehler  /**
199185e2535SAndreas Boehler   * Set the calendar color for a given page.
200185e2535SAndreas Boehler   *
201185e2535SAndreas Boehler   * @param string $color The color definition
202185e2535SAndreas Boehler   * @param string $id optional The page ID
203185e2535SAndreas Boehler   * @return boolean True on success, otherwise false
204185e2535SAndreas Boehler   */
205185e2535SAndreas Boehler  public function setCalendarColorForPage($color, $id = null)
206185e2535SAndreas Boehler  {
207185e2535SAndreas Boehler      if(is_null($id))
208185e2535SAndreas Boehler      {
209185e2535SAndreas Boehler          global $ID;
210185e2535SAndreas Boehler          $id = $ID;
211185e2535SAndreas Boehler      }
212185e2535SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
213185e2535SAndreas Boehler      if($calid === false)
214185e2535SAndreas Boehler        return false;
215185e2535SAndreas Boehler
21651f4febbSAndreas Boehler      $query = "UPDATE calendars SET calendarcolor = ? ".
21751f4febbSAndreas Boehler               " WHERE id = ?";
21851f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $color, $calid);
219185e2535SAndreas Boehler      if($res !== false)
220185e2535SAndreas Boehler      {
221185e2535SAndreas Boehler        $this->cachedValues['calendarcolor'][$calid] = $color;
222185e2535SAndreas Boehler        return true;
223185e2535SAndreas Boehler      }
224185e2535SAndreas Boehler      return false;
225185e2535SAndreas Boehler  }
226185e2535SAndreas Boehler
227185e2535SAndreas Boehler  /**
228cb71a62aSAndreas Boehler   * Set the calendar name and description for a given page with a given
229cb71a62aSAndreas Boehler   * page id.
230cb71a62aSAndreas Boehler   * If the calendar doesn't exist, the calendar is created!
231cb71a62aSAndreas Boehler   *
232cb71a62aSAndreas Boehler   * @param string  $name The name of the new calendar
233cb71a62aSAndreas Boehler   * @param string  $description The description of the new calendar
234cb71a62aSAndreas Boehler   * @param string  $id (optional) The ID of the page
235cb71a62aSAndreas Boehler   * @param string  $userid The userid of the creating user
236cb71a62aSAndreas Boehler   *
237cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false.
238cb71a62aSAndreas Boehler   */
239a1a3b679SAndreas Boehler  public function setCalendarNameForPage($name, $description, $id = null, $userid = null)
240a1a3b679SAndreas Boehler  {
241a1a3b679SAndreas Boehler      if(is_null($id))
242a1a3b679SAndreas Boehler      {
243a1a3b679SAndreas Boehler          global $ID;
244a1a3b679SAndreas Boehler          $id = $ID;
245a1a3b679SAndreas Boehler      }
246a1a3b679SAndreas Boehler      if(is_null($userid))
24734a47953SAndreas Boehler      {
24834a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
24934a47953SAndreas Boehler        {
250a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
25134a47953SAndreas Boehler        }
25234a47953SAndreas Boehler        else
25334a47953SAndreas Boehler        {
25434a47953SAndreas Boehler          $userid = uniqid('davcal-');
25534a47953SAndreas Boehler        }
25634a47953SAndreas Boehler      }
257a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
258a1a3b679SAndreas Boehler      if($calid === false)
259a1a3b679SAndreas Boehler        return $this->createCalendarForPage($name, $description, $id, $userid);
260a1a3b679SAndreas Boehler
26151f4febbSAndreas Boehler      $query = "UPDATE calendars SET displayname = ?, description = ? WHERE id = ?";
26251f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $name, $description, $calid);
263b269830cSAndreas Boehler      if($res !== false)
264b269830cSAndreas Boehler        return true;
265b269830cSAndreas Boehler      return false;
266a1a3b679SAndreas Boehler  }
267a1a3b679SAndreas Boehler
268cb71a62aSAndreas Boehler  /**
269cb71a62aSAndreas Boehler   * Save the personal settings to the SQLite database 'calendarsettings'.
270cb71a62aSAndreas Boehler   *
271cb71a62aSAndreas Boehler   * @param array  $settings The settings array to store
272cb71a62aSAndreas Boehler   * @param string $userid (optional) The userid to store
273cb71a62aSAndreas Boehler   *
274cb71a62aSAndreas Boehler   * @param boolean True on success, otherwise false
275cb71a62aSAndreas Boehler   */
276a495d34cSAndreas Boehler  public function savePersonalSettings($settings, $userid = null)
277a495d34cSAndreas Boehler  {
278a495d34cSAndreas Boehler      if(is_null($userid))
27934a47953SAndreas Boehler      {
28034a47953SAndreas Boehler          if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
28134a47953SAndreas Boehler          {
282a495d34cSAndreas Boehler            $userid = $_SERVER['REMOTE_USER'];
28334a47953SAndreas Boehler          }
28434a47953SAndreas Boehler          else
28534a47953SAndreas Boehler          {
28634a47953SAndreas Boehler              return false;
28734a47953SAndreas Boehler          }
28834a47953SAndreas Boehler      }
289a495d34cSAndreas Boehler      $this->sqlite->query("BEGIN TRANSACTION");
290a495d34cSAndreas Boehler
29151f4febbSAndreas Boehler      $query = "DELETE FROM calendarsettings WHERE userid = ?";
29251f4febbSAndreas Boehler      $this->sqlite->query($query, $userid);
293bd883736SAndreas Boehler
294a495d34cSAndreas Boehler      foreach($settings as $key => $value)
295a495d34cSAndreas Boehler      {
29651f4febbSAndreas Boehler          $query = "INSERT INTO calendarsettings (userid, key, value) VALUES (?, ?, ?)";
29751f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $userid, $key, $value);
298a495d34cSAndreas Boehler          if($res === false)
299a495d34cSAndreas Boehler              return false;
300a495d34cSAndreas Boehler      }
301a495d34cSAndreas Boehler      $this->sqlite->query("COMMIT TRANSACTION");
302185e2535SAndreas Boehler      $this->cachedValues['settings'][$userid] = $settings;
303a495d34cSAndreas Boehler      return true;
304a495d34cSAndreas Boehler  }
305a495d34cSAndreas Boehler
306cb71a62aSAndreas Boehler  /**
307cb71a62aSAndreas Boehler   * Retrieve the settings array for a given user id.
308cb71a62aSAndreas Boehler   * Some sane defaults are returned, currently:
309cb71a62aSAndreas Boehler   *
310cb71a62aSAndreas Boehler   *    timezone    => local
311cb71a62aSAndreas Boehler   *    weeknumbers => 0
312cb71a62aSAndreas Boehler   *    workweek    => 0
313cb71a62aSAndreas Boehler   *
314cb71a62aSAndreas Boehler   * @param string $userid (optional) The user id to retrieve
315cb71a62aSAndreas Boehler   *
316cb71a62aSAndreas Boehler   * @return array The settings array
317cb71a62aSAndreas Boehler   */
318a495d34cSAndreas Boehler  public function getPersonalSettings($userid = null)
319a495d34cSAndreas Boehler  {
320bd883736SAndreas Boehler      // Some sane default settings
321bd883736SAndreas Boehler      $settings = array(
322fb813b30SAndreas Boehler        'timezone' => $this->getConf('timezone'),
323fb813b30SAndreas Boehler        'weeknumbers' => $this->getConf('weeknumbers'),
324fb813b30SAndreas Boehler        'workweek' => $this->getConf('workweek'),
3251d5bdcd0SAndreas Boehler        'monday' => $this->getConf('monday'),
3261d5bdcd0SAndreas Boehler        'timeformat' => $this->getConf('timeformat')
327bd883736SAndreas Boehler      );
32834a47953SAndreas Boehler      if(is_null($userid))
32934a47953SAndreas Boehler      {
33034a47953SAndreas Boehler          if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
33134a47953SAndreas Boehler          {
33234a47953SAndreas Boehler            $userid = $_SERVER['REMOTE_USER'];
33334a47953SAndreas Boehler          }
33434a47953SAndreas Boehler          else
33534a47953SAndreas Boehler          {
33634a47953SAndreas Boehler            return $settings;
33734a47953SAndreas Boehler          }
33834a47953SAndreas Boehler      }
33934a47953SAndreas Boehler
34034a47953SAndreas Boehler      if(isset($this->cachedValues['settings'][$userid]))
34134a47953SAndreas Boehler        return $this->cachedValues['settings'][$userid];
34251f4febbSAndreas Boehler      $query = "SELECT key, value FROM calendarsettings WHERE userid = ?";
34351f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $userid);
344a495d34cSAndreas Boehler      $arr = $this->sqlite->res2arr($res);
345a495d34cSAndreas Boehler      foreach($arr as $row)
346a495d34cSAndreas Boehler      {
347a495d34cSAndreas Boehler          $settings[$row['key']] = $row['value'];
348a495d34cSAndreas Boehler      }
349185e2535SAndreas Boehler      $this->cachedValues['settings'][$userid] = $settings;
350a495d34cSAndreas Boehler      return $settings;
351a495d34cSAndreas Boehler  }
352a495d34cSAndreas Boehler
353cb71a62aSAndreas Boehler  /**
354cb71a62aSAndreas Boehler   * Retrieve the calendar ID based on a page ID from the SQLite table
355cb71a62aSAndreas Boehler   * 'pagetocalendarmapping'.
356cb71a62aSAndreas Boehler   *
357cb71a62aSAndreas Boehler   * @param string $id (optional) The page ID to retrieve the corresponding calendar
358cb71a62aSAndreas Boehler   *
359cb71a62aSAndreas Boehler   * @return mixed the ID on success, otherwise false
360cb71a62aSAndreas Boehler   */
361a1a3b679SAndreas Boehler  public function getCalendarIdForPage($id = null)
362a1a3b679SAndreas Boehler  {
363a1a3b679SAndreas Boehler      if(is_null($id))
364a1a3b679SAndreas Boehler      {
365a1a3b679SAndreas Boehler          global $ID;
366a1a3b679SAndreas Boehler          $id = $ID;
367a1a3b679SAndreas Boehler      }
368a1a3b679SAndreas Boehler
369185e2535SAndreas Boehler      if(isset($this->cachedValues['calid'][$id]))
370185e2535SAndreas Boehler        return $this->cachedValues['calid'][$id];
371185e2535SAndreas Boehler
37251f4febbSAndreas Boehler      $query = "SELECT calid FROM pagetocalendarmapping WHERE page = ?";
37351f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $id);
374a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
375a1a3b679SAndreas Boehler      if(isset($row['calid']))
376185e2535SAndreas Boehler      {
377185e2535SAndreas Boehler        $calid = $row['calid'];
378185e2535SAndreas Boehler        $this->cachedValues['calid'] = $calid;
379185e2535SAndreas Boehler        return $calid;
380185e2535SAndreas Boehler      }
381a1a3b679SAndreas Boehler      return false;
382a1a3b679SAndreas Boehler  }
383a1a3b679SAndreas Boehler
384cb71a62aSAndreas Boehler  /**
385cb71a62aSAndreas Boehler   * Retrieve the complete calendar id to page mapping.
386cb71a62aSAndreas Boehler   * This is necessary to be able to retrieve a list of
387cb71a62aSAndreas Boehler   * calendars for a given user and check the access rights.
388cb71a62aSAndreas Boehler   *
389cb71a62aSAndreas Boehler   * @return array The mapping array
390cb71a62aSAndreas Boehler   */
391a1a3b679SAndreas Boehler  public function getCalendarIdToPageMapping()
392a1a3b679SAndreas Boehler  {
393a1a3b679SAndreas Boehler      $query = "SELECT calid, page FROM pagetocalendarmapping";
394a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
395a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
396a1a3b679SAndreas Boehler      return $arr;
397a1a3b679SAndreas Boehler  }
398a1a3b679SAndreas Boehler
399cb71a62aSAndreas Boehler  /**
400cb71a62aSAndreas Boehler   * Retrieve all calendar IDs a given user has access to.
401cb71a62aSAndreas Boehler   * The user is specified by the principalUri, so the
402cb71a62aSAndreas Boehler   * user name is actually split from the URI component.
403cb71a62aSAndreas Boehler   *
404cb71a62aSAndreas Boehler   * Access rights are checked against DokuWiki's ACL
405cb71a62aSAndreas Boehler   * and applied accordingly.
406cb71a62aSAndreas Boehler   *
407cb71a62aSAndreas Boehler   * @param string $principalUri The principal URI to work on
408cb71a62aSAndreas Boehler   *
409cb71a62aSAndreas Boehler   * @return array An associative array of calendar IDs
410cb71a62aSAndreas Boehler   */
411a1a3b679SAndreas Boehler  public function getCalendarIdsForUser($principalUri)
412a1a3b679SAndreas Boehler  {
41334a47953SAndreas Boehler      global $auth;
414a1a3b679SAndreas Boehler      $user = explode('/', $principalUri);
415a1a3b679SAndreas Boehler      $user = end($user);
416a1a3b679SAndreas Boehler      $mapping = $this->getCalendarIdToPageMapping();
417a1a3b679SAndreas Boehler      $calids = array();
41834a47953SAndreas Boehler      $ud = $auth->getUserData($user);
41934a47953SAndreas Boehler      $groups = $ud['grps'];
420a1a3b679SAndreas Boehler      foreach($mapping as $row)
421a1a3b679SAndreas Boehler      {
422a1a3b679SAndreas Boehler          $id = $row['calid'];
423a1a3b679SAndreas Boehler          $page = $row['page'];
42434a47953SAndreas Boehler          $acl = auth_aclcheck($page, $user, $groups);
425a1a3b679SAndreas Boehler          if($acl >= AUTH_READ)
426a1a3b679SAndreas Boehler          {
427a1a3b679SAndreas Boehler              $write = $acl > AUTH_READ;
428a1a3b679SAndreas Boehler              $calids[$id] = array('readonly' => !$write);
429a1a3b679SAndreas Boehler          }
430a1a3b679SAndreas Boehler      }
431a1a3b679SAndreas Boehler      return $calids;
432a1a3b679SAndreas Boehler  }
433a1a3b679SAndreas Boehler
434cb71a62aSAndreas Boehler  /**
435cb71a62aSAndreas Boehler   * Create a new calendar for a given page ID and set name and description
436cb71a62aSAndreas Boehler   * accordingly. Also update the pagetocalendarmapping table on success.
437cb71a62aSAndreas Boehler   *
438cb71a62aSAndreas Boehler   * @param string $name The calendar's name
439cb71a62aSAndreas Boehler   * @param string $description The calendar's description
440cb71a62aSAndreas Boehler   * @param string $id (optional) The page ID to work on
441cb71a62aSAndreas Boehler   * @param string $userid (optional) The user ID that created the calendar
442cb71a62aSAndreas Boehler   *
443cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
444cb71a62aSAndreas Boehler   */
445a1a3b679SAndreas Boehler  public function createCalendarForPage($name, $description, $id = null, $userid = null)
446a1a3b679SAndreas Boehler  {
447a1a3b679SAndreas Boehler      if(is_null($id))
448a1a3b679SAndreas Boehler      {
449a1a3b679SAndreas Boehler          global $ID;
450a1a3b679SAndreas Boehler          $id = $ID;
451a1a3b679SAndreas Boehler      }
452a1a3b679SAndreas Boehler      if(is_null($userid))
45334a47953SAndreas Boehler      {
45434a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
45534a47953SAndreas Boehler        {
456a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
45734a47953SAndreas Boehler        }
45834a47953SAndreas Boehler        else
45934a47953SAndreas Boehler        {
46034a47953SAndreas Boehler          $userid = uniqid('davcal-');
46134a47953SAndreas Boehler        }
46234a47953SAndreas Boehler      }
463a1a3b679SAndreas Boehler      $values = array('principals/'.$userid,
464a1a3b679SAndreas Boehler                      $name,
465a1a3b679SAndreas Boehler                      str_replace(array('/', ' ', ':'), '_', $id),
466a1a3b679SAndreas Boehler                      $description,
467a1a3b679SAndreas Boehler                      'VEVENT,VTODO',
46855a741c0SAndreas Boehler                      0,
46955a741c0SAndreas Boehler                      1);
47051f4febbSAndreas Boehler      $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) ".
47151f4febbSAndreas Boehler               "VALUES (?, ?, ?, ?, ?, ?, ?)";
47251f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3], $values[4], $values[5], $values[6]);
47355a741c0SAndreas Boehler      if($res === false)
47455a741c0SAndreas Boehler        return false;
475cb71a62aSAndreas Boehler
476cb71a62aSAndreas Boehler      // Get the new calendar ID
47751f4febbSAndreas Boehler      $query = "SELECT id FROM calendars WHERE principaluri = ? AND displayname = ? AND ".
47851f4febbSAndreas Boehler               "uri = ? AND description = ?";
47951f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3]);
480a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
481cb71a62aSAndreas Boehler
482cb71a62aSAndreas Boehler      // Update the pagetocalendarmapping table with the new calendar ID
483a1a3b679SAndreas Boehler      if(isset($row['id']))
484a1a3b679SAndreas Boehler      {
48551f4febbSAndreas Boehler          $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (?, ?)";
48651f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $id, $row['id']);
48755a741c0SAndreas Boehler          return ($res !== false);
488a1a3b679SAndreas Boehler      }
489a1a3b679SAndreas Boehler
490a1a3b679SAndreas Boehler      return false;
491a1a3b679SAndreas Boehler  }
492a1a3b679SAndreas Boehler
493cb71a62aSAndreas Boehler  /**
494cb71a62aSAndreas Boehler   * Add a new iCal entry for a given page, i.e. a given calendar.
495cb71a62aSAndreas Boehler   *
496cb71a62aSAndreas Boehler   * The parameter array needs to contain
497cb71a62aSAndreas Boehler   *   detectedtz       => The timezone as detected by the browser
49882a48dfbSAndreas Boehler   *   currenttz        => The timezone in use by the calendar
499cb71a62aSAndreas Boehler   *   eventfrom        => The event's start date
500cb71a62aSAndreas Boehler   *   eventfromtime    => The event's start time
501cb71a62aSAndreas Boehler   *   eventto          => The event's end date
502cb71a62aSAndreas Boehler   *   eventtotime      => The event's end time
503cb71a62aSAndreas Boehler   *   eventname        => The event's name
504cb71a62aSAndreas Boehler   *   eventdescription => The event's description
505cb71a62aSAndreas Boehler   *
506cb71a62aSAndreas Boehler   * @param string $id The page ID to work on
507cb71a62aSAndreas Boehler   * @param string $user The user who created the calendar
508cb71a62aSAndreas Boehler   * @param string $params A parameter array with values to create
509cb71a62aSAndreas Boehler   *
510cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
511cb71a62aSAndreas Boehler   */
512a1a3b679SAndreas Boehler  public function addCalendarEntryToCalendarForPage($id, $user, $params)
513a1a3b679SAndreas Boehler  {
51482a48dfbSAndreas Boehler      if($params['currenttz'] !== '' && $params['currenttz'] !== 'local')
51582a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($params['currenttz']);
51682a48dfbSAndreas Boehler      elseif($params['currenttz'] === 'local')
517a25c89eaSAndreas Boehler          $timezone = new \DateTimeZone($params['detectedtz']);
518bd883736SAndreas Boehler      else
519bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
520cb71a62aSAndreas Boehler
521cb71a62aSAndreas Boehler      // Retrieve dates from settings
522b269830cSAndreas Boehler      $startDate = explode('-', $params['eventfrom']);
523b269830cSAndreas Boehler      $startTime = explode(':', $params['eventfromtime']);
524b269830cSAndreas Boehler      $endDate = explode('-', $params['eventto']);
525b269830cSAndreas Boehler      $endTime = explode(':', $params['eventtotime']);
526cb71a62aSAndreas Boehler
527cb71a62aSAndreas Boehler      // Load SabreDAV
5289bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
529a1a3b679SAndreas Boehler      $vcalendar = new \Sabre\VObject\Component\VCalendar();
530cb71a62aSAndreas Boehler
531cb71a62aSAndreas Boehler      // Add VCalendar, UID and Event Name
532a1a3b679SAndreas Boehler      $event = $vcalendar->add('VEVENT');
533b269830cSAndreas Boehler      $uuid = \Sabre\VObject\UUIDUtil::getUUID();
534b269830cSAndreas Boehler      $event->add('UID', $uuid);
535a1a3b679SAndreas Boehler      $event->summary = $params['eventname'];
536cb71a62aSAndreas Boehler
537cb71a62aSAndreas Boehler      // Add a description if requested
5380eebc909SAndreas Boehler      $description = $params['eventdescription'];
5390eebc909SAndreas Boehler      if($description !== '')
5400eebc909SAndreas Boehler        $event->add('DESCRIPTION', $description);
541cb71a62aSAndreas Boehler
5424ecb526cSAndreas Boehler      // Add attachments
5434ecb526cSAndreas Boehler      $attachments = $params['attachments'];
54482a48dfbSAndreas Boehler      if(!is_null($attachments))
5454ecb526cSAndreas Boehler        foreach($attachments as $attachment)
5464ecb526cSAndreas Boehler          $event->add('ATTACH', $attachment);
5474ecb526cSAndreas Boehler
548cb71a62aSAndreas Boehler      // Create a timestamp for last modified, created and dtstamp values in UTC
549b269830cSAndreas Boehler      $dtStamp = new \DateTime(null, new \DateTimeZone('UTC'));
550b269830cSAndreas Boehler      $event->add('DTSTAMP', $dtStamp);
551b269830cSAndreas Boehler      $event->add('CREATED', $dtStamp);
552b269830cSAndreas Boehler      $event->add('LAST-MODIFIED', $dtStamp);
553cb71a62aSAndreas Boehler
554cb71a62aSAndreas Boehler      // Adjust the start date, based on the given timezone information
555b269830cSAndreas Boehler      $dtStart = new \DateTime();
556a25c89eaSAndreas Boehler      $dtStart->setTimezone($timezone);
557b269830cSAndreas Boehler      $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2]));
558cb71a62aSAndreas Boehler
559cb71a62aSAndreas Boehler      // Only add the time values if it's not an allday event
560b269830cSAndreas Boehler      if($params['allday'] != '1')
561b269830cSAndreas Boehler        $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0);
562cb71a62aSAndreas Boehler
563cb71a62aSAndreas Boehler      // Adjust the end date, based on the given timezone information
564b269830cSAndreas Boehler      $dtEnd = new \DateTime();
565a25c89eaSAndreas Boehler      $dtEnd->setTimezone($timezone);
566b269830cSAndreas Boehler      $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2]));
567cb71a62aSAndreas Boehler
568cb71a62aSAndreas Boehler      // Only add the time values if it's not an allday event
569b269830cSAndreas Boehler      if($params['allday'] != '1')
570b269830cSAndreas Boehler        $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0);
571cb71a62aSAndreas Boehler
572b269830cSAndreas Boehler      // According to the VCal spec, we need to add a whole day here
573b269830cSAndreas Boehler      if($params['allday'] == '1')
574b269830cSAndreas Boehler          $dtEnd->add(new \DateInterval('P1D'));
575cb71a62aSAndreas Boehler
576cb71a62aSAndreas Boehler      // Really add Start and End events
577b269830cSAndreas Boehler      $dtStartEv = $event->add('DTSTART', $dtStart);
578b269830cSAndreas Boehler      $dtEndEv = $event->add('DTEND', $dtEnd);
579cb71a62aSAndreas Boehler
580cb71a62aSAndreas Boehler      // Adjust the DATE format for allday events
581b269830cSAndreas Boehler      if($params['allday'] == '1')
582b269830cSAndreas Boehler      {
583b269830cSAndreas Boehler          $dtStartEv['VALUE'] = 'DATE';
584b269830cSAndreas Boehler          $dtEndEv['VALUE'] = 'DATE';
585b269830cSAndreas Boehler      }
586cb71a62aSAndreas Boehler
587cb71a62aSAndreas Boehler      // Actually add the values to the database
588a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
589a1a3b679SAndreas Boehler      $uri = uniqid('dokuwiki-').'.ics';
590a1a3b679SAndreas Boehler      $now = new DateTime();
591a1a3b679SAndreas Boehler      $eventStr = $vcalendar->serialize();
592a1a3b679SAndreas Boehler
59351f4febbSAndreas Boehler      $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
59451f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid, $uri, $eventStr, $now->getTimestamp(), 'VEVENT',
59551f4febbSAndreas Boehler                                  $event->DTSTART->getDateTime()->getTimeStamp(), $event->DTEND->getDateTime()->getTimeStamp(),
59651f4febbSAndreas Boehler                                  strlen($eventStr), md5($eventStr), $uuid);
597cb71a62aSAndreas Boehler
598cb71a62aSAndreas Boehler      // If successfully, update the sync token database
59955a741c0SAndreas Boehler      if($res !== false)
60055a741c0SAndreas Boehler      {
60155a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'added');
602a1a3b679SAndreas Boehler          return true;
603a1a3b679SAndreas Boehler      }
60455a741c0SAndreas Boehler      return false;
60555a741c0SAndreas Boehler  }
606a1a3b679SAndreas Boehler
607cb71a62aSAndreas Boehler  /**
608cb71a62aSAndreas Boehler   * Retrieve the calendar settings of a given calendar id
609cb71a62aSAndreas Boehler   *
610cb71a62aSAndreas Boehler   * @param string $calid The calendar ID
611cb71a62aSAndreas Boehler   *
612cb71a62aSAndreas Boehler   * @return array The calendar settings array
613cb71a62aSAndreas Boehler   */
614b269830cSAndreas Boehler  public function getCalendarSettings($calid)
615b269830cSAndreas Boehler  {
61651f4febbSAndreas Boehler      $query = "SELECT principaluri, calendarcolor, displayname, uri, description, components, transparent, synctoken FROM calendars WHERE id= ? ";
61751f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
618b269830cSAndreas Boehler      $row = $this->sqlite->res2row($res);
619b269830cSAndreas Boehler      return $row;
620b269830cSAndreas Boehler  }
621b269830cSAndreas Boehler
622cb71a62aSAndreas Boehler  /**
623cb71a62aSAndreas Boehler   * Retrieve all events that are within a given date range,
624cb71a62aSAndreas Boehler   * based on the timezone setting.
625cb71a62aSAndreas Boehler   *
626cb71a62aSAndreas Boehler   * There is also support for retrieving recurring events,
627cb71a62aSAndreas Boehler   * using Sabre's VObject Iterator. Recurring events are represented
628cb71a62aSAndreas Boehler   * as individual calendar entries with the same UID.
629cb71a62aSAndreas Boehler   *
630cb71a62aSAndreas Boehler   * @param string $id The page ID to work with
631cb71a62aSAndreas Boehler   * @param string $user The user ID to work with
632cb71a62aSAndreas Boehler   * @param string $startDate The start date as a string
633cb71a62aSAndreas Boehler   * @param string $endDate The end date as a string
634cb71a62aSAndreas Boehler   *
635cb71a62aSAndreas Boehler   * @return array An array containing the calendar entries.
636cb71a62aSAndreas Boehler   */
63782a48dfbSAndreas Boehler  public function getEventsWithinDateRange($id, $user, $startDate, $endDate, $timezone)
638a1a3b679SAndreas Boehler  {
63982a48dfbSAndreas Boehler      if($timezone !== '' && $timezone !== 'local')
64082a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($timezone);
641bd883736SAndreas Boehler      else
642bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
643a1a3b679SAndreas Boehler      $data = array();
644cb71a62aSAndreas Boehler
645cb71a62aSAndreas Boehler      // Load SabreDAV
6469bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
647a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
648185e2535SAndreas Boehler      $color = $this->getCalendarColorForCalendar($calid);
649a469597cSAndreas Boehler      $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid = ?";
650a469597cSAndreas Boehler      $startTs = null;
651a469597cSAndreas Boehler      $endTs = null;
652a469597cSAndreas Boehler      if($startDate !== null)
653a469597cSAndreas Boehler      {
654a1a3b679SAndreas Boehler        $startTs = new \DateTime($startDate);
655a469597cSAndreas Boehler        $query .= " AND lastoccurence > ".$this->sqlite->quote_string($startTs->getTimestamp());
656a469597cSAndreas Boehler      }
657a469597cSAndreas Boehler      if($endDate !== null)
658a469597cSAndreas Boehler      {
659a1a3b679SAndreas Boehler        $endTs = new \DateTime($endDate);
660a469597cSAndreas Boehler        $query .= " AND firstoccurence < ".$this->sqlite->quote_string($endTs->getTimestamp());
661a469597cSAndreas Boehler      }
662cb71a62aSAndreas Boehler
663cb71a62aSAndreas Boehler      // Retrieve matching calendar objects
664a469597cSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
665a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
666cb71a62aSAndreas Boehler
667cb71a62aSAndreas Boehler      // Parse individual calendar entries
668a1a3b679SAndreas Boehler      foreach($arr as $row)
669a1a3b679SAndreas Boehler      {
670a1a3b679SAndreas Boehler          if(isset($row['calendardata']))
671a1a3b679SAndreas Boehler          {
672b269830cSAndreas Boehler              $entry = array();
673a1a3b679SAndreas Boehler              $vcal = \Sabre\VObject\Reader::read($row['calendardata']);
674ebc4eb57SAndreas Boehler              $recurrence = $vcal->VEVENT->RRULE;
675cb71a62aSAndreas Boehler              // If it is a recurring event, pass it through Sabre's EventIterator
676ebc4eb57SAndreas Boehler              if($recurrence != null)
677ebc4eb57SAndreas Boehler              {
678ebc4eb57SAndreas Boehler                  $rEvents = new \Sabre\VObject\Recur\EventIterator(array($vcal->VEVENT));
679ebc4eb57SAndreas Boehler                  $rEvents->rewind();
680e9b7d302SAndreas Boehler                  while($rEvents->valid())
681ebc4eb57SAndreas Boehler                  {
682ebc4eb57SAndreas Boehler                      $event = $rEvents->getEventObject();
683cb71a62aSAndreas Boehler                      // If we are after the given time range, exit
684a469597cSAndreas Boehler                      if(($endTs !== null) && ($rEvents->getDtStart()->getTimestamp() > $endTs->getTimestamp()))
685e9b7d302SAndreas Boehler                          break;
686cb71a62aSAndreas Boehler
687cb71a62aSAndreas Boehler                      // If we are before the given time range, continue
688a469597cSAndreas Boehler                      if(($startTs != null) && ($rEvents->getDtEnd()->getTimestamp() < $startTs->getTimestamp()))
689ebc4eb57SAndreas Boehler                      {
690ebc4eb57SAndreas Boehler                          $rEvents->next();
691ebc4eb57SAndreas Boehler                          continue;
692ebc4eb57SAndreas Boehler                      }
693cb71a62aSAndreas Boehler
694cb71a62aSAndreas Boehler                      // If we are within the given time range, parse the event
695185e2535SAndreas Boehler                      $data[] = $this->convertIcalDataToEntry($event, $id, $timezone, $row['uid'], $color, true);
696ebc4eb57SAndreas Boehler                      $rEvents->next();
697ebc4eb57SAndreas Boehler                  }
698ebc4eb57SAndreas Boehler              }
699ebc4eb57SAndreas Boehler              else
700185e2535SAndreas Boehler                $data[] = $this->convertIcalDataToEntry($vcal->VEVENT, $id, $timezone, $row['uid'], $color);
701ebc4eb57SAndreas Boehler          }
702ebc4eb57SAndreas Boehler      }
703ebc4eb57SAndreas Boehler      return $data;
704ebc4eb57SAndreas Boehler  }
705ebc4eb57SAndreas Boehler
706cb71a62aSAndreas Boehler  /**
707cb71a62aSAndreas Boehler   * Helper function that parses the iCal data of a VEVENT to a calendar entry.
708cb71a62aSAndreas Boehler   *
709cb71a62aSAndreas Boehler   * @param \Sabre\VObject\VEvent $event The event to parse
710cb71a62aSAndreas Boehler   * @param \DateTimeZone $timezone The timezone object
711cb71a62aSAndreas Boehler   * @param string $uid The entry's UID
7123c86dda8SAndreas Boehler   * @param boolean $recurring (optional) Set to true to define a recurring event
713cb71a62aSAndreas Boehler   *
714cb71a62aSAndreas Boehler   * @return array The parse calendar entry
715cb71a62aSAndreas Boehler   */
716185e2535SAndreas Boehler  private function convertIcalDataToEntry($event, $page, $timezone, $uid, $color, $recurring = false)
717ebc4eb57SAndreas Boehler  {
718ebc4eb57SAndreas Boehler      $entry = array();
719ebc4eb57SAndreas Boehler      $start = $event->DTSTART;
720cb71a62aSAndreas Boehler      // Parse only if the start date/time is present
721b269830cSAndreas Boehler      if($start !== null)
722b269830cSAndreas Boehler      {
723b269830cSAndreas Boehler        $dtStart = $start->getDateTime();
724b269830cSAndreas Boehler        $dtStart->setTimezone($timezone);
725bf0ad2b4SAndreas Boehler
726bf0ad2b4SAndreas Boehler        // moment.js doesn't like times be given even if
727bf0ad2b4SAndreas Boehler        // allDay is set to true
728bf0ad2b4SAndreas Boehler        // This should fix T23
729b269830cSAndreas Boehler        if($start['VALUE'] == 'DATE')
730bf0ad2b4SAndreas Boehler        {
731b269830cSAndreas Boehler          $entry['allDay'] = true;
732bf0ad2b4SAndreas Boehler          $entry['start'] = $dtStart->format("Y-m-d");
733bf0ad2b4SAndreas Boehler        }
734b269830cSAndreas Boehler        else
735bf0ad2b4SAndreas Boehler        {
736b269830cSAndreas Boehler          $entry['allDay'] = false;
737bf0ad2b4SAndreas Boehler          $entry['start'] = $dtStart->format(\DateTime::ATOM);
738bf0ad2b4SAndreas Boehler        }
739b269830cSAndreas Boehler      }
740ebc4eb57SAndreas Boehler      $end = $event->DTEND;
741bf0ad2b4SAndreas Boehler      // Parse only if the end date/time is present
742b269830cSAndreas Boehler      if($end !== null)
743b269830cSAndreas Boehler      {
744b269830cSAndreas Boehler        $dtEnd = $end->getDateTime();
745b269830cSAndreas Boehler        $dtEnd->setTimezone($timezone);
746bf0ad2b4SAndreas Boehler        if($end['VALUE'] == 'DATE')
747bf0ad2b4SAndreas Boehler          $entry['end'] = $dtEnd->format("Y-m-d");
748bf0ad2b4SAndreas Boehler        else
749b269830cSAndreas Boehler          $entry['end'] = $dtEnd->format(\DateTime::ATOM);
750b269830cSAndreas Boehler      }
751ebc4eb57SAndreas Boehler      $description = $event->DESCRIPTION;
7520eebc909SAndreas Boehler      if($description !== null)
7530eebc909SAndreas Boehler        $entry['description'] = (string)$description;
7540eebc909SAndreas Boehler      else
7550eebc909SAndreas Boehler        $entry['description'] = '';
7564ecb526cSAndreas Boehler      $attachments = $event->ATTACH;
7574ecb526cSAndreas Boehler      if($attachments !== null)
7584ecb526cSAndreas Boehler      {
7594ecb526cSAndreas Boehler        $entry['attachments'] = array();
7604ecb526cSAndreas Boehler        foreach($attachments as $attachment)
7614ecb526cSAndreas Boehler          $entry['attachments'][] = (string)$attachment;
7624ecb526cSAndreas Boehler      }
763ebc4eb57SAndreas Boehler      $entry['title'] = (string)$event->summary;
764ebc4eb57SAndreas Boehler      $entry['id'] = $uid;
765185e2535SAndreas Boehler      $entry['page'] = $page;
766185e2535SAndreas Boehler      $entry['color'] = $color;
7673c86dda8SAndreas Boehler      $entry['recurring'] = $recurring;
768185e2535SAndreas Boehler
769ebc4eb57SAndreas Boehler      return $entry;
770a1a3b679SAndreas Boehler  }
771a1a3b679SAndreas Boehler
772cb71a62aSAndreas Boehler  /**
773cb71a62aSAndreas Boehler   * Retrieve an event by its UID
774cb71a62aSAndreas Boehler   *
775cb71a62aSAndreas Boehler   * @param string $uid The event's UID
776cb71a62aSAndreas Boehler   *
777cb71a62aSAndreas Boehler   * @return mixed The table row with the given event
778cb71a62aSAndreas Boehler   */
779a1a3b679SAndreas Boehler  public function getEventWithUid($uid)
780a1a3b679SAndreas Boehler  {
78151f4febbSAndreas Boehler      $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid = ?";
78251f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uid);
783a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
784a1a3b679SAndreas Boehler      return $row;
785a1a3b679SAndreas Boehler  }
786a1a3b679SAndreas Boehler
787cb71a62aSAndreas Boehler  /**
788cb71a62aSAndreas Boehler   * Retrieve all calendar events for a given calendar ID
789cb71a62aSAndreas Boehler   *
790cb71a62aSAndreas Boehler   * @param string $calid The calendar's ID
791cb71a62aSAndreas Boehler   *
792cb71a62aSAndreas Boehler   * @return array An array containing all calendar data
793cb71a62aSAndreas Boehler   */
794f69bb449SAndreas Boehler  public function getAllCalendarEvents($calid)
795f69bb449SAndreas Boehler  {
7967e0b8590SAndreas Boehler      $query = "SELECT calendardata, uid, componenttype, uri FROM calendarobjects WHERE calendarid = ?";
79751f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
798f69bb449SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
799f69bb449SAndreas Boehler      return $arr;
800f69bb449SAndreas Boehler  }
801f69bb449SAndreas Boehler
802cb71a62aSAndreas Boehler  /**
803cb71a62aSAndreas Boehler   * Edit a calendar entry for a page, given by its parameters.
804cb71a62aSAndreas Boehler   * The params array has the same format as @see addCalendarEntryForPage
805cb71a62aSAndreas Boehler   *
806cb71a62aSAndreas Boehler   * @param string $id The page's ID to work on
807cb71a62aSAndreas Boehler   * @param string $user The user's ID to work on
808cb71a62aSAndreas Boehler   * @param array $params The parameter array for the edited calendar event
809cb71a62aSAndreas Boehler   *
810cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
811cb71a62aSAndreas Boehler   */
812a1a3b679SAndreas Boehler  public function editCalendarEntryForPage($id, $user, $params)
813a1a3b679SAndreas Boehler  {
81482a48dfbSAndreas Boehler      if($params['currenttz'] !== '' && $params['currenttz'] !== 'local')
81582a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($params['currenttz']);
81682a48dfbSAndreas Boehler      elseif($params['currenttz'] === 'local')
817a25c89eaSAndreas Boehler          $timezone = new \DateTimeZone($params['detectedtz']);
818bd883736SAndreas Boehler      else
819bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
820cb71a62aSAndreas Boehler
821cb71a62aSAndreas Boehler      // Parse dates
822b269830cSAndreas Boehler      $startDate = explode('-', $params['eventfrom']);
823b269830cSAndreas Boehler      $startTime = explode(':', $params['eventfromtime']);
824b269830cSAndreas Boehler      $endDate = explode('-', $params['eventto']);
825b269830cSAndreas Boehler      $endTime = explode(':', $params['eventtotime']);
826cb71a62aSAndreas Boehler
827cb71a62aSAndreas Boehler      // Retrieve the existing event based on the UID
82855a741c0SAndreas Boehler      $uid = $params['uid'];
82955a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
830cb71a62aSAndreas Boehler
831cb71a62aSAndreas Boehler      // Load SabreDAV
8329bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
833a1a3b679SAndreas Boehler      if(!isset($event['calendardata']))
834a1a3b679SAndreas Boehler        return false;
83555a741c0SAndreas Boehler      $uri = $event['uri'];
83655a741c0SAndreas Boehler      $calid = $event['calendarid'];
837cb71a62aSAndreas Boehler
838cb71a62aSAndreas Boehler      // Parse the existing event
839a1a3b679SAndreas Boehler      $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
840b269830cSAndreas Boehler      $vevent = $vcal->VEVENT;
841cb71a62aSAndreas Boehler
842cb71a62aSAndreas Boehler      // Set the new event values
843b269830cSAndreas Boehler      $vevent->summary = $params['eventname'];
844b269830cSAndreas Boehler      $dtStamp = new \DateTime(null, new \DateTimeZone('UTC'));
8450eebc909SAndreas Boehler      $description = $params['eventdescription'];
846cb71a62aSAndreas Boehler
847cb71a62aSAndreas Boehler      // Remove existing timestamps to overwrite them
8480eebc909SAndreas Boehler      $vevent->remove('DESCRIPTION');
849b269830cSAndreas Boehler      $vevent->remove('DTSTAMP');
850b269830cSAndreas Boehler      $vevent->remove('LAST-MODIFIED');
8514ecb526cSAndreas Boehler      $vevent->remove('ATTACH');
852cb71a62aSAndreas Boehler
853cb71a62aSAndreas Boehler      // Add new time stamps and description
854b269830cSAndreas Boehler      $vevent->add('DTSTAMP', $dtStamp);
855b269830cSAndreas Boehler      $vevent->add('LAST-MODIFIED', $dtStamp);
8560eebc909SAndreas Boehler      if($description !== '')
8570eebc909SAndreas Boehler        $vevent->add('DESCRIPTION', $description);
858cb71a62aSAndreas Boehler
8594ecb526cSAndreas Boehler      // Add attachments
8604ecb526cSAndreas Boehler      $attachments = $params['attachments'];
86182a48dfbSAndreas Boehler      if(!is_null($attachments))
8624ecb526cSAndreas Boehler        foreach($attachments as $attachment)
8634ecb526cSAndreas Boehler          $vevent->add('ATTACH', $attachment);
8644ecb526cSAndreas Boehler
865cb71a62aSAndreas Boehler      // Setup DTSTART
866b269830cSAndreas Boehler      $dtStart = new \DateTime();
867a25c89eaSAndreas Boehler      $dtStart->setTimezone($timezone);
868b269830cSAndreas Boehler      $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2]));
869b269830cSAndreas Boehler      if($params['allday'] != '1')
870b269830cSAndreas Boehler        $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0);
871cb71a62aSAndreas Boehler
8724ecb526cSAndreas Boehler      // Setup DTEND
873b269830cSAndreas Boehler      $dtEnd = new \DateTime();
874a25c89eaSAndreas Boehler      $dtEnd->setTimezone($timezone);
875b269830cSAndreas Boehler      $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2]));
876b269830cSAndreas Boehler      if($params['allday'] != '1')
877b269830cSAndreas Boehler        $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0);
878cb71a62aSAndreas Boehler
879b269830cSAndreas Boehler      // According to the VCal spec, we need to add a whole day here
880b269830cSAndreas Boehler      if($params['allday'] == '1')
881b269830cSAndreas Boehler          $dtEnd->add(new \DateInterval('P1D'));
882b269830cSAndreas Boehler      $vevent->remove('DTSTART');
883b269830cSAndreas Boehler      $vevent->remove('DTEND');
884b269830cSAndreas Boehler      $dtStartEv = $vevent->add('DTSTART', $dtStart);
885b269830cSAndreas Boehler      $dtEndEv = $vevent->add('DTEND', $dtEnd);
886cb71a62aSAndreas Boehler
887cb71a62aSAndreas Boehler      // Remove the time for allday events
888b269830cSAndreas Boehler      if($params['allday'] == '1')
889b269830cSAndreas Boehler      {
890b269830cSAndreas Boehler          $dtStartEv['VALUE'] = 'DATE';
891b269830cSAndreas Boehler          $dtEndEv['VALUE'] = 'DATE';
892b269830cSAndreas Boehler      }
893a1a3b679SAndreas Boehler      $now = new DateTime();
894a1a3b679SAndreas Boehler      $eventStr = $vcal->serialize();
895cb71a62aSAndreas Boehler      // Actually write to the database
89651f4febbSAndreas Boehler      $query = "UPDATE calendarobjects SET calendardata = ?, lastmodified = ?, ".
89751f4febbSAndreas Boehler               "firstoccurence = ?, lastoccurence = ?, size = ?, etag = ? WHERE uid = ?";
89851f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $eventStr, $now->getTimestamp(), $dtStart->getTimestamp(),
89951f4febbSAndreas Boehler                                  $dtEnd->getTimestamp(), strlen($eventStr), md5($eventStr), $uid);
90055a741c0SAndreas Boehler      if($res !== false)
90155a741c0SAndreas Boehler      {
90255a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'modified');
903a1a3b679SAndreas Boehler          return true;
904a1a3b679SAndreas Boehler      }
90555a741c0SAndreas Boehler      return false;
90655a741c0SAndreas Boehler  }
907a1a3b679SAndreas Boehler
908cb71a62aSAndreas Boehler  /**
909cb71a62aSAndreas Boehler   * Delete a calendar entry for a given page. Actually, the event is removed
910cb71a62aSAndreas Boehler   * based on the entry's UID, so that page ID is no used.
911cb71a62aSAndreas Boehler   *
912cb71a62aSAndreas Boehler   * @param string $id The page's ID (unused)
913cb71a62aSAndreas Boehler   * @param array $params The parameter array to work with
914cb71a62aSAndreas Boehler   *
915cb71a62aSAndreas Boehler   * @return boolean True
916cb71a62aSAndreas Boehler   */
917a1a3b679SAndreas Boehler  public function deleteCalendarEntryForPage($id, $params)
918a1a3b679SAndreas Boehler  {
919a1a3b679SAndreas Boehler      $uid = $params['uid'];
92055a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
9212c14b82bSAndreas Boehler      $calid = $event['calendarid'];
92255a741c0SAndreas Boehler      $uri = $event['uri'];
92351f4febbSAndreas Boehler      $query = "DELETE FROM calendarobjects WHERE uid = ?";
92451f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uid);
92555a741c0SAndreas Boehler      if($res !== false)
92655a741c0SAndreas Boehler      {
92755a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'deleted');
92855a741c0SAndreas Boehler      }
929a1a3b679SAndreas Boehler      return true;
930a1a3b679SAndreas Boehler  }
931a1a3b679SAndreas Boehler
932cb71a62aSAndreas Boehler  /**
933cb71a62aSAndreas Boehler   * Retrieve the current sync token for a calendar
934cb71a62aSAndreas Boehler   *
935cb71a62aSAndreas Boehler   * @param string $calid The calendar id
936cb71a62aSAndreas Boehler   *
937cb71a62aSAndreas Boehler   * @return mixed The synctoken or false
938cb71a62aSAndreas Boehler   */
93955a741c0SAndreas Boehler  public function getSyncTokenForCalendar($calid)
94055a741c0SAndreas Boehler  {
941b269830cSAndreas Boehler      $row = $this->getCalendarSettings($calid);
94255a741c0SAndreas Boehler      if(isset($row['synctoken']))
94355a741c0SAndreas Boehler          return $row['synctoken'];
94455a741c0SAndreas Boehler      return false;
94555a741c0SAndreas Boehler  }
94655a741c0SAndreas Boehler
947cb71a62aSAndreas Boehler  /**
948cb71a62aSAndreas Boehler   * Helper function to convert the operation name to
949cb71a62aSAndreas Boehler   * an operation code as stored in the database
950cb71a62aSAndreas Boehler   *
951cb71a62aSAndreas Boehler   * @param string $operationName The operation name
952cb71a62aSAndreas Boehler   *
953cb71a62aSAndreas Boehler   * @return mixed The operation code or false
954cb71a62aSAndreas Boehler   */
95555a741c0SAndreas Boehler  public function operationNameToOperation($operationName)
95655a741c0SAndreas Boehler  {
95755a741c0SAndreas Boehler      switch($operationName)
95855a741c0SAndreas Boehler      {
95955a741c0SAndreas Boehler          case 'added':
96055a741c0SAndreas Boehler              return 1;
96155a741c0SAndreas Boehler          break;
96255a741c0SAndreas Boehler          case 'modified':
96355a741c0SAndreas Boehler              return 2;
96455a741c0SAndreas Boehler          break;
96555a741c0SAndreas Boehler          case 'deleted':
96655a741c0SAndreas Boehler              return 3;
96755a741c0SAndreas Boehler          break;
96855a741c0SAndreas Boehler      }
96955a741c0SAndreas Boehler      return false;
97055a741c0SAndreas Boehler  }
97155a741c0SAndreas Boehler
972cb71a62aSAndreas Boehler  /**
973cb71a62aSAndreas Boehler   * Update the sync token log based on the calendar id and the
974cb71a62aSAndreas Boehler   * operation that was performed.
975cb71a62aSAndreas Boehler   *
976cb71a62aSAndreas Boehler   * @param string $calid The calendar ID that was modified
977cb71a62aSAndreas Boehler   * @param string $uri The calendar URI that was modified
978cb71a62aSAndreas Boehler   * @param string $operation The operation that was performed
979cb71a62aSAndreas Boehler   *
980cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
981cb71a62aSAndreas Boehler   */
98255a741c0SAndreas Boehler  private function updateSyncTokenLog($calid, $uri, $operation)
98355a741c0SAndreas Boehler  {
98455a741c0SAndreas Boehler      $currentToken = $this->getSyncTokenForCalendar($calid);
98555a741c0SAndreas Boehler      $operationCode = $this->operationNameToOperation($operation);
98655a741c0SAndreas Boehler      if(($operationCode === false) || ($currentToken === false))
98755a741c0SAndreas Boehler          return false;
98855a741c0SAndreas Boehler      $values = array($uri,
98955a741c0SAndreas Boehler                      $currentToken,
99055a741c0SAndreas Boehler                      $calid,
99155a741c0SAndreas Boehler                      $operationCode
99255a741c0SAndreas Boehler      );
99351f4febbSAndreas Boehler      $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(?, ?, ?, ?)";
99451f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uri, $currentToken, $calid, $operationCode);
99555a741c0SAndreas Boehler      if($res === false)
99655a741c0SAndreas Boehler        return false;
99755a741c0SAndreas Boehler      $currentToken++;
99851f4febbSAndreas Boehler      $query = "UPDATE calendars SET synctoken = ? WHERE id = ?";
99951f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $currentToken, $calid);
100055a741c0SAndreas Boehler      return ($res !== false);
100155a741c0SAndreas Boehler  }
100255a741c0SAndreas Boehler
1003cb71a62aSAndreas Boehler  /**
1004cb71a62aSAndreas Boehler   * Return the sync URL for a given Page, i.e. a calendar
1005cb71a62aSAndreas Boehler   *
1006cb71a62aSAndreas Boehler   * @param string $id The page's ID
1007cb71a62aSAndreas Boehler   * @param string $user (optional) The user's ID
1008cb71a62aSAndreas Boehler   *
1009cb71a62aSAndreas Boehler   * @return mixed The sync url or false
1010cb71a62aSAndreas Boehler   */
1011b269830cSAndreas Boehler  public function getSyncUrlForPage($id, $user = null)
1012b269830cSAndreas Boehler  {
101334a47953SAndreas Boehler      if(is_null($userid))
101434a47953SAndreas Boehler      {
101534a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
101634a47953SAndreas Boehler        {
101734a47953SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
101834a47953SAndreas Boehler        }
101934a47953SAndreas Boehler        else
102034a47953SAndreas Boehler        {
102134a47953SAndreas Boehler          return false;
102234a47953SAndreas Boehler        }
102334a47953SAndreas Boehler      }
1024b269830cSAndreas Boehler
1025b269830cSAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
1026b269830cSAndreas Boehler      if($calid === false)
1027b269830cSAndreas Boehler        return false;
1028b269830cSAndreas Boehler
1029b269830cSAndreas Boehler      $calsettings = $this->getCalendarSettings($calid);
1030b269830cSAndreas Boehler      if(!isset($calsettings['uri']))
1031b269830cSAndreas Boehler        return false;
1032b269830cSAndreas Boehler
1033b269830cSAndreas Boehler      $syncurl = DOKU_URL.'lib/plugins/davcal/calendarserver.php/calendars/'.$user.'/'.$calsettings['uri'];
1034b269830cSAndreas Boehler      return $syncurl;
1035b269830cSAndreas Boehler  }
1036b269830cSAndreas Boehler
1037cb71a62aSAndreas Boehler  /**
1038cb71a62aSAndreas Boehler   * Return the private calendar's URL for a given page
1039cb71a62aSAndreas Boehler   *
1040cb71a62aSAndreas Boehler   * @param string $id the page ID
1041cb71a62aSAndreas Boehler   *
1042cb71a62aSAndreas Boehler   * @return mixed The private URL or false
1043cb71a62aSAndreas Boehler   */
1044f69bb449SAndreas Boehler  public function getPrivateURLForPage($id)
1045f69bb449SAndreas Boehler  {
1046f69bb449SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
1047f69bb449SAndreas Boehler      if($calid === false)
1048f69bb449SAndreas Boehler        return false;
1049f69bb449SAndreas Boehler
1050f69bb449SAndreas Boehler      return $this->getPrivateURLForCalendar($calid);
1051f69bb449SAndreas Boehler  }
1052f69bb449SAndreas Boehler
1053cb71a62aSAndreas Boehler  /**
1054cb71a62aSAndreas Boehler   * Return the private calendar's URL for a given calendar ID
1055cb71a62aSAndreas Boehler   *
1056cb71a62aSAndreas Boehler   * @param string $calid The calendar's ID
1057cb71a62aSAndreas Boehler   *
1058cb71a62aSAndreas Boehler   * @return mixed The private URL or false
1059cb71a62aSAndreas Boehler   */
1060f69bb449SAndreas Boehler  public function getPrivateURLForCalendar($calid)
1061f69bb449SAndreas Boehler  {
1062185e2535SAndreas Boehler      if(isset($this->cachedValues['privateurl'][$calid]))
1063185e2535SAndreas Boehler        return $this->cachedValues['privateurl'][$calid];
106451f4febbSAndreas Boehler      $query = "SELECT url FROM calendartoprivateurlmapping WHERE calid = ?";
106551f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
1066f69bb449SAndreas Boehler      $row = $this->sqlite->res2row($res);
1067f69bb449SAndreas Boehler      if(!isset($row['url']))
1068f69bb449SAndreas Boehler      {
1069f69bb449SAndreas Boehler          $url = uniqid("dokuwiki-").".ics";
107051f4febbSAndreas Boehler          $query = "INSERT INTO calendartoprivateurlmapping (url, calid) VALUES(?, ?)";
107151f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $url, $calid);
1072f69bb449SAndreas Boehler          if($res === false)
1073f69bb449SAndreas Boehler            return false;
1074f69bb449SAndreas Boehler      }
1075f69bb449SAndreas Boehler      else
1076f69bb449SAndreas Boehler      {
1077f69bb449SAndreas Boehler          $url = $row['url'];
1078f69bb449SAndreas Boehler      }
1079185e2535SAndreas Boehler
1080185e2535SAndreas Boehler      $url = DOKU_URL.'lib/plugins/davcal/ics.php/'.$url;
1081185e2535SAndreas Boehler      $this->cachedValues['privateurl'][$calid] = $url;
1082185e2535SAndreas Boehler      return $url;
1083f69bb449SAndreas Boehler  }
1084f69bb449SAndreas Boehler
1085cb71a62aSAndreas Boehler  /**
1086cb71a62aSAndreas Boehler   * Retrieve the calendar ID for a given private calendar URL
1087cb71a62aSAndreas Boehler   *
1088cb71a62aSAndreas Boehler   * @param string $url The private URL
1089cb71a62aSAndreas Boehler   *
1090cb71a62aSAndreas Boehler   * @return mixed The calendar ID or false
1091cb71a62aSAndreas Boehler   */
1092f69bb449SAndreas Boehler  public function getCalendarForPrivateURL($url)
1093f69bb449SAndreas Boehler  {
109451f4febbSAndreas Boehler      $query = "SELECT calid FROM calendartoprivateurlmapping WHERE url = ?";
109551f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $url);
1096f69bb449SAndreas Boehler      $row = $this->sqlite->res2row($res);
1097f69bb449SAndreas Boehler      if(!isset($row['calid']))
1098f69bb449SAndreas Boehler        return false;
1099f69bb449SAndreas Boehler      return $row['calid'];
1100f69bb449SAndreas Boehler  }
1101f69bb449SAndreas Boehler
1102cb71a62aSAndreas Boehler  /**
1103cb71a62aSAndreas Boehler   * Return a given calendar as ICS feed, i.e. all events in one ICS file.
1104cb71a62aSAndreas Boehler   *
11057e0b8590SAndreas Boehler   * @param string $calid The calendar ID to retrieve
1106cb71a62aSAndreas Boehler   *
1107cb71a62aSAndreas Boehler   * @return mixed The calendar events as string or false
1108cb71a62aSAndreas Boehler   */
1109f69bb449SAndreas Boehler  public function getCalendarAsICSFeed($calid)
1110f69bb449SAndreas Boehler  {
1111f69bb449SAndreas Boehler      $calSettings = $this->getCalendarSettings($calid);
1112f69bb449SAndreas Boehler      if($calSettings === false)
1113f69bb449SAndreas Boehler        return false;
1114f69bb449SAndreas Boehler      $events = $this->getAllCalendarEvents($calid);
1115f69bb449SAndreas Boehler      if($events === false)
1116f69bb449SAndreas Boehler        return false;
1117f69bb449SAndreas Boehler
11187e0b8590SAndreas Boehler      // Load SabreDAV
11197e0b8590SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
11207e0b8590SAndreas Boehler      $out = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//DAVCal//DAVCal for DokuWiki//EN\r\nCALSCALE:GREGORIAN\r\nX-WR-CALNAME:";
11217e0b8590SAndreas Boehler      $out .= $calSettings['displayname']."\r\n";
1122f69bb449SAndreas Boehler      foreach($events as $event)
1123f69bb449SAndreas Boehler      {
11247e0b8590SAndreas Boehler          $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
11257e0b8590SAndreas Boehler          $evt = $vcal->VEVENT;
11267e0b8590SAndreas Boehler          $out .= $evt->serialize();
1127f69bb449SAndreas Boehler      }
11287e0b8590SAndreas Boehler      $out .= "END:VCALENDAR\r\n";
1129f69bb449SAndreas Boehler      return $out;
1130f69bb449SAndreas Boehler  }
1131f69bb449SAndreas Boehler
11327c7c6b0bSAndreas Boehler  /**
11337c7c6b0bSAndreas Boehler   * Retrieve a configuration option for the plugin
11347c7c6b0bSAndreas Boehler   *
11357c7c6b0bSAndreas Boehler   * @param string $key The key to query
113621d04f73SAndreas Boehler   * @return mixed The option set, null if not found
11377c7c6b0bSAndreas Boehler   */
11387c7c6b0bSAndreas Boehler  public function getConfig($key)
11397c7c6b0bSAndreas Boehler  {
11407c7c6b0bSAndreas Boehler      return $this->getConf($key);
11417c7c6b0bSAndreas Boehler  }
11427c7c6b0bSAndreas Boehler
1143a1a3b679SAndreas Boehler}
1144