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 /** 8380e1ddf7SAndreas Boehler * Filter calendar pages and return only those where the current 8480e1ddf7SAndreas Boehler * user has at least read permission. 8580e1ddf7SAndreas Boehler * 8680e1ddf7SAndreas Boehler * @param array $calendarPages Array with calendar pages to check 8780e1ddf7SAndreas Boehler * @return array with filtered calendar pages 8880e1ddf7SAndreas Boehler */ 8980e1ddf7SAndreas Boehler public function filterCalendarPagesByUserPermission($calendarPages) 9080e1ddf7SAndreas Boehler { 9180e1ddf7SAndreas Boehler $retList = array(); 9280e1ddf7SAndreas Boehler foreach($calendarPages as $page => $data) 9380e1ddf7SAndreas Boehler { 94*0b805092SAndreas Boehler // WebDAV Connections are always readable 95*0b805092SAndreas Boehler if(strpos($page, 'webdav://') === 0) 96*0b805092SAndreas Boehler { 97*0b805092SAndreas Boehler $retList[$page] = $data; 98*0b805092SAndreas Boehler } 99*0b805092SAndreas Boehler elseif(auth_quickaclcheck($page) >= AUTH_READ) 10080e1ddf7SAndreas Boehler { 10180e1ddf7SAndreas Boehler $retList[$page] = $data; 10280e1ddf7SAndreas Boehler } 10380e1ddf7SAndreas Boehler } 10480e1ddf7SAndreas Boehler return $retList; 10580e1ddf7SAndreas Boehler } 10680e1ddf7SAndreas Boehler 10780e1ddf7SAndreas Boehler /** 108185e2535SAndreas Boehler * Get all calendar pages used by a given page 109185e2535SAndreas Boehler * based on the stored metadata 110185e2535SAndreas Boehler * 111185e2535SAndreas Boehler * @param string $id optional The page id 112185e2535SAndreas Boehler * @return mixed The pages as array or false 113185e2535SAndreas Boehler */ 114185e2535SAndreas Boehler public function getCalendarPagesByMeta($id = null) 115185e2535SAndreas Boehler { 116185e2535SAndreas Boehler if(is_null($id)) 117185e2535SAndreas Boehler { 118185e2535SAndreas Boehler global $ID; 119185e2535SAndreas Boehler $id = $ID; 120185e2535SAndreas Boehler } 121185e2535SAndreas Boehler 122185e2535SAndreas Boehler $meta = $this->getCalendarMetaForPage($id); 123*0b805092SAndreas Boehler 124185e2535SAndreas Boehler if(isset($meta['id'])) 125ed764890SAndreas Boehler { 126ed764890SAndreas Boehler // Filter the list of pages by permission 12780e1ddf7SAndreas Boehler $pages = $this->filterCalendarPagesByUserPermission($meta['id']); 12880e1ddf7SAndreas Boehler if(empty($pages)) 129ed764890SAndreas Boehler return false; 13080e1ddf7SAndreas Boehler return $pages; 131ed764890SAndreas Boehler } 132185e2535SAndreas Boehler return false; 133185e2535SAndreas Boehler } 134185e2535SAndreas Boehler 135185e2535SAndreas Boehler /** 136185e2535SAndreas Boehler * Get a list of calendar names/pages/ids/colors 137185e2535SAndreas Boehler * for an array of page ids 138185e2535SAndreas Boehler * 139185e2535SAndreas Boehler * @param array $calendarPages The calendar pages to retrieve 140185e2535SAndreas Boehler * @return array The list 141185e2535SAndreas Boehler */ 142185e2535SAndreas Boehler public function getCalendarMapForIDs($calendarPages) 143185e2535SAndreas Boehler { 144185e2535SAndreas Boehler $data = array(); 1454a2bf5eeSAndreas Boehler foreach($calendarPages as $page => $color) 146185e2535SAndreas Boehler { 147*0b805092SAndreas Boehler if(strpos($page, 'webdav://') === 0) 148*0b805092SAndreas Boehler { 149*0b805092SAndreas Boehler $wdc =& plugin_load('helper', 'webdavclient'); 150*0b805092SAndreas Boehler if(is_null($wdc)) 151*0b805092SAndreas Boehler continue; 152*0b805092SAndreas Boehler $connectionId = str_replace('webdav://', '', $page); 153*0b805092SAndreas Boehler $settings = $wdc->getConnection($connectionId); 154*0b805092SAndreas Boehler $name = $settings['displayname']; 155*0b805092SAndreas Boehler $write = false; 156*0b805092SAndreas Boehler $calid = $connectionId; 157*0b805092SAndreas Boehler } 158*0b805092SAndreas Boehler else 159*0b805092SAndreas Boehler { 160185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($page); 161185e2535SAndreas Boehler if($calid !== false) 162185e2535SAndreas Boehler { 163185e2535SAndreas Boehler $settings = $this->getCalendarSettings($calid); 164185e2535SAndreas Boehler $name = $settings['displayname']; 165*0b805092SAndreas Boehler //$color = $settings['calendarcolor']; 166ed764890SAndreas Boehler $write = (auth_quickaclcheck($page) > AUTH_READ); 167*0b805092SAndreas Boehler } 168*0b805092SAndreas Boehler else 169*0b805092SAndreas Boehler { 170*0b805092SAndreas Boehler continue; 171*0b805092SAndreas Boehler } 172*0b805092SAndreas Boehler } 173185e2535SAndreas Boehler $data[] = array('name' => $name, 'page' => $page, 'calid' => $calid, 174ed764890SAndreas Boehler 'color' => $color, 'write' => $write); 175185e2535SAndreas Boehler } 176185e2535SAndreas Boehler return $data; 177185e2535SAndreas Boehler } 178185e2535SAndreas Boehler 179185e2535SAndreas Boehler /** 180185e2535SAndreas Boehler * Get the saved calendar color for a given page. 181185e2535SAndreas Boehler * 182185e2535SAndreas Boehler * @param string $id optional The page ID 183185e2535SAndreas Boehler * @return mixed The color on success, otherwise false 184185e2535SAndreas Boehler */ 185185e2535SAndreas Boehler public function getCalendarColorForPage($id = null) 186185e2535SAndreas Boehler { 187185e2535SAndreas Boehler if(is_null($id)) 188185e2535SAndreas Boehler { 189185e2535SAndreas Boehler global $ID; 190185e2535SAndreas Boehler $id = $ID; 191185e2535SAndreas Boehler } 192185e2535SAndreas Boehler 193185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 194185e2535SAndreas Boehler if($calid === false) 195185e2535SAndreas Boehler return false; 196185e2535SAndreas Boehler 197185e2535SAndreas Boehler return $this->getCalendarColorForCalendar($calid); 198185e2535SAndreas Boehler } 199185e2535SAndreas Boehler 200185e2535SAndreas Boehler /** 201185e2535SAndreas Boehler * Get the saved calendar color for a given calendar ID. 202185e2535SAndreas Boehler * 203185e2535SAndreas Boehler * @param string $id optional The calendar ID 204185e2535SAndreas Boehler * @return mixed The color on success, otherwise false 205185e2535SAndreas Boehler */ 206185e2535SAndreas Boehler public function getCalendarColorForCalendar($calid) 207185e2535SAndreas Boehler { 208185e2535SAndreas Boehler if(isset($this->cachedValues['calendarcolor'][$calid])) 209185e2535SAndreas Boehler return $this->cachedValues['calendarcolor'][$calid]; 210185e2535SAndreas Boehler 211185e2535SAndreas Boehler $row = $this->getCalendarSettings($calid); 212185e2535SAndreas Boehler 213185e2535SAndreas Boehler if(!isset($row['calendarcolor'])) 214185e2535SAndreas Boehler return false; 215185e2535SAndreas Boehler 216185e2535SAndreas Boehler $color = $row['calendarcolor']; 217185e2535SAndreas Boehler $this->cachedValues['calendarcolor'][$calid] = $color; 218185e2535SAndreas Boehler return $color; 219185e2535SAndreas Boehler } 220185e2535SAndreas Boehler 221185e2535SAndreas Boehler /** 222e86c8dd3SAndreas Boehler * Get the user's principal URL for iOS sync 223e86c8dd3SAndreas Boehler * @param string $user the user name 224e86c8dd3SAndreas Boehler * @return the URL to the principal sync 225e86c8dd3SAndreas Boehler */ 226e86c8dd3SAndreas Boehler public function getPrincipalUrlForUser($user) 227e86c8dd3SAndreas Boehler { 228e86c8dd3SAndreas Boehler if(is_null($user)) 229e86c8dd3SAndreas Boehler return false; 230e86c8dd3SAndreas Boehler $url = DOKU_URL.'lib/plugins/davcal/calendarserver.php/principals/'.$user; 231e86c8dd3SAndreas Boehler return $url; 232e86c8dd3SAndreas Boehler } 233e86c8dd3SAndreas Boehler 234e86c8dd3SAndreas Boehler /** 235185e2535SAndreas Boehler * Set the calendar color for a given page. 236185e2535SAndreas Boehler * 237185e2535SAndreas Boehler * @param string $color The color definition 238185e2535SAndreas Boehler * @param string $id optional The page ID 239185e2535SAndreas Boehler * @return boolean True on success, otherwise false 240185e2535SAndreas Boehler */ 241185e2535SAndreas Boehler public function setCalendarColorForPage($color, $id = null) 242185e2535SAndreas Boehler { 243185e2535SAndreas Boehler if(is_null($id)) 244185e2535SAndreas Boehler { 245185e2535SAndreas Boehler global $ID; 246185e2535SAndreas Boehler $id = $ID; 247185e2535SAndreas Boehler } 248185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 249185e2535SAndreas Boehler if($calid === false) 250185e2535SAndreas Boehler return false; 251185e2535SAndreas Boehler 25251f4febbSAndreas Boehler $query = "UPDATE calendars SET calendarcolor = ? ". 25351f4febbSAndreas Boehler " WHERE id = ?"; 25451f4febbSAndreas Boehler $res = $this->sqlite->query($query, $color, $calid); 255185e2535SAndreas Boehler if($res !== false) 256185e2535SAndreas Boehler { 257185e2535SAndreas Boehler $this->cachedValues['calendarcolor'][$calid] = $color; 258185e2535SAndreas Boehler return true; 259185e2535SAndreas Boehler } 260185e2535SAndreas Boehler return false; 261185e2535SAndreas Boehler } 262185e2535SAndreas Boehler 263185e2535SAndreas Boehler /** 264cb71a62aSAndreas Boehler * Set the calendar name and description for a given page with a given 265cb71a62aSAndreas Boehler * page id. 266cb71a62aSAndreas Boehler * If the calendar doesn't exist, the calendar is created! 267cb71a62aSAndreas Boehler * 268cb71a62aSAndreas Boehler * @param string $name The name of the new calendar 269cb71a62aSAndreas Boehler * @param string $description The description of the new calendar 270cb71a62aSAndreas Boehler * @param string $id (optional) The ID of the page 271cb71a62aSAndreas Boehler * @param string $userid The userid of the creating user 272cb71a62aSAndreas Boehler * 273cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false. 274cb71a62aSAndreas Boehler */ 275a1a3b679SAndreas Boehler public function setCalendarNameForPage($name, $description, $id = null, $userid = null) 276a1a3b679SAndreas Boehler { 277a1a3b679SAndreas Boehler if(is_null($id)) 278a1a3b679SAndreas Boehler { 279a1a3b679SAndreas Boehler global $ID; 280a1a3b679SAndreas Boehler $id = $ID; 281a1a3b679SAndreas Boehler } 282a1a3b679SAndreas Boehler if(is_null($userid)) 28334a47953SAndreas Boehler { 28434a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 28534a47953SAndreas Boehler { 286a1a3b679SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 28734a47953SAndreas Boehler } 28834a47953SAndreas Boehler else 28934a47953SAndreas Boehler { 29034a47953SAndreas Boehler $userid = uniqid('davcal-'); 29134a47953SAndreas Boehler } 29234a47953SAndreas Boehler } 293a1a3b679SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 294a1a3b679SAndreas Boehler if($calid === false) 295a1a3b679SAndreas Boehler return $this->createCalendarForPage($name, $description, $id, $userid); 296a1a3b679SAndreas Boehler 29751f4febbSAndreas Boehler $query = "UPDATE calendars SET displayname = ?, description = ? WHERE id = ?"; 29851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $name, $description, $calid); 299b269830cSAndreas Boehler if($res !== false) 300b269830cSAndreas Boehler return true; 301b269830cSAndreas Boehler return false; 302a1a3b679SAndreas Boehler } 303a1a3b679SAndreas Boehler 304cb71a62aSAndreas Boehler /** 305cb71a62aSAndreas Boehler * Save the personal settings to the SQLite database 'calendarsettings'. 306cb71a62aSAndreas Boehler * 307cb71a62aSAndreas Boehler * @param array $settings The settings array to store 308cb71a62aSAndreas Boehler * @param string $userid (optional) The userid to store 309cb71a62aSAndreas Boehler * 310cb71a62aSAndreas Boehler * @param boolean True on success, otherwise false 311cb71a62aSAndreas Boehler */ 312a495d34cSAndreas Boehler public function savePersonalSettings($settings, $userid = null) 313a495d34cSAndreas Boehler { 314a495d34cSAndreas Boehler if(is_null($userid)) 31534a47953SAndreas Boehler { 31634a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 31734a47953SAndreas Boehler { 318a495d34cSAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 31934a47953SAndreas Boehler } 32034a47953SAndreas Boehler else 32134a47953SAndreas Boehler { 32234a47953SAndreas Boehler return false; 32334a47953SAndreas Boehler } 32434a47953SAndreas Boehler } 325a495d34cSAndreas Boehler $this->sqlite->query("BEGIN TRANSACTION"); 326a495d34cSAndreas Boehler 32751f4febbSAndreas Boehler $query = "DELETE FROM calendarsettings WHERE userid = ?"; 32851f4febbSAndreas Boehler $this->sqlite->query($query, $userid); 329bd883736SAndreas Boehler 330a495d34cSAndreas Boehler foreach($settings as $key => $value) 331a495d34cSAndreas Boehler { 33251f4febbSAndreas Boehler $query = "INSERT INTO calendarsettings (userid, key, value) VALUES (?, ?, ?)"; 33351f4febbSAndreas Boehler $res = $this->sqlite->query($query, $userid, $key, $value); 334a495d34cSAndreas Boehler if($res === false) 335a495d34cSAndreas Boehler return false; 336a495d34cSAndreas Boehler } 337a495d34cSAndreas Boehler $this->sqlite->query("COMMIT TRANSACTION"); 338185e2535SAndreas Boehler $this->cachedValues['settings'][$userid] = $settings; 339a495d34cSAndreas Boehler return true; 340a495d34cSAndreas Boehler } 341a495d34cSAndreas Boehler 342cb71a62aSAndreas Boehler /** 343cb71a62aSAndreas Boehler * Retrieve the settings array for a given user id. 344cb71a62aSAndreas Boehler * Some sane defaults are returned, currently: 345cb71a62aSAndreas Boehler * 346cb71a62aSAndreas Boehler * timezone => local 347cb71a62aSAndreas Boehler * weeknumbers => 0 348cb71a62aSAndreas Boehler * workweek => 0 349cb71a62aSAndreas Boehler * 350cb71a62aSAndreas Boehler * @param string $userid (optional) The user id to retrieve 351cb71a62aSAndreas Boehler * 352cb71a62aSAndreas Boehler * @return array The settings array 353cb71a62aSAndreas Boehler */ 354a495d34cSAndreas Boehler public function getPersonalSettings($userid = null) 355a495d34cSAndreas Boehler { 356bd883736SAndreas Boehler // Some sane default settings 357bd883736SAndreas Boehler $settings = array( 358fb813b30SAndreas Boehler 'timezone' => $this->getConf('timezone'), 359fb813b30SAndreas Boehler 'weeknumbers' => $this->getConf('weeknumbers'), 360fb813b30SAndreas Boehler 'workweek' => $this->getConf('workweek'), 3611d5bdcd0SAndreas Boehler 'monday' => $this->getConf('monday'), 3621d5bdcd0SAndreas Boehler 'timeformat' => $this->getConf('timeformat') 363bd883736SAndreas Boehler ); 36434a47953SAndreas Boehler if(is_null($userid)) 36534a47953SAndreas Boehler { 36634a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 36734a47953SAndreas Boehler { 36834a47953SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 36934a47953SAndreas Boehler } 37034a47953SAndreas Boehler else 37134a47953SAndreas Boehler { 37234a47953SAndreas Boehler return $settings; 37334a47953SAndreas Boehler } 37434a47953SAndreas Boehler } 37534a47953SAndreas Boehler 37634a47953SAndreas Boehler if(isset($this->cachedValues['settings'][$userid])) 37734a47953SAndreas Boehler return $this->cachedValues['settings'][$userid]; 37851f4febbSAndreas Boehler $query = "SELECT key, value FROM calendarsettings WHERE userid = ?"; 37951f4febbSAndreas Boehler $res = $this->sqlite->query($query, $userid); 380a495d34cSAndreas Boehler $arr = $this->sqlite->res2arr($res); 381a495d34cSAndreas Boehler foreach($arr as $row) 382a495d34cSAndreas Boehler { 383a495d34cSAndreas Boehler $settings[$row['key']] = $row['value']; 384a495d34cSAndreas Boehler } 385185e2535SAndreas Boehler $this->cachedValues['settings'][$userid] = $settings; 386a495d34cSAndreas Boehler return $settings; 387a495d34cSAndreas Boehler } 388a495d34cSAndreas Boehler 389cb71a62aSAndreas Boehler /** 390cb71a62aSAndreas Boehler * Retrieve the calendar ID based on a page ID from the SQLite table 391cb71a62aSAndreas Boehler * 'pagetocalendarmapping'. 392cb71a62aSAndreas Boehler * 393cb71a62aSAndreas Boehler * @param string $id (optional) The page ID to retrieve the corresponding calendar 394cb71a62aSAndreas Boehler * 395cb71a62aSAndreas Boehler * @return mixed the ID on success, otherwise false 396cb71a62aSAndreas Boehler */ 397a1a3b679SAndreas Boehler public function getCalendarIdForPage($id = null) 398a1a3b679SAndreas Boehler { 399a1a3b679SAndreas Boehler if(is_null($id)) 400a1a3b679SAndreas Boehler { 401a1a3b679SAndreas Boehler global $ID; 402a1a3b679SAndreas Boehler $id = $ID; 403a1a3b679SAndreas Boehler } 404a1a3b679SAndreas Boehler 405185e2535SAndreas Boehler if(isset($this->cachedValues['calid'][$id])) 406185e2535SAndreas Boehler return $this->cachedValues['calid'][$id]; 407185e2535SAndreas Boehler 40851f4febbSAndreas Boehler $query = "SELECT calid FROM pagetocalendarmapping WHERE page = ?"; 40951f4febbSAndreas Boehler $res = $this->sqlite->query($query, $id); 410a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 411a1a3b679SAndreas Boehler if(isset($row['calid'])) 412185e2535SAndreas Boehler { 413185e2535SAndreas Boehler $calid = $row['calid']; 414185e2535SAndreas Boehler $this->cachedValues['calid'] = $calid; 415185e2535SAndreas Boehler return $calid; 416185e2535SAndreas Boehler } 417a1a3b679SAndreas Boehler return false; 418a1a3b679SAndreas Boehler } 419a1a3b679SAndreas Boehler 420cb71a62aSAndreas Boehler /** 421cb71a62aSAndreas Boehler * Retrieve the complete calendar id to page mapping. 422cb71a62aSAndreas Boehler * This is necessary to be able to retrieve a list of 423cb71a62aSAndreas Boehler * calendars for a given user and check the access rights. 424cb71a62aSAndreas Boehler * 425cb71a62aSAndreas Boehler * @return array The mapping array 426cb71a62aSAndreas Boehler */ 427a1a3b679SAndreas Boehler public function getCalendarIdToPageMapping() 428a1a3b679SAndreas Boehler { 429a1a3b679SAndreas Boehler $query = "SELECT calid, page FROM pagetocalendarmapping"; 430a1a3b679SAndreas Boehler $res = $this->sqlite->query($query); 431a1a3b679SAndreas Boehler $arr = $this->sqlite->res2arr($res); 432a1a3b679SAndreas Boehler return $arr; 433a1a3b679SAndreas Boehler } 434a1a3b679SAndreas Boehler 435cb71a62aSAndreas Boehler /** 436cb71a62aSAndreas Boehler * Retrieve all calendar IDs a given user has access to. 437cb71a62aSAndreas Boehler * The user is specified by the principalUri, so the 438cb71a62aSAndreas Boehler * user name is actually split from the URI component. 439cb71a62aSAndreas Boehler * 440cb71a62aSAndreas Boehler * Access rights are checked against DokuWiki's ACL 441cb71a62aSAndreas Boehler * and applied accordingly. 442cb71a62aSAndreas Boehler * 443cb71a62aSAndreas Boehler * @param string $principalUri The principal URI to work on 444cb71a62aSAndreas Boehler * 445cb71a62aSAndreas Boehler * @return array An associative array of calendar IDs 446cb71a62aSAndreas Boehler */ 447a1a3b679SAndreas Boehler public function getCalendarIdsForUser($principalUri) 448a1a3b679SAndreas Boehler { 44934a47953SAndreas Boehler global $auth; 450a1a3b679SAndreas Boehler $user = explode('/', $principalUri); 451a1a3b679SAndreas Boehler $user = end($user); 452a1a3b679SAndreas Boehler $mapping = $this->getCalendarIdToPageMapping(); 453a1a3b679SAndreas Boehler $calids = array(); 45434a47953SAndreas Boehler $ud = $auth->getUserData($user); 45534a47953SAndreas Boehler $groups = $ud['grps']; 456a1a3b679SAndreas Boehler foreach($mapping as $row) 457a1a3b679SAndreas Boehler { 458a1a3b679SAndreas Boehler $id = $row['calid']; 459a1a3b679SAndreas Boehler $page = $row['page']; 46034a47953SAndreas Boehler $acl = auth_aclcheck($page, $user, $groups); 461a1a3b679SAndreas Boehler if($acl >= AUTH_READ) 462a1a3b679SAndreas Boehler { 463a1a3b679SAndreas Boehler $write = $acl > AUTH_READ; 464a1a3b679SAndreas Boehler $calids[$id] = array('readonly' => !$write); 465a1a3b679SAndreas Boehler } 466a1a3b679SAndreas Boehler } 467a1a3b679SAndreas Boehler return $calids; 468a1a3b679SAndreas Boehler } 469a1a3b679SAndreas Boehler 470cb71a62aSAndreas Boehler /** 471cb71a62aSAndreas Boehler * Create a new calendar for a given page ID and set name and description 472cb71a62aSAndreas Boehler * accordingly. Also update the pagetocalendarmapping table on success. 473cb71a62aSAndreas Boehler * 474cb71a62aSAndreas Boehler * @param string $name The calendar's name 475cb71a62aSAndreas Boehler * @param string $description The calendar's description 476cb71a62aSAndreas Boehler * @param string $id (optional) The page ID to work on 477cb71a62aSAndreas Boehler * @param string $userid (optional) The user ID that created the calendar 478cb71a62aSAndreas Boehler * 479cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 480cb71a62aSAndreas Boehler */ 481a1a3b679SAndreas Boehler public function createCalendarForPage($name, $description, $id = null, $userid = null) 482a1a3b679SAndreas Boehler { 483a1a3b679SAndreas Boehler if(is_null($id)) 484a1a3b679SAndreas Boehler { 485a1a3b679SAndreas Boehler global $ID; 486a1a3b679SAndreas Boehler $id = $ID; 487a1a3b679SAndreas Boehler } 488a1a3b679SAndreas Boehler if(is_null($userid)) 48934a47953SAndreas Boehler { 49034a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 49134a47953SAndreas Boehler { 492a1a3b679SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 49334a47953SAndreas Boehler } 49434a47953SAndreas Boehler else 49534a47953SAndreas Boehler { 49634a47953SAndreas Boehler $userid = uniqid('davcal-'); 49734a47953SAndreas Boehler } 49834a47953SAndreas Boehler } 499a1a3b679SAndreas Boehler $values = array('principals/'.$userid, 500a1a3b679SAndreas Boehler $name, 501a1a3b679SAndreas Boehler str_replace(array('/', ' ', ':'), '_', $id), 502a1a3b679SAndreas Boehler $description, 503a1a3b679SAndreas Boehler 'VEVENT,VTODO', 50455a741c0SAndreas Boehler 0, 50555a741c0SAndreas Boehler 1); 50651f4febbSAndreas Boehler $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) ". 50751f4febbSAndreas Boehler "VALUES (?, ?, ?, ?, ?, ?, ?)"; 50851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3], $values[4], $values[5], $values[6]); 50955a741c0SAndreas Boehler if($res === false) 51055a741c0SAndreas Boehler return false; 511cb71a62aSAndreas Boehler 512cb71a62aSAndreas Boehler // Get the new calendar ID 51351f4febbSAndreas Boehler $query = "SELECT id FROM calendars WHERE principaluri = ? AND displayname = ? AND ". 51451f4febbSAndreas Boehler "uri = ? AND description = ?"; 51551f4febbSAndreas Boehler $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3]); 516a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 517cb71a62aSAndreas Boehler 518cb71a62aSAndreas Boehler // Update the pagetocalendarmapping table with the new calendar ID 519a1a3b679SAndreas Boehler if(isset($row['id'])) 520a1a3b679SAndreas Boehler { 52151f4febbSAndreas Boehler $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (?, ?)"; 52251f4febbSAndreas Boehler $res = $this->sqlite->query($query, $id, $row['id']); 52355a741c0SAndreas Boehler return ($res !== false); 524a1a3b679SAndreas Boehler } 525a1a3b679SAndreas Boehler 526a1a3b679SAndreas Boehler return false; 527a1a3b679SAndreas Boehler } 528a1a3b679SAndreas Boehler 529cb71a62aSAndreas Boehler /** 530cb71a62aSAndreas Boehler * Add a new iCal entry for a given page, i.e. a given calendar. 531cb71a62aSAndreas Boehler * 532cb71a62aSAndreas Boehler * The parameter array needs to contain 533cb71a62aSAndreas Boehler * detectedtz => The timezone as detected by the browser 53482a48dfbSAndreas Boehler * currenttz => The timezone in use by the calendar 535cb71a62aSAndreas Boehler * eventfrom => The event's start date 536cb71a62aSAndreas Boehler * eventfromtime => The event's start time 537cb71a62aSAndreas Boehler * eventto => The event's end date 538cb71a62aSAndreas Boehler * eventtotime => The event's end time 539cb71a62aSAndreas Boehler * eventname => The event's name 540cb71a62aSAndreas Boehler * eventdescription => The event's description 541cb71a62aSAndreas Boehler * 542cb71a62aSAndreas Boehler * @param string $id The page ID to work on 543cb71a62aSAndreas Boehler * @param string $user The user who created the calendar 544cb71a62aSAndreas Boehler * @param string $params A parameter array with values to create 545cb71a62aSAndreas Boehler * 546cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 547cb71a62aSAndreas Boehler */ 548a1a3b679SAndreas Boehler public function addCalendarEntryToCalendarForPage($id, $user, $params) 549a1a3b679SAndreas Boehler { 55082a48dfbSAndreas Boehler if($params['currenttz'] !== '' && $params['currenttz'] !== 'local') 55182a48dfbSAndreas Boehler $timezone = new \DateTimeZone($params['currenttz']); 55282a48dfbSAndreas Boehler elseif($params['currenttz'] === 'local') 553a25c89eaSAndreas Boehler $timezone = new \DateTimeZone($params['detectedtz']); 554bd883736SAndreas Boehler else 555bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 556cb71a62aSAndreas Boehler 557cb71a62aSAndreas Boehler // Retrieve dates from settings 558b269830cSAndreas Boehler $startDate = explode('-', $params['eventfrom']); 559b269830cSAndreas Boehler $startTime = explode(':', $params['eventfromtime']); 560b269830cSAndreas Boehler $endDate = explode('-', $params['eventto']); 561b269830cSAndreas Boehler $endTime = explode(':', $params['eventtotime']); 562cb71a62aSAndreas Boehler 563cb71a62aSAndreas Boehler // Load SabreDAV 5649bef4ad8SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 565a1a3b679SAndreas Boehler $vcalendar = new \Sabre\VObject\Component\VCalendar(); 566cb71a62aSAndreas Boehler 567cb71a62aSAndreas Boehler // Add VCalendar, UID and Event Name 568a1a3b679SAndreas Boehler $event = $vcalendar->add('VEVENT'); 569b269830cSAndreas Boehler $uuid = \Sabre\VObject\UUIDUtil::getUUID(); 570b269830cSAndreas Boehler $event->add('UID', $uuid); 571a1a3b679SAndreas Boehler $event->summary = $params['eventname']; 572cb71a62aSAndreas Boehler 573cb71a62aSAndreas Boehler // Add a description if requested 5740eebc909SAndreas Boehler $description = $params['eventdescription']; 5750eebc909SAndreas Boehler if($description !== '') 5760eebc909SAndreas Boehler $event->add('DESCRIPTION', $description); 577cb71a62aSAndreas Boehler 5784ecb526cSAndreas Boehler // Add attachments 5794ecb526cSAndreas Boehler $attachments = $params['attachments']; 58082a48dfbSAndreas Boehler if(!is_null($attachments)) 5814ecb526cSAndreas Boehler foreach($attachments as $attachment) 5824ecb526cSAndreas Boehler $event->add('ATTACH', $attachment); 5834ecb526cSAndreas Boehler 584cb71a62aSAndreas Boehler // Create a timestamp for last modified, created and dtstamp values in UTC 585b269830cSAndreas Boehler $dtStamp = new \DateTime(null, new \DateTimeZone('UTC')); 586b269830cSAndreas Boehler $event->add('DTSTAMP', $dtStamp); 587b269830cSAndreas Boehler $event->add('CREATED', $dtStamp); 588b269830cSAndreas Boehler $event->add('LAST-MODIFIED', $dtStamp); 589cb71a62aSAndreas Boehler 590cb71a62aSAndreas Boehler // Adjust the start date, based on the given timezone information 591b269830cSAndreas Boehler $dtStart = new \DateTime(); 592a25c89eaSAndreas Boehler $dtStart->setTimezone($timezone); 593b269830cSAndreas Boehler $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2])); 594cb71a62aSAndreas Boehler 595cb71a62aSAndreas Boehler // Only add the time values if it's not an allday event 596b269830cSAndreas Boehler if($params['allday'] != '1') 597b269830cSAndreas Boehler $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0); 598cb71a62aSAndreas Boehler 599cb71a62aSAndreas Boehler // Adjust the end date, based on the given timezone information 600b269830cSAndreas Boehler $dtEnd = new \DateTime(); 601a25c89eaSAndreas Boehler $dtEnd->setTimezone($timezone); 602b269830cSAndreas Boehler $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2])); 603cb71a62aSAndreas Boehler 604cb71a62aSAndreas Boehler // Only add the time values if it's not an allday event 605b269830cSAndreas Boehler if($params['allday'] != '1') 606b269830cSAndreas Boehler $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0); 607cb71a62aSAndreas Boehler 608b269830cSAndreas Boehler // According to the VCal spec, we need to add a whole day here 609b269830cSAndreas Boehler if($params['allday'] == '1') 610b269830cSAndreas Boehler $dtEnd->add(new \DateInterval('P1D')); 611cb71a62aSAndreas Boehler 612cb71a62aSAndreas Boehler // Really add Start and End events 613b269830cSAndreas Boehler $dtStartEv = $event->add('DTSTART', $dtStart); 614b269830cSAndreas Boehler $dtEndEv = $event->add('DTEND', $dtEnd); 615cb71a62aSAndreas Boehler 616cb71a62aSAndreas Boehler // Adjust the DATE format for allday events 617b269830cSAndreas Boehler if($params['allday'] == '1') 618b269830cSAndreas Boehler { 619b269830cSAndreas Boehler $dtStartEv['VALUE'] = 'DATE'; 620b269830cSAndreas Boehler $dtEndEv['VALUE'] = 'DATE'; 621b269830cSAndreas Boehler } 622cb71a62aSAndreas Boehler 623cb71a62aSAndreas Boehler // Actually add the values to the database 624a1a3b679SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 625a1a3b679SAndreas Boehler $uri = uniqid('dokuwiki-').'.ics'; 626a1a3b679SAndreas Boehler $now = new DateTime(); 627a1a3b679SAndreas Boehler $eventStr = $vcalendar->serialize(); 628a1a3b679SAndreas Boehler 62951f4febbSAndreas Boehler $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 63051f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid, $uri, $eventStr, $now->getTimestamp(), 'VEVENT', 63151f4febbSAndreas Boehler $event->DTSTART->getDateTime()->getTimeStamp(), $event->DTEND->getDateTime()->getTimeStamp(), 63251f4febbSAndreas Boehler strlen($eventStr), md5($eventStr), $uuid); 633cb71a62aSAndreas Boehler 634cb71a62aSAndreas Boehler // If successfully, update the sync token database 63555a741c0SAndreas Boehler if($res !== false) 63655a741c0SAndreas Boehler { 63755a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'added'); 638a1a3b679SAndreas Boehler return true; 639a1a3b679SAndreas Boehler } 64055a741c0SAndreas Boehler return false; 64155a741c0SAndreas Boehler } 642a1a3b679SAndreas Boehler 643cb71a62aSAndreas Boehler /** 644cb71a62aSAndreas Boehler * Retrieve the calendar settings of a given calendar id 645cb71a62aSAndreas Boehler * 646cb71a62aSAndreas Boehler * @param string $calid The calendar ID 647cb71a62aSAndreas Boehler * 648cb71a62aSAndreas Boehler * @return array The calendar settings array 649cb71a62aSAndreas Boehler */ 650b269830cSAndreas Boehler public function getCalendarSettings($calid) 651b269830cSAndreas Boehler { 65251f4febbSAndreas Boehler $query = "SELECT principaluri, calendarcolor, displayname, uri, description, components, transparent, synctoken FROM calendars WHERE id= ? "; 65351f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 654b269830cSAndreas Boehler $row = $this->sqlite->res2row($res); 655b269830cSAndreas Boehler return $row; 656b269830cSAndreas Boehler } 657b269830cSAndreas Boehler 658cb71a62aSAndreas Boehler /** 659cb71a62aSAndreas Boehler * Retrieve all events that are within a given date range, 660cb71a62aSAndreas Boehler * based on the timezone setting. 661cb71a62aSAndreas Boehler * 662cb71a62aSAndreas Boehler * There is also support for retrieving recurring events, 663cb71a62aSAndreas Boehler * using Sabre's VObject Iterator. Recurring events are represented 664cb71a62aSAndreas Boehler * as individual calendar entries with the same UID. 665cb71a62aSAndreas Boehler * 666cb71a62aSAndreas Boehler * @param string $id The page ID to work with 667cb71a62aSAndreas Boehler * @param string $user The user ID to work with 668cb71a62aSAndreas Boehler * @param string $startDate The start date as a string 669cb71a62aSAndreas Boehler * @param string $endDate The end date as a string 6704a2bf5eeSAndreas Boehler * @param string $color (optional) The calendar's color 671cb71a62aSAndreas Boehler * 672cb71a62aSAndreas Boehler * @return array An array containing the calendar entries. 673cb71a62aSAndreas Boehler */ 6744a2bf5eeSAndreas Boehler public function getEventsWithinDateRange($id, $user, $startDate, $endDate, $timezone, $color = null) 675a1a3b679SAndreas Boehler { 67682a48dfbSAndreas Boehler if($timezone !== '' && $timezone !== 'local') 67782a48dfbSAndreas Boehler $timezone = new \DateTimeZone($timezone); 678bd883736SAndreas Boehler else 679bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 680a1a3b679SAndreas Boehler $data = array(); 681cb71a62aSAndreas Boehler 682a469597cSAndreas Boehler $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid = ?"; 683a469597cSAndreas Boehler $startTs = null; 684a469597cSAndreas Boehler $endTs = null; 685a469597cSAndreas Boehler if($startDate !== null) 686a469597cSAndreas Boehler { 687a1a3b679SAndreas Boehler $startTs = new \DateTime($startDate); 688a469597cSAndreas Boehler $query .= " AND lastoccurence > ".$this->sqlite->quote_string($startTs->getTimestamp()); 689a469597cSAndreas Boehler } 690a469597cSAndreas Boehler if($endDate !== null) 691a469597cSAndreas Boehler { 692a1a3b679SAndreas Boehler $endTs = new \DateTime($endDate); 693a469597cSAndreas Boehler $query .= " AND firstoccurence < ".$this->sqlite->quote_string($endTs->getTimestamp()); 694a469597cSAndreas Boehler } 695cb71a62aSAndreas Boehler 696*0b805092SAndreas Boehler // Load SabreDAV 697*0b805092SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 698*0b805092SAndreas Boehler 699*0b805092SAndreas Boehler if(strpos($id, 'webdav://') === 0) 700*0b805092SAndreas Boehler { 701*0b805092SAndreas Boehler // FIXME: This returns *all* events, not only those within the 702*0b805092SAndreas Boehler // requested date range. 703*0b805092SAndreas Boehler $wdc =& plugin_load('helper', 'webdavclient'); 704*0b805092SAndreas Boehler if(is_null($wdc)) 705*0b805092SAndreas Boehler return $data; 706*0b805092SAndreas Boehler $connectionId = str_replace('webdav://', '', $id); 707*0b805092SAndreas Boehler $arr = $wdc->getCalendarEntries($connectionId, $startDate, $endDate); 708*0b805092SAndreas Boehler } 709*0b805092SAndreas Boehler else 710*0b805092SAndreas Boehler { 711*0b805092SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 712*0b805092SAndreas Boehler if(is_null($color)) 713*0b805092SAndreas Boehler $color = $this->getCalendarColorForCalendar($calid); 714*0b805092SAndreas Boehler 715cb71a62aSAndreas Boehler // Retrieve matching calendar objects 716a469597cSAndreas Boehler $res = $this->sqlite->query($query, $calid); 717a1a3b679SAndreas Boehler $arr = $this->sqlite->res2arr($res); 718*0b805092SAndreas Boehler } 719cb71a62aSAndreas Boehler 720cb71a62aSAndreas Boehler // Parse individual calendar entries 721a1a3b679SAndreas Boehler foreach($arr as $row) 722a1a3b679SAndreas Boehler { 723a1a3b679SAndreas Boehler if(isset($row['calendardata'])) 724a1a3b679SAndreas Boehler { 725b269830cSAndreas Boehler $entry = array(); 726a1a3b679SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($row['calendardata']); 727ebc4eb57SAndreas Boehler $recurrence = $vcal->VEVENT->RRULE; 728cb71a62aSAndreas Boehler // If it is a recurring event, pass it through Sabre's EventIterator 729ebc4eb57SAndreas Boehler if($recurrence != null) 730ebc4eb57SAndreas Boehler { 731ebc4eb57SAndreas Boehler $rEvents = new \Sabre\VObject\Recur\EventIterator(array($vcal->VEVENT)); 732ebc4eb57SAndreas Boehler $rEvents->rewind(); 733e9b7d302SAndreas Boehler while($rEvents->valid()) 734ebc4eb57SAndreas Boehler { 735ebc4eb57SAndreas Boehler $event = $rEvents->getEventObject(); 736cb71a62aSAndreas Boehler // If we are after the given time range, exit 737a469597cSAndreas Boehler if(($endTs !== null) && ($rEvents->getDtStart()->getTimestamp() > $endTs->getTimestamp())) 738e9b7d302SAndreas Boehler break; 739cb71a62aSAndreas Boehler 740cb71a62aSAndreas Boehler // If we are before the given time range, continue 741a469597cSAndreas Boehler if(($startTs != null) && ($rEvents->getDtEnd()->getTimestamp() < $startTs->getTimestamp())) 742ebc4eb57SAndreas Boehler { 743ebc4eb57SAndreas Boehler $rEvents->next(); 744ebc4eb57SAndreas Boehler continue; 745ebc4eb57SAndreas Boehler } 746cb71a62aSAndreas Boehler 747cb71a62aSAndreas Boehler // If we are within the given time range, parse the event 748185e2535SAndreas Boehler $data[] = $this->convertIcalDataToEntry($event, $id, $timezone, $row['uid'], $color, true); 749ebc4eb57SAndreas Boehler $rEvents->next(); 750ebc4eb57SAndreas Boehler } 751ebc4eb57SAndreas Boehler } 752ebc4eb57SAndreas Boehler else 753185e2535SAndreas Boehler $data[] = $this->convertIcalDataToEntry($vcal->VEVENT, $id, $timezone, $row['uid'], $color); 754ebc4eb57SAndreas Boehler } 755ebc4eb57SAndreas Boehler } 756ebc4eb57SAndreas Boehler return $data; 757ebc4eb57SAndreas Boehler } 758ebc4eb57SAndreas Boehler 759cb71a62aSAndreas Boehler /** 760cb71a62aSAndreas Boehler * Helper function that parses the iCal data of a VEVENT to a calendar entry. 761cb71a62aSAndreas Boehler * 762cb71a62aSAndreas Boehler * @param \Sabre\VObject\VEvent $event The event to parse 763cb71a62aSAndreas Boehler * @param \DateTimeZone $timezone The timezone object 764cb71a62aSAndreas Boehler * @param string $uid The entry's UID 7653c86dda8SAndreas Boehler * @param boolean $recurring (optional) Set to true to define a recurring event 766cb71a62aSAndreas Boehler * 767cb71a62aSAndreas Boehler * @return array The parse calendar entry 768cb71a62aSAndreas Boehler */ 769185e2535SAndreas Boehler private function convertIcalDataToEntry($event, $page, $timezone, $uid, $color, $recurring = false) 770ebc4eb57SAndreas Boehler { 771ebc4eb57SAndreas Boehler $entry = array(); 772ebc4eb57SAndreas Boehler $start = $event->DTSTART; 773cb71a62aSAndreas Boehler // Parse only if the start date/time is present 774b269830cSAndreas Boehler if($start !== null) 775b269830cSAndreas Boehler { 776b269830cSAndreas Boehler $dtStart = $start->getDateTime(); 777b269830cSAndreas Boehler $dtStart->setTimezone($timezone); 778bf0ad2b4SAndreas Boehler 779bf0ad2b4SAndreas Boehler // moment.js doesn't like times be given even if 780bf0ad2b4SAndreas Boehler // allDay is set to true 781bf0ad2b4SAndreas Boehler // This should fix T23 782b269830cSAndreas Boehler if($start['VALUE'] == 'DATE') 783bf0ad2b4SAndreas Boehler { 784b269830cSAndreas Boehler $entry['allDay'] = true; 785bf0ad2b4SAndreas Boehler $entry['start'] = $dtStart->format("Y-m-d"); 786bf0ad2b4SAndreas Boehler } 787b269830cSAndreas Boehler else 788bf0ad2b4SAndreas Boehler { 789b269830cSAndreas Boehler $entry['allDay'] = false; 790bf0ad2b4SAndreas Boehler $entry['start'] = $dtStart->format(\DateTime::ATOM); 791bf0ad2b4SAndreas Boehler } 792b269830cSAndreas Boehler } 793ebc4eb57SAndreas Boehler $end = $event->DTEND; 794bf0ad2b4SAndreas Boehler // Parse only if the end date/time is present 795b269830cSAndreas Boehler if($end !== null) 796b269830cSAndreas Boehler { 797b269830cSAndreas Boehler $dtEnd = $end->getDateTime(); 798b269830cSAndreas Boehler $dtEnd->setTimezone($timezone); 799bf0ad2b4SAndreas Boehler if($end['VALUE'] == 'DATE') 800bf0ad2b4SAndreas Boehler $entry['end'] = $dtEnd->format("Y-m-d"); 801bf0ad2b4SAndreas Boehler else 802b269830cSAndreas Boehler $entry['end'] = $dtEnd->format(\DateTime::ATOM); 803b269830cSAndreas Boehler } 804ebc4eb57SAndreas Boehler $description = $event->DESCRIPTION; 8050eebc909SAndreas Boehler if($description !== null) 8060eebc909SAndreas Boehler $entry['description'] = (string)$description; 8070eebc909SAndreas Boehler else 8080eebc909SAndreas Boehler $entry['description'] = ''; 8094ecb526cSAndreas Boehler $attachments = $event->ATTACH; 8104ecb526cSAndreas Boehler if($attachments !== null) 8114ecb526cSAndreas Boehler { 8124ecb526cSAndreas Boehler $entry['attachments'] = array(); 8134ecb526cSAndreas Boehler foreach($attachments as $attachment) 8144ecb526cSAndreas Boehler $entry['attachments'][] = (string)$attachment; 8154ecb526cSAndreas Boehler } 816ebc4eb57SAndreas Boehler $entry['title'] = (string)$event->summary; 817ebc4eb57SAndreas Boehler $entry['id'] = $uid; 818185e2535SAndreas Boehler $entry['page'] = $page; 819185e2535SAndreas Boehler $entry['color'] = $color; 8203c86dda8SAndreas Boehler $entry['recurring'] = $recurring; 821185e2535SAndreas Boehler 822ebc4eb57SAndreas Boehler return $entry; 823a1a3b679SAndreas Boehler } 824a1a3b679SAndreas Boehler 825cb71a62aSAndreas Boehler /** 826cb71a62aSAndreas Boehler * Retrieve an event by its UID 827cb71a62aSAndreas Boehler * 828cb71a62aSAndreas Boehler * @param string $uid The event's UID 829cb71a62aSAndreas Boehler * 830cb71a62aSAndreas Boehler * @return mixed The table row with the given event 831cb71a62aSAndreas Boehler */ 832a1a3b679SAndreas Boehler public function getEventWithUid($uid) 833a1a3b679SAndreas Boehler { 83451f4febbSAndreas Boehler $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid = ?"; 83551f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uid); 836a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 837a1a3b679SAndreas Boehler return $row; 838a1a3b679SAndreas Boehler } 839a1a3b679SAndreas Boehler 840cb71a62aSAndreas Boehler /** 841cb71a62aSAndreas Boehler * Retrieve all calendar events for a given calendar ID 842cb71a62aSAndreas Boehler * 843cb71a62aSAndreas Boehler * @param string $calid The calendar's ID 844cb71a62aSAndreas Boehler * 845cb71a62aSAndreas Boehler * @return array An array containing all calendar data 846cb71a62aSAndreas Boehler */ 847f69bb449SAndreas Boehler public function getAllCalendarEvents($calid) 848f69bb449SAndreas Boehler { 8497e0b8590SAndreas Boehler $query = "SELECT calendardata, uid, componenttype, uri FROM calendarobjects WHERE calendarid = ?"; 85051f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 851f69bb449SAndreas Boehler $arr = $this->sqlite->res2arr($res); 852f69bb449SAndreas Boehler return $arr; 853f69bb449SAndreas Boehler } 854f69bb449SAndreas Boehler 855cb71a62aSAndreas Boehler /** 856cb71a62aSAndreas Boehler * Edit a calendar entry for a page, given by its parameters. 857cb71a62aSAndreas Boehler * The params array has the same format as @see addCalendarEntryForPage 858cb71a62aSAndreas Boehler * 859cb71a62aSAndreas Boehler * @param string $id The page's ID to work on 860cb71a62aSAndreas Boehler * @param string $user The user's ID to work on 861cb71a62aSAndreas Boehler * @param array $params The parameter array for the edited calendar event 862cb71a62aSAndreas Boehler * 863cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 864cb71a62aSAndreas Boehler */ 865a1a3b679SAndreas Boehler public function editCalendarEntryForPage($id, $user, $params) 866a1a3b679SAndreas Boehler { 86782a48dfbSAndreas Boehler if($params['currenttz'] !== '' && $params['currenttz'] !== 'local') 86882a48dfbSAndreas Boehler $timezone = new \DateTimeZone($params['currenttz']); 86982a48dfbSAndreas Boehler elseif($params['currenttz'] === 'local') 870a25c89eaSAndreas Boehler $timezone = new \DateTimeZone($params['detectedtz']); 871bd883736SAndreas Boehler else 872bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 873cb71a62aSAndreas Boehler 874cb71a62aSAndreas Boehler // Parse dates 875b269830cSAndreas Boehler $startDate = explode('-', $params['eventfrom']); 876b269830cSAndreas Boehler $startTime = explode(':', $params['eventfromtime']); 877b269830cSAndreas Boehler $endDate = explode('-', $params['eventto']); 878b269830cSAndreas Boehler $endTime = explode(':', $params['eventtotime']); 879cb71a62aSAndreas Boehler 880cb71a62aSAndreas Boehler // Retrieve the existing event based on the UID 88155a741c0SAndreas Boehler $uid = $params['uid']; 88255a741c0SAndreas Boehler $event = $this->getEventWithUid($uid); 883cb71a62aSAndreas Boehler 884cb71a62aSAndreas Boehler // Load SabreDAV 8859bef4ad8SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 886a1a3b679SAndreas Boehler if(!isset($event['calendardata'])) 887a1a3b679SAndreas Boehler return false; 88855a741c0SAndreas Boehler $uri = $event['uri']; 88955a741c0SAndreas Boehler $calid = $event['calendarid']; 890cb71a62aSAndreas Boehler 891cb71a62aSAndreas Boehler // Parse the existing event 892a1a3b679SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($event['calendardata']); 893b269830cSAndreas Boehler $vevent = $vcal->VEVENT; 894cb71a62aSAndreas Boehler 895cb71a62aSAndreas Boehler // Set the new event values 896b269830cSAndreas Boehler $vevent->summary = $params['eventname']; 897b269830cSAndreas Boehler $dtStamp = new \DateTime(null, new \DateTimeZone('UTC')); 8980eebc909SAndreas Boehler $description = $params['eventdescription']; 899cb71a62aSAndreas Boehler 900cb71a62aSAndreas Boehler // Remove existing timestamps to overwrite them 9010eebc909SAndreas Boehler $vevent->remove('DESCRIPTION'); 902b269830cSAndreas Boehler $vevent->remove('DTSTAMP'); 903b269830cSAndreas Boehler $vevent->remove('LAST-MODIFIED'); 9044ecb526cSAndreas Boehler $vevent->remove('ATTACH'); 905cb71a62aSAndreas Boehler 906cb71a62aSAndreas Boehler // Add new time stamps and description 907b269830cSAndreas Boehler $vevent->add('DTSTAMP', $dtStamp); 908b269830cSAndreas Boehler $vevent->add('LAST-MODIFIED', $dtStamp); 9090eebc909SAndreas Boehler if($description !== '') 9100eebc909SAndreas Boehler $vevent->add('DESCRIPTION', $description); 911cb71a62aSAndreas Boehler 9124ecb526cSAndreas Boehler // Add attachments 9134ecb526cSAndreas Boehler $attachments = $params['attachments']; 91482a48dfbSAndreas Boehler if(!is_null($attachments)) 9154ecb526cSAndreas Boehler foreach($attachments as $attachment) 9164ecb526cSAndreas Boehler $vevent->add('ATTACH', $attachment); 9174ecb526cSAndreas Boehler 918cb71a62aSAndreas Boehler // Setup DTSTART 919b269830cSAndreas Boehler $dtStart = new \DateTime(); 920a25c89eaSAndreas Boehler $dtStart->setTimezone($timezone); 921b269830cSAndreas Boehler $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2])); 922b269830cSAndreas Boehler if($params['allday'] != '1') 923b269830cSAndreas Boehler $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0); 924cb71a62aSAndreas Boehler 9254ecb526cSAndreas Boehler // Setup DTEND 926b269830cSAndreas Boehler $dtEnd = new \DateTime(); 927a25c89eaSAndreas Boehler $dtEnd->setTimezone($timezone); 928b269830cSAndreas Boehler $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2])); 929b269830cSAndreas Boehler if($params['allday'] != '1') 930b269830cSAndreas Boehler $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0); 931cb71a62aSAndreas Boehler 932b269830cSAndreas Boehler // According to the VCal spec, we need to add a whole day here 933b269830cSAndreas Boehler if($params['allday'] == '1') 934b269830cSAndreas Boehler $dtEnd->add(new \DateInterval('P1D')); 935b269830cSAndreas Boehler $vevent->remove('DTSTART'); 936b269830cSAndreas Boehler $vevent->remove('DTEND'); 937b269830cSAndreas Boehler $dtStartEv = $vevent->add('DTSTART', $dtStart); 938b269830cSAndreas Boehler $dtEndEv = $vevent->add('DTEND', $dtEnd); 939cb71a62aSAndreas Boehler 940cb71a62aSAndreas Boehler // Remove the time for allday events 941b269830cSAndreas Boehler if($params['allday'] == '1') 942b269830cSAndreas Boehler { 943b269830cSAndreas Boehler $dtStartEv['VALUE'] = 'DATE'; 944b269830cSAndreas Boehler $dtEndEv['VALUE'] = 'DATE'; 945b269830cSAndreas Boehler } 946a1a3b679SAndreas Boehler $now = new DateTime(); 947a1a3b679SAndreas Boehler $eventStr = $vcal->serialize(); 948cb71a62aSAndreas Boehler // Actually write to the database 94951f4febbSAndreas Boehler $query = "UPDATE calendarobjects SET calendardata = ?, lastmodified = ?, ". 95051f4febbSAndreas Boehler "firstoccurence = ?, lastoccurence = ?, size = ?, etag = ? WHERE uid = ?"; 95151f4febbSAndreas Boehler $res = $this->sqlite->query($query, $eventStr, $now->getTimestamp(), $dtStart->getTimestamp(), 95251f4febbSAndreas Boehler $dtEnd->getTimestamp(), strlen($eventStr), md5($eventStr), $uid); 95355a741c0SAndreas Boehler if($res !== false) 95455a741c0SAndreas Boehler { 95555a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'modified'); 956a1a3b679SAndreas Boehler return true; 957a1a3b679SAndreas Boehler } 95855a741c0SAndreas Boehler return false; 95955a741c0SAndreas Boehler } 960a1a3b679SAndreas Boehler 961cb71a62aSAndreas Boehler /** 962cb71a62aSAndreas Boehler * Delete a calendar entry for a given page. Actually, the event is removed 963cb71a62aSAndreas Boehler * based on the entry's UID, so that page ID is no used. 964cb71a62aSAndreas Boehler * 965cb71a62aSAndreas Boehler * @param string $id The page's ID (unused) 966cb71a62aSAndreas Boehler * @param array $params The parameter array to work with 967cb71a62aSAndreas Boehler * 968cb71a62aSAndreas Boehler * @return boolean True 969cb71a62aSAndreas Boehler */ 970a1a3b679SAndreas Boehler public function deleteCalendarEntryForPage($id, $params) 971a1a3b679SAndreas Boehler { 972a1a3b679SAndreas Boehler $uid = $params['uid']; 97355a741c0SAndreas Boehler $event = $this->getEventWithUid($uid); 9742c14b82bSAndreas Boehler $calid = $event['calendarid']; 97555a741c0SAndreas Boehler $uri = $event['uri']; 97651f4febbSAndreas Boehler $query = "DELETE FROM calendarobjects WHERE uid = ?"; 97751f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uid); 97855a741c0SAndreas Boehler if($res !== false) 97955a741c0SAndreas Boehler { 98055a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'deleted'); 98155a741c0SAndreas Boehler } 982a1a3b679SAndreas Boehler return true; 983a1a3b679SAndreas Boehler } 984a1a3b679SAndreas Boehler 985cb71a62aSAndreas Boehler /** 986cb71a62aSAndreas Boehler * Retrieve the current sync token for a calendar 987cb71a62aSAndreas Boehler * 988cb71a62aSAndreas Boehler * @param string $calid The calendar id 989cb71a62aSAndreas Boehler * 990cb71a62aSAndreas Boehler * @return mixed The synctoken or false 991cb71a62aSAndreas Boehler */ 99255a741c0SAndreas Boehler public function getSyncTokenForCalendar($calid) 99355a741c0SAndreas Boehler { 994b269830cSAndreas Boehler $row = $this->getCalendarSettings($calid); 99555a741c0SAndreas Boehler if(isset($row['synctoken'])) 99655a741c0SAndreas Boehler return $row['synctoken']; 99755a741c0SAndreas Boehler return false; 99855a741c0SAndreas Boehler } 99955a741c0SAndreas Boehler 1000cb71a62aSAndreas Boehler /** 1001cb71a62aSAndreas Boehler * Helper function to convert the operation name to 1002cb71a62aSAndreas Boehler * an operation code as stored in the database 1003cb71a62aSAndreas Boehler * 1004cb71a62aSAndreas Boehler * @param string $operationName The operation name 1005cb71a62aSAndreas Boehler * 1006cb71a62aSAndreas Boehler * @return mixed The operation code or false 1007cb71a62aSAndreas Boehler */ 100855a741c0SAndreas Boehler public function operationNameToOperation($operationName) 100955a741c0SAndreas Boehler { 101055a741c0SAndreas Boehler switch($operationName) 101155a741c0SAndreas Boehler { 101255a741c0SAndreas Boehler case 'added': 101355a741c0SAndreas Boehler return 1; 101455a741c0SAndreas Boehler break; 101555a741c0SAndreas Boehler case 'modified': 101655a741c0SAndreas Boehler return 2; 101755a741c0SAndreas Boehler break; 101855a741c0SAndreas Boehler case 'deleted': 101955a741c0SAndreas Boehler return 3; 102055a741c0SAndreas Boehler break; 102155a741c0SAndreas Boehler } 102255a741c0SAndreas Boehler return false; 102355a741c0SAndreas Boehler } 102455a741c0SAndreas Boehler 1025cb71a62aSAndreas Boehler /** 1026cb71a62aSAndreas Boehler * Update the sync token log based on the calendar id and the 1027cb71a62aSAndreas Boehler * operation that was performed. 1028cb71a62aSAndreas Boehler * 1029cb71a62aSAndreas Boehler * @param string $calid The calendar ID that was modified 1030cb71a62aSAndreas Boehler * @param string $uri The calendar URI that was modified 1031cb71a62aSAndreas Boehler * @param string $operation The operation that was performed 1032cb71a62aSAndreas Boehler * 1033cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 1034cb71a62aSAndreas Boehler */ 103555a741c0SAndreas Boehler private function updateSyncTokenLog($calid, $uri, $operation) 103655a741c0SAndreas Boehler { 103755a741c0SAndreas Boehler $currentToken = $this->getSyncTokenForCalendar($calid); 103855a741c0SAndreas Boehler $operationCode = $this->operationNameToOperation($operation); 103955a741c0SAndreas Boehler if(($operationCode === false) || ($currentToken === false)) 104055a741c0SAndreas Boehler return false; 104155a741c0SAndreas Boehler $values = array($uri, 104255a741c0SAndreas Boehler $currentToken, 104355a741c0SAndreas Boehler $calid, 104455a741c0SAndreas Boehler $operationCode 104555a741c0SAndreas Boehler ); 104651f4febbSAndreas Boehler $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(?, ?, ?, ?)"; 104751f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uri, $currentToken, $calid, $operationCode); 104855a741c0SAndreas Boehler if($res === false) 104955a741c0SAndreas Boehler return false; 105055a741c0SAndreas Boehler $currentToken++; 105151f4febbSAndreas Boehler $query = "UPDATE calendars SET synctoken = ? WHERE id = ?"; 105251f4febbSAndreas Boehler $res = $this->sqlite->query($query, $currentToken, $calid); 105355a741c0SAndreas Boehler return ($res !== false); 105455a741c0SAndreas Boehler } 105555a741c0SAndreas Boehler 1056cb71a62aSAndreas Boehler /** 1057cb71a62aSAndreas Boehler * Return the sync URL for a given Page, i.e. a calendar 1058cb71a62aSAndreas Boehler * 1059cb71a62aSAndreas Boehler * @param string $id The page's ID 1060cb71a62aSAndreas Boehler * @param string $user (optional) The user's ID 1061cb71a62aSAndreas Boehler * 1062cb71a62aSAndreas Boehler * @return mixed The sync url or false 1063cb71a62aSAndreas Boehler */ 1064b269830cSAndreas Boehler public function getSyncUrlForPage($id, $user = null) 1065b269830cSAndreas Boehler { 106634a47953SAndreas Boehler if(is_null($userid)) 106734a47953SAndreas Boehler { 106834a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 106934a47953SAndreas Boehler { 107034a47953SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 107134a47953SAndreas Boehler } 107234a47953SAndreas Boehler else 107334a47953SAndreas Boehler { 107434a47953SAndreas Boehler return false; 107534a47953SAndreas Boehler } 107634a47953SAndreas Boehler } 1077b269830cSAndreas Boehler 1078b269830cSAndreas Boehler $calid = $this->getCalendarIdForPage($id); 1079b269830cSAndreas Boehler if($calid === false) 1080b269830cSAndreas Boehler return false; 1081b269830cSAndreas Boehler 1082b269830cSAndreas Boehler $calsettings = $this->getCalendarSettings($calid); 1083b269830cSAndreas Boehler if(!isset($calsettings['uri'])) 1084b269830cSAndreas Boehler return false; 1085b269830cSAndreas Boehler 1086b269830cSAndreas Boehler $syncurl = DOKU_URL.'lib/plugins/davcal/calendarserver.php/calendars/'.$user.'/'.$calsettings['uri']; 1087b269830cSAndreas Boehler return $syncurl; 1088b269830cSAndreas Boehler } 1089b269830cSAndreas Boehler 1090cb71a62aSAndreas Boehler /** 1091cb71a62aSAndreas Boehler * Return the private calendar's URL for a given page 1092cb71a62aSAndreas Boehler * 1093cb71a62aSAndreas Boehler * @param string $id the page ID 1094cb71a62aSAndreas Boehler * 1095cb71a62aSAndreas Boehler * @return mixed The private URL or false 1096cb71a62aSAndreas Boehler */ 1097f69bb449SAndreas Boehler public function getPrivateURLForPage($id) 1098f69bb449SAndreas Boehler { 1099f69bb449SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 1100f69bb449SAndreas Boehler if($calid === false) 1101f69bb449SAndreas Boehler return false; 1102f69bb449SAndreas Boehler 1103f69bb449SAndreas Boehler return $this->getPrivateURLForCalendar($calid); 1104f69bb449SAndreas Boehler } 1105f69bb449SAndreas Boehler 1106cb71a62aSAndreas Boehler /** 1107cb71a62aSAndreas Boehler * Return the private calendar's URL for a given calendar ID 1108cb71a62aSAndreas Boehler * 1109cb71a62aSAndreas Boehler * @param string $calid The calendar's ID 1110cb71a62aSAndreas Boehler * 1111cb71a62aSAndreas Boehler * @return mixed The private URL or false 1112cb71a62aSAndreas Boehler */ 1113f69bb449SAndreas Boehler public function getPrivateURLForCalendar($calid) 1114f69bb449SAndreas Boehler { 1115185e2535SAndreas Boehler if(isset($this->cachedValues['privateurl'][$calid])) 1116185e2535SAndreas Boehler return $this->cachedValues['privateurl'][$calid]; 111751f4febbSAndreas Boehler $query = "SELECT url FROM calendartoprivateurlmapping WHERE calid = ?"; 111851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 1119f69bb449SAndreas Boehler $row = $this->sqlite->res2row($res); 1120f69bb449SAndreas Boehler if(!isset($row['url'])) 1121f69bb449SAndreas Boehler { 1122f69bb449SAndreas Boehler $url = uniqid("dokuwiki-").".ics"; 112351f4febbSAndreas Boehler $query = "INSERT INTO calendartoprivateurlmapping (url, calid) VALUES(?, ?)"; 112451f4febbSAndreas Boehler $res = $this->sqlite->query($query, $url, $calid); 1125f69bb449SAndreas Boehler if($res === false) 1126f69bb449SAndreas Boehler return false; 1127f69bb449SAndreas Boehler } 1128f69bb449SAndreas Boehler else 1129f69bb449SAndreas Boehler { 1130f69bb449SAndreas Boehler $url = $row['url']; 1131f69bb449SAndreas Boehler } 1132185e2535SAndreas Boehler 1133185e2535SAndreas Boehler $url = DOKU_URL.'lib/plugins/davcal/ics.php/'.$url; 1134185e2535SAndreas Boehler $this->cachedValues['privateurl'][$calid] = $url; 1135185e2535SAndreas Boehler return $url; 1136f69bb449SAndreas Boehler } 1137f69bb449SAndreas Boehler 1138cb71a62aSAndreas Boehler /** 1139cb71a62aSAndreas Boehler * Retrieve the calendar ID for a given private calendar URL 1140cb71a62aSAndreas Boehler * 1141cb71a62aSAndreas Boehler * @param string $url The private URL 1142cb71a62aSAndreas Boehler * 1143cb71a62aSAndreas Boehler * @return mixed The calendar ID or false 1144cb71a62aSAndreas Boehler */ 1145f69bb449SAndreas Boehler public function getCalendarForPrivateURL($url) 1146f69bb449SAndreas Boehler { 114751f4febbSAndreas Boehler $query = "SELECT calid FROM calendartoprivateurlmapping WHERE url = ?"; 114851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $url); 1149f69bb449SAndreas Boehler $row = $this->sqlite->res2row($res); 1150f69bb449SAndreas Boehler if(!isset($row['calid'])) 1151f69bb449SAndreas Boehler return false; 1152f69bb449SAndreas Boehler return $row['calid']; 1153f69bb449SAndreas Boehler } 1154f69bb449SAndreas Boehler 1155cb71a62aSAndreas Boehler /** 1156cb71a62aSAndreas Boehler * Return a given calendar as ICS feed, i.e. all events in one ICS file. 1157cb71a62aSAndreas Boehler * 11587e0b8590SAndreas Boehler * @param string $calid The calendar ID to retrieve 1159cb71a62aSAndreas Boehler * 1160cb71a62aSAndreas Boehler * @return mixed The calendar events as string or false 1161cb71a62aSAndreas Boehler */ 1162f69bb449SAndreas Boehler public function getCalendarAsICSFeed($calid) 1163f69bb449SAndreas Boehler { 1164f69bb449SAndreas Boehler $calSettings = $this->getCalendarSettings($calid); 1165f69bb449SAndreas Boehler if($calSettings === false) 1166f69bb449SAndreas Boehler return false; 1167f69bb449SAndreas Boehler $events = $this->getAllCalendarEvents($calid); 1168f69bb449SAndreas Boehler if($events === false) 1169f69bb449SAndreas Boehler return false; 1170f69bb449SAndreas Boehler 11717e0b8590SAndreas Boehler // Load SabreDAV 11727e0b8590SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 11737e0b8590SAndreas Boehler $out = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//DAVCal//DAVCal for DokuWiki//EN\r\nCALSCALE:GREGORIAN\r\nX-WR-CALNAME:"; 11747e0b8590SAndreas Boehler $out .= $calSettings['displayname']."\r\n"; 1175f69bb449SAndreas Boehler foreach($events as $event) 1176f69bb449SAndreas Boehler { 11777e0b8590SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($event['calendardata']); 11787e0b8590SAndreas Boehler $evt = $vcal->VEVENT; 11797e0b8590SAndreas Boehler $out .= $evt->serialize(); 1180f69bb449SAndreas Boehler } 11817e0b8590SAndreas Boehler $out .= "END:VCALENDAR\r\n"; 1182f69bb449SAndreas Boehler return $out; 1183f69bb449SAndreas Boehler } 1184f69bb449SAndreas Boehler 11857c7c6b0bSAndreas Boehler /** 11867c7c6b0bSAndreas Boehler * Retrieve a configuration option for the plugin 11877c7c6b0bSAndreas Boehler * 11887c7c6b0bSAndreas Boehler * @param string $key The key to query 118921d04f73SAndreas Boehler * @return mixed The option set, null if not found 11907c7c6b0bSAndreas Boehler */ 11917c7c6b0bSAndreas Boehler public function getConfig($key) 11927c7c6b0bSAndreas Boehler { 11937c7c6b0bSAndreas Boehler return $this->getConf($key); 11947c7c6b0bSAndreas Boehler } 11957c7c6b0bSAndreas Boehler 1196a1a3b679SAndreas Boehler} 1197