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