xref: /plugin/davcal/helper.php (revision 80e1ddf76ff9879b01dd835b0e45e33631480f72)
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  /**
83*80e1ddf7SAndreas Boehler   * Filter calendar pages and return only those where the current
84*80e1ddf7SAndreas Boehler   * user has at least read permission.
85*80e1ddf7SAndreas Boehler   *
86*80e1ddf7SAndreas Boehler   * @param array $calendarPages Array with calendar pages to check
87*80e1ddf7SAndreas Boehler   * @return array with filtered calendar pages
88*80e1ddf7SAndreas Boehler   */
89*80e1ddf7SAndreas Boehler  public function filterCalendarPagesByUserPermission($calendarPages)
90*80e1ddf7SAndreas Boehler  {
91*80e1ddf7SAndreas Boehler      $retList = array();
92*80e1ddf7SAndreas Boehler      foreach($calendarPages as $page => $data)
93*80e1ddf7SAndreas Boehler      {
94*80e1ddf7SAndreas Boehler          if(auth_quickaclcheck($page) >= AUTH_READ)
95*80e1ddf7SAndreas Boehler          {
96*80e1ddf7SAndreas Boehler              $retList[$page] = $data;
97*80e1ddf7SAndreas Boehler          }
98*80e1ddf7SAndreas Boehler      }
99*80e1ddf7SAndreas Boehler      return $retList;
100*80e1ddf7SAndreas Boehler  }
101*80e1ddf7SAndreas Boehler
102*80e1ddf7SAndreas Boehler  /**
103185e2535SAndreas Boehler   * Get all calendar pages used by a given page
104185e2535SAndreas Boehler   * based on the stored metadata
105185e2535SAndreas Boehler   *
106185e2535SAndreas Boehler   * @param string $id optional The page id
107185e2535SAndreas Boehler   * @return mixed The pages as array or false
108185e2535SAndreas Boehler   */
109185e2535SAndreas Boehler  public function getCalendarPagesByMeta($id = null)
110185e2535SAndreas Boehler  {
111185e2535SAndreas Boehler      if(is_null($id))
112185e2535SAndreas Boehler      {
113185e2535SAndreas Boehler          global $ID;
114185e2535SAndreas Boehler          $id = $ID;
115185e2535SAndreas Boehler      }
116185e2535SAndreas Boehler
117185e2535SAndreas Boehler      $meta = $this->getCalendarMetaForPage($id);
118185e2535SAndreas Boehler      if(isset($meta['id']))
119ed764890SAndreas Boehler      {
120ed764890SAndreas Boehler          // Filter the list of pages by permission
121*80e1ddf7SAndreas Boehler          $pages = $this->filterCalendarPagesByUserPermission($meta['id']);
122*80e1ddf7SAndreas Boehler          $pages = array_keys($pages);
123*80e1ddf7SAndreas Boehler          if(empty($pages))
124ed764890SAndreas Boehler            return false;
125*80e1ddf7SAndreas Boehler          return $pages;
126ed764890SAndreas Boehler      }
127185e2535SAndreas Boehler      return false;
128185e2535SAndreas Boehler  }
129185e2535SAndreas Boehler
130185e2535SAndreas Boehler  /**
131185e2535SAndreas Boehler   * Get a list of calendar names/pages/ids/colors
132185e2535SAndreas Boehler   * for an array of page ids
133185e2535SAndreas Boehler   *
134185e2535SAndreas Boehler   * @param array $calendarPages The calendar pages to retrieve
135185e2535SAndreas Boehler   * @return array The list
136185e2535SAndreas Boehler   */
137185e2535SAndreas Boehler  public function getCalendarMapForIDs($calendarPages)
138185e2535SAndreas Boehler  {
139185e2535SAndreas Boehler      $data = array();
140185e2535SAndreas Boehler      foreach($calendarPages as $page)
141185e2535SAndreas Boehler      {
142185e2535SAndreas Boehler          $calid = $this->getCalendarIdForPage($page);
143185e2535SAndreas Boehler          if($calid !== false)
144185e2535SAndreas Boehler          {
145185e2535SAndreas Boehler            $settings = $this->getCalendarSettings($calid);
146185e2535SAndreas Boehler            $name = $settings['displayname'];
147185e2535SAndreas Boehler            $color = $settings['calendarcolor'];
148ed764890SAndreas Boehler            $write = (auth_quickaclcheck($page) > AUTH_READ);
149185e2535SAndreas Boehler            $data[] = array('name' => $name, 'page' => $page, 'calid' => $calid,
150ed764890SAndreas Boehler                            'color' => $color, 'write' => $write);
151185e2535SAndreas Boehler          }
152185e2535SAndreas Boehler      }
153185e2535SAndreas Boehler      return $data;
154185e2535SAndreas Boehler  }
155185e2535SAndreas Boehler
156185e2535SAndreas Boehler  /**
157185e2535SAndreas Boehler   * Get the saved calendar color for a given page.
158185e2535SAndreas Boehler   *
159185e2535SAndreas Boehler   * @param string $id optional The page ID
160185e2535SAndreas Boehler   * @return mixed The color on success, otherwise false
161185e2535SAndreas Boehler   */
162185e2535SAndreas Boehler  public function getCalendarColorForPage($id = null)
163185e2535SAndreas Boehler  {
164185e2535SAndreas Boehler      if(is_null($id))
165185e2535SAndreas Boehler      {
166185e2535SAndreas Boehler          global $ID;
167185e2535SAndreas Boehler          $id = $ID;
168185e2535SAndreas Boehler      }
169185e2535SAndreas Boehler
170185e2535SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
171185e2535SAndreas Boehler      if($calid === false)
172185e2535SAndreas Boehler        return false;
173185e2535SAndreas Boehler
174185e2535SAndreas Boehler      return $this->getCalendarColorForCalendar($calid);
175185e2535SAndreas Boehler  }
176185e2535SAndreas Boehler
177185e2535SAndreas Boehler  /**
178185e2535SAndreas Boehler   * Get the saved calendar color for a given calendar ID.
179185e2535SAndreas Boehler   *
180185e2535SAndreas Boehler   * @param string $id optional The calendar ID
181185e2535SAndreas Boehler   * @return mixed The color on success, otherwise false
182185e2535SAndreas Boehler   */
183185e2535SAndreas Boehler  public function getCalendarColorForCalendar($calid)
184185e2535SAndreas Boehler  {
185185e2535SAndreas Boehler      if(isset($this->cachedValues['calendarcolor'][$calid]))
186185e2535SAndreas Boehler        return $this->cachedValues['calendarcolor'][$calid];
187185e2535SAndreas Boehler
188185e2535SAndreas Boehler      $row = $this->getCalendarSettings($calid);
189185e2535SAndreas Boehler
190185e2535SAndreas Boehler      if(!isset($row['calendarcolor']))
191185e2535SAndreas Boehler        return false;
192185e2535SAndreas Boehler
193185e2535SAndreas Boehler      $color = $row['calendarcolor'];
194185e2535SAndreas Boehler      $this->cachedValues['calendarcolor'][$calid] = $color;
195185e2535SAndreas Boehler      return $color;
196185e2535SAndreas Boehler  }
197185e2535SAndreas Boehler
198185e2535SAndreas Boehler  /**
199e86c8dd3SAndreas Boehler   * Get the user's principal URL for iOS sync
200e86c8dd3SAndreas Boehler   * @param string $user the user name
201e86c8dd3SAndreas Boehler   * @return the URL to the principal sync
202e86c8dd3SAndreas Boehler   */
203e86c8dd3SAndreas Boehler  public function getPrincipalUrlForUser($user)
204e86c8dd3SAndreas Boehler  {
205e86c8dd3SAndreas Boehler      if(is_null($user))
206e86c8dd3SAndreas Boehler        return false;
207e86c8dd3SAndreas Boehler      $url = DOKU_URL.'lib/plugins/davcal/calendarserver.php/principals/'.$user;
208e86c8dd3SAndreas Boehler      return $url;
209e86c8dd3SAndreas Boehler  }
210e86c8dd3SAndreas Boehler
211e86c8dd3SAndreas Boehler  /**
212185e2535SAndreas Boehler   * Set the calendar color for a given page.
213185e2535SAndreas Boehler   *
214185e2535SAndreas Boehler   * @param string $color The color definition
215185e2535SAndreas Boehler   * @param string $id optional The page ID
216185e2535SAndreas Boehler   * @return boolean True on success, otherwise false
217185e2535SAndreas Boehler   */
218185e2535SAndreas Boehler  public function setCalendarColorForPage($color, $id = null)
219185e2535SAndreas Boehler  {
220185e2535SAndreas Boehler      if(is_null($id))
221185e2535SAndreas Boehler      {
222185e2535SAndreas Boehler          global $ID;
223185e2535SAndreas Boehler          $id = $ID;
224185e2535SAndreas Boehler      }
225185e2535SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
226185e2535SAndreas Boehler      if($calid === false)
227185e2535SAndreas Boehler        return false;
228185e2535SAndreas Boehler
22951f4febbSAndreas Boehler      $query = "UPDATE calendars SET calendarcolor = ? ".
23051f4febbSAndreas Boehler               " WHERE id = ?";
23151f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $color, $calid);
232185e2535SAndreas Boehler      if($res !== false)
233185e2535SAndreas Boehler      {
234185e2535SAndreas Boehler        $this->cachedValues['calendarcolor'][$calid] = $color;
235185e2535SAndreas Boehler        return true;
236185e2535SAndreas Boehler      }
237185e2535SAndreas Boehler      return false;
238185e2535SAndreas Boehler  }
239185e2535SAndreas Boehler
240185e2535SAndreas Boehler  /**
241cb71a62aSAndreas Boehler   * Set the calendar name and description for a given page with a given
242cb71a62aSAndreas Boehler   * page id.
243cb71a62aSAndreas Boehler   * If the calendar doesn't exist, the calendar is created!
244cb71a62aSAndreas Boehler   *
245cb71a62aSAndreas Boehler   * @param string  $name The name of the new calendar
246cb71a62aSAndreas Boehler   * @param string  $description The description of the new calendar
247cb71a62aSAndreas Boehler   * @param string  $id (optional) The ID of the page
248cb71a62aSAndreas Boehler   * @param string  $userid The userid of the creating user
249cb71a62aSAndreas Boehler   *
250cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false.
251cb71a62aSAndreas Boehler   */
252a1a3b679SAndreas Boehler  public function setCalendarNameForPage($name, $description, $id = null, $userid = null)
253a1a3b679SAndreas Boehler  {
254a1a3b679SAndreas Boehler      if(is_null($id))
255a1a3b679SAndreas Boehler      {
256a1a3b679SAndreas Boehler          global $ID;
257a1a3b679SAndreas Boehler          $id = $ID;
258a1a3b679SAndreas Boehler      }
259a1a3b679SAndreas Boehler      if(is_null($userid))
26034a47953SAndreas Boehler      {
26134a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
26234a47953SAndreas Boehler        {
263a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
26434a47953SAndreas Boehler        }
26534a47953SAndreas Boehler        else
26634a47953SAndreas Boehler        {
26734a47953SAndreas Boehler          $userid = uniqid('davcal-');
26834a47953SAndreas Boehler        }
26934a47953SAndreas Boehler      }
270a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
271a1a3b679SAndreas Boehler      if($calid === false)
272a1a3b679SAndreas Boehler        return $this->createCalendarForPage($name, $description, $id, $userid);
273a1a3b679SAndreas Boehler
27451f4febbSAndreas Boehler      $query = "UPDATE calendars SET displayname = ?, description = ? WHERE id = ?";
27551f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $name, $description, $calid);
276b269830cSAndreas Boehler      if($res !== false)
277b269830cSAndreas Boehler        return true;
278b269830cSAndreas Boehler      return false;
279a1a3b679SAndreas Boehler  }
280a1a3b679SAndreas Boehler
281cb71a62aSAndreas Boehler  /**
282cb71a62aSAndreas Boehler   * Save the personal settings to the SQLite database 'calendarsettings'.
283cb71a62aSAndreas Boehler   *
284cb71a62aSAndreas Boehler   * @param array  $settings The settings array to store
285cb71a62aSAndreas Boehler   * @param string $userid (optional) The userid to store
286cb71a62aSAndreas Boehler   *
287cb71a62aSAndreas Boehler   * @param boolean True on success, otherwise false
288cb71a62aSAndreas Boehler   */
289a495d34cSAndreas Boehler  public function savePersonalSettings($settings, $userid = null)
290a495d34cSAndreas Boehler  {
291a495d34cSAndreas Boehler      if(is_null($userid))
29234a47953SAndreas Boehler      {
29334a47953SAndreas Boehler          if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
29434a47953SAndreas Boehler          {
295a495d34cSAndreas Boehler            $userid = $_SERVER['REMOTE_USER'];
29634a47953SAndreas Boehler          }
29734a47953SAndreas Boehler          else
29834a47953SAndreas Boehler          {
29934a47953SAndreas Boehler              return false;
30034a47953SAndreas Boehler          }
30134a47953SAndreas Boehler      }
302a495d34cSAndreas Boehler      $this->sqlite->query("BEGIN TRANSACTION");
303a495d34cSAndreas Boehler
30451f4febbSAndreas Boehler      $query = "DELETE FROM calendarsettings WHERE userid = ?";
30551f4febbSAndreas Boehler      $this->sqlite->query($query, $userid);
306bd883736SAndreas Boehler
307a495d34cSAndreas Boehler      foreach($settings as $key => $value)
308a495d34cSAndreas Boehler      {
30951f4febbSAndreas Boehler          $query = "INSERT INTO calendarsettings (userid, key, value) VALUES (?, ?, ?)";
31051f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $userid, $key, $value);
311a495d34cSAndreas Boehler          if($res === false)
312a495d34cSAndreas Boehler              return false;
313a495d34cSAndreas Boehler      }
314a495d34cSAndreas Boehler      $this->sqlite->query("COMMIT TRANSACTION");
315185e2535SAndreas Boehler      $this->cachedValues['settings'][$userid] = $settings;
316a495d34cSAndreas Boehler      return true;
317a495d34cSAndreas Boehler  }
318a495d34cSAndreas Boehler
319cb71a62aSAndreas Boehler  /**
320cb71a62aSAndreas Boehler   * Retrieve the settings array for a given user id.
321cb71a62aSAndreas Boehler   * Some sane defaults are returned, currently:
322cb71a62aSAndreas Boehler   *
323cb71a62aSAndreas Boehler   *    timezone    => local
324cb71a62aSAndreas Boehler   *    weeknumbers => 0
325cb71a62aSAndreas Boehler   *    workweek    => 0
326cb71a62aSAndreas Boehler   *
327cb71a62aSAndreas Boehler   * @param string $userid (optional) The user id to retrieve
328cb71a62aSAndreas Boehler   *
329cb71a62aSAndreas Boehler   * @return array The settings array
330cb71a62aSAndreas Boehler   */
331a495d34cSAndreas Boehler  public function getPersonalSettings($userid = null)
332a495d34cSAndreas Boehler  {
333bd883736SAndreas Boehler      // Some sane default settings
334bd883736SAndreas Boehler      $settings = array(
335fb813b30SAndreas Boehler        'timezone' => $this->getConf('timezone'),
336fb813b30SAndreas Boehler        'weeknumbers' => $this->getConf('weeknumbers'),
337fb813b30SAndreas Boehler        'workweek' => $this->getConf('workweek'),
3381d5bdcd0SAndreas Boehler        'monday' => $this->getConf('monday'),
3391d5bdcd0SAndreas Boehler        'timeformat' => $this->getConf('timeformat')
340bd883736SAndreas Boehler      );
34134a47953SAndreas Boehler      if(is_null($userid))
34234a47953SAndreas Boehler      {
34334a47953SAndreas Boehler          if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
34434a47953SAndreas Boehler          {
34534a47953SAndreas Boehler            $userid = $_SERVER['REMOTE_USER'];
34634a47953SAndreas Boehler          }
34734a47953SAndreas Boehler          else
34834a47953SAndreas Boehler          {
34934a47953SAndreas Boehler            return $settings;
35034a47953SAndreas Boehler          }
35134a47953SAndreas Boehler      }
35234a47953SAndreas Boehler
35334a47953SAndreas Boehler      if(isset($this->cachedValues['settings'][$userid]))
35434a47953SAndreas Boehler        return $this->cachedValues['settings'][$userid];
35551f4febbSAndreas Boehler      $query = "SELECT key, value FROM calendarsettings WHERE userid = ?";
35651f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $userid);
357a495d34cSAndreas Boehler      $arr = $this->sqlite->res2arr($res);
358a495d34cSAndreas Boehler      foreach($arr as $row)
359a495d34cSAndreas Boehler      {
360a495d34cSAndreas Boehler          $settings[$row['key']] = $row['value'];
361a495d34cSAndreas Boehler      }
362185e2535SAndreas Boehler      $this->cachedValues['settings'][$userid] = $settings;
363a495d34cSAndreas Boehler      return $settings;
364a495d34cSAndreas Boehler  }
365a495d34cSAndreas Boehler
366cb71a62aSAndreas Boehler  /**
367cb71a62aSAndreas Boehler   * Retrieve the calendar ID based on a page ID from the SQLite table
368cb71a62aSAndreas Boehler   * 'pagetocalendarmapping'.
369cb71a62aSAndreas Boehler   *
370cb71a62aSAndreas Boehler   * @param string $id (optional) The page ID to retrieve the corresponding calendar
371cb71a62aSAndreas Boehler   *
372cb71a62aSAndreas Boehler   * @return mixed the ID on success, otherwise false
373cb71a62aSAndreas Boehler   */
374a1a3b679SAndreas Boehler  public function getCalendarIdForPage($id = null)
375a1a3b679SAndreas Boehler  {
376a1a3b679SAndreas Boehler      if(is_null($id))
377a1a3b679SAndreas Boehler      {
378a1a3b679SAndreas Boehler          global $ID;
379a1a3b679SAndreas Boehler          $id = $ID;
380a1a3b679SAndreas Boehler      }
381a1a3b679SAndreas Boehler
382185e2535SAndreas Boehler      if(isset($this->cachedValues['calid'][$id]))
383185e2535SAndreas Boehler        return $this->cachedValues['calid'][$id];
384185e2535SAndreas Boehler
38551f4febbSAndreas Boehler      $query = "SELECT calid FROM pagetocalendarmapping WHERE page = ?";
38651f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $id);
387a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
388a1a3b679SAndreas Boehler      if(isset($row['calid']))
389185e2535SAndreas Boehler      {
390185e2535SAndreas Boehler        $calid = $row['calid'];
391185e2535SAndreas Boehler        $this->cachedValues['calid'] = $calid;
392185e2535SAndreas Boehler        return $calid;
393185e2535SAndreas Boehler      }
394a1a3b679SAndreas Boehler      return false;
395a1a3b679SAndreas Boehler  }
396a1a3b679SAndreas Boehler
397cb71a62aSAndreas Boehler  /**
398cb71a62aSAndreas Boehler   * Retrieve the complete calendar id to page mapping.
399cb71a62aSAndreas Boehler   * This is necessary to be able to retrieve a list of
400cb71a62aSAndreas Boehler   * calendars for a given user and check the access rights.
401cb71a62aSAndreas Boehler   *
402cb71a62aSAndreas Boehler   * @return array The mapping array
403cb71a62aSAndreas Boehler   */
404a1a3b679SAndreas Boehler  public function getCalendarIdToPageMapping()
405a1a3b679SAndreas Boehler  {
406a1a3b679SAndreas Boehler      $query = "SELECT calid, page FROM pagetocalendarmapping";
407a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
408a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
409a1a3b679SAndreas Boehler      return $arr;
410a1a3b679SAndreas Boehler  }
411a1a3b679SAndreas Boehler
412cb71a62aSAndreas Boehler  /**
413cb71a62aSAndreas Boehler   * Retrieve all calendar IDs a given user has access to.
414cb71a62aSAndreas Boehler   * The user is specified by the principalUri, so the
415cb71a62aSAndreas Boehler   * user name is actually split from the URI component.
416cb71a62aSAndreas Boehler   *
417cb71a62aSAndreas Boehler   * Access rights are checked against DokuWiki's ACL
418cb71a62aSAndreas Boehler   * and applied accordingly.
419cb71a62aSAndreas Boehler   *
420cb71a62aSAndreas Boehler   * @param string $principalUri The principal URI to work on
421cb71a62aSAndreas Boehler   *
422cb71a62aSAndreas Boehler   * @return array An associative array of calendar IDs
423cb71a62aSAndreas Boehler   */
424a1a3b679SAndreas Boehler  public function getCalendarIdsForUser($principalUri)
425a1a3b679SAndreas Boehler  {
42634a47953SAndreas Boehler      global $auth;
427a1a3b679SAndreas Boehler      $user = explode('/', $principalUri);
428a1a3b679SAndreas Boehler      $user = end($user);
429a1a3b679SAndreas Boehler      $mapping = $this->getCalendarIdToPageMapping();
430a1a3b679SAndreas Boehler      $calids = array();
43134a47953SAndreas Boehler      $ud = $auth->getUserData($user);
43234a47953SAndreas Boehler      $groups = $ud['grps'];
433a1a3b679SAndreas Boehler      foreach($mapping as $row)
434a1a3b679SAndreas Boehler      {
435a1a3b679SAndreas Boehler          $id = $row['calid'];
436a1a3b679SAndreas Boehler          $page = $row['page'];
43734a47953SAndreas Boehler          $acl = auth_aclcheck($page, $user, $groups);
438a1a3b679SAndreas Boehler          if($acl >= AUTH_READ)
439a1a3b679SAndreas Boehler          {
440a1a3b679SAndreas Boehler              $write = $acl > AUTH_READ;
441a1a3b679SAndreas Boehler              $calids[$id] = array('readonly' => !$write);
442a1a3b679SAndreas Boehler          }
443a1a3b679SAndreas Boehler      }
444a1a3b679SAndreas Boehler      return $calids;
445a1a3b679SAndreas Boehler  }
446a1a3b679SAndreas Boehler
447cb71a62aSAndreas Boehler  /**
448cb71a62aSAndreas Boehler   * Create a new calendar for a given page ID and set name and description
449cb71a62aSAndreas Boehler   * accordingly. Also update the pagetocalendarmapping table on success.
450cb71a62aSAndreas Boehler   *
451cb71a62aSAndreas Boehler   * @param string $name The calendar's name
452cb71a62aSAndreas Boehler   * @param string $description The calendar's description
453cb71a62aSAndreas Boehler   * @param string $id (optional) The page ID to work on
454cb71a62aSAndreas Boehler   * @param string $userid (optional) The user ID that created the calendar
455cb71a62aSAndreas Boehler   *
456cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
457cb71a62aSAndreas Boehler   */
458a1a3b679SAndreas Boehler  public function createCalendarForPage($name, $description, $id = null, $userid = null)
459a1a3b679SAndreas Boehler  {
460a1a3b679SAndreas Boehler      if(is_null($id))
461a1a3b679SAndreas Boehler      {
462a1a3b679SAndreas Boehler          global $ID;
463a1a3b679SAndreas Boehler          $id = $ID;
464a1a3b679SAndreas Boehler      }
465a1a3b679SAndreas Boehler      if(is_null($userid))
46634a47953SAndreas Boehler      {
46734a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
46834a47953SAndreas Boehler        {
469a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
47034a47953SAndreas Boehler        }
47134a47953SAndreas Boehler        else
47234a47953SAndreas Boehler        {
47334a47953SAndreas Boehler          $userid = uniqid('davcal-');
47434a47953SAndreas Boehler        }
47534a47953SAndreas Boehler      }
476a1a3b679SAndreas Boehler      $values = array('principals/'.$userid,
477a1a3b679SAndreas Boehler                      $name,
478a1a3b679SAndreas Boehler                      str_replace(array('/', ' ', ':'), '_', $id),
479a1a3b679SAndreas Boehler                      $description,
480a1a3b679SAndreas Boehler                      'VEVENT,VTODO',
48155a741c0SAndreas Boehler                      0,
48255a741c0SAndreas Boehler                      1);
48351f4febbSAndreas Boehler      $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) ".
48451f4febbSAndreas Boehler               "VALUES (?, ?, ?, ?, ?, ?, ?)";
48551f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3], $values[4], $values[5], $values[6]);
48655a741c0SAndreas Boehler      if($res === false)
48755a741c0SAndreas Boehler        return false;
488cb71a62aSAndreas Boehler
489cb71a62aSAndreas Boehler      // Get the new calendar ID
49051f4febbSAndreas Boehler      $query = "SELECT id FROM calendars WHERE principaluri = ? AND displayname = ? AND ".
49151f4febbSAndreas Boehler               "uri = ? AND description = ?";
49251f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3]);
493a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
494cb71a62aSAndreas Boehler
495cb71a62aSAndreas Boehler      // Update the pagetocalendarmapping table with the new calendar ID
496a1a3b679SAndreas Boehler      if(isset($row['id']))
497a1a3b679SAndreas Boehler      {
49851f4febbSAndreas Boehler          $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (?, ?)";
49951f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $id, $row['id']);
50055a741c0SAndreas Boehler          return ($res !== false);
501a1a3b679SAndreas Boehler      }
502a1a3b679SAndreas Boehler
503a1a3b679SAndreas Boehler      return false;
504a1a3b679SAndreas Boehler  }
505a1a3b679SAndreas Boehler
506cb71a62aSAndreas Boehler  /**
507cb71a62aSAndreas Boehler   * Add a new iCal entry for a given page, i.e. a given calendar.
508cb71a62aSAndreas Boehler   *
509cb71a62aSAndreas Boehler   * The parameter array needs to contain
510cb71a62aSAndreas Boehler   *   detectedtz       => The timezone as detected by the browser
51182a48dfbSAndreas Boehler   *   currenttz        => The timezone in use by the calendar
512cb71a62aSAndreas Boehler   *   eventfrom        => The event's start date
513cb71a62aSAndreas Boehler   *   eventfromtime    => The event's start time
514cb71a62aSAndreas Boehler   *   eventto          => The event's end date
515cb71a62aSAndreas Boehler   *   eventtotime      => The event's end time
516cb71a62aSAndreas Boehler   *   eventname        => The event's name
517cb71a62aSAndreas Boehler   *   eventdescription => The event's description
518cb71a62aSAndreas Boehler   *
519cb71a62aSAndreas Boehler   * @param string $id The page ID to work on
520cb71a62aSAndreas Boehler   * @param string $user The user who created the calendar
521cb71a62aSAndreas Boehler   * @param string $params A parameter array with values to create
522cb71a62aSAndreas Boehler   *
523cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
524cb71a62aSAndreas Boehler   */
525a1a3b679SAndreas Boehler  public function addCalendarEntryToCalendarForPage($id, $user, $params)
526a1a3b679SAndreas Boehler  {
52782a48dfbSAndreas Boehler      if($params['currenttz'] !== '' && $params['currenttz'] !== 'local')
52882a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($params['currenttz']);
52982a48dfbSAndreas Boehler      elseif($params['currenttz'] === 'local')
530a25c89eaSAndreas Boehler          $timezone = new \DateTimeZone($params['detectedtz']);
531bd883736SAndreas Boehler      else
532bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
533cb71a62aSAndreas Boehler
534cb71a62aSAndreas Boehler      // Retrieve dates from settings
535b269830cSAndreas Boehler      $startDate = explode('-', $params['eventfrom']);
536b269830cSAndreas Boehler      $startTime = explode(':', $params['eventfromtime']);
537b269830cSAndreas Boehler      $endDate = explode('-', $params['eventto']);
538b269830cSAndreas Boehler      $endTime = explode(':', $params['eventtotime']);
539cb71a62aSAndreas Boehler
540cb71a62aSAndreas Boehler      // Load SabreDAV
5419bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
542a1a3b679SAndreas Boehler      $vcalendar = new \Sabre\VObject\Component\VCalendar();
543cb71a62aSAndreas Boehler
544cb71a62aSAndreas Boehler      // Add VCalendar, UID and Event Name
545a1a3b679SAndreas Boehler      $event = $vcalendar->add('VEVENT');
546b269830cSAndreas Boehler      $uuid = \Sabre\VObject\UUIDUtil::getUUID();
547b269830cSAndreas Boehler      $event->add('UID', $uuid);
548a1a3b679SAndreas Boehler      $event->summary = $params['eventname'];
549cb71a62aSAndreas Boehler
550cb71a62aSAndreas Boehler      // Add a description if requested
5510eebc909SAndreas Boehler      $description = $params['eventdescription'];
5520eebc909SAndreas Boehler      if($description !== '')
5530eebc909SAndreas Boehler        $event->add('DESCRIPTION', $description);
554cb71a62aSAndreas Boehler
5554ecb526cSAndreas Boehler      // Add attachments
5564ecb526cSAndreas Boehler      $attachments = $params['attachments'];
55782a48dfbSAndreas Boehler      if(!is_null($attachments))
5584ecb526cSAndreas Boehler        foreach($attachments as $attachment)
5594ecb526cSAndreas Boehler          $event->add('ATTACH', $attachment);
5604ecb526cSAndreas Boehler
561cb71a62aSAndreas Boehler      // Create a timestamp for last modified, created and dtstamp values in UTC
562b269830cSAndreas Boehler      $dtStamp = new \DateTime(null, new \DateTimeZone('UTC'));
563b269830cSAndreas Boehler      $event->add('DTSTAMP', $dtStamp);
564b269830cSAndreas Boehler      $event->add('CREATED', $dtStamp);
565b269830cSAndreas Boehler      $event->add('LAST-MODIFIED', $dtStamp);
566cb71a62aSAndreas Boehler
567cb71a62aSAndreas Boehler      // Adjust the start date, based on the given timezone information
568b269830cSAndreas Boehler      $dtStart = new \DateTime();
569a25c89eaSAndreas Boehler      $dtStart->setTimezone($timezone);
570b269830cSAndreas Boehler      $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2]));
571cb71a62aSAndreas Boehler
572cb71a62aSAndreas Boehler      // Only add the time values if it's not an allday event
573b269830cSAndreas Boehler      if($params['allday'] != '1')
574b269830cSAndreas Boehler        $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0);
575cb71a62aSAndreas Boehler
576cb71a62aSAndreas Boehler      // Adjust the end date, based on the given timezone information
577b269830cSAndreas Boehler      $dtEnd = new \DateTime();
578a25c89eaSAndreas Boehler      $dtEnd->setTimezone($timezone);
579b269830cSAndreas Boehler      $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2]));
580cb71a62aSAndreas Boehler
581cb71a62aSAndreas Boehler      // Only add the time values if it's not an allday event
582b269830cSAndreas Boehler      if($params['allday'] != '1')
583b269830cSAndreas Boehler        $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0);
584cb71a62aSAndreas Boehler
585b269830cSAndreas Boehler      // According to the VCal spec, we need to add a whole day here
586b269830cSAndreas Boehler      if($params['allday'] == '1')
587b269830cSAndreas Boehler          $dtEnd->add(new \DateInterval('P1D'));
588cb71a62aSAndreas Boehler
589cb71a62aSAndreas Boehler      // Really add Start and End events
590b269830cSAndreas Boehler      $dtStartEv = $event->add('DTSTART', $dtStart);
591b269830cSAndreas Boehler      $dtEndEv = $event->add('DTEND', $dtEnd);
592cb71a62aSAndreas Boehler
593cb71a62aSAndreas Boehler      // Adjust the DATE format for allday events
594b269830cSAndreas Boehler      if($params['allday'] == '1')
595b269830cSAndreas Boehler      {
596b269830cSAndreas Boehler          $dtStartEv['VALUE'] = 'DATE';
597b269830cSAndreas Boehler          $dtEndEv['VALUE'] = 'DATE';
598b269830cSAndreas Boehler      }
599cb71a62aSAndreas Boehler
600cb71a62aSAndreas Boehler      // Actually add the values to the database
601a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
602a1a3b679SAndreas Boehler      $uri = uniqid('dokuwiki-').'.ics';
603a1a3b679SAndreas Boehler      $now = new DateTime();
604a1a3b679SAndreas Boehler      $eventStr = $vcalendar->serialize();
605a1a3b679SAndreas Boehler
60651f4febbSAndreas Boehler      $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
60751f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid, $uri, $eventStr, $now->getTimestamp(), 'VEVENT',
60851f4febbSAndreas Boehler                                  $event->DTSTART->getDateTime()->getTimeStamp(), $event->DTEND->getDateTime()->getTimeStamp(),
60951f4febbSAndreas Boehler                                  strlen($eventStr), md5($eventStr), $uuid);
610cb71a62aSAndreas Boehler
611cb71a62aSAndreas Boehler      // If successfully, update the sync token database
61255a741c0SAndreas Boehler      if($res !== false)
61355a741c0SAndreas Boehler      {
61455a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'added');
615a1a3b679SAndreas Boehler          return true;
616a1a3b679SAndreas Boehler      }
61755a741c0SAndreas Boehler      return false;
61855a741c0SAndreas Boehler  }
619a1a3b679SAndreas Boehler
620cb71a62aSAndreas Boehler  /**
621cb71a62aSAndreas Boehler   * Retrieve the calendar settings of a given calendar id
622cb71a62aSAndreas Boehler   *
623cb71a62aSAndreas Boehler   * @param string $calid The calendar ID
624cb71a62aSAndreas Boehler   *
625cb71a62aSAndreas Boehler   * @return array The calendar settings array
626cb71a62aSAndreas Boehler   */
627b269830cSAndreas Boehler  public function getCalendarSettings($calid)
628b269830cSAndreas Boehler  {
62951f4febbSAndreas Boehler      $query = "SELECT principaluri, calendarcolor, displayname, uri, description, components, transparent, synctoken FROM calendars WHERE id= ? ";
63051f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
631b269830cSAndreas Boehler      $row = $this->sqlite->res2row($res);
632b269830cSAndreas Boehler      return $row;
633b269830cSAndreas Boehler  }
634b269830cSAndreas Boehler
635cb71a62aSAndreas Boehler  /**
636cb71a62aSAndreas Boehler   * Retrieve all events that are within a given date range,
637cb71a62aSAndreas Boehler   * based on the timezone setting.
638cb71a62aSAndreas Boehler   *
639cb71a62aSAndreas Boehler   * There is also support for retrieving recurring events,
640cb71a62aSAndreas Boehler   * using Sabre's VObject Iterator. Recurring events are represented
641cb71a62aSAndreas Boehler   * as individual calendar entries with the same UID.
642cb71a62aSAndreas Boehler   *
643cb71a62aSAndreas Boehler   * @param string $id The page ID to work with
644cb71a62aSAndreas Boehler   * @param string $user The user ID to work with
645cb71a62aSAndreas Boehler   * @param string $startDate The start date as a string
646cb71a62aSAndreas Boehler   * @param string $endDate The end date as a string
647cb71a62aSAndreas Boehler   *
648cb71a62aSAndreas Boehler   * @return array An array containing the calendar entries.
649cb71a62aSAndreas Boehler   */
65082a48dfbSAndreas Boehler  public function getEventsWithinDateRange($id, $user, $startDate, $endDate, $timezone)
651a1a3b679SAndreas Boehler  {
65282a48dfbSAndreas Boehler      if($timezone !== '' && $timezone !== 'local')
65382a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($timezone);
654bd883736SAndreas Boehler      else
655bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
656a1a3b679SAndreas Boehler      $data = array();
657cb71a62aSAndreas Boehler
658cb71a62aSAndreas Boehler      // Load SabreDAV
6599bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
660a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
661185e2535SAndreas Boehler      $color = $this->getCalendarColorForCalendar($calid);
662a469597cSAndreas Boehler      $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid = ?";
663a469597cSAndreas Boehler      $startTs = null;
664a469597cSAndreas Boehler      $endTs = null;
665a469597cSAndreas Boehler      if($startDate !== null)
666a469597cSAndreas Boehler      {
667a1a3b679SAndreas Boehler        $startTs = new \DateTime($startDate);
668a469597cSAndreas Boehler        $query .= " AND lastoccurence > ".$this->sqlite->quote_string($startTs->getTimestamp());
669a469597cSAndreas Boehler      }
670a469597cSAndreas Boehler      if($endDate !== null)
671a469597cSAndreas Boehler      {
672a1a3b679SAndreas Boehler        $endTs = new \DateTime($endDate);
673a469597cSAndreas Boehler        $query .= " AND firstoccurence < ".$this->sqlite->quote_string($endTs->getTimestamp());
674a469597cSAndreas Boehler      }
675cb71a62aSAndreas Boehler
676cb71a62aSAndreas Boehler      // Retrieve matching calendar objects
677a469597cSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
678a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
679cb71a62aSAndreas Boehler
680cb71a62aSAndreas Boehler      // Parse individual calendar entries
681a1a3b679SAndreas Boehler      foreach($arr as $row)
682a1a3b679SAndreas Boehler      {
683a1a3b679SAndreas Boehler          if(isset($row['calendardata']))
684a1a3b679SAndreas Boehler          {
685b269830cSAndreas Boehler              $entry = array();
686a1a3b679SAndreas Boehler              $vcal = \Sabre\VObject\Reader::read($row['calendardata']);
687ebc4eb57SAndreas Boehler              $recurrence = $vcal->VEVENT->RRULE;
688cb71a62aSAndreas Boehler              // If it is a recurring event, pass it through Sabre's EventIterator
689ebc4eb57SAndreas Boehler              if($recurrence != null)
690ebc4eb57SAndreas Boehler              {
691ebc4eb57SAndreas Boehler                  $rEvents = new \Sabre\VObject\Recur\EventIterator(array($vcal->VEVENT));
692ebc4eb57SAndreas Boehler                  $rEvents->rewind();
693e9b7d302SAndreas Boehler                  while($rEvents->valid())
694ebc4eb57SAndreas Boehler                  {
695ebc4eb57SAndreas Boehler                      $event = $rEvents->getEventObject();
696cb71a62aSAndreas Boehler                      // If we are after the given time range, exit
697a469597cSAndreas Boehler                      if(($endTs !== null) && ($rEvents->getDtStart()->getTimestamp() > $endTs->getTimestamp()))
698e9b7d302SAndreas Boehler                          break;
699cb71a62aSAndreas Boehler
700cb71a62aSAndreas Boehler                      // If we are before the given time range, continue
701a469597cSAndreas Boehler                      if(($startTs != null) && ($rEvents->getDtEnd()->getTimestamp() < $startTs->getTimestamp()))
702ebc4eb57SAndreas Boehler                      {
703ebc4eb57SAndreas Boehler                          $rEvents->next();
704ebc4eb57SAndreas Boehler                          continue;
705ebc4eb57SAndreas Boehler                      }
706cb71a62aSAndreas Boehler
707cb71a62aSAndreas Boehler                      // If we are within the given time range, parse the event
708185e2535SAndreas Boehler                      $data[] = $this->convertIcalDataToEntry($event, $id, $timezone, $row['uid'], $color, true);
709ebc4eb57SAndreas Boehler                      $rEvents->next();
710ebc4eb57SAndreas Boehler                  }
711ebc4eb57SAndreas Boehler              }
712ebc4eb57SAndreas Boehler              else
713185e2535SAndreas Boehler                $data[] = $this->convertIcalDataToEntry($vcal->VEVENT, $id, $timezone, $row['uid'], $color);
714ebc4eb57SAndreas Boehler          }
715ebc4eb57SAndreas Boehler      }
716ebc4eb57SAndreas Boehler      return $data;
717ebc4eb57SAndreas Boehler  }
718ebc4eb57SAndreas Boehler
719cb71a62aSAndreas Boehler  /**
720cb71a62aSAndreas Boehler   * Helper function that parses the iCal data of a VEVENT to a calendar entry.
721cb71a62aSAndreas Boehler   *
722cb71a62aSAndreas Boehler   * @param \Sabre\VObject\VEvent $event The event to parse
723cb71a62aSAndreas Boehler   * @param \DateTimeZone $timezone The timezone object
724cb71a62aSAndreas Boehler   * @param string $uid The entry's UID
7253c86dda8SAndreas Boehler   * @param boolean $recurring (optional) Set to true to define a recurring event
726cb71a62aSAndreas Boehler   *
727cb71a62aSAndreas Boehler   * @return array The parse calendar entry
728cb71a62aSAndreas Boehler   */
729185e2535SAndreas Boehler  private function convertIcalDataToEntry($event, $page, $timezone, $uid, $color, $recurring = false)
730ebc4eb57SAndreas Boehler  {
731ebc4eb57SAndreas Boehler      $entry = array();
732ebc4eb57SAndreas Boehler      $start = $event->DTSTART;
733cb71a62aSAndreas Boehler      // Parse only if the start date/time is present
734b269830cSAndreas Boehler      if($start !== null)
735b269830cSAndreas Boehler      {
736b269830cSAndreas Boehler        $dtStart = $start->getDateTime();
737b269830cSAndreas Boehler        $dtStart->setTimezone($timezone);
738bf0ad2b4SAndreas Boehler
739bf0ad2b4SAndreas Boehler        // moment.js doesn't like times be given even if
740bf0ad2b4SAndreas Boehler        // allDay is set to true
741bf0ad2b4SAndreas Boehler        // This should fix T23
742b269830cSAndreas Boehler        if($start['VALUE'] == 'DATE')
743bf0ad2b4SAndreas Boehler        {
744b269830cSAndreas Boehler          $entry['allDay'] = true;
745bf0ad2b4SAndreas Boehler          $entry['start'] = $dtStart->format("Y-m-d");
746bf0ad2b4SAndreas Boehler        }
747b269830cSAndreas Boehler        else
748bf0ad2b4SAndreas Boehler        {
749b269830cSAndreas Boehler          $entry['allDay'] = false;
750bf0ad2b4SAndreas Boehler          $entry['start'] = $dtStart->format(\DateTime::ATOM);
751bf0ad2b4SAndreas Boehler        }
752b269830cSAndreas Boehler      }
753ebc4eb57SAndreas Boehler      $end = $event->DTEND;
754bf0ad2b4SAndreas Boehler      // Parse only if the end date/time is present
755b269830cSAndreas Boehler      if($end !== null)
756b269830cSAndreas Boehler      {
757b269830cSAndreas Boehler        $dtEnd = $end->getDateTime();
758b269830cSAndreas Boehler        $dtEnd->setTimezone($timezone);
759bf0ad2b4SAndreas Boehler        if($end['VALUE'] == 'DATE')
760bf0ad2b4SAndreas Boehler          $entry['end'] = $dtEnd->format("Y-m-d");
761bf0ad2b4SAndreas Boehler        else
762b269830cSAndreas Boehler          $entry['end'] = $dtEnd->format(\DateTime::ATOM);
763b269830cSAndreas Boehler      }
764ebc4eb57SAndreas Boehler      $description = $event->DESCRIPTION;
7650eebc909SAndreas Boehler      if($description !== null)
7660eebc909SAndreas Boehler        $entry['description'] = (string)$description;
7670eebc909SAndreas Boehler      else
7680eebc909SAndreas Boehler        $entry['description'] = '';
7694ecb526cSAndreas Boehler      $attachments = $event->ATTACH;
7704ecb526cSAndreas Boehler      if($attachments !== null)
7714ecb526cSAndreas Boehler      {
7724ecb526cSAndreas Boehler        $entry['attachments'] = array();
7734ecb526cSAndreas Boehler        foreach($attachments as $attachment)
7744ecb526cSAndreas Boehler          $entry['attachments'][] = (string)$attachment;
7754ecb526cSAndreas Boehler      }
776ebc4eb57SAndreas Boehler      $entry['title'] = (string)$event->summary;
777ebc4eb57SAndreas Boehler      $entry['id'] = $uid;
778185e2535SAndreas Boehler      $entry['page'] = $page;
779185e2535SAndreas Boehler      $entry['color'] = $color;
7803c86dda8SAndreas Boehler      $entry['recurring'] = $recurring;
781185e2535SAndreas Boehler
782ebc4eb57SAndreas Boehler      return $entry;
783a1a3b679SAndreas Boehler  }
784a1a3b679SAndreas Boehler
785cb71a62aSAndreas Boehler  /**
786cb71a62aSAndreas Boehler   * Retrieve an event by its UID
787cb71a62aSAndreas Boehler   *
788cb71a62aSAndreas Boehler   * @param string $uid The event's UID
789cb71a62aSAndreas Boehler   *
790cb71a62aSAndreas Boehler   * @return mixed The table row with the given event
791cb71a62aSAndreas Boehler   */
792a1a3b679SAndreas Boehler  public function getEventWithUid($uid)
793a1a3b679SAndreas Boehler  {
79451f4febbSAndreas Boehler      $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid = ?";
79551f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uid);
796a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
797a1a3b679SAndreas Boehler      return $row;
798a1a3b679SAndreas Boehler  }
799a1a3b679SAndreas Boehler
800cb71a62aSAndreas Boehler  /**
801cb71a62aSAndreas Boehler   * Retrieve all calendar events for a given calendar ID
802cb71a62aSAndreas Boehler   *
803cb71a62aSAndreas Boehler   * @param string $calid The calendar's ID
804cb71a62aSAndreas Boehler   *
805cb71a62aSAndreas Boehler   * @return array An array containing all calendar data
806cb71a62aSAndreas Boehler   */
807f69bb449SAndreas Boehler  public function getAllCalendarEvents($calid)
808f69bb449SAndreas Boehler  {
8097e0b8590SAndreas Boehler      $query = "SELECT calendardata, uid, componenttype, uri FROM calendarobjects WHERE calendarid = ?";
81051f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
811f69bb449SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
812f69bb449SAndreas Boehler      return $arr;
813f69bb449SAndreas Boehler  }
814f69bb449SAndreas Boehler
815cb71a62aSAndreas Boehler  /**
816cb71a62aSAndreas Boehler   * Edit a calendar entry for a page, given by its parameters.
817cb71a62aSAndreas Boehler   * The params array has the same format as @see addCalendarEntryForPage
818cb71a62aSAndreas Boehler   *
819cb71a62aSAndreas Boehler   * @param string $id The page's ID to work on
820cb71a62aSAndreas Boehler   * @param string $user The user's ID to work on
821cb71a62aSAndreas Boehler   * @param array $params The parameter array for the edited calendar event
822cb71a62aSAndreas Boehler   *
823cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
824cb71a62aSAndreas Boehler   */
825a1a3b679SAndreas Boehler  public function editCalendarEntryForPage($id, $user, $params)
826a1a3b679SAndreas Boehler  {
82782a48dfbSAndreas Boehler      if($params['currenttz'] !== '' && $params['currenttz'] !== 'local')
82882a48dfbSAndreas Boehler          $timezone = new \DateTimeZone($params['currenttz']);
82982a48dfbSAndreas Boehler      elseif($params['currenttz'] === 'local')
830a25c89eaSAndreas Boehler          $timezone = new \DateTimeZone($params['detectedtz']);
831bd883736SAndreas Boehler      else
832bd883736SAndreas Boehler          $timezone = new \DateTimeZone('UTC');
833cb71a62aSAndreas Boehler
834cb71a62aSAndreas Boehler      // Parse dates
835b269830cSAndreas Boehler      $startDate = explode('-', $params['eventfrom']);
836b269830cSAndreas Boehler      $startTime = explode(':', $params['eventfromtime']);
837b269830cSAndreas Boehler      $endDate = explode('-', $params['eventto']);
838b269830cSAndreas Boehler      $endTime = explode(':', $params['eventtotime']);
839cb71a62aSAndreas Boehler
840cb71a62aSAndreas Boehler      // Retrieve the existing event based on the UID
84155a741c0SAndreas Boehler      $uid = $params['uid'];
84255a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
843cb71a62aSAndreas Boehler
844cb71a62aSAndreas Boehler      // Load SabreDAV
8459bef4ad8SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
846a1a3b679SAndreas Boehler      if(!isset($event['calendardata']))
847a1a3b679SAndreas Boehler        return false;
84855a741c0SAndreas Boehler      $uri = $event['uri'];
84955a741c0SAndreas Boehler      $calid = $event['calendarid'];
850cb71a62aSAndreas Boehler
851cb71a62aSAndreas Boehler      // Parse the existing event
852a1a3b679SAndreas Boehler      $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
853b269830cSAndreas Boehler      $vevent = $vcal->VEVENT;
854cb71a62aSAndreas Boehler
855cb71a62aSAndreas Boehler      // Set the new event values
856b269830cSAndreas Boehler      $vevent->summary = $params['eventname'];
857b269830cSAndreas Boehler      $dtStamp = new \DateTime(null, new \DateTimeZone('UTC'));
8580eebc909SAndreas Boehler      $description = $params['eventdescription'];
859cb71a62aSAndreas Boehler
860cb71a62aSAndreas Boehler      // Remove existing timestamps to overwrite them
8610eebc909SAndreas Boehler      $vevent->remove('DESCRIPTION');
862b269830cSAndreas Boehler      $vevent->remove('DTSTAMP');
863b269830cSAndreas Boehler      $vevent->remove('LAST-MODIFIED');
8644ecb526cSAndreas Boehler      $vevent->remove('ATTACH');
865cb71a62aSAndreas Boehler
866cb71a62aSAndreas Boehler      // Add new time stamps and description
867b269830cSAndreas Boehler      $vevent->add('DTSTAMP', $dtStamp);
868b269830cSAndreas Boehler      $vevent->add('LAST-MODIFIED', $dtStamp);
8690eebc909SAndreas Boehler      if($description !== '')
8700eebc909SAndreas Boehler        $vevent->add('DESCRIPTION', $description);
871cb71a62aSAndreas Boehler
8724ecb526cSAndreas Boehler      // Add attachments
8734ecb526cSAndreas Boehler      $attachments = $params['attachments'];
87482a48dfbSAndreas Boehler      if(!is_null($attachments))
8754ecb526cSAndreas Boehler        foreach($attachments as $attachment)
8764ecb526cSAndreas Boehler          $vevent->add('ATTACH', $attachment);
8774ecb526cSAndreas Boehler
878cb71a62aSAndreas Boehler      // Setup DTSTART
879b269830cSAndreas Boehler      $dtStart = new \DateTime();
880a25c89eaSAndreas Boehler      $dtStart->setTimezone($timezone);
881b269830cSAndreas Boehler      $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2]));
882b269830cSAndreas Boehler      if($params['allday'] != '1')
883b269830cSAndreas Boehler        $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0);
884cb71a62aSAndreas Boehler
8854ecb526cSAndreas Boehler      // Setup DTEND
886b269830cSAndreas Boehler      $dtEnd = new \DateTime();
887a25c89eaSAndreas Boehler      $dtEnd->setTimezone($timezone);
888b269830cSAndreas Boehler      $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2]));
889b269830cSAndreas Boehler      if($params['allday'] != '1')
890b269830cSAndreas Boehler        $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0);
891cb71a62aSAndreas Boehler
892b269830cSAndreas Boehler      // According to the VCal spec, we need to add a whole day here
893b269830cSAndreas Boehler      if($params['allday'] == '1')
894b269830cSAndreas Boehler          $dtEnd->add(new \DateInterval('P1D'));
895b269830cSAndreas Boehler      $vevent->remove('DTSTART');
896b269830cSAndreas Boehler      $vevent->remove('DTEND');
897b269830cSAndreas Boehler      $dtStartEv = $vevent->add('DTSTART', $dtStart);
898b269830cSAndreas Boehler      $dtEndEv = $vevent->add('DTEND', $dtEnd);
899cb71a62aSAndreas Boehler
900cb71a62aSAndreas Boehler      // Remove the time for allday events
901b269830cSAndreas Boehler      if($params['allday'] == '1')
902b269830cSAndreas Boehler      {
903b269830cSAndreas Boehler          $dtStartEv['VALUE'] = 'DATE';
904b269830cSAndreas Boehler          $dtEndEv['VALUE'] = 'DATE';
905b269830cSAndreas Boehler      }
906a1a3b679SAndreas Boehler      $now = new DateTime();
907a1a3b679SAndreas Boehler      $eventStr = $vcal->serialize();
908cb71a62aSAndreas Boehler      // Actually write to the database
90951f4febbSAndreas Boehler      $query = "UPDATE calendarobjects SET calendardata = ?, lastmodified = ?, ".
91051f4febbSAndreas Boehler               "firstoccurence = ?, lastoccurence = ?, size = ?, etag = ? WHERE uid = ?";
91151f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $eventStr, $now->getTimestamp(), $dtStart->getTimestamp(),
91251f4febbSAndreas Boehler                                  $dtEnd->getTimestamp(), strlen($eventStr), md5($eventStr), $uid);
91355a741c0SAndreas Boehler      if($res !== false)
91455a741c0SAndreas Boehler      {
91555a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'modified');
916a1a3b679SAndreas Boehler          return true;
917a1a3b679SAndreas Boehler      }
91855a741c0SAndreas Boehler      return false;
91955a741c0SAndreas Boehler  }
920a1a3b679SAndreas Boehler
921cb71a62aSAndreas Boehler  /**
922cb71a62aSAndreas Boehler   * Delete a calendar entry for a given page. Actually, the event is removed
923cb71a62aSAndreas Boehler   * based on the entry's UID, so that page ID is no used.
924cb71a62aSAndreas Boehler   *
925cb71a62aSAndreas Boehler   * @param string $id The page's ID (unused)
926cb71a62aSAndreas Boehler   * @param array $params The parameter array to work with
927cb71a62aSAndreas Boehler   *
928cb71a62aSAndreas Boehler   * @return boolean True
929cb71a62aSAndreas Boehler   */
930a1a3b679SAndreas Boehler  public function deleteCalendarEntryForPage($id, $params)
931a1a3b679SAndreas Boehler  {
932a1a3b679SAndreas Boehler      $uid = $params['uid'];
93355a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
9342c14b82bSAndreas Boehler      $calid = $event['calendarid'];
93555a741c0SAndreas Boehler      $uri = $event['uri'];
93651f4febbSAndreas Boehler      $query = "DELETE FROM calendarobjects WHERE uid = ?";
93751f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uid);
93855a741c0SAndreas Boehler      if($res !== false)
93955a741c0SAndreas Boehler      {
94055a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'deleted');
94155a741c0SAndreas Boehler      }
942a1a3b679SAndreas Boehler      return true;
943a1a3b679SAndreas Boehler  }
944a1a3b679SAndreas Boehler
945cb71a62aSAndreas Boehler  /**
946cb71a62aSAndreas Boehler   * Retrieve the current sync token for a calendar
947cb71a62aSAndreas Boehler   *
948cb71a62aSAndreas Boehler   * @param string $calid The calendar id
949cb71a62aSAndreas Boehler   *
950cb71a62aSAndreas Boehler   * @return mixed The synctoken or false
951cb71a62aSAndreas Boehler   */
95255a741c0SAndreas Boehler  public function getSyncTokenForCalendar($calid)
95355a741c0SAndreas Boehler  {
954b269830cSAndreas Boehler      $row = $this->getCalendarSettings($calid);
95555a741c0SAndreas Boehler      if(isset($row['synctoken']))
95655a741c0SAndreas Boehler          return $row['synctoken'];
95755a741c0SAndreas Boehler      return false;
95855a741c0SAndreas Boehler  }
95955a741c0SAndreas Boehler
960cb71a62aSAndreas Boehler  /**
961cb71a62aSAndreas Boehler   * Helper function to convert the operation name to
962cb71a62aSAndreas Boehler   * an operation code as stored in the database
963cb71a62aSAndreas Boehler   *
964cb71a62aSAndreas Boehler   * @param string $operationName The operation name
965cb71a62aSAndreas Boehler   *
966cb71a62aSAndreas Boehler   * @return mixed The operation code or false
967cb71a62aSAndreas Boehler   */
96855a741c0SAndreas Boehler  public function operationNameToOperation($operationName)
96955a741c0SAndreas Boehler  {
97055a741c0SAndreas Boehler      switch($operationName)
97155a741c0SAndreas Boehler      {
97255a741c0SAndreas Boehler          case 'added':
97355a741c0SAndreas Boehler              return 1;
97455a741c0SAndreas Boehler          break;
97555a741c0SAndreas Boehler          case 'modified':
97655a741c0SAndreas Boehler              return 2;
97755a741c0SAndreas Boehler          break;
97855a741c0SAndreas Boehler          case 'deleted':
97955a741c0SAndreas Boehler              return 3;
98055a741c0SAndreas Boehler          break;
98155a741c0SAndreas Boehler      }
98255a741c0SAndreas Boehler      return false;
98355a741c0SAndreas Boehler  }
98455a741c0SAndreas Boehler
985cb71a62aSAndreas Boehler  /**
986cb71a62aSAndreas Boehler   * Update the sync token log based on the calendar id and the
987cb71a62aSAndreas Boehler   * operation that was performed.
988cb71a62aSAndreas Boehler   *
989cb71a62aSAndreas Boehler   * @param string $calid The calendar ID that was modified
990cb71a62aSAndreas Boehler   * @param string $uri The calendar URI that was modified
991cb71a62aSAndreas Boehler   * @param string $operation The operation that was performed
992cb71a62aSAndreas Boehler   *
993cb71a62aSAndreas Boehler   * @return boolean True on success, otherwise false
994cb71a62aSAndreas Boehler   */
99555a741c0SAndreas Boehler  private function updateSyncTokenLog($calid, $uri, $operation)
99655a741c0SAndreas Boehler  {
99755a741c0SAndreas Boehler      $currentToken = $this->getSyncTokenForCalendar($calid);
99855a741c0SAndreas Boehler      $operationCode = $this->operationNameToOperation($operation);
99955a741c0SAndreas Boehler      if(($operationCode === false) || ($currentToken === false))
100055a741c0SAndreas Boehler          return false;
100155a741c0SAndreas Boehler      $values = array($uri,
100255a741c0SAndreas Boehler                      $currentToken,
100355a741c0SAndreas Boehler                      $calid,
100455a741c0SAndreas Boehler                      $operationCode
100555a741c0SAndreas Boehler      );
100651f4febbSAndreas Boehler      $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(?, ?, ?, ?)";
100751f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $uri, $currentToken, $calid, $operationCode);
100855a741c0SAndreas Boehler      if($res === false)
100955a741c0SAndreas Boehler        return false;
101055a741c0SAndreas Boehler      $currentToken++;
101151f4febbSAndreas Boehler      $query = "UPDATE calendars SET synctoken = ? WHERE id = ?";
101251f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $currentToken, $calid);
101355a741c0SAndreas Boehler      return ($res !== false);
101455a741c0SAndreas Boehler  }
101555a741c0SAndreas Boehler
1016cb71a62aSAndreas Boehler  /**
1017cb71a62aSAndreas Boehler   * Return the sync URL for a given Page, i.e. a calendar
1018cb71a62aSAndreas Boehler   *
1019cb71a62aSAndreas Boehler   * @param string $id The page's ID
1020cb71a62aSAndreas Boehler   * @param string $user (optional) The user's ID
1021cb71a62aSAndreas Boehler   *
1022cb71a62aSAndreas Boehler   * @return mixed The sync url or false
1023cb71a62aSAndreas Boehler   */
1024b269830cSAndreas Boehler  public function getSyncUrlForPage($id, $user = null)
1025b269830cSAndreas Boehler  {
102634a47953SAndreas Boehler      if(is_null($userid))
102734a47953SAndreas Boehler      {
102834a47953SAndreas Boehler        if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
102934a47953SAndreas Boehler        {
103034a47953SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
103134a47953SAndreas Boehler        }
103234a47953SAndreas Boehler        else
103334a47953SAndreas Boehler        {
103434a47953SAndreas Boehler          return false;
103534a47953SAndreas Boehler        }
103634a47953SAndreas Boehler      }
1037b269830cSAndreas Boehler
1038b269830cSAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
1039b269830cSAndreas Boehler      if($calid === false)
1040b269830cSAndreas Boehler        return false;
1041b269830cSAndreas Boehler
1042b269830cSAndreas Boehler      $calsettings = $this->getCalendarSettings($calid);
1043b269830cSAndreas Boehler      if(!isset($calsettings['uri']))
1044b269830cSAndreas Boehler        return false;
1045b269830cSAndreas Boehler
1046b269830cSAndreas Boehler      $syncurl = DOKU_URL.'lib/plugins/davcal/calendarserver.php/calendars/'.$user.'/'.$calsettings['uri'];
1047b269830cSAndreas Boehler      return $syncurl;
1048b269830cSAndreas Boehler  }
1049b269830cSAndreas Boehler
1050cb71a62aSAndreas Boehler  /**
1051cb71a62aSAndreas Boehler   * Return the private calendar's URL for a given page
1052cb71a62aSAndreas Boehler   *
1053cb71a62aSAndreas Boehler   * @param string $id the page ID
1054cb71a62aSAndreas Boehler   *
1055cb71a62aSAndreas Boehler   * @return mixed The private URL or false
1056cb71a62aSAndreas Boehler   */
1057f69bb449SAndreas Boehler  public function getPrivateURLForPage($id)
1058f69bb449SAndreas Boehler  {
1059f69bb449SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
1060f69bb449SAndreas Boehler      if($calid === false)
1061f69bb449SAndreas Boehler        return false;
1062f69bb449SAndreas Boehler
1063f69bb449SAndreas Boehler      return $this->getPrivateURLForCalendar($calid);
1064f69bb449SAndreas Boehler  }
1065f69bb449SAndreas Boehler
1066cb71a62aSAndreas Boehler  /**
1067cb71a62aSAndreas Boehler   * Return the private calendar's URL for a given calendar ID
1068cb71a62aSAndreas Boehler   *
1069cb71a62aSAndreas Boehler   * @param string $calid The calendar's ID
1070cb71a62aSAndreas Boehler   *
1071cb71a62aSAndreas Boehler   * @return mixed The private URL or false
1072cb71a62aSAndreas Boehler   */
1073f69bb449SAndreas Boehler  public function getPrivateURLForCalendar($calid)
1074f69bb449SAndreas Boehler  {
1075185e2535SAndreas Boehler      if(isset($this->cachedValues['privateurl'][$calid]))
1076185e2535SAndreas Boehler        return $this->cachedValues['privateurl'][$calid];
107751f4febbSAndreas Boehler      $query = "SELECT url FROM calendartoprivateurlmapping WHERE calid = ?";
107851f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $calid);
1079f69bb449SAndreas Boehler      $row = $this->sqlite->res2row($res);
1080f69bb449SAndreas Boehler      if(!isset($row['url']))
1081f69bb449SAndreas Boehler      {
1082f69bb449SAndreas Boehler          $url = uniqid("dokuwiki-").".ics";
108351f4febbSAndreas Boehler          $query = "INSERT INTO calendartoprivateurlmapping (url, calid) VALUES(?, ?)";
108451f4febbSAndreas Boehler          $res = $this->sqlite->query($query, $url, $calid);
1085f69bb449SAndreas Boehler          if($res === false)
1086f69bb449SAndreas Boehler            return false;
1087f69bb449SAndreas Boehler      }
1088f69bb449SAndreas Boehler      else
1089f69bb449SAndreas Boehler      {
1090f69bb449SAndreas Boehler          $url = $row['url'];
1091f69bb449SAndreas Boehler      }
1092185e2535SAndreas Boehler
1093185e2535SAndreas Boehler      $url = DOKU_URL.'lib/plugins/davcal/ics.php/'.$url;
1094185e2535SAndreas Boehler      $this->cachedValues['privateurl'][$calid] = $url;
1095185e2535SAndreas Boehler      return $url;
1096f69bb449SAndreas Boehler  }
1097f69bb449SAndreas Boehler
1098cb71a62aSAndreas Boehler  /**
1099cb71a62aSAndreas Boehler   * Retrieve the calendar ID for a given private calendar URL
1100cb71a62aSAndreas Boehler   *
1101cb71a62aSAndreas Boehler   * @param string $url The private URL
1102cb71a62aSAndreas Boehler   *
1103cb71a62aSAndreas Boehler   * @return mixed The calendar ID or false
1104cb71a62aSAndreas Boehler   */
1105f69bb449SAndreas Boehler  public function getCalendarForPrivateURL($url)
1106f69bb449SAndreas Boehler  {
110751f4febbSAndreas Boehler      $query = "SELECT calid FROM calendartoprivateurlmapping WHERE url = ?";
110851f4febbSAndreas Boehler      $res = $this->sqlite->query($query, $url);
1109f69bb449SAndreas Boehler      $row = $this->sqlite->res2row($res);
1110f69bb449SAndreas Boehler      if(!isset($row['calid']))
1111f69bb449SAndreas Boehler        return false;
1112f69bb449SAndreas Boehler      return $row['calid'];
1113f69bb449SAndreas Boehler  }
1114f69bb449SAndreas Boehler
1115cb71a62aSAndreas Boehler  /**
1116cb71a62aSAndreas Boehler   * Return a given calendar as ICS feed, i.e. all events in one ICS file.
1117cb71a62aSAndreas Boehler   *
11187e0b8590SAndreas Boehler   * @param string $calid The calendar ID to retrieve
1119cb71a62aSAndreas Boehler   *
1120cb71a62aSAndreas Boehler   * @return mixed The calendar events as string or false
1121cb71a62aSAndreas Boehler   */
1122f69bb449SAndreas Boehler  public function getCalendarAsICSFeed($calid)
1123f69bb449SAndreas Boehler  {
1124f69bb449SAndreas Boehler      $calSettings = $this->getCalendarSettings($calid);
1125f69bb449SAndreas Boehler      if($calSettings === false)
1126f69bb449SAndreas Boehler        return false;
1127f69bb449SAndreas Boehler      $events = $this->getAllCalendarEvents($calid);
1128f69bb449SAndreas Boehler      if($events === false)
1129f69bb449SAndreas Boehler        return false;
1130f69bb449SAndreas Boehler
11317e0b8590SAndreas Boehler      // Load SabreDAV
11327e0b8590SAndreas Boehler      require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php');
11337e0b8590SAndreas Boehler      $out = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//DAVCal//DAVCal for DokuWiki//EN\r\nCALSCALE:GREGORIAN\r\nX-WR-CALNAME:";
11347e0b8590SAndreas Boehler      $out .= $calSettings['displayname']."\r\n";
1135f69bb449SAndreas Boehler      foreach($events as $event)
1136f69bb449SAndreas Boehler      {
11377e0b8590SAndreas Boehler          $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
11387e0b8590SAndreas Boehler          $evt = $vcal->VEVENT;
11397e0b8590SAndreas Boehler          $out .= $evt->serialize();
1140f69bb449SAndreas Boehler      }
11417e0b8590SAndreas Boehler      $out .= "END:VCALENDAR\r\n";
1142f69bb449SAndreas Boehler      return $out;
1143f69bb449SAndreas Boehler  }
1144f69bb449SAndreas Boehler
11457c7c6b0bSAndreas Boehler  /**
11467c7c6b0bSAndreas Boehler   * Retrieve a configuration option for the plugin
11477c7c6b0bSAndreas Boehler   *
11487c7c6b0bSAndreas Boehler   * @param string $key The key to query
114921d04f73SAndreas Boehler   * @return mixed The option set, null if not found
11507c7c6b0bSAndreas Boehler   */
11517c7c6b0bSAndreas Boehler  public function getConfig($key)
11527c7c6b0bSAndreas Boehler  {
11537c7c6b0bSAndreas Boehler      return $this->getConf($key);
11547c7c6b0bSAndreas Boehler  }
11557c7c6b0bSAndreas Boehler
1156a1a3b679SAndreas Boehler}
1157