xref: /plugin/davcal/helper.php (revision 55a741c0ad08b9f9e3b9d9e51875cfdf1f79b2c2)
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
50a1a3b679SAndreas Boehler  public function getCalendarIdForPage($id = null)
51a1a3b679SAndreas Boehler  {
52a1a3b679SAndreas Boehler      if(is_null($id))
53a1a3b679SAndreas Boehler      {
54a1a3b679SAndreas Boehler          global $ID;
55a1a3b679SAndreas Boehler          $id = $ID;
56a1a3b679SAndreas Boehler      }
57a1a3b679SAndreas Boehler
58a1a3b679SAndreas Boehler      $query = "SELECT calid FROM pagetocalendarmapping WHERE page=".$this->sqlite->quote_string($id);
59a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
60a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
61a1a3b679SAndreas Boehler      if(isset($row['calid']))
62a1a3b679SAndreas Boehler        return $row['calid'];
63a1a3b679SAndreas Boehler      else
64a1a3b679SAndreas Boehler        return false;
65a1a3b679SAndreas Boehler  }
66a1a3b679SAndreas Boehler
67a1a3b679SAndreas Boehler  public function getCalendarIdToPageMapping()
68a1a3b679SAndreas Boehler  {
69a1a3b679SAndreas Boehler      $query = "SELECT calid, page FROM pagetocalendarmapping";
70a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
71a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
72a1a3b679SAndreas Boehler      return $arr;
73a1a3b679SAndreas Boehler  }
74a1a3b679SAndreas Boehler
75a1a3b679SAndreas Boehler  public function getCalendarIdsForUser($principalUri)
76a1a3b679SAndreas Boehler  {
77a1a3b679SAndreas Boehler      $user = explode('/', $principalUri);
78a1a3b679SAndreas Boehler      $user = end($user);
79a1a3b679SAndreas Boehler      $mapping = $this->getCalendarIdToPageMapping();
80a1a3b679SAndreas Boehler      $calids = array();
81a1a3b679SAndreas Boehler      foreach($mapping as $row)
82a1a3b679SAndreas Boehler      {
83a1a3b679SAndreas Boehler          $id = $row['calid'];
84a1a3b679SAndreas Boehler          $page = $row['page'];
85a1a3b679SAndreas Boehler          $acl = auth_quickaclcheck($page);
86a1a3b679SAndreas Boehler          if($acl >= AUTH_READ)
87a1a3b679SAndreas Boehler          {
88a1a3b679SAndreas Boehler              $write = $acl > AUTH_READ;
89a1a3b679SAndreas Boehler              $calids[$id] = array('readonly' => !$write);
90a1a3b679SAndreas Boehler          }
91a1a3b679SAndreas Boehler      }
92a1a3b679SAndreas Boehler      return $calids;
93a1a3b679SAndreas Boehler  }
94a1a3b679SAndreas Boehler
95a1a3b679SAndreas Boehler  public function createCalendarForPage($name, $description, $id = null, $userid = null)
96a1a3b679SAndreas Boehler  {
97a1a3b679SAndreas Boehler      if(is_null($id))
98a1a3b679SAndreas Boehler      {
99a1a3b679SAndreas Boehler          global $ID;
100a1a3b679SAndreas Boehler          $id = $ID;
101a1a3b679SAndreas Boehler      }
102a1a3b679SAndreas Boehler      if(is_null($userid))
103a1a3b679SAndreas Boehler          $userid = $_SERVER['REMOTE_USER'];
104a1a3b679SAndreas Boehler      $values = array('principals/'.$userid,
105a1a3b679SAndreas Boehler                      $name,
106a1a3b679SAndreas Boehler                      str_replace(array('/', ' ', ':'), '_', $id),
107a1a3b679SAndreas Boehler                      $description,
108a1a3b679SAndreas Boehler                      'VEVENT,VTODO',
109*55a741c0SAndreas Boehler                      0,
110*55a741c0SAndreas Boehler                      1);
111*55a741c0SAndreas Boehler      $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) VALUES (".$this->sqlite->quote_and_join($values, ',').");";
112a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
113*55a741c0SAndreas Boehler      if($res === false)
114*55a741c0SAndreas Boehler        return false;
115a1a3b679SAndreas Boehler      $query = "SELECT id FROM calendars WHERE principaluri=".$this->sqlite->quote_string($values[0])." AND ".
116a1a3b679SAndreas Boehler               "displayname=".$this->sqlite->quote_string($values[1])." AND ".
117a1a3b679SAndreas Boehler               "uri=".$this->sqlite->quote_string($values[2])." AND ".
118a1a3b679SAndreas Boehler               "description=".$this->sqlite->quote_string($values[3]);
119a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
120a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
121a1a3b679SAndreas Boehler      if(isset($row['id']))
122a1a3b679SAndreas Boehler      {
123a1a3b679SAndreas Boehler          $values = array($id, $row['id']);
124a1a3b679SAndreas Boehler          $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (".$this->sqlite->quote_and_join($values, ',').")";
125a1a3b679SAndreas Boehler          $res = $this->sqlite->query($query);
126*55a741c0SAndreas Boehler          return ($res !== false);
127a1a3b679SAndreas Boehler      }
128a1a3b679SAndreas Boehler
129a1a3b679SAndreas Boehler      return false;
130a1a3b679SAndreas Boehler  }
131a1a3b679SAndreas Boehler
132a1a3b679SAndreas Boehler  public function addCalendarEntryToCalendarForPage($id, $user, $params)
133a1a3b679SAndreas Boehler  {
134a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
135a1a3b679SAndreas Boehler      $vcalendar = new \Sabre\VObject\Component\VCalendar();
136a1a3b679SAndreas Boehler      $event = $vcalendar->add('VEVENT');
137a1a3b679SAndreas Boehler      $event->summary = $params['eventname'];
138a1a3b679SAndreas Boehler      $dtStart = new \DateTime($params['eventfrom'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
139a1a3b679SAndreas Boehler      $dtEnd = new \DateTime($params['eventto'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
140a1a3b679SAndreas Boehler      $event->DTSTART = $dtStart;
141a1a3b679SAndreas Boehler      $event->DTEND = $dtEnd;
142a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
143a1a3b679SAndreas Boehler      $uri = uniqid('dokuwiki-').'.ics';
144a1a3b679SAndreas Boehler      $now = new DateTime();
145a1a3b679SAndreas Boehler      $eventStr = $vcalendar->serialize();
146a1a3b679SAndreas Boehler
147a1a3b679SAndreas Boehler      $values = array($calid,
148a1a3b679SAndreas Boehler                      $uri,
149a1a3b679SAndreas Boehler                      $eventStr,
150a1a3b679SAndreas Boehler                      $now->getTimestamp(),
151a1a3b679SAndreas Boehler                      'VEVENT',
152a1a3b679SAndreas Boehler                      $event->DTSTART->getDateTime()->getTimeStamp(),
153a1a3b679SAndreas Boehler                      $event->DTEND->getDateTime()->getTimeStamp(),
154a1a3b679SAndreas Boehler                      strlen($eventStr),
155a1a3b679SAndreas Boehler                      md5($eventStr),
156a1a3b679SAndreas Boehler                      uniqid()
157a1a3b679SAndreas Boehler      );
158a1a3b679SAndreas Boehler
159a1a3b679SAndreas Boehler      $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (".$this->sqlite->quote_and_join($values, ',').")";
160a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
161*55a741c0SAndreas Boehler      if($res !== false)
162*55a741c0SAndreas Boehler      {
163*55a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'added');
164a1a3b679SAndreas Boehler          return true;
165a1a3b679SAndreas Boehler      }
166*55a741c0SAndreas Boehler      return false;
167*55a741c0SAndreas Boehler  }
168a1a3b679SAndreas Boehler
169a1a3b679SAndreas Boehler  public function getEventsWithinDateRange($id, $user, $startDate, $endDate)
170a1a3b679SAndreas Boehler  {
171a1a3b679SAndreas Boehler      $data = array();
172a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
173a1a3b679SAndreas Boehler      $calid = $this->getCalendarIdForPage($id);
174a1a3b679SAndreas Boehler      $startTs = new \DateTime($startDate);
175a1a3b679SAndreas Boehler      $endTs = new \DateTime($endDate);
176a1a3b679SAndreas Boehler      $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid=".
177a1a3b679SAndreas Boehler                $this->sqlite->quote_string($calid)." AND firstoccurence > ".
178a1a3b679SAndreas Boehler                $this->sqlite->quote_string($startTs->getTimestamp())." AND firstoccurence < ".
179a1a3b679SAndreas Boehler                $this->sqlite->quote_string($endTs->getTimestamp());
180a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
181a1a3b679SAndreas Boehler      $arr = $this->sqlite->res2arr($res);
182a1a3b679SAndreas Boehler      foreach($arr as $row)
183a1a3b679SAndreas Boehler      {
184a1a3b679SAndreas Boehler          if(isset($row['calendardata']))
185a1a3b679SAndreas Boehler          {
186a1a3b679SAndreas Boehler              $vcal = \Sabre\VObject\Reader::read($row['calendardata']);
187a1a3b679SAndreas Boehler              $start = $vcal->VEVENT->DTSTART->getDateTime();
188a1a3b679SAndreas Boehler              $end = $vcal->VEVENT->DTEND->getDateTime();
189a1a3b679SAndreas Boehler              $summary = (string)$vcal->VEVENT->summary;
190a1a3b679SAndreas Boehler              $data[] = array("title" => $summary, "start" => $start->format(\DateTime::W3C),
191a1a3b679SAndreas Boehler                              "end" => $end->format(\DateTime::W3C),
192a1a3b679SAndreas Boehler                              "id" => $row['uid']);
193a1a3b679SAndreas Boehler          }
194a1a3b679SAndreas Boehler      }
195a1a3b679SAndreas Boehler      return $data;
196a1a3b679SAndreas Boehler  }
197a1a3b679SAndreas Boehler
198a1a3b679SAndreas Boehler  public function getEventWithUid($uid)
199a1a3b679SAndreas Boehler  {
200*55a741c0SAndreas Boehler      $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid=".
201a1a3b679SAndreas Boehler                $this->sqlite->quote_string($uid);
202a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
203a1a3b679SAndreas Boehler      $row = $this->sqlite->res2row($res);
204a1a3b679SAndreas Boehler      return $row;
205a1a3b679SAndreas Boehler  }
206a1a3b679SAndreas Boehler
207a1a3b679SAndreas Boehler  public function editCalendarEntryForPage($id, $user, $params)
208a1a3b679SAndreas Boehler  {
209*55a741c0SAndreas Boehler      $uid = $params['uid'];
210*55a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
211a1a3b679SAndreas Boehler      require_once('vendor/autoload.php');
212a1a3b679SAndreas Boehler      if(!isset($event['calendardata']))
213a1a3b679SAndreas Boehler        return false;
214*55a741c0SAndreas Boehler      $uri = $event['uri'];
215*55a741c0SAndreas Boehler      $calid = $event['calendarid'];
216a1a3b679SAndreas Boehler      $vcal = \Sabre\VObject\Reader::read($event['calendardata']);
217a1a3b679SAndreas Boehler      $vcal->VEVENT->summary = $params['eventname'];
218a1a3b679SAndreas Boehler      $dtStart = new \DateTime($params['eventfrom'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
219a1a3b679SAndreas Boehler      $dtEnd = new \DateTime($params['eventto'], new \DateTimeZone('Europe/Vienna')); // FIXME: Timezone
220a1a3b679SAndreas Boehler      $vcal->VEVENT->DTSTART = $dtStart;
221a1a3b679SAndreas Boehler      $vcal->VEVENT->DTEND = $dtEnd;
222a1a3b679SAndreas Boehler      $now = new DateTime();
223a1a3b679SAndreas Boehler      $eventStr = $vcal->serialize();
224a1a3b679SAndreas Boehler
225a1a3b679SAndreas Boehler      $query = "UPDATE calendarobjects SET calendardata=".$this->sqlite->quote_string($eventStr).
226a1a3b679SAndreas Boehler               ", lastmodified=".$this->sqlite->quote_string($now->getTimestamp()).
227a1a3b679SAndreas Boehler               ", firstoccurence=".$this->sqlite->quote_string($dtStart->getTimestamp()).
228a1a3b679SAndreas Boehler               ", lastoccurence=".$this->sqlite->quote_string($dtEnd->getTimestamp()).
229a1a3b679SAndreas Boehler               ", size=".strlen($eventStr).
230a1a3b679SAndreas Boehler               ", etag=".$this->sqlite->quote_string(md5($eventStr)).
231*55a741c0SAndreas Boehler               " WHERE uid=".$this->sqlite->quote_string($uid);
232a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
233*55a741c0SAndreas Boehler      if($res !== false)
234*55a741c0SAndreas Boehler      {
235*55a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'modified');
236a1a3b679SAndreas Boehler          return true;
237a1a3b679SAndreas Boehler      }
238*55a741c0SAndreas Boehler      return false;
239*55a741c0SAndreas Boehler  }
240a1a3b679SAndreas Boehler
241a1a3b679SAndreas Boehler  public function deleteCalendarEntryForPage($id, $params)
242a1a3b679SAndreas Boehler  {
243a1a3b679SAndreas Boehler      $uid = $params['uid'];
244*55a741c0SAndreas Boehler      $event = $this->getEventWithUid($uid);
245*55a741c0SAndreas Boehler      $uri = $event['uri'];
246a1a3b679SAndreas Boehler      $query = "DELETE FROM calendarobjects WHERE uid=".$this->sqlite->quote_string($uid);
247a1a3b679SAndreas Boehler      $res = $this->sqlite->query($query);
248*55a741c0SAndreas Boehler      if($res !== false)
249*55a741c0SAndreas Boehler      {
250*55a741c0SAndreas Boehler          $this->updateSyncTokenLog($calid, $uri, 'deleted');
251*55a741c0SAndreas Boehler      }
252a1a3b679SAndreas Boehler      return true;
253a1a3b679SAndreas Boehler  }
254a1a3b679SAndreas Boehler
255*55a741c0SAndreas Boehler  public function getSyncTokenForCalendar($calid)
256*55a741c0SAndreas Boehler  {
257*55a741c0SAndreas Boehler      $query = "SELECT synctoken FROM calendars WHERE id=".$this->sqlite->quote_string($calid);
258*55a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
259*55a741c0SAndreas Boehler      $row = $this->sqlite->res2row($res);
260*55a741c0SAndreas Boehler      if(isset($row['synctoken']))
261*55a741c0SAndreas Boehler          return $row['synctoken'];
262*55a741c0SAndreas Boehler      return false;
263*55a741c0SAndreas Boehler  }
264*55a741c0SAndreas Boehler
265*55a741c0SAndreas Boehler  public function operationNameToOperation($operationName)
266*55a741c0SAndreas Boehler  {
267*55a741c0SAndreas Boehler      switch($operationName)
268*55a741c0SAndreas Boehler      {
269*55a741c0SAndreas Boehler          case 'added':
270*55a741c0SAndreas Boehler              return 1;
271*55a741c0SAndreas Boehler          break;
272*55a741c0SAndreas Boehler          case 'modified':
273*55a741c0SAndreas Boehler              return 2;
274*55a741c0SAndreas Boehler          break;
275*55a741c0SAndreas Boehler          case 'deleted':
276*55a741c0SAndreas Boehler              return 3;
277*55a741c0SAndreas Boehler          break;
278*55a741c0SAndreas Boehler      }
279*55a741c0SAndreas Boehler      return false;
280*55a741c0SAndreas Boehler  }
281*55a741c0SAndreas Boehler
282*55a741c0SAndreas Boehler  private function updateSyncTokenLog($calid, $uri, $operation)
283*55a741c0SAndreas Boehler  {
284*55a741c0SAndreas Boehler      $currentToken = $this->getSyncTokenForCalendar($calid);
285*55a741c0SAndreas Boehler      $operationCode = $this->operationNameToOperation($operation);
286*55a741c0SAndreas Boehler      if(($operationCode === false) || ($currentToken === false))
287*55a741c0SAndreas Boehler          return false;
288*55a741c0SAndreas Boehler      $values = array($uri,
289*55a741c0SAndreas Boehler                      $currentToken,
290*55a741c0SAndreas Boehler                      $calid,
291*55a741c0SAndreas Boehler                      $operationCode
292*55a741c0SAndreas Boehler      );
293*55a741c0SAndreas Boehler      $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(".
294*55a741c0SAndreas Boehler               $this->sqlite->quote_and_join($values, ',').")";
295*55a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
296*55a741c0SAndreas Boehler      if($res === false)
297*55a741c0SAndreas Boehler        return false;
298*55a741c0SAndreas Boehler      $currentToken++;
299*55a741c0SAndreas Boehler      $query = "UPDATE calendars SET synctoken=".$this->sqlite->quote_string($currentToken)." WHERE id=".
300*55a741c0SAndreas Boehler               $this->sqlite->quote_string($calid);
301*55a741c0SAndreas Boehler      $res = $this->sqlite->query($query);
302*55a741c0SAndreas Boehler      return ($res !== false);
303*55a741c0SAndreas Boehler  }
304*55a741c0SAndreas Boehler
305a1a3b679SAndreas Boehler}
306