xref: /plugin/davcal/helper.php (revision a495d34c25233615fa25fba79abef99239c1dd50)
1a1a3b679SAndreas Boehler<?php
2a1a3b679SAndreas Boehler/**
3a1a3b679SAndreas Boehler  * Helper Class for the tagrevisions plugin
4a1a3b679SAndreas Boehler  * This helper does the actual work.
5a1a3b679SAndreas Boehler  *
6a1a3b679SAndreas Boehler  * Configurable in DokuWiki's configuration
7a1a3b679SAndreas Boehler  */
8a1a3b679SAndreas Boehler
9a1a3b679SAndreas Boehler// must be run within Dokuwiki
10a1a3b679SAndreas Boehlerif(!defined('DOKU_INC')) die();
11a1a3b679SAndreas Boehler
12a1a3b679SAndreas Boehlerclass helper_plugin_davcal extends DokuWiki_Plugin {
13a1a3b679SAndreas Boehler
14a1a3b679SAndreas Boehler  protected $sqlite = null;
15a1a3b679SAndreas Boehler
16a1a3b679SAndreas Boehler  /**
17a1a3b679SAndreas Boehler    * Constructor to load the configuration
18a1a3b679SAndreas Boehler    */
19a1a3b679SAndreas Boehler  public function helper_plugin_davcal() {
20a1a3b679SAndreas Boehler    $this->sqlite =& plugin_load('helper', 'sqlite');
21a1a3b679SAndreas Boehler    if(!$this->sqlite)
22a1a3b679SAndreas Boehler    {
23a1a3b679SAndreas Boehler        msg('This plugin requires the sqlite plugin. Please install it.');
24a1a3b679SAndreas Boehler        return;
25a1a3b679SAndreas Boehler    }
26a1a3b679SAndreas Boehler
27a1a3b679SAndreas Boehler    if(!$this->sqlite->init('davcal', DOKU_PLUGIN.'davcal/db/'))
28a1a3b679SAndreas Boehler    {
29a1a3b679SAndreas Boehler        return;
30a1a3b679SAndreas Boehler    }
31a1a3b679SAndreas Boehler  }
32a1a3b679SAndreas Boehler
33a1a3b679SAndreas Boehler  public function setCalendarNameForPage($name, $description, $id = null, $userid = null)
34a1a3b679SAndreas Boehler  {
35a1a3b679SAndreas Boehler      if(is_null($id))
36a1a3b679SAndreas Boehler      {
37a1a3b679SAndreas Boehler          global $ID;
38a1a3b679SAndreas Boehler          $id = $ID;
39a1a3b679SAndreas Boehler      }
40a1a3b679SAndreas Boehler      if(is_null($userid))
41a1a3b679SAndreas Boehler        $userid = $_SERVER['REMOTE_USER'];
42a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
43a1a3b679SAndreas Boehler      if($calid === false)
44a1a3b679SAndreas Boehler        return $this->createCalendarForPage($name, $description, $id, $userid);
45a1a3b679SAndreas Boehler
46a1a3b679SAndreas Boehler      // Update the calendar name here
47a1a3b679SAndreas Boehler
48a1a3b679SAndreas Boehler  }
49a1a3b679SAndreas Boehler
50*a495d34cSAndreas Boehler  public function savePersonalSettings($settings, $userid = null)
51*a495d34cSAndreas Boehler  {
52*a495d34cSAndreas Boehler      if(is_null($userid))
53*a495d34cSAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
54*a495d34cSAndreas Boehler      $this->sqlite->query("BEGIN TRANSACTION");
55*a495d34cSAndreas Boehler
56*a495d34cSAndreas Boehler      foreach($settings as $key => $value)
57*a495d34cSAndreas Boehler      {
58*a495d34cSAndreas Boehler          $query = "INSERT OR REPLACE INTO calendarsettings (userid, key, value) VALUES (".
59*a495d34cSAndreas Boehler                   $this->sqlite->quote_string($userid).", ".
60*a495d34cSAndreas Boehler                   $this->sqlite->quote_string($key).", ".
61*a495d34cSAndreas Boehler                   $this->sqlite->quote_string($value).")";
62*a495d34cSAndreas Boehler          $res = $this->sqlite->query($query);
63*a495d34cSAndreas Boehler          if($res === false)
64*a495d34cSAndreas Boehler              return false;
65*a495d34cSAndreas Boehler      }
66*a495d34cSAndreas Boehler      $this->sqlite->query("COMMIT TRANSACTION");
67*a495d34cSAndreas Boehler      return true;
68*a495d34cSAndreas Boehler  }
69*a495d34cSAndreas Boehler
70*a495d34cSAndreas Boehler  public function getPersonalSettings($userid = null)
71*a495d34cSAndreas Boehler  {
72*a495d34cSAndreas Boehler      if(is_null($userid))
73*a495d34cSAndreas Boehler        $userid = $_SERVER['REMOTE_USER'];
74*a495d34cSAndreas Boehler
75*a495d34cSAndreas Boehler      $settings = array();
76*a495d34cSAndreas Boehler      $query = "SELECT key, value FROM calendarsettings WHERE userid=".$this->sqlite->quote_string($userid);
77*a495d34cSAndreas Boehler      $res = $this->sqlite->query($query);
78*a495d34cSAndreas Boehler      $arr = $this->sqlite->res2arr($res);
79*a495d34cSAndreas Boehler      foreach($arr as $row)
80*a495d34cSAndreas Boehler      {
81*a495d34cSAndreas Boehler          $settings[$row['key']] = $row['value'];
82*a495d34cSAndreas Boehler      }
83*a495d34cSAndreas Boehler      return $settings;
84*a495d34cSAndreas Boehler  }
85*a495d34cSAndreas Boehler
86a1a3b679SAndreas Boehler  public function getCalendarIdForPage($id = null)
87a1a3b679SAndreas Boehler  {
88a1a3b679SAndreas Boehler      if(is_null($id))
89a1a3b679SAndreas Boehler      {
90a1a3b679SAndreas Boehler          global $ID;
91a1a3b679SAndreas Boehler          $id = $ID;
92a1a3b679SAndreas Boehler      }
93a1a3b679SAndreas Boehler
94a1a3b679SAndreas Boehler      $query = "SELECT calid FROM pagetocalendarmapping WHERE page=".$this->sqlite->quote_string($id);
95a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
96a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
97a1a3b679SAndreas Boehler      if(isset($row['calid']))
98a1a3b679SAndreas Boehler        return $row['calid'];
99a1a3b679SAndreas Boehler      else
100a1a3b679SAndreas Boehler        return false;
101a1a3b679SAndreas Boehler  }
102a1a3b679SAndreas Boehler
103a1a3b679SAndreas Boehler  public function getCalendarIdToPageMapping()
104a1a3b679SAndreas Boehler  {
105a1a3b679SAndreas Boehler      $query = "SELECT calid, page FROM pagetocalendarmapping";
106a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
107a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
108a1a3b679SAndreas Boehler      return $arr;
109a1a3b679SAndreas Boehler  }
110a1a3b679SAndreas Boehler
111a1a3b679SAndreas Boehler  public function getCalendarIdsForUser($principalUri)
112a1a3b679SAndreas Boehler  {
113a1a3b679SAndreas Boehler      $user = explode('/', $principalUri);
114a1a3b679SAndreas Boehler      $user = end($user);
115a1a3b679SAndreas Boehler      $mapping = $this->getCalendarIdToPageMapping();
116a1a3b679SAndreas Boehler      $calids = array();
117a1a3b679SAndreas Boehler      foreach($mapping as $row)
118a1a3b679SAndreas Boehler      {
119a1a3b679SAndreas Boehler          $id = $row['calid'];
120a1a3b679SAndreas Boehler          $page = $row['page'];
121a1a3b679SAndreas Boehler          $acl = auth_quickaclcheck($page);
122a1a3b679SAndreas Boehler          if($acl >= AUTH_READ)
123a1a3b679SAndreas Boehler          {
124a1a3b679SAndreas Boehler              $write = $acl > AUTH_READ;
125a1a3b679SAndreas Boehler              $calids[$id] = array('readonly' => !$write);
126a1a3b679SAndreas Boehler          }
127a1a3b679SAndreas Boehler      }
128a1a3b679SAndreas Boehler      return $calids;
129a1a3b679SAndreas Boehler  }
130a1a3b679SAndreas Boehler
131a1a3b679SAndreas Boehler  public function createCalendarForPage($name, $description, $id = null, $userid = null)
132a1a3b679SAndreas Boehler  {
133a1a3b679SAndreas Boehler      if(is_null($id))
134a1a3b679SAndreas Boehler      {
135a1a3b679SAndreas Boehler          global $ID;
136a1a3b679SAndreas Boehler          $id = $ID;
137a1a3b679SAndreas Boehler      }
138a1a3b679SAndreas Boehler      if(is_null($userid))
139a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
140a1a3b679SAndreas Boehler      $values = array('principals/'.$userid,
141a1a3b679SAndreas Boehler                      $name,
142a1a3b679SAndreas Boehler                      str_replace(array('/', ' ', ':'), '_', $id),
143a1a3b679SAndreas Boehler                      $description,
144a1a3b679SAndreas Boehler                      'VEVENT,VTODO',
14555a741c0SAndreas Boehler                      0,
14655a741c0SAndreas Boehler                      1);
14755a741c0SAndreas Boehler      $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) VALUES (".$this->sqlite->quote_and_join($values, ',').");";
148a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
14955a741c0SAndreas Boehler      if($res === false)
15055a741c0SAndreas Boehler        return false;
151a1a3b679SAndreas Boehler      $query = "SELECT id FROM calendars WHERE principaluri=".$this->sqlite->quote_string($values[0])." AND ".
152a1a3b679SAndreas Boehler               "displayname=".$this->sqlite->quote_string($values[1])." AND ".
153a1a3b679SAndreas Boehler               "uri=".$this->sqlite->quote_string($values[2])." AND ".
154a1a3b679SAndreas Boehler               "description=".$this->sqlite->quote_string($values[3]);
155a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
156a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
157a1a3b679SAndreas Boehler      if(isset($row['id']))
158a1a3b679SAndreas Boehler      {
159a1a3b679SAndreas Boehler          $values = array($id, $row['id']);
160a1a3b679SAndreas Boehler          $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (".$this->sqlite->quote_and_join($values, ',').")";
161a1a3b679SAndreas Boehler          $res = $this->sqlite->query($query);
16255a741c0SAndreas Boehler          return ($res !== false);
163a1a3b679SAndreas Boehler      }
164a1a3b679SAndreas Boehler
165a1a3b679SAndreas Boehler      return false;
166a1a3b679SAndreas Boehler  }
167a1a3b679SAndreas Boehler
168a1a3b679SAndreas Boehler  public function addCalendarEntryToCalendarForPage($id, $user, $params)
169a1a3b679SAndreas Boehler  {
170a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
171a1a3b679SAndreas Boehler      $vcalendar = new \Sabre\VObject\Component\VCalendar();
172a1a3b679SAndreas Boehler      $event = $vcalendar->add('VEVENT');
173a1a3b679SAndreas Boehler      $event->summary = $params['eventname'];
174a1a3b679SAndreas Boehler      $dtStart = new \DateTime($params['eventfrom'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
175a1a3b679SAndreas Boehler      $dtEnd = new \DateTime($params['eventto'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
176a1a3b679SAndreas Boehler      $event->DTSTART = $dtStart;
177a1a3b679SAndreas Boehler      $event->DTEND = $dtEnd;
178a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
179a1a3b679SAndreas Boehler      $uri = uniqid('dokuwiki-').'.ics';
180a1a3b679SAndreas Boehler      $now = new DateTime();
181a1a3b679SAndreas Boehler      $eventStr = $vcalendar->serialize();
182a1a3b679SAndreas Boehler
183a1a3b679SAndreas Boehler      $values = array($calid,
184a1a3b679SAndreas Boehler                      $uri,
185a1a3b679SAndreas Boehler                      $eventStr,
186a1a3b679SAndreas Boehler                      $now->getTimestamp(),
187a1a3b679SAndreas Boehler                      'VEVENT',
188a1a3b679SAndreas Boehler                      $event->DTSTART->getDateTime()->getTimeStamp(),
189a1a3b679SAndreas Boehler                      $event->DTEND->getDateTime()->getTimeStamp(),
190a1a3b679SAndreas Boehler                      strlen($eventStr),
191a1a3b679SAndreas Boehler                      md5($eventStr),
192a1a3b679SAndreas Boehler                      uniqid()
193a1a3b679SAndreas Boehler      );
194a1a3b679SAndreas Boehler
195a1a3b679SAndreas Boehler      $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (".$this->sqlite->quote_and_join($values, ',').")";
196a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
19755a741c0SAndreas Boehler      if($res !== false)
19855a741c0SAndreas Boehler      {
19955a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'added');
200a1a3b679SAndreas Boehler          return true;
201a1a3b679SAndreas Boehler      }
20255a741c0SAndreas Boehler      return false;
20355a741c0SAndreas Boehler  }
204a1a3b679SAndreas Boehler
205a1a3b679SAndreas Boehler  public function getEventsWithinDateRange($id, $user, $startDate, $endDate)
206a1a3b679SAndreas Boehler  {
207a1a3b679SAndreas Boehler      $data = array();
208a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
209a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
210a1a3b679SAndreas Boehler      $startTs = new \DateTime($startDate);
211a1a3b679SAndreas Boehler      $endTs = new \DateTime($endDate);
212a1a3b679SAndreas Boehler      $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid=".
213a1a3b679SAndreas Boehler                $this->sqlite->quote_string($calid)." AND firstoccurence > ".
214a1a3b679SAndreas Boehler                $this->sqlite->quote_string($startTs->getTimestamp())." AND firstoccurence < ".
215a1a3b679SAndreas Boehler                $this->sqlite->quote_string($endTs->getTimestamp());
216a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
217a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
218a1a3b679SAndreas Boehler      foreach($arr as $row)
219a1a3b679SAndreas Boehler      {
220a1a3b679SAndreas Boehler          if(isset($row['calendardata']))
221a1a3b679SAndreas Boehler          {
222a1a3b679SAndreas Boehler              $vcal = \Sabre\VObject\Reader::read($row['calendardata']);
223a1a3b679SAndreas Boehler              $start = $vcal->VEVENT->DTSTART->getDateTime();
224a1a3b679SAndreas Boehler              $end = $vcal->VEVENT->DTEND->getDateTime();
225a1a3b679SAndreas Boehler              $summary = (string)$vcal->VEVENT->summary;
226a1a3b679SAndreas Boehler              $data[] = array("title" => $summary, "start" => $start->format(\DateTime::W3C),
227a1a3b679SAndreas Boehler                              "end" => $end->format(\DateTime::W3C),
228a1a3b679SAndreas Boehler                              "id" => $row['uid']);
229a1a3b679SAndreas Boehler          }
230a1a3b679SAndreas Boehler      }
231a1a3b679SAndreas Boehler      return $data;
232a1a3b679SAndreas Boehler  }
233a1a3b679SAndreas Boehler
234a1a3b679SAndreas Boehler  public function getEventWithUid($uid)
235a1a3b679SAndreas Boehler  {
23655a741c0SAndreas Boehler      $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid=".
237a1a3b679SAndreas Boehler                $this->sqlite->quote_string($uid);
238a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
239a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
240a1a3b679SAndreas Boehler      return $row;
241a1a3b679SAndreas Boehler  }
242a1a3b679SAndreas Boehler
243a1a3b679SAndreas Boehler  public function editCalendarEntryForPage($id, $user, $params)
244a1a3b679SAndreas Boehler  {
24555a741c0SAndreas Boehler      $uid = $params['uid'];
24655a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
247a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
248a1a3b679SAndreas Boehler      if(!isset($event['calendardata']))
249a1a3b679SAndreas Boehler        return false;
25055a741c0SAndreas Boehler      $uri = $event['uri'];
25155a741c0SAndreas Boehler      $calid = $event['calendarid'];
252a1a3b679SAndreas Boehler      $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
253a1a3b679SAndreas Boehler      $vcal->VEVENT->summary = $params['eventname'];
254a1a3b679SAndreas Boehler      $dtStart = new \DateTime($params['eventfrom'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
255a1a3b679SAndreas Boehler      $dtEnd = new \DateTime($params['eventto'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
256a1a3b679SAndreas Boehler      $vcal->VEVENT->DTSTART = $dtStart;
257a1a3b679SAndreas Boehler      $vcal->VEVENT->DTEND = $dtEnd;
258a1a3b679SAndreas Boehler      $now = new DateTime();
259a1a3b679SAndreas Boehler      $eventStr = $vcal->serialize();
260a1a3b679SAndreas Boehler
261a1a3b679SAndreas Boehler      $query = "UPDATE calendarobjects SET calendardata=".$this->sqlite->quote_string($eventStr).
262a1a3b679SAndreas Boehler               ", lastmodified=".$this->sqlite->quote_string($now->getTimestamp()).
263a1a3b679SAndreas Boehler               ", firstoccurence=".$this->sqlite->quote_string($dtStart->getTimestamp()).
264a1a3b679SAndreas Boehler               ", lastoccurence=".$this->sqlite->quote_string($dtEnd->getTimestamp()).
265a1a3b679SAndreas Boehler               ", size=".strlen($eventStr).
266a1a3b679SAndreas Boehler               ", etag=".$this->sqlite->quote_string(md5($eventStr)).
26755a741c0SAndreas Boehler               " WHERE uid=".$this->sqlite->quote_string($uid);
268a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
26955a741c0SAndreas Boehler      if($res !== false)
27055a741c0SAndreas Boehler      {
27155a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'modified');
272a1a3b679SAndreas Boehler          return true;
273a1a3b679SAndreas Boehler      }
27455a741c0SAndreas Boehler      return false;
27555a741c0SAndreas Boehler  }
276a1a3b679SAndreas Boehler
277a1a3b679SAndreas Boehler  public function deleteCalendarEntryForPage($id, $params)
278a1a3b679SAndreas Boehler  {
279a1a3b679SAndreas Boehler      $uid = $params['uid'];
28055a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
2812c14b82bSAndreas Boehler      $calid = $event['calendarid'];
28255a741c0SAndreas Boehler      $uri = $event['uri'];
283a1a3b679SAndreas Boehler      $query = "DELETE FROM calendarobjects WHERE uid=".$this->sqlite->quote_string($uid);
284a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
28555a741c0SAndreas Boehler      if($res !== false)
28655a741c0SAndreas Boehler      {
28755a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'deleted');
28855a741c0SAndreas Boehler      }
289a1a3b679SAndreas Boehler      return true;
290a1a3b679SAndreas Boehler  }
291a1a3b679SAndreas Boehler
29255a741c0SAndreas Boehler  public function getSyncTokenForCalendar($calid)
29355a741c0SAndreas Boehler  {
29455a741c0SAndreas Boehler      $query = "SELECT synctoken FROM calendars WHERE id=".$this->sqlite->quote_string($calid);
29555a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
29655a741c0SAndreas Boehler      $row = $this->sqlite->res2row($res);
29755a741c0SAndreas Boehler      if(isset($row['synctoken']))
29855a741c0SAndreas Boehler          return $row['synctoken'];
29955a741c0SAndreas Boehler      return false;
30055a741c0SAndreas Boehler  }
30155a741c0SAndreas Boehler
30255a741c0SAndreas Boehler  public function operationNameToOperation($operationName)
30355a741c0SAndreas Boehler  {
30455a741c0SAndreas Boehler      switch($operationName)
30555a741c0SAndreas Boehler      {
30655a741c0SAndreas Boehler          case 'added':
30755a741c0SAndreas Boehler              return 1;
30855a741c0SAndreas Boehler          break;
30955a741c0SAndreas Boehler          case 'modified':
31055a741c0SAndreas Boehler              return 2;
31155a741c0SAndreas Boehler          break;
31255a741c0SAndreas Boehler          case 'deleted':
31355a741c0SAndreas Boehler              return 3;
31455a741c0SAndreas Boehler          break;
31555a741c0SAndreas Boehler      }
31655a741c0SAndreas Boehler      return false;
31755a741c0SAndreas Boehler  }
31855a741c0SAndreas Boehler
31955a741c0SAndreas Boehler  private function updateSyncTokenLog($calid, $uri, $operation)
32055a741c0SAndreas Boehler  {
32155a741c0SAndreas Boehler      $currentToken = $this->getSyncTokenForCalendar($calid);
32255a741c0SAndreas Boehler      $operationCode = $this->operationNameToOperation($operation);
32355a741c0SAndreas Boehler      if(($operationCode === false) || ($currentToken === false))
32455a741c0SAndreas Boehler          return false;
32555a741c0SAndreas Boehler      $values = array($uri,
32655a741c0SAndreas Boehler                      $currentToken,
32755a741c0SAndreas Boehler                      $calid,
32855a741c0SAndreas Boehler                      $operationCode
32955a741c0SAndreas Boehler      );
33055a741c0SAndreas Boehler      $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(".
33155a741c0SAndreas Boehler               $this->sqlite->quote_and_join($values, ',').")";
33255a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
33355a741c0SAndreas Boehler      if($res === false)
33455a741c0SAndreas Boehler        return false;
33555a741c0SAndreas Boehler      $currentToken++;
33655a741c0SAndreas Boehler      $query = "UPDATE calendars SET synctoken=".$this->sqlite->quote_string($currentToken)." WHERE id=".
33755a741c0SAndreas Boehler               $this->sqlite->quote_string($calid);
33855a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
33955a741c0SAndreas Boehler      return ($res !== false);
34055a741c0SAndreas Boehler  }
34155a741c0SAndreas Boehler
342a1a3b679SAndreas Boehler}
343