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 /** 83185e2535SAndreas Boehler * Get all calendar pages used by a given page 84185e2535SAndreas Boehler * based on the stored metadata 85185e2535SAndreas Boehler * 86185e2535SAndreas Boehler * @param string $id optional The page id 87185e2535SAndreas Boehler * @return mixed The pages as array or false 88185e2535SAndreas Boehler */ 89185e2535SAndreas Boehler public function getCalendarPagesByMeta($id = null) 90185e2535SAndreas Boehler { 91185e2535SAndreas Boehler if(is_null($id)) 92185e2535SAndreas Boehler { 93185e2535SAndreas Boehler global $ID; 94185e2535SAndreas Boehler $id = $ID; 95185e2535SAndreas Boehler } 96185e2535SAndreas Boehler 97185e2535SAndreas Boehler $meta = $this->getCalendarMetaForPage($id); 98185e2535SAndreas Boehler if(isset($meta['id'])) 99*ed764890SAndreas Boehler { 100*ed764890SAndreas Boehler // Filter the list of pages by permission 101*ed764890SAndreas Boehler $pages = array_keys($meta['id']); 102*ed764890SAndreas Boehler $retList = array(); 103*ed764890SAndreas Boehler foreach($pages as $page) 104*ed764890SAndreas Boehler { 105*ed764890SAndreas Boehler if(auth_quickaclcheck($page) >= AUTH_READ) 106*ed764890SAndreas Boehler { 107*ed764890SAndreas Boehler $retList[] = $page; 108*ed764890SAndreas Boehler } 109*ed764890SAndreas Boehler } 110*ed764890SAndreas Boehler if(empty($retList)) 111*ed764890SAndreas Boehler return false; 112*ed764890SAndreas Boehler return $retList; 113*ed764890SAndreas Boehler } 114185e2535SAndreas Boehler return false; 115185e2535SAndreas Boehler } 116185e2535SAndreas Boehler 117185e2535SAndreas Boehler /** 118185e2535SAndreas Boehler * Get a list of calendar names/pages/ids/colors 119185e2535SAndreas Boehler * for an array of page ids 120185e2535SAndreas Boehler * 121185e2535SAndreas Boehler * @param array $calendarPages The calendar pages to retrieve 122185e2535SAndreas Boehler * @return array The list 123185e2535SAndreas Boehler */ 124185e2535SAndreas Boehler public function getCalendarMapForIDs($calendarPages) 125185e2535SAndreas Boehler { 126185e2535SAndreas Boehler $data = array(); 127185e2535SAndreas Boehler foreach($calendarPages as $page) 128185e2535SAndreas Boehler { 129185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($page); 130185e2535SAndreas Boehler if($calid !== false) 131185e2535SAndreas Boehler { 132185e2535SAndreas Boehler $settings = $this->getCalendarSettings($calid); 133185e2535SAndreas Boehler $name = $settings['displayname']; 134185e2535SAndreas Boehler $color = $settings['calendarcolor']; 135*ed764890SAndreas Boehler $write = (auth_quickaclcheck($page) > AUTH_READ); 136185e2535SAndreas Boehler $data[] = array('name' => $name, 'page' => $page, 'calid' => $calid, 137*ed764890SAndreas Boehler 'color' => $color, 'write' => $write); 138185e2535SAndreas Boehler } 139185e2535SAndreas Boehler } 140185e2535SAndreas Boehler return $data; 141185e2535SAndreas Boehler } 142185e2535SAndreas Boehler 143185e2535SAndreas Boehler /** 144185e2535SAndreas Boehler * Get the saved calendar color for a given page. 145185e2535SAndreas Boehler * 146185e2535SAndreas Boehler * @param string $id optional The page ID 147185e2535SAndreas Boehler * @return mixed The color on success, otherwise false 148185e2535SAndreas Boehler */ 149185e2535SAndreas Boehler public function getCalendarColorForPage($id = null) 150185e2535SAndreas Boehler { 151185e2535SAndreas Boehler if(is_null($id)) 152185e2535SAndreas Boehler { 153185e2535SAndreas Boehler global $ID; 154185e2535SAndreas Boehler $id = $ID; 155185e2535SAndreas Boehler } 156185e2535SAndreas Boehler 157185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 158185e2535SAndreas Boehler if($calid === false) 159185e2535SAndreas Boehler return false; 160185e2535SAndreas Boehler 161185e2535SAndreas Boehler return $this->getCalendarColorForCalendar($calid); 162185e2535SAndreas Boehler } 163185e2535SAndreas Boehler 164185e2535SAndreas Boehler /** 165185e2535SAndreas Boehler * Get the saved calendar color for a given calendar ID. 166185e2535SAndreas Boehler * 167185e2535SAndreas Boehler * @param string $id optional The calendar ID 168185e2535SAndreas Boehler * @return mixed The color on success, otherwise false 169185e2535SAndreas Boehler */ 170185e2535SAndreas Boehler public function getCalendarColorForCalendar($calid) 171185e2535SAndreas Boehler { 172185e2535SAndreas Boehler if(isset($this->cachedValues['calendarcolor'][$calid])) 173185e2535SAndreas Boehler return $this->cachedValues['calendarcolor'][$calid]; 174185e2535SAndreas Boehler 175185e2535SAndreas Boehler $row = $this->getCalendarSettings($calid); 176185e2535SAndreas Boehler 177185e2535SAndreas Boehler if(!isset($row['calendarcolor'])) 178185e2535SAndreas Boehler return false; 179185e2535SAndreas Boehler 180185e2535SAndreas Boehler $color = $row['calendarcolor']; 181185e2535SAndreas Boehler $this->cachedValues['calendarcolor'][$calid] = $color; 182185e2535SAndreas Boehler return $color; 183185e2535SAndreas Boehler } 184185e2535SAndreas Boehler 185185e2535SAndreas Boehler /** 186e86c8dd3SAndreas Boehler * Get the user's principal URL for iOS sync 187e86c8dd3SAndreas Boehler * @param string $user the user name 188e86c8dd3SAndreas Boehler * @return the URL to the principal sync 189e86c8dd3SAndreas Boehler */ 190e86c8dd3SAndreas Boehler public function getPrincipalUrlForUser($user) 191e86c8dd3SAndreas Boehler { 192e86c8dd3SAndreas Boehler if(is_null($user)) 193e86c8dd3SAndreas Boehler return false; 194e86c8dd3SAndreas Boehler $url = DOKU_URL.'lib/plugins/davcal/calendarserver.php/principals/'.$user; 195e86c8dd3SAndreas Boehler return $url; 196e86c8dd3SAndreas Boehler } 197e86c8dd3SAndreas Boehler 198e86c8dd3SAndreas Boehler /** 199185e2535SAndreas Boehler * Set the calendar color for a given page. 200185e2535SAndreas Boehler * 201185e2535SAndreas Boehler * @param string $color The color definition 202185e2535SAndreas Boehler * @param string $id optional The page ID 203185e2535SAndreas Boehler * @return boolean True on success, otherwise false 204185e2535SAndreas Boehler */ 205185e2535SAndreas Boehler public function setCalendarColorForPage($color, $id = null) 206185e2535SAndreas Boehler { 207185e2535SAndreas Boehler if(is_null($id)) 208185e2535SAndreas Boehler { 209185e2535SAndreas Boehler global $ID; 210185e2535SAndreas Boehler $id = $ID; 211185e2535SAndreas Boehler } 212185e2535SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 213185e2535SAndreas Boehler if($calid === false) 214185e2535SAndreas Boehler return false; 215185e2535SAndreas Boehler 21651f4febbSAndreas Boehler $query = "UPDATE calendars SET calendarcolor = ? ". 21751f4febbSAndreas Boehler " WHERE id = ?"; 21851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $color, $calid); 219185e2535SAndreas Boehler if($res !== false) 220185e2535SAndreas Boehler { 221185e2535SAndreas Boehler $this->cachedValues['calendarcolor'][$calid] = $color; 222185e2535SAndreas Boehler return true; 223185e2535SAndreas Boehler } 224185e2535SAndreas Boehler return false; 225185e2535SAndreas Boehler } 226185e2535SAndreas Boehler 227185e2535SAndreas Boehler /** 228cb71a62aSAndreas Boehler * Set the calendar name and description for a given page with a given 229cb71a62aSAndreas Boehler * page id. 230cb71a62aSAndreas Boehler * If the calendar doesn't exist, the calendar is created! 231cb71a62aSAndreas Boehler * 232cb71a62aSAndreas Boehler * @param string $name The name of the new calendar 233cb71a62aSAndreas Boehler * @param string $description The description of the new calendar 234cb71a62aSAndreas Boehler * @param string $id (optional) The ID of the page 235cb71a62aSAndreas Boehler * @param string $userid The userid of the creating user 236cb71a62aSAndreas Boehler * 237cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false. 238cb71a62aSAndreas Boehler */ 239a1a3b679SAndreas Boehler public function setCalendarNameForPage($name, $description, $id = null, $userid = null) 240a1a3b679SAndreas Boehler { 241a1a3b679SAndreas Boehler if(is_null($id)) 242a1a3b679SAndreas Boehler { 243a1a3b679SAndreas Boehler global $ID; 244a1a3b679SAndreas Boehler $id = $ID; 245a1a3b679SAndreas Boehler } 246a1a3b679SAndreas Boehler if(is_null($userid)) 24734a47953SAndreas Boehler { 24834a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 24934a47953SAndreas Boehler { 250a1a3b679SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 25134a47953SAndreas Boehler } 25234a47953SAndreas Boehler else 25334a47953SAndreas Boehler { 25434a47953SAndreas Boehler $userid = uniqid('davcal-'); 25534a47953SAndreas Boehler } 25634a47953SAndreas Boehler } 257a1a3b679SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 258a1a3b679SAndreas Boehler if($calid === false) 259a1a3b679SAndreas Boehler return $this->createCalendarForPage($name, $description, $id, $userid); 260a1a3b679SAndreas Boehler 26151f4febbSAndreas Boehler $query = "UPDATE calendars SET displayname = ?, description = ? WHERE id = ?"; 26251f4febbSAndreas Boehler $res = $this->sqlite->query($query, $name, $description, $calid); 263b269830cSAndreas Boehler if($res !== false) 264b269830cSAndreas Boehler return true; 265b269830cSAndreas Boehler return false; 266a1a3b679SAndreas Boehler } 267a1a3b679SAndreas Boehler 268cb71a62aSAndreas Boehler /** 269cb71a62aSAndreas Boehler * Save the personal settings to the SQLite database 'calendarsettings'. 270cb71a62aSAndreas Boehler * 271cb71a62aSAndreas Boehler * @param array $settings The settings array to store 272cb71a62aSAndreas Boehler * @param string $userid (optional) The userid to store 273cb71a62aSAndreas Boehler * 274cb71a62aSAndreas Boehler * @param boolean True on success, otherwise false 275cb71a62aSAndreas Boehler */ 276a495d34cSAndreas Boehler public function savePersonalSettings($settings, $userid = null) 277a495d34cSAndreas Boehler { 278a495d34cSAndreas Boehler if(is_null($userid)) 27934a47953SAndreas Boehler { 28034a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 28134a47953SAndreas Boehler { 282a495d34cSAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 28334a47953SAndreas Boehler } 28434a47953SAndreas Boehler else 28534a47953SAndreas Boehler { 28634a47953SAndreas Boehler return false; 28734a47953SAndreas Boehler } 28834a47953SAndreas Boehler } 289a495d34cSAndreas Boehler $this->sqlite->query("BEGIN TRANSACTION"); 290a495d34cSAndreas Boehler 29151f4febbSAndreas Boehler $query = "DELETE FROM calendarsettings WHERE userid = ?"; 29251f4febbSAndreas Boehler $this->sqlite->query($query, $userid); 293bd883736SAndreas Boehler 294a495d34cSAndreas Boehler foreach($settings as $key => $value) 295a495d34cSAndreas Boehler { 29651f4febbSAndreas Boehler $query = "INSERT INTO calendarsettings (userid, key, value) VALUES (?, ?, ?)"; 29751f4febbSAndreas Boehler $res = $this->sqlite->query($query, $userid, $key, $value); 298a495d34cSAndreas Boehler if($res === false) 299a495d34cSAndreas Boehler return false; 300a495d34cSAndreas Boehler } 301a495d34cSAndreas Boehler $this->sqlite->query("COMMIT TRANSACTION"); 302185e2535SAndreas Boehler $this->cachedValues['settings'][$userid] = $settings; 303a495d34cSAndreas Boehler return true; 304a495d34cSAndreas Boehler } 305a495d34cSAndreas Boehler 306cb71a62aSAndreas Boehler /** 307cb71a62aSAndreas Boehler * Retrieve the settings array for a given user id. 308cb71a62aSAndreas Boehler * Some sane defaults are returned, currently: 309cb71a62aSAndreas Boehler * 310cb71a62aSAndreas Boehler * timezone => local 311cb71a62aSAndreas Boehler * weeknumbers => 0 312cb71a62aSAndreas Boehler * workweek => 0 313cb71a62aSAndreas Boehler * 314cb71a62aSAndreas Boehler * @param string $userid (optional) The user id to retrieve 315cb71a62aSAndreas Boehler * 316cb71a62aSAndreas Boehler * @return array The settings array 317cb71a62aSAndreas Boehler */ 318a495d34cSAndreas Boehler public function getPersonalSettings($userid = null) 319a495d34cSAndreas Boehler { 320bd883736SAndreas Boehler // Some sane default settings 321bd883736SAndreas Boehler $settings = array( 322fb813b30SAndreas Boehler 'timezone' => $this->getConf('timezone'), 323fb813b30SAndreas Boehler 'weeknumbers' => $this->getConf('weeknumbers'), 324fb813b30SAndreas Boehler 'workweek' => $this->getConf('workweek'), 3251d5bdcd0SAndreas Boehler 'monday' => $this->getConf('monday'), 3261d5bdcd0SAndreas Boehler 'timeformat' => $this->getConf('timeformat') 327bd883736SAndreas Boehler ); 32834a47953SAndreas Boehler if(is_null($userid)) 32934a47953SAndreas Boehler { 33034a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 33134a47953SAndreas Boehler { 33234a47953SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 33334a47953SAndreas Boehler } 33434a47953SAndreas Boehler else 33534a47953SAndreas Boehler { 33634a47953SAndreas Boehler return $settings; 33734a47953SAndreas Boehler } 33834a47953SAndreas Boehler } 33934a47953SAndreas Boehler 34034a47953SAndreas Boehler if(isset($this->cachedValues['settings'][$userid])) 34134a47953SAndreas Boehler return $this->cachedValues['settings'][$userid]; 34251f4febbSAndreas Boehler $query = "SELECT key, value FROM calendarsettings WHERE userid = ?"; 34351f4febbSAndreas Boehler $res = $this->sqlite->query($query, $userid); 344a495d34cSAndreas Boehler $arr = $this->sqlite->res2arr($res); 345a495d34cSAndreas Boehler foreach($arr as $row) 346a495d34cSAndreas Boehler { 347a495d34cSAndreas Boehler $settings[$row['key']] = $row['value']; 348a495d34cSAndreas Boehler } 349185e2535SAndreas Boehler $this->cachedValues['settings'][$userid] = $settings; 350a495d34cSAndreas Boehler return $settings; 351a495d34cSAndreas Boehler } 352a495d34cSAndreas Boehler 353cb71a62aSAndreas Boehler /** 354cb71a62aSAndreas Boehler * Retrieve the calendar ID based on a page ID from the SQLite table 355cb71a62aSAndreas Boehler * 'pagetocalendarmapping'. 356cb71a62aSAndreas Boehler * 357cb71a62aSAndreas Boehler * @param string $id (optional) The page ID to retrieve the corresponding calendar 358cb71a62aSAndreas Boehler * 359cb71a62aSAndreas Boehler * @return mixed the ID on success, otherwise false 360cb71a62aSAndreas Boehler */ 361a1a3b679SAndreas Boehler public function getCalendarIdForPage($id = null) 362a1a3b679SAndreas Boehler { 363a1a3b679SAndreas Boehler if(is_null($id)) 364a1a3b679SAndreas Boehler { 365a1a3b679SAndreas Boehler global $ID; 366a1a3b679SAndreas Boehler $id = $ID; 367a1a3b679SAndreas Boehler } 368a1a3b679SAndreas Boehler 369185e2535SAndreas Boehler if(isset($this->cachedValues['calid'][$id])) 370185e2535SAndreas Boehler return $this->cachedValues['calid'][$id]; 371185e2535SAndreas Boehler 37251f4febbSAndreas Boehler $query = "SELECT calid FROM pagetocalendarmapping WHERE page = ?"; 37351f4febbSAndreas Boehler $res = $this->sqlite->query($query, $id); 374a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 375a1a3b679SAndreas Boehler if(isset($row['calid'])) 376185e2535SAndreas Boehler { 377185e2535SAndreas Boehler $calid = $row['calid']; 378185e2535SAndreas Boehler $this->cachedValues['calid'] = $calid; 379185e2535SAndreas Boehler return $calid; 380185e2535SAndreas Boehler } 381a1a3b679SAndreas Boehler return false; 382a1a3b679SAndreas Boehler } 383a1a3b679SAndreas Boehler 384cb71a62aSAndreas Boehler /** 385cb71a62aSAndreas Boehler * Retrieve the complete calendar id to page mapping. 386cb71a62aSAndreas Boehler * This is necessary to be able to retrieve a list of 387cb71a62aSAndreas Boehler * calendars for a given user and check the access rights. 388cb71a62aSAndreas Boehler * 389cb71a62aSAndreas Boehler * @return array The mapping array 390cb71a62aSAndreas Boehler */ 391a1a3b679SAndreas Boehler public function getCalendarIdToPageMapping() 392a1a3b679SAndreas Boehler { 393a1a3b679SAndreas Boehler $query = "SELECT calid, page FROM pagetocalendarmapping"; 394a1a3b679SAndreas Boehler $res = $this->sqlite->query($query); 395a1a3b679SAndreas Boehler $arr = $this->sqlite->res2arr($res); 396a1a3b679SAndreas Boehler return $arr; 397a1a3b679SAndreas Boehler } 398a1a3b679SAndreas Boehler 399cb71a62aSAndreas Boehler /** 400cb71a62aSAndreas Boehler * Retrieve all calendar IDs a given user has access to. 401cb71a62aSAndreas Boehler * The user is specified by the principalUri, so the 402cb71a62aSAndreas Boehler * user name is actually split from the URI component. 403cb71a62aSAndreas Boehler * 404cb71a62aSAndreas Boehler * Access rights are checked against DokuWiki's ACL 405cb71a62aSAndreas Boehler * and applied accordingly. 406cb71a62aSAndreas Boehler * 407cb71a62aSAndreas Boehler * @param string $principalUri The principal URI to work on 408cb71a62aSAndreas Boehler * 409cb71a62aSAndreas Boehler * @return array An associative array of calendar IDs 410cb71a62aSAndreas Boehler */ 411a1a3b679SAndreas Boehler public function getCalendarIdsForUser($principalUri) 412a1a3b679SAndreas Boehler { 41334a47953SAndreas Boehler global $auth; 414a1a3b679SAndreas Boehler $user = explode('/', $principalUri); 415a1a3b679SAndreas Boehler $user = end($user); 416a1a3b679SAndreas Boehler $mapping = $this->getCalendarIdToPageMapping(); 417a1a3b679SAndreas Boehler $calids = array(); 41834a47953SAndreas Boehler $ud = $auth->getUserData($user); 41934a47953SAndreas Boehler $groups = $ud['grps']; 420a1a3b679SAndreas Boehler foreach($mapping as $row) 421a1a3b679SAndreas Boehler { 422a1a3b679SAndreas Boehler $id = $row['calid']; 423a1a3b679SAndreas Boehler $page = $row['page']; 42434a47953SAndreas Boehler $acl = auth_aclcheck($page, $user, $groups); 425a1a3b679SAndreas Boehler if($acl >= AUTH_READ) 426a1a3b679SAndreas Boehler { 427a1a3b679SAndreas Boehler $write = $acl > AUTH_READ; 428a1a3b679SAndreas Boehler $calids[$id] = array('readonly' => !$write); 429a1a3b679SAndreas Boehler } 430a1a3b679SAndreas Boehler } 431a1a3b679SAndreas Boehler return $calids; 432a1a3b679SAndreas Boehler } 433a1a3b679SAndreas Boehler 434cb71a62aSAndreas Boehler /** 435cb71a62aSAndreas Boehler * Create a new calendar for a given page ID and set name and description 436cb71a62aSAndreas Boehler * accordingly. Also update the pagetocalendarmapping table on success. 437cb71a62aSAndreas Boehler * 438cb71a62aSAndreas Boehler * @param string $name The calendar's name 439cb71a62aSAndreas Boehler * @param string $description The calendar's description 440cb71a62aSAndreas Boehler * @param string $id (optional) The page ID to work on 441cb71a62aSAndreas Boehler * @param string $userid (optional) The user ID that created the calendar 442cb71a62aSAndreas Boehler * 443cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 444cb71a62aSAndreas Boehler */ 445a1a3b679SAndreas Boehler public function createCalendarForPage($name, $description, $id = null, $userid = null) 446a1a3b679SAndreas Boehler { 447a1a3b679SAndreas Boehler if(is_null($id)) 448a1a3b679SAndreas Boehler { 449a1a3b679SAndreas Boehler global $ID; 450a1a3b679SAndreas Boehler $id = $ID; 451a1a3b679SAndreas Boehler } 452a1a3b679SAndreas Boehler if(is_null($userid)) 45334a47953SAndreas Boehler { 45434a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 45534a47953SAndreas Boehler { 456a1a3b679SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 45734a47953SAndreas Boehler } 45834a47953SAndreas Boehler else 45934a47953SAndreas Boehler { 46034a47953SAndreas Boehler $userid = uniqid('davcal-'); 46134a47953SAndreas Boehler } 46234a47953SAndreas Boehler } 463a1a3b679SAndreas Boehler $values = array('principals/'.$userid, 464a1a3b679SAndreas Boehler $name, 465a1a3b679SAndreas Boehler str_replace(array('/', ' ', ':'), '_', $id), 466a1a3b679SAndreas Boehler $description, 467a1a3b679SAndreas Boehler 'VEVENT,VTODO', 46855a741c0SAndreas Boehler 0, 46955a741c0SAndreas Boehler 1); 47051f4febbSAndreas Boehler $query = "INSERT INTO calendars (principaluri, displayname, uri, description, components, transparent, synctoken) ". 47151f4febbSAndreas Boehler "VALUES (?, ?, ?, ?, ?, ?, ?)"; 47251f4febbSAndreas Boehler $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3], $values[4], $values[5], $values[6]); 47355a741c0SAndreas Boehler if($res === false) 47455a741c0SAndreas Boehler return false; 475cb71a62aSAndreas Boehler 476cb71a62aSAndreas Boehler // Get the new calendar ID 47751f4febbSAndreas Boehler $query = "SELECT id FROM calendars WHERE principaluri = ? AND displayname = ? AND ". 47851f4febbSAndreas Boehler "uri = ? AND description = ?"; 47951f4febbSAndreas Boehler $res = $this->sqlite->query($query, $values[0], $values[1], $values[2], $values[3]); 480a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 481cb71a62aSAndreas Boehler 482cb71a62aSAndreas Boehler // Update the pagetocalendarmapping table with the new calendar ID 483a1a3b679SAndreas Boehler if(isset($row['id'])) 484a1a3b679SAndreas Boehler { 48551f4febbSAndreas Boehler $query = "INSERT INTO pagetocalendarmapping (page, calid) VALUES (?, ?)"; 48651f4febbSAndreas Boehler $res = $this->sqlite->query($query, $id, $row['id']); 48755a741c0SAndreas Boehler return ($res !== false); 488a1a3b679SAndreas Boehler } 489a1a3b679SAndreas Boehler 490a1a3b679SAndreas Boehler return false; 491a1a3b679SAndreas Boehler } 492a1a3b679SAndreas Boehler 493cb71a62aSAndreas Boehler /** 494cb71a62aSAndreas Boehler * Add a new iCal entry for a given page, i.e. a given calendar. 495cb71a62aSAndreas Boehler * 496cb71a62aSAndreas Boehler * The parameter array needs to contain 497cb71a62aSAndreas Boehler * detectedtz => The timezone as detected by the browser 49882a48dfbSAndreas Boehler * currenttz => The timezone in use by the calendar 499cb71a62aSAndreas Boehler * eventfrom => The event's start date 500cb71a62aSAndreas Boehler * eventfromtime => The event's start time 501cb71a62aSAndreas Boehler * eventto => The event's end date 502cb71a62aSAndreas Boehler * eventtotime => The event's end time 503cb71a62aSAndreas Boehler * eventname => The event's name 504cb71a62aSAndreas Boehler * eventdescription => The event's description 505cb71a62aSAndreas Boehler * 506cb71a62aSAndreas Boehler * @param string $id The page ID to work on 507cb71a62aSAndreas Boehler * @param string $user The user who created the calendar 508cb71a62aSAndreas Boehler * @param string $params A parameter array with values to create 509cb71a62aSAndreas Boehler * 510cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 511cb71a62aSAndreas Boehler */ 512a1a3b679SAndreas Boehler public function addCalendarEntryToCalendarForPage($id, $user, $params) 513a1a3b679SAndreas Boehler { 51482a48dfbSAndreas Boehler if($params['currenttz'] !== '' && $params['currenttz'] !== 'local') 51582a48dfbSAndreas Boehler $timezone = new \DateTimeZone($params['currenttz']); 51682a48dfbSAndreas Boehler elseif($params['currenttz'] === 'local') 517a25c89eaSAndreas Boehler $timezone = new \DateTimeZone($params['detectedtz']); 518bd883736SAndreas Boehler else 519bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 520cb71a62aSAndreas Boehler 521cb71a62aSAndreas Boehler // Retrieve dates from settings 522b269830cSAndreas Boehler $startDate = explode('-', $params['eventfrom']); 523b269830cSAndreas Boehler $startTime = explode(':', $params['eventfromtime']); 524b269830cSAndreas Boehler $endDate = explode('-', $params['eventto']); 525b269830cSAndreas Boehler $endTime = explode(':', $params['eventtotime']); 526cb71a62aSAndreas Boehler 527cb71a62aSAndreas Boehler // Load SabreDAV 5289bef4ad8SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 529a1a3b679SAndreas Boehler $vcalendar = new \Sabre\VObject\Component\VCalendar(); 530cb71a62aSAndreas Boehler 531cb71a62aSAndreas Boehler // Add VCalendar, UID and Event Name 532a1a3b679SAndreas Boehler $event = $vcalendar->add('VEVENT'); 533b269830cSAndreas Boehler $uuid = \Sabre\VObject\UUIDUtil::getUUID(); 534b269830cSAndreas Boehler $event->add('UID', $uuid); 535a1a3b679SAndreas Boehler $event->summary = $params['eventname']; 536cb71a62aSAndreas Boehler 537cb71a62aSAndreas Boehler // Add a description if requested 5380eebc909SAndreas Boehler $description = $params['eventdescription']; 5390eebc909SAndreas Boehler if($description !== '') 5400eebc909SAndreas Boehler $event->add('DESCRIPTION', $description); 541cb71a62aSAndreas Boehler 5424ecb526cSAndreas Boehler // Add attachments 5434ecb526cSAndreas Boehler $attachments = $params['attachments']; 54482a48dfbSAndreas Boehler if(!is_null($attachments)) 5454ecb526cSAndreas Boehler foreach($attachments as $attachment) 5464ecb526cSAndreas Boehler $event->add('ATTACH', $attachment); 5474ecb526cSAndreas Boehler 548cb71a62aSAndreas Boehler // Create a timestamp for last modified, created and dtstamp values in UTC 549b269830cSAndreas Boehler $dtStamp = new \DateTime(null, new \DateTimeZone('UTC')); 550b269830cSAndreas Boehler $event->add('DTSTAMP', $dtStamp); 551b269830cSAndreas Boehler $event->add('CREATED', $dtStamp); 552b269830cSAndreas Boehler $event->add('LAST-MODIFIED', $dtStamp); 553cb71a62aSAndreas Boehler 554cb71a62aSAndreas Boehler // Adjust the start date, based on the given timezone information 555b269830cSAndreas Boehler $dtStart = new \DateTime(); 556a25c89eaSAndreas Boehler $dtStart->setTimezone($timezone); 557b269830cSAndreas Boehler $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2])); 558cb71a62aSAndreas Boehler 559cb71a62aSAndreas Boehler // Only add the time values if it's not an allday event 560b269830cSAndreas Boehler if($params['allday'] != '1') 561b269830cSAndreas Boehler $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0); 562cb71a62aSAndreas Boehler 563cb71a62aSAndreas Boehler // Adjust the end date, based on the given timezone information 564b269830cSAndreas Boehler $dtEnd = new \DateTime(); 565a25c89eaSAndreas Boehler $dtEnd->setTimezone($timezone); 566b269830cSAndreas Boehler $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2])); 567cb71a62aSAndreas Boehler 568cb71a62aSAndreas Boehler // Only add the time values if it's not an allday event 569b269830cSAndreas Boehler if($params['allday'] != '1') 570b269830cSAndreas Boehler $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0); 571cb71a62aSAndreas Boehler 572b269830cSAndreas Boehler // According to the VCal spec, we need to add a whole day here 573b269830cSAndreas Boehler if($params['allday'] == '1') 574b269830cSAndreas Boehler $dtEnd->add(new \DateInterval('P1D')); 575cb71a62aSAndreas Boehler 576cb71a62aSAndreas Boehler // Really add Start and End events 577b269830cSAndreas Boehler $dtStartEv = $event->add('DTSTART', $dtStart); 578b269830cSAndreas Boehler $dtEndEv = $event->add('DTEND', $dtEnd); 579cb71a62aSAndreas Boehler 580cb71a62aSAndreas Boehler // Adjust the DATE format for allday events 581b269830cSAndreas Boehler if($params['allday'] == '1') 582b269830cSAndreas Boehler { 583b269830cSAndreas Boehler $dtStartEv['VALUE'] = 'DATE'; 584b269830cSAndreas Boehler $dtEndEv['VALUE'] = 'DATE'; 585b269830cSAndreas Boehler } 586cb71a62aSAndreas Boehler 587cb71a62aSAndreas Boehler // Actually add the values to the database 588a1a3b679SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 589a1a3b679SAndreas Boehler $uri = uniqid('dokuwiki-').'.ics'; 590a1a3b679SAndreas Boehler $now = new DateTime(); 591a1a3b679SAndreas Boehler $eventStr = $vcalendar->serialize(); 592a1a3b679SAndreas Boehler 59351f4febbSAndreas Boehler $query = "INSERT INTO calendarobjects (calendarid, uri, calendardata, lastmodified, componenttype, firstoccurence, lastoccurence, size, etag, uid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 59451f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid, $uri, $eventStr, $now->getTimestamp(), 'VEVENT', 59551f4febbSAndreas Boehler $event->DTSTART->getDateTime()->getTimeStamp(), $event->DTEND->getDateTime()->getTimeStamp(), 59651f4febbSAndreas Boehler strlen($eventStr), md5($eventStr), $uuid); 597cb71a62aSAndreas Boehler 598cb71a62aSAndreas Boehler // If successfully, update the sync token database 59955a741c0SAndreas Boehler if($res !== false) 60055a741c0SAndreas Boehler { 60155a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'added'); 602a1a3b679SAndreas Boehler return true; 603a1a3b679SAndreas Boehler } 60455a741c0SAndreas Boehler return false; 60555a741c0SAndreas Boehler } 606a1a3b679SAndreas Boehler 607cb71a62aSAndreas Boehler /** 608cb71a62aSAndreas Boehler * Retrieve the calendar settings of a given calendar id 609cb71a62aSAndreas Boehler * 610cb71a62aSAndreas Boehler * @param string $calid The calendar ID 611cb71a62aSAndreas Boehler * 612cb71a62aSAndreas Boehler * @return array The calendar settings array 613cb71a62aSAndreas Boehler */ 614b269830cSAndreas Boehler public function getCalendarSettings($calid) 615b269830cSAndreas Boehler { 61651f4febbSAndreas Boehler $query = "SELECT principaluri, calendarcolor, displayname, uri, description, components, transparent, synctoken FROM calendars WHERE id= ? "; 61751f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 618b269830cSAndreas Boehler $row = $this->sqlite->res2row($res); 619b269830cSAndreas Boehler return $row; 620b269830cSAndreas Boehler } 621b269830cSAndreas Boehler 622cb71a62aSAndreas Boehler /** 623cb71a62aSAndreas Boehler * Retrieve all events that are within a given date range, 624cb71a62aSAndreas Boehler * based on the timezone setting. 625cb71a62aSAndreas Boehler * 626cb71a62aSAndreas Boehler * There is also support for retrieving recurring events, 627cb71a62aSAndreas Boehler * using Sabre's VObject Iterator. Recurring events are represented 628cb71a62aSAndreas Boehler * as individual calendar entries with the same UID. 629cb71a62aSAndreas Boehler * 630cb71a62aSAndreas Boehler * @param string $id The page ID to work with 631cb71a62aSAndreas Boehler * @param string $user The user ID to work with 632cb71a62aSAndreas Boehler * @param string $startDate The start date as a string 633cb71a62aSAndreas Boehler * @param string $endDate The end date as a string 634cb71a62aSAndreas Boehler * 635cb71a62aSAndreas Boehler * @return array An array containing the calendar entries. 636cb71a62aSAndreas Boehler */ 63782a48dfbSAndreas Boehler public function getEventsWithinDateRange($id, $user, $startDate, $endDate, $timezone) 638a1a3b679SAndreas Boehler { 63982a48dfbSAndreas Boehler if($timezone !== '' && $timezone !== 'local') 64082a48dfbSAndreas Boehler $timezone = new \DateTimeZone($timezone); 641bd883736SAndreas Boehler else 642bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 643a1a3b679SAndreas Boehler $data = array(); 644cb71a62aSAndreas Boehler 645cb71a62aSAndreas Boehler // Load SabreDAV 6469bef4ad8SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 647a1a3b679SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 648185e2535SAndreas Boehler $color = $this->getCalendarColorForCalendar($calid); 649a469597cSAndreas Boehler $query = "SELECT calendardata, componenttype, uid FROM calendarobjects WHERE calendarid = ?"; 650a469597cSAndreas Boehler $startTs = null; 651a469597cSAndreas Boehler $endTs = null; 652a469597cSAndreas Boehler if($startDate !== null) 653a469597cSAndreas Boehler { 654a1a3b679SAndreas Boehler $startTs = new \DateTime($startDate); 655a469597cSAndreas Boehler $query .= " AND lastoccurence > ".$this->sqlite->quote_string($startTs->getTimestamp()); 656a469597cSAndreas Boehler } 657a469597cSAndreas Boehler if($endDate !== null) 658a469597cSAndreas Boehler { 659a1a3b679SAndreas Boehler $endTs = new \DateTime($endDate); 660a469597cSAndreas Boehler $query .= " AND firstoccurence < ".$this->sqlite->quote_string($endTs->getTimestamp()); 661a469597cSAndreas Boehler } 662cb71a62aSAndreas Boehler 663cb71a62aSAndreas Boehler // Retrieve matching calendar objects 664a469597cSAndreas Boehler $res = $this->sqlite->query($query, $calid); 665a1a3b679SAndreas Boehler $arr = $this->sqlite->res2arr($res); 666cb71a62aSAndreas Boehler 667cb71a62aSAndreas Boehler // Parse individual calendar entries 668a1a3b679SAndreas Boehler foreach($arr as $row) 669a1a3b679SAndreas Boehler { 670a1a3b679SAndreas Boehler if(isset($row['calendardata'])) 671a1a3b679SAndreas Boehler { 672b269830cSAndreas Boehler $entry = array(); 673a1a3b679SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($row['calendardata']); 674ebc4eb57SAndreas Boehler $recurrence = $vcal->VEVENT->RRULE; 675cb71a62aSAndreas Boehler // If it is a recurring event, pass it through Sabre's EventIterator 676ebc4eb57SAndreas Boehler if($recurrence != null) 677ebc4eb57SAndreas Boehler { 678ebc4eb57SAndreas Boehler $rEvents = new \Sabre\VObject\Recur\EventIterator(array($vcal->VEVENT)); 679ebc4eb57SAndreas Boehler $rEvents->rewind(); 680e9b7d302SAndreas Boehler while($rEvents->valid()) 681ebc4eb57SAndreas Boehler { 682ebc4eb57SAndreas Boehler $event = $rEvents->getEventObject(); 683cb71a62aSAndreas Boehler // If we are after the given time range, exit 684a469597cSAndreas Boehler if(($endTs !== null) && ($rEvents->getDtStart()->getTimestamp() > $endTs->getTimestamp())) 685e9b7d302SAndreas Boehler break; 686cb71a62aSAndreas Boehler 687cb71a62aSAndreas Boehler // If we are before the given time range, continue 688a469597cSAndreas Boehler if(($startTs != null) && ($rEvents->getDtEnd()->getTimestamp() < $startTs->getTimestamp())) 689ebc4eb57SAndreas Boehler { 690ebc4eb57SAndreas Boehler $rEvents->next(); 691ebc4eb57SAndreas Boehler continue; 692ebc4eb57SAndreas Boehler } 693cb71a62aSAndreas Boehler 694cb71a62aSAndreas Boehler // If we are within the given time range, parse the event 695185e2535SAndreas Boehler $data[] = $this->convertIcalDataToEntry($event, $id, $timezone, $row['uid'], $color, true); 696ebc4eb57SAndreas Boehler $rEvents->next(); 697ebc4eb57SAndreas Boehler } 698ebc4eb57SAndreas Boehler } 699ebc4eb57SAndreas Boehler else 700185e2535SAndreas Boehler $data[] = $this->convertIcalDataToEntry($vcal->VEVENT, $id, $timezone, $row['uid'], $color); 701ebc4eb57SAndreas Boehler } 702ebc4eb57SAndreas Boehler } 703ebc4eb57SAndreas Boehler return $data; 704ebc4eb57SAndreas Boehler } 705ebc4eb57SAndreas Boehler 706cb71a62aSAndreas Boehler /** 707cb71a62aSAndreas Boehler * Helper function that parses the iCal data of a VEVENT to a calendar entry. 708cb71a62aSAndreas Boehler * 709cb71a62aSAndreas Boehler * @param \Sabre\VObject\VEvent $event The event to parse 710cb71a62aSAndreas Boehler * @param \DateTimeZone $timezone The timezone object 711cb71a62aSAndreas Boehler * @param string $uid The entry's UID 7123c86dda8SAndreas Boehler * @param boolean $recurring (optional) Set to true to define a recurring event 713cb71a62aSAndreas Boehler * 714cb71a62aSAndreas Boehler * @return array The parse calendar entry 715cb71a62aSAndreas Boehler */ 716185e2535SAndreas Boehler private function convertIcalDataToEntry($event, $page, $timezone, $uid, $color, $recurring = false) 717ebc4eb57SAndreas Boehler { 718ebc4eb57SAndreas Boehler $entry = array(); 719ebc4eb57SAndreas Boehler $start = $event->DTSTART; 720cb71a62aSAndreas Boehler // Parse only if the start date/time is present 721b269830cSAndreas Boehler if($start !== null) 722b269830cSAndreas Boehler { 723b269830cSAndreas Boehler $dtStart = $start->getDateTime(); 724b269830cSAndreas Boehler $dtStart->setTimezone($timezone); 725bf0ad2b4SAndreas Boehler 726bf0ad2b4SAndreas Boehler // moment.js doesn't like times be given even if 727bf0ad2b4SAndreas Boehler // allDay is set to true 728bf0ad2b4SAndreas Boehler // This should fix T23 729b269830cSAndreas Boehler if($start['VALUE'] == 'DATE') 730bf0ad2b4SAndreas Boehler { 731b269830cSAndreas Boehler $entry['allDay'] = true; 732bf0ad2b4SAndreas Boehler $entry['start'] = $dtStart->format("Y-m-d"); 733bf0ad2b4SAndreas Boehler } 734b269830cSAndreas Boehler else 735bf0ad2b4SAndreas Boehler { 736b269830cSAndreas Boehler $entry['allDay'] = false; 737bf0ad2b4SAndreas Boehler $entry['start'] = $dtStart->format(\DateTime::ATOM); 738bf0ad2b4SAndreas Boehler } 739b269830cSAndreas Boehler } 740ebc4eb57SAndreas Boehler $end = $event->DTEND; 741bf0ad2b4SAndreas Boehler // Parse only if the end date/time is present 742b269830cSAndreas Boehler if($end !== null) 743b269830cSAndreas Boehler { 744b269830cSAndreas Boehler $dtEnd = $end->getDateTime(); 745b269830cSAndreas Boehler $dtEnd->setTimezone($timezone); 746bf0ad2b4SAndreas Boehler if($end['VALUE'] == 'DATE') 747bf0ad2b4SAndreas Boehler $entry['end'] = $dtEnd->format("Y-m-d"); 748bf0ad2b4SAndreas Boehler else 749b269830cSAndreas Boehler $entry['end'] = $dtEnd->format(\DateTime::ATOM); 750b269830cSAndreas Boehler } 751ebc4eb57SAndreas Boehler $description = $event->DESCRIPTION; 7520eebc909SAndreas Boehler if($description !== null) 7530eebc909SAndreas Boehler $entry['description'] = (string)$description; 7540eebc909SAndreas Boehler else 7550eebc909SAndreas Boehler $entry['description'] = ''; 7564ecb526cSAndreas Boehler $attachments = $event->ATTACH; 7574ecb526cSAndreas Boehler if($attachments !== null) 7584ecb526cSAndreas Boehler { 7594ecb526cSAndreas Boehler $entry['attachments'] = array(); 7604ecb526cSAndreas Boehler foreach($attachments as $attachment) 7614ecb526cSAndreas Boehler $entry['attachments'][] = (string)$attachment; 7624ecb526cSAndreas Boehler } 763ebc4eb57SAndreas Boehler $entry['title'] = (string)$event->summary; 764ebc4eb57SAndreas Boehler $entry['id'] = $uid; 765185e2535SAndreas Boehler $entry['page'] = $page; 766185e2535SAndreas Boehler $entry['color'] = $color; 7673c86dda8SAndreas Boehler $entry['recurring'] = $recurring; 768185e2535SAndreas Boehler 769ebc4eb57SAndreas Boehler return $entry; 770a1a3b679SAndreas Boehler } 771a1a3b679SAndreas Boehler 772cb71a62aSAndreas Boehler /** 773cb71a62aSAndreas Boehler * Retrieve an event by its UID 774cb71a62aSAndreas Boehler * 775cb71a62aSAndreas Boehler * @param string $uid The event's UID 776cb71a62aSAndreas Boehler * 777cb71a62aSAndreas Boehler * @return mixed The table row with the given event 778cb71a62aSAndreas Boehler */ 779a1a3b679SAndreas Boehler public function getEventWithUid($uid) 780a1a3b679SAndreas Boehler { 78151f4febbSAndreas Boehler $query = "SELECT calendardata, calendarid, componenttype, uri FROM calendarobjects WHERE uid = ?"; 78251f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uid); 783a1a3b679SAndreas Boehler $row = $this->sqlite->res2row($res); 784a1a3b679SAndreas Boehler return $row; 785a1a3b679SAndreas Boehler } 786a1a3b679SAndreas Boehler 787cb71a62aSAndreas Boehler /** 788cb71a62aSAndreas Boehler * Retrieve all calendar events for a given calendar ID 789cb71a62aSAndreas Boehler * 790cb71a62aSAndreas Boehler * @param string $calid The calendar's ID 791cb71a62aSAndreas Boehler * 792cb71a62aSAndreas Boehler * @return array An array containing all calendar data 793cb71a62aSAndreas Boehler */ 794f69bb449SAndreas Boehler public function getAllCalendarEvents($calid) 795f69bb449SAndreas Boehler { 7967e0b8590SAndreas Boehler $query = "SELECT calendardata, uid, componenttype, uri FROM calendarobjects WHERE calendarid = ?"; 79751f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 798f69bb449SAndreas Boehler $arr = $this->sqlite->res2arr($res); 799f69bb449SAndreas Boehler return $arr; 800f69bb449SAndreas Boehler } 801f69bb449SAndreas Boehler 802cb71a62aSAndreas Boehler /** 803cb71a62aSAndreas Boehler * Edit a calendar entry for a page, given by its parameters. 804cb71a62aSAndreas Boehler * The params array has the same format as @see addCalendarEntryForPage 805cb71a62aSAndreas Boehler * 806cb71a62aSAndreas Boehler * @param string $id The page's ID to work on 807cb71a62aSAndreas Boehler * @param string $user The user's ID to work on 808cb71a62aSAndreas Boehler * @param array $params The parameter array for the edited calendar event 809cb71a62aSAndreas Boehler * 810cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 811cb71a62aSAndreas Boehler */ 812a1a3b679SAndreas Boehler public function editCalendarEntryForPage($id, $user, $params) 813a1a3b679SAndreas Boehler { 81482a48dfbSAndreas Boehler if($params['currenttz'] !== '' && $params['currenttz'] !== 'local') 81582a48dfbSAndreas Boehler $timezone = new \DateTimeZone($params['currenttz']); 81682a48dfbSAndreas Boehler elseif($params['currenttz'] === 'local') 817a25c89eaSAndreas Boehler $timezone = new \DateTimeZone($params['detectedtz']); 818bd883736SAndreas Boehler else 819bd883736SAndreas Boehler $timezone = new \DateTimeZone('UTC'); 820cb71a62aSAndreas Boehler 821cb71a62aSAndreas Boehler // Parse dates 822b269830cSAndreas Boehler $startDate = explode('-', $params['eventfrom']); 823b269830cSAndreas Boehler $startTime = explode(':', $params['eventfromtime']); 824b269830cSAndreas Boehler $endDate = explode('-', $params['eventto']); 825b269830cSAndreas Boehler $endTime = explode(':', $params['eventtotime']); 826cb71a62aSAndreas Boehler 827cb71a62aSAndreas Boehler // Retrieve the existing event based on the UID 82855a741c0SAndreas Boehler $uid = $params['uid']; 82955a741c0SAndreas Boehler $event = $this->getEventWithUid($uid); 830cb71a62aSAndreas Boehler 831cb71a62aSAndreas Boehler // Load SabreDAV 8329bef4ad8SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 833a1a3b679SAndreas Boehler if(!isset($event['calendardata'])) 834a1a3b679SAndreas Boehler return false; 83555a741c0SAndreas Boehler $uri = $event['uri']; 83655a741c0SAndreas Boehler $calid = $event['calendarid']; 837cb71a62aSAndreas Boehler 838cb71a62aSAndreas Boehler // Parse the existing event 839a1a3b679SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($event['calendardata']); 840b269830cSAndreas Boehler $vevent = $vcal->VEVENT; 841cb71a62aSAndreas Boehler 842cb71a62aSAndreas Boehler // Set the new event values 843b269830cSAndreas Boehler $vevent->summary = $params['eventname']; 844b269830cSAndreas Boehler $dtStamp = new \DateTime(null, new \DateTimeZone('UTC')); 8450eebc909SAndreas Boehler $description = $params['eventdescription']; 846cb71a62aSAndreas Boehler 847cb71a62aSAndreas Boehler // Remove existing timestamps to overwrite them 8480eebc909SAndreas Boehler $vevent->remove('DESCRIPTION'); 849b269830cSAndreas Boehler $vevent->remove('DTSTAMP'); 850b269830cSAndreas Boehler $vevent->remove('LAST-MODIFIED'); 8514ecb526cSAndreas Boehler $vevent->remove('ATTACH'); 852cb71a62aSAndreas Boehler 853cb71a62aSAndreas Boehler // Add new time stamps and description 854b269830cSAndreas Boehler $vevent->add('DTSTAMP', $dtStamp); 855b269830cSAndreas Boehler $vevent->add('LAST-MODIFIED', $dtStamp); 8560eebc909SAndreas Boehler if($description !== '') 8570eebc909SAndreas Boehler $vevent->add('DESCRIPTION', $description); 858cb71a62aSAndreas Boehler 8594ecb526cSAndreas Boehler // Add attachments 8604ecb526cSAndreas Boehler $attachments = $params['attachments']; 86182a48dfbSAndreas Boehler if(!is_null($attachments)) 8624ecb526cSAndreas Boehler foreach($attachments as $attachment) 8634ecb526cSAndreas Boehler $vevent->add('ATTACH', $attachment); 8644ecb526cSAndreas Boehler 865cb71a62aSAndreas Boehler // Setup DTSTART 866b269830cSAndreas Boehler $dtStart = new \DateTime(); 867a25c89eaSAndreas Boehler $dtStart->setTimezone($timezone); 868b269830cSAndreas Boehler $dtStart->setDate(intval($startDate[0]), intval($startDate[1]), intval($startDate[2])); 869b269830cSAndreas Boehler if($params['allday'] != '1') 870b269830cSAndreas Boehler $dtStart->setTime(intval($startTime[0]), intval($startTime[1]), 0); 871cb71a62aSAndreas Boehler 8724ecb526cSAndreas Boehler // Setup DTEND 873b269830cSAndreas Boehler $dtEnd = new \DateTime(); 874a25c89eaSAndreas Boehler $dtEnd->setTimezone($timezone); 875b269830cSAndreas Boehler $dtEnd->setDate(intval($endDate[0]), intval($endDate[1]), intval($endDate[2])); 876b269830cSAndreas Boehler if($params['allday'] != '1') 877b269830cSAndreas Boehler $dtEnd->setTime(intval($endTime[0]), intval($endTime[1]), 0); 878cb71a62aSAndreas Boehler 879b269830cSAndreas Boehler // According to the VCal spec, we need to add a whole day here 880b269830cSAndreas Boehler if($params['allday'] == '1') 881b269830cSAndreas Boehler $dtEnd->add(new \DateInterval('P1D')); 882b269830cSAndreas Boehler $vevent->remove('DTSTART'); 883b269830cSAndreas Boehler $vevent->remove('DTEND'); 884b269830cSAndreas Boehler $dtStartEv = $vevent->add('DTSTART', $dtStart); 885b269830cSAndreas Boehler $dtEndEv = $vevent->add('DTEND', $dtEnd); 886cb71a62aSAndreas Boehler 887cb71a62aSAndreas Boehler // Remove the time for allday events 888b269830cSAndreas Boehler if($params['allday'] == '1') 889b269830cSAndreas Boehler { 890b269830cSAndreas Boehler $dtStartEv['VALUE'] = 'DATE'; 891b269830cSAndreas Boehler $dtEndEv['VALUE'] = 'DATE'; 892b269830cSAndreas Boehler } 893a1a3b679SAndreas Boehler $now = new DateTime(); 894a1a3b679SAndreas Boehler $eventStr = $vcal->serialize(); 895cb71a62aSAndreas Boehler // Actually write to the database 89651f4febbSAndreas Boehler $query = "UPDATE calendarobjects SET calendardata = ?, lastmodified = ?, ". 89751f4febbSAndreas Boehler "firstoccurence = ?, lastoccurence = ?, size = ?, etag = ? WHERE uid = ?"; 89851f4febbSAndreas Boehler $res = $this->sqlite->query($query, $eventStr, $now->getTimestamp(), $dtStart->getTimestamp(), 89951f4febbSAndreas Boehler $dtEnd->getTimestamp(), strlen($eventStr), md5($eventStr), $uid); 90055a741c0SAndreas Boehler if($res !== false) 90155a741c0SAndreas Boehler { 90255a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'modified'); 903a1a3b679SAndreas Boehler return true; 904a1a3b679SAndreas Boehler } 90555a741c0SAndreas Boehler return false; 90655a741c0SAndreas Boehler } 907a1a3b679SAndreas Boehler 908cb71a62aSAndreas Boehler /** 909cb71a62aSAndreas Boehler * Delete a calendar entry for a given page. Actually, the event is removed 910cb71a62aSAndreas Boehler * based on the entry's UID, so that page ID is no used. 911cb71a62aSAndreas Boehler * 912cb71a62aSAndreas Boehler * @param string $id The page's ID (unused) 913cb71a62aSAndreas Boehler * @param array $params The parameter array to work with 914cb71a62aSAndreas Boehler * 915cb71a62aSAndreas Boehler * @return boolean True 916cb71a62aSAndreas Boehler */ 917a1a3b679SAndreas Boehler public function deleteCalendarEntryForPage($id, $params) 918a1a3b679SAndreas Boehler { 919a1a3b679SAndreas Boehler $uid = $params['uid']; 92055a741c0SAndreas Boehler $event = $this->getEventWithUid($uid); 9212c14b82bSAndreas Boehler $calid = $event['calendarid']; 92255a741c0SAndreas Boehler $uri = $event['uri']; 92351f4febbSAndreas Boehler $query = "DELETE FROM calendarobjects WHERE uid = ?"; 92451f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uid); 92555a741c0SAndreas Boehler if($res !== false) 92655a741c0SAndreas Boehler { 92755a741c0SAndreas Boehler $this->updateSyncTokenLog($calid, $uri, 'deleted'); 92855a741c0SAndreas Boehler } 929a1a3b679SAndreas Boehler return true; 930a1a3b679SAndreas Boehler } 931a1a3b679SAndreas Boehler 932cb71a62aSAndreas Boehler /** 933cb71a62aSAndreas Boehler * Retrieve the current sync token for a calendar 934cb71a62aSAndreas Boehler * 935cb71a62aSAndreas Boehler * @param string $calid The calendar id 936cb71a62aSAndreas Boehler * 937cb71a62aSAndreas Boehler * @return mixed The synctoken or false 938cb71a62aSAndreas Boehler */ 93955a741c0SAndreas Boehler public function getSyncTokenForCalendar($calid) 94055a741c0SAndreas Boehler { 941b269830cSAndreas Boehler $row = $this->getCalendarSettings($calid); 94255a741c0SAndreas Boehler if(isset($row['synctoken'])) 94355a741c0SAndreas Boehler return $row['synctoken']; 94455a741c0SAndreas Boehler return false; 94555a741c0SAndreas Boehler } 94655a741c0SAndreas Boehler 947cb71a62aSAndreas Boehler /** 948cb71a62aSAndreas Boehler * Helper function to convert the operation name to 949cb71a62aSAndreas Boehler * an operation code as stored in the database 950cb71a62aSAndreas Boehler * 951cb71a62aSAndreas Boehler * @param string $operationName The operation name 952cb71a62aSAndreas Boehler * 953cb71a62aSAndreas Boehler * @return mixed The operation code or false 954cb71a62aSAndreas Boehler */ 95555a741c0SAndreas Boehler public function operationNameToOperation($operationName) 95655a741c0SAndreas Boehler { 95755a741c0SAndreas Boehler switch($operationName) 95855a741c0SAndreas Boehler { 95955a741c0SAndreas Boehler case 'added': 96055a741c0SAndreas Boehler return 1; 96155a741c0SAndreas Boehler break; 96255a741c0SAndreas Boehler case 'modified': 96355a741c0SAndreas Boehler return 2; 96455a741c0SAndreas Boehler break; 96555a741c0SAndreas Boehler case 'deleted': 96655a741c0SAndreas Boehler return 3; 96755a741c0SAndreas Boehler break; 96855a741c0SAndreas Boehler } 96955a741c0SAndreas Boehler return false; 97055a741c0SAndreas Boehler } 97155a741c0SAndreas Boehler 972cb71a62aSAndreas Boehler /** 973cb71a62aSAndreas Boehler * Update the sync token log based on the calendar id and the 974cb71a62aSAndreas Boehler * operation that was performed. 975cb71a62aSAndreas Boehler * 976cb71a62aSAndreas Boehler * @param string $calid The calendar ID that was modified 977cb71a62aSAndreas Boehler * @param string $uri The calendar URI that was modified 978cb71a62aSAndreas Boehler * @param string $operation The operation that was performed 979cb71a62aSAndreas Boehler * 980cb71a62aSAndreas Boehler * @return boolean True on success, otherwise false 981cb71a62aSAndreas Boehler */ 98255a741c0SAndreas Boehler private function updateSyncTokenLog($calid, $uri, $operation) 98355a741c0SAndreas Boehler { 98455a741c0SAndreas Boehler $currentToken = $this->getSyncTokenForCalendar($calid); 98555a741c0SAndreas Boehler $operationCode = $this->operationNameToOperation($operation); 98655a741c0SAndreas Boehler if(($operationCode === false) || ($currentToken === false)) 98755a741c0SAndreas Boehler return false; 98855a741c0SAndreas Boehler $values = array($uri, 98955a741c0SAndreas Boehler $currentToken, 99055a741c0SAndreas Boehler $calid, 99155a741c0SAndreas Boehler $operationCode 99255a741c0SAndreas Boehler ); 99351f4febbSAndreas Boehler $query = "INSERT INTO calendarchanges (uri, synctoken, calendarid, operation) VALUES(?, ?, ?, ?)"; 99451f4febbSAndreas Boehler $res = $this->sqlite->query($query, $uri, $currentToken, $calid, $operationCode); 99555a741c0SAndreas Boehler if($res === false) 99655a741c0SAndreas Boehler return false; 99755a741c0SAndreas Boehler $currentToken++; 99851f4febbSAndreas Boehler $query = "UPDATE calendars SET synctoken = ? WHERE id = ?"; 99951f4febbSAndreas Boehler $res = $this->sqlite->query($query, $currentToken, $calid); 100055a741c0SAndreas Boehler return ($res !== false); 100155a741c0SAndreas Boehler } 100255a741c0SAndreas Boehler 1003cb71a62aSAndreas Boehler /** 1004cb71a62aSAndreas Boehler * Return the sync URL for a given Page, i.e. a calendar 1005cb71a62aSAndreas Boehler * 1006cb71a62aSAndreas Boehler * @param string $id The page's ID 1007cb71a62aSAndreas Boehler * @param string $user (optional) The user's ID 1008cb71a62aSAndreas Boehler * 1009cb71a62aSAndreas Boehler * @return mixed The sync url or false 1010cb71a62aSAndreas Boehler */ 1011b269830cSAndreas Boehler public function getSyncUrlForPage($id, $user = null) 1012b269830cSAndreas Boehler { 101334a47953SAndreas Boehler if(is_null($userid)) 101434a47953SAndreas Boehler { 101534a47953SAndreas Boehler if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 101634a47953SAndreas Boehler { 101734a47953SAndreas Boehler $userid = $_SERVER['REMOTE_USER']; 101834a47953SAndreas Boehler } 101934a47953SAndreas Boehler else 102034a47953SAndreas Boehler { 102134a47953SAndreas Boehler return false; 102234a47953SAndreas Boehler } 102334a47953SAndreas Boehler } 1024b269830cSAndreas Boehler 1025b269830cSAndreas Boehler $calid = $this->getCalendarIdForPage($id); 1026b269830cSAndreas Boehler if($calid === false) 1027b269830cSAndreas Boehler return false; 1028b269830cSAndreas Boehler 1029b269830cSAndreas Boehler $calsettings = $this->getCalendarSettings($calid); 1030b269830cSAndreas Boehler if(!isset($calsettings['uri'])) 1031b269830cSAndreas Boehler return false; 1032b269830cSAndreas Boehler 1033b269830cSAndreas Boehler $syncurl = DOKU_URL.'lib/plugins/davcal/calendarserver.php/calendars/'.$user.'/'.$calsettings['uri']; 1034b269830cSAndreas Boehler return $syncurl; 1035b269830cSAndreas Boehler } 1036b269830cSAndreas Boehler 1037cb71a62aSAndreas Boehler /** 1038cb71a62aSAndreas Boehler * Return the private calendar's URL for a given page 1039cb71a62aSAndreas Boehler * 1040cb71a62aSAndreas Boehler * @param string $id the page ID 1041cb71a62aSAndreas Boehler * 1042cb71a62aSAndreas Boehler * @return mixed The private URL or false 1043cb71a62aSAndreas Boehler */ 1044f69bb449SAndreas Boehler public function getPrivateURLForPage($id) 1045f69bb449SAndreas Boehler { 1046f69bb449SAndreas Boehler $calid = $this->getCalendarIdForPage($id); 1047f69bb449SAndreas Boehler if($calid === false) 1048f69bb449SAndreas Boehler return false; 1049f69bb449SAndreas Boehler 1050f69bb449SAndreas Boehler return $this->getPrivateURLForCalendar($calid); 1051f69bb449SAndreas Boehler } 1052f69bb449SAndreas Boehler 1053cb71a62aSAndreas Boehler /** 1054cb71a62aSAndreas Boehler * Return the private calendar's URL for a given calendar ID 1055cb71a62aSAndreas Boehler * 1056cb71a62aSAndreas Boehler * @param string $calid The calendar's ID 1057cb71a62aSAndreas Boehler * 1058cb71a62aSAndreas Boehler * @return mixed The private URL or false 1059cb71a62aSAndreas Boehler */ 1060f69bb449SAndreas Boehler public function getPrivateURLForCalendar($calid) 1061f69bb449SAndreas Boehler { 1062185e2535SAndreas Boehler if(isset($this->cachedValues['privateurl'][$calid])) 1063185e2535SAndreas Boehler return $this->cachedValues['privateurl'][$calid]; 106451f4febbSAndreas Boehler $query = "SELECT url FROM calendartoprivateurlmapping WHERE calid = ?"; 106551f4febbSAndreas Boehler $res = $this->sqlite->query($query, $calid); 1066f69bb449SAndreas Boehler $row = $this->sqlite->res2row($res); 1067f69bb449SAndreas Boehler if(!isset($row['url'])) 1068f69bb449SAndreas Boehler { 1069f69bb449SAndreas Boehler $url = uniqid("dokuwiki-").".ics"; 107051f4febbSAndreas Boehler $query = "INSERT INTO calendartoprivateurlmapping (url, calid) VALUES(?, ?)"; 107151f4febbSAndreas Boehler $res = $this->sqlite->query($query, $url, $calid); 1072f69bb449SAndreas Boehler if($res === false) 1073f69bb449SAndreas Boehler return false; 1074f69bb449SAndreas Boehler } 1075f69bb449SAndreas Boehler else 1076f69bb449SAndreas Boehler { 1077f69bb449SAndreas Boehler $url = $row['url']; 1078f69bb449SAndreas Boehler } 1079185e2535SAndreas Boehler 1080185e2535SAndreas Boehler $url = DOKU_URL.'lib/plugins/davcal/ics.php/'.$url; 1081185e2535SAndreas Boehler $this->cachedValues['privateurl'][$calid] = $url; 1082185e2535SAndreas Boehler return $url; 1083f69bb449SAndreas Boehler } 1084f69bb449SAndreas Boehler 1085cb71a62aSAndreas Boehler /** 1086cb71a62aSAndreas Boehler * Retrieve the calendar ID for a given private calendar URL 1087cb71a62aSAndreas Boehler * 1088cb71a62aSAndreas Boehler * @param string $url The private URL 1089cb71a62aSAndreas Boehler * 1090cb71a62aSAndreas Boehler * @return mixed The calendar ID or false 1091cb71a62aSAndreas Boehler */ 1092f69bb449SAndreas Boehler public function getCalendarForPrivateURL($url) 1093f69bb449SAndreas Boehler { 109451f4febbSAndreas Boehler $query = "SELECT calid FROM calendartoprivateurlmapping WHERE url = ?"; 109551f4febbSAndreas Boehler $res = $this->sqlite->query($query, $url); 1096f69bb449SAndreas Boehler $row = $this->sqlite->res2row($res); 1097f69bb449SAndreas Boehler if(!isset($row['calid'])) 1098f69bb449SAndreas Boehler return false; 1099f69bb449SAndreas Boehler return $row['calid']; 1100f69bb449SAndreas Boehler } 1101f69bb449SAndreas Boehler 1102cb71a62aSAndreas Boehler /** 1103cb71a62aSAndreas Boehler * Return a given calendar as ICS feed, i.e. all events in one ICS file. 1104cb71a62aSAndreas Boehler * 11057e0b8590SAndreas Boehler * @param string $calid The calendar ID to retrieve 1106cb71a62aSAndreas Boehler * 1107cb71a62aSAndreas Boehler * @return mixed The calendar events as string or false 1108cb71a62aSAndreas Boehler */ 1109f69bb449SAndreas Boehler public function getCalendarAsICSFeed($calid) 1110f69bb449SAndreas Boehler { 1111f69bb449SAndreas Boehler $calSettings = $this->getCalendarSettings($calid); 1112f69bb449SAndreas Boehler if($calSettings === false) 1113f69bb449SAndreas Boehler return false; 1114f69bb449SAndreas Boehler $events = $this->getAllCalendarEvents($calid); 1115f69bb449SAndreas Boehler if($events === false) 1116f69bb449SAndreas Boehler return false; 1117f69bb449SAndreas Boehler 11187e0b8590SAndreas Boehler // Load SabreDAV 11197e0b8590SAndreas Boehler require_once(DOKU_PLUGIN.'davcal/vendor/autoload.php'); 11207e0b8590SAndreas Boehler $out = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//DAVCal//DAVCal for DokuWiki//EN\r\nCALSCALE:GREGORIAN\r\nX-WR-CALNAME:"; 11217e0b8590SAndreas Boehler $out .= $calSettings['displayname']."\r\n"; 1122f69bb449SAndreas Boehler foreach($events as $event) 1123f69bb449SAndreas Boehler { 11247e0b8590SAndreas Boehler $vcal = \Sabre\VObject\Reader::read($event['calendardata']); 11257e0b8590SAndreas Boehler $evt = $vcal->VEVENT; 11267e0b8590SAndreas Boehler $out .= $evt->serialize(); 1127f69bb449SAndreas Boehler } 11287e0b8590SAndreas Boehler $out .= "END:VCALENDAR\r\n"; 1129f69bb449SAndreas Boehler return $out; 1130f69bb449SAndreas Boehler } 1131f69bb449SAndreas Boehler 11327c7c6b0bSAndreas Boehler /** 11337c7c6b0bSAndreas Boehler * Retrieve a configuration option for the plugin 11347c7c6b0bSAndreas Boehler * 11357c7c6b0bSAndreas Boehler * @param string $key The key to query 113621d04f73SAndreas Boehler * @return mixed The option set, null if not found 11377c7c6b0bSAndreas Boehler */ 11387c7c6b0bSAndreas Boehler public function getConfig($key) 11397c7c6b0bSAndreas Boehler { 11407c7c6b0bSAndreas Boehler return $this->getConf($key); 11417c7c6b0bSAndreas Boehler } 11427c7c6b0bSAndreas Boehler 1143a1a3b679SAndreas Boehler} 1144