16fbb086dSAndreas Boehler<?php 26fbb086dSAndreas Boehler/** 36fbb086dSAndreas Boehler * DokuWiki Plugin DAVCal (Table Syntax Component) 46fbb086dSAndreas Boehler * 56fbb086dSAndreas Boehler * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 66fbb086dSAndreas Boehler * @author Andreas Böhler <dev@aboehler.at> 76fbb086dSAndreas Boehler */ 86fbb086dSAndreas Boehler 96fbb086dSAndreas Boehlerclass syntax_plugin_davcal_table extends DokuWiki_Syntax_Plugin { 106fbb086dSAndreas Boehler 116fbb086dSAndreas Boehler protected $hlp = null; 126fbb086dSAndreas Boehler 136fbb086dSAndreas Boehler // Load the helper plugin 14*efddf2afSGerrit Uitslag public function __construct() { 156fbb086dSAndreas Boehler $this->hlp =& plugin_load('helper', 'davcal'); 166fbb086dSAndreas Boehler } 176fbb086dSAndreas Boehler 186fbb086dSAndreas Boehler 196fbb086dSAndreas Boehler /** 206fbb086dSAndreas Boehler * What kind of syntax are we? 216fbb086dSAndreas Boehler */ 226fbb086dSAndreas Boehler function getType(){ 236fbb086dSAndreas Boehler return 'substition'; 246fbb086dSAndreas Boehler } 256fbb086dSAndreas Boehler 266fbb086dSAndreas Boehler /** 276fbb086dSAndreas Boehler * What about paragraphs? 286fbb086dSAndreas Boehler */ 296fbb086dSAndreas Boehler function getPType(){ 306fbb086dSAndreas Boehler return 'normal'; 316fbb086dSAndreas Boehler } 326fbb086dSAndreas Boehler 336fbb086dSAndreas Boehler /** 346fbb086dSAndreas Boehler * Where to sort in? 356fbb086dSAndreas Boehler */ 366fbb086dSAndreas Boehler function getSort(){ 376fbb086dSAndreas Boehler return 165; 386fbb086dSAndreas Boehler } 396fbb086dSAndreas Boehler 406fbb086dSAndreas Boehler /** 416fbb086dSAndreas Boehler * Connect pattern to lexer 426fbb086dSAndreas Boehler */ 436fbb086dSAndreas Boehler function connectTo($mode) { 446fbb086dSAndreas Boehler $this->Lexer->addSpecialPattern('\{\{davcaltable>[^}]*\}\}',$mode,'plugin_davcal_table'); 456fbb086dSAndreas Boehler } 466fbb086dSAndreas Boehler 476fbb086dSAndreas Boehler /** 486fbb086dSAndreas Boehler * Handle the match 496fbb086dSAndreas Boehler */ 500b57b6d7SAndreas Boehler function handle($match, $state, $pos, Doku_Handler $handler){ 516fbb086dSAndreas Boehler global $ID; 526fbb086dSAndreas Boehler $options = trim(substr($match,14,-2)); 536fbb086dSAndreas Boehler $options = explode(',', $options); 546fbb086dSAndreas Boehler 556fbb086dSAndreas Boehler $data = array('id' => array(), 566fbb086dSAndreas Boehler 'startdate' => 'today', 576fbb086dSAndreas Boehler 'numdays' => 30, 58a469597cSAndreas Boehler 'startisend' => false, 596fbb086dSAndreas Boehler 'dateformat' => 'Y-m-d H:i', 607bbaf436SAndreas Boehler 'alldayformat' => 'Y-m-d', 616fbb086dSAndreas Boehler 'onlystart' => false, 62d0b117dfSAndreas Boehler 'location' => true, 63b8265976SAndreas Boehler 'calname' => false, 6482a48dfbSAndreas Boehler 'sort' => 'desc', 6582a48dfbSAndreas Boehler 'timezone' => 'local' 666fbb086dSAndreas Boehler ); 676fbb086dSAndreas Boehler $lastid = $ID; 686fbb086dSAndreas Boehler 696fbb086dSAndreas Boehler foreach($options as $option) 706fbb086dSAndreas Boehler { 716fbb086dSAndreas Boehler list($key, $val) = explode('=', $option); 726fbb086dSAndreas Boehler $key = strtolower(trim($key)); 736fbb086dSAndreas Boehler $val = trim($val); 746fbb086dSAndreas Boehler switch($key) 756fbb086dSAndreas Boehler { 766fbb086dSAndreas Boehler case 'id': 776fbb086dSAndreas Boehler $lastid = $val; 786fbb086dSAndreas Boehler if(!in_array($val, $data['id'])) 796fbb086dSAndreas Boehler $data['id'][$val] = '#3a87ad'; 806fbb086dSAndreas Boehler break; 816fbb086dSAndreas Boehler case 'onlystart': 826fbb086dSAndreas Boehler if(($val === 'on') || ($val === 'true')) 836fbb086dSAndreas Boehler $data['onlystart'] = true; 846fbb086dSAndreas Boehler break; 85a469597cSAndreas Boehler case 'startisend': 86a469597cSAndreas Boehler if(($val === 'on') || ($val === 'true')) 87a469597cSAndreas Boehler $data['startisend'] = true; 88a469597cSAndreas Boehler break; 8982a48dfbSAndreas Boehler case 'timezone': 9082a48dfbSAndreas Boehler $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); 9182a48dfbSAndreas Boehler if(in_array($val, $tzlist) || $val === 'no') 9282a48dfbSAndreas Boehler $data['timezone'] = $val; 9382a48dfbSAndreas Boehler else 9482a48dfbSAndreas Boehler msg($this->getLang('error_timezone_not_in_list'), -1); 9582a48dfbSAndreas Boehler break; 96d0b117dfSAndreas Boehler case 'nolocation': 97d0b117dfSAndreas Boehler $data['location'] = false; 98d0b117dfSAndreas Boehler break; 99b8265976SAndreas Boehler case 'calname': 1003cb96734SAndreas Boehler if(($val === 'on') || ($val === 'true')) 101b8265976SAndreas Boehler $data['calname'] = true; 102b8265976SAndreas Boehler break; 1036fbb086dSAndreas Boehler default: 1046fbb086dSAndreas Boehler $data[$key] = $val; 1056fbb086dSAndreas Boehler } 1066fbb086dSAndreas Boehler } 1076fbb086dSAndreas Boehler 1086fbb086dSAndreas Boehler // Handle the default case when the user didn't enter a different ID 1096fbb086dSAndreas Boehler if(empty($data['id'])) 1106fbb086dSAndreas Boehler { 1116fbb086dSAndreas Boehler $data['id'] = array($ID => '#3a87ad'); 1126fbb086dSAndreas Boehler } 1136fbb086dSAndreas Boehler 1146fbb086dSAndreas Boehler return $data; 1156fbb086dSAndreas Boehler } 1166fbb086dSAndreas Boehler 1176fbb086dSAndreas Boehler private static function sort_events_asc($a, $b) 1186fbb086dSAndreas Boehler { 1196fbb086dSAndreas Boehler $from1 = new \DateTime($a['start']); 1206fbb086dSAndreas Boehler $from2 = new \DateTime($b['start']); 1216fbb086dSAndreas Boehler return $from2 < $from1; 1226fbb086dSAndreas Boehler } 1236fbb086dSAndreas Boehler 1246fbb086dSAndreas Boehler private static function sort_events_desc($a, $b) 1256fbb086dSAndreas Boehler { 1266fbb086dSAndreas Boehler $from1 = new \DateTime($a['start']); 1276fbb086dSAndreas Boehler $from2 = new \DateTime($b['start']); 1286fbb086dSAndreas Boehler return $from1 < $from2; 1296fbb086dSAndreas Boehler } 1306fbb086dSAndreas Boehler 1316fbb086dSAndreas Boehler /** 1326fbb086dSAndreas Boehler * Create output 1336fbb086dSAndreas Boehler */ 1340b57b6d7SAndreas Boehler function render($format, Doku_Renderer $R, $data) { 1356fbb086dSAndreas Boehler if($format == 'metadata') 1366fbb086dSAndreas Boehler { 1376fbb086dSAndreas Boehler $R->meta['plugin_davcal']['table'] = true; 1386fbb086dSAndreas Boehler return true; 1396fbb086dSAndreas Boehler } 1406fbb086dSAndreas Boehler if(($format != 'xhtml') && ($format != 'odt')) return false; 1416fbb086dSAndreas Boehler global $ID; 1426fbb086dSAndreas Boehler 1436fbb086dSAndreas Boehler $events = array(); 1446fbb086dSAndreas Boehler $from = $data['startdate']; 145a469597cSAndreas Boehler $toStr = null; 146a469597cSAndreas Boehler 147a469597cSAndreas Boehler // Handle the various options to 'startDate' 1486fbb086dSAndreas Boehler if($from === 'today') 1497bbaf436SAndreas Boehler { 1506fbb086dSAndreas Boehler $from = new \DateTime(); 1517bbaf436SAndreas Boehler } 1527bbaf436SAndreas Boehler elseif(strpos($from, 'today-') === 0) 1537bbaf436SAndreas Boehler { 154a469597cSAndreas Boehler $days = intval(str_replace('today-', '', $from)); 1557bbaf436SAndreas Boehler $from = new \DateTime(); 1567bbaf436SAndreas Boehler $from->sub(new \DateInterval('P'.$days.'D')); 1577bbaf436SAndreas Boehler } 158a469597cSAndreas Boehler elseif(strpos($from, 'today+') === 0) 159a469597cSAndreas Boehler { 160a469597cSAndreas Boehler $days = intval(str_replace('today+', '', $from)); 161a469597cSAndreas Boehler $from = new \DateTime(); 162a469597cSAndreas Boehler $from->add(new \DateInterval('P'.$days.'D')); 163a469597cSAndreas Boehler } 1646fbb086dSAndreas Boehler else 1657bbaf436SAndreas Boehler { 1666fbb086dSAndreas Boehler $from = new \DateTime($from); 1677bbaf436SAndreas Boehler } 168a469597cSAndreas Boehler 169a469597cSAndreas Boehler // Handle the option 'startisend' 170a469597cSAndreas Boehler if($data['startisend'] === true) 171a469597cSAndreas Boehler { 172a469597cSAndreas Boehler if($data['numdays'] > 0) 173a469597cSAndreas Boehler { 174a469597cSAndreas Boehler $to = clone $from; 175a469597cSAndreas Boehler $to->sub(new \DateInterval('P'.$data['numdays'].'D')); 176a469597cSAndreas Boehler $fromStr = $to->format('Y-m-d'); 177a469597cSAndreas Boehler } 178a469597cSAndreas Boehler else 179a469597cSAndreas Boehler { 180a469597cSAndreas Boehler $fromStr = null; 181a469597cSAndreas Boehler } 182a469597cSAndreas Boehler $toStr = $from->format('Y-m-d'); 183a469597cSAndreas Boehler } 184a469597cSAndreas Boehler else 185a469597cSAndreas Boehler { 186a469597cSAndreas Boehler if($data['numdays'] > 0) 187a469597cSAndreas Boehler { 1886fbb086dSAndreas Boehler $to = clone $from; 1896fbb086dSAndreas Boehler $to->add(new \DateInterval('P'.$data['numdays'].'D')); 190a469597cSAndreas Boehler $toStr = $to->format('Y-m-d'); 191a469597cSAndreas Boehler } 192a469597cSAndreas Boehler else 193a469597cSAndreas Boehler { 194a469597cSAndreas Boehler $toStr = null; 195a469597cSAndreas Boehler } 196a469597cSAndreas Boehler $fromStr = $from->format('Y-m-d'); 197a469597cSAndreas Boehler } 198a469597cSAndreas Boehler 199a469597cSAndreas Boehler // Support for timezone 20082a48dfbSAndreas Boehler $timezone = $data['timezone']; 201a469597cSAndreas Boehler 20280e1ddf7SAndreas Boehler // Filter events by user permissions 20380e1ddf7SAndreas Boehler $userEvents = $this->hlp->filterCalendarPagesByUserPermission($data['id']); 20480e1ddf7SAndreas Boehler 205a469597cSAndreas Boehler // Fetch the events 20680e1ddf7SAndreas Boehler foreach($userEvents as $calPage => $color) 2076fbb086dSAndreas Boehler { 2086fbb086dSAndreas Boehler $events = array_merge($events, $this->hlp->getEventsWithinDateRange($calPage, 209a469597cSAndreas Boehler $user, $fromStr, $toStr, $timezone)); 2106fbb086dSAndreas Boehler } 211b8265976SAndreas Boehler 212a469597cSAndreas Boehler // Sort the events 2136fbb086dSAndreas Boehler if($data['sort'] === 'desc') 2146fbb086dSAndreas Boehler usort($events, array("syntax_plugin_davcal_table", "sort_events_desc")); 2156fbb086dSAndreas Boehler else 2166fbb086dSAndreas Boehler usort($events, array("syntax_plugin_davcal_table", "sort_events_asc")); 2176fbb086dSAndreas Boehler 218a469597cSAndreas Boehler // Create tabular output 2196fbb086dSAndreas Boehler $R->table_open(); 2206fbb086dSAndreas Boehler $R->tablethead_open(); 2216fbb086dSAndreas Boehler $R->tableheader_open(); 222f6f0bafeSAndreas Boehler $R->doc .= $data['onlystart'] ? hsc($this->getLang('at')) : hsc($this->getLang('from')); 2236fbb086dSAndreas Boehler $R->tableheader_close(); 2246fbb086dSAndreas Boehler if(!$data['onlystart']) 2256fbb086dSAndreas Boehler { 2266fbb086dSAndreas Boehler $R->tableheader_open(); 227f6f0bafeSAndreas Boehler $R->doc .= hsc($this->getLang('to')); 2286fbb086dSAndreas Boehler $R->tableheader_close(); 2296fbb086dSAndreas Boehler } 2306fbb086dSAndreas Boehler $R->tableheader_open(); 231f6f0bafeSAndreas Boehler $R->doc .= hsc($this->getLang('title')); 2326fbb086dSAndreas Boehler $R->tableheader_close(); 233d0b117dfSAndreas Boehler if($data['location']) 234d0b117dfSAndreas Boehler { 235d0b117dfSAndreas Boehler $R->tableheader_open(); 236d0b117dfSAndreas Boehler $R->doc .= hsc($this->getLang('location')); 237d0b117dfSAndreas Boehler $R->tableheader_close(); 238d0b117dfSAndreas Boehler } 239b8265976SAndreas Boehler if($data['calname']) 240b8265976SAndreas Boehler { 241b8265976SAndreas Boehler $R->tableheader_open(); 242b8265976SAndreas Boehler $R->doc .= hsc($this->getLang('calendar')); 243b8265976SAndreas Boehler $R->tableheader_close(); 244b8265976SAndreas Boehler } 2456fbb086dSAndreas Boehler $R->tableheader_open(); 246f6f0bafeSAndreas Boehler $R->doc .= hsc($this->getLang('description')); 2476fbb086dSAndreas Boehler $R->tableheader_close(); 2486fbb086dSAndreas Boehler $R->tablethead_close(); 2496fbb086dSAndreas Boehler foreach($events as $event) 2506fbb086dSAndreas Boehler { 2516fbb086dSAndreas Boehler $R->tablerow_open(); 2526fbb086dSAndreas Boehler $R->tablecell_open(); 2536fbb086dSAndreas Boehler $from = new \DateTime($event['start']); 25432cad826SAndreas Boehler if($timezone !== 'local') 25532cad826SAndreas Boehler { 256c841370aSAndreas Boehler $from->setTimezone(new \DateTimeZone($timezone)); 257c841370aSAndreas Boehler $to->setTimezone(new \DateTimeZone($timezone)); 25832cad826SAndreas Boehler } 2597bbaf436SAndreas Boehler if($event['allDay'] === true) 2607bbaf436SAndreas Boehler $R->doc .= $from->format($data['alldayformat']); 2617bbaf436SAndreas Boehler else 2626fbb086dSAndreas Boehler $R->doc .= $from->format($data['dateformat']); 2636fbb086dSAndreas Boehler $R->tablecell_close(); 2646fbb086dSAndreas Boehler if(!$data['onlystart']) 2656fbb086dSAndreas Boehler { 26606f3ffd9SAndreas Boehler $to = new \DateTime($event['end']); 26706f3ffd9SAndreas Boehler // Fixup all day events, which have one day in excess 26806f3ffd9SAndreas Boehler if($event['allDay'] === true) 26906f3ffd9SAndreas Boehler { 27006f3ffd9SAndreas Boehler $to->sub(new \DateInterval('P1D')); 27106f3ffd9SAndreas Boehler } 2726fbb086dSAndreas Boehler $R->tablecell_open(); 2737bbaf436SAndreas Boehler if($event['allDay'] === true) 2747bbaf436SAndreas Boehler $R->doc .= $to->format($data['alldayformat']); 2757bbaf436SAndreas Boehler else 2766fbb086dSAndreas Boehler $R->doc .= $to->format($data['dateformat']); 2776fbb086dSAndreas Boehler $R->tablecell_close(); 2786fbb086dSAndreas Boehler } 2796fbb086dSAndreas Boehler $R->tablecell_open(); 280f6f0bafeSAndreas Boehler $R->doc .= hsc($event['title']); 2816fbb086dSAndreas Boehler $R->tablecell_close(); 282d0b117dfSAndreas Boehler if($data['location']) 283d0b117dfSAndreas Boehler { 284d0b117dfSAndreas Boehler $R->tablecell_open(); 285d0b117dfSAndreas Boehler $R->doc .= hsc($event['location']); 286d0b117dfSAndreas Boehler $R->tablecell_close(); 287d0b117dfSAndreas Boehler } 288b8265976SAndreas Boehler if($data['calname']) 289b8265976SAndreas Boehler { 290b8265976SAndreas Boehler $R->tablecell_open(); 291b8265976SAndreas Boehler $R->doc .= hsc($event['calendarname']); 292b8265976SAndreas Boehler $R->tablecell_close(); 293b8265976SAndreas Boehler } 2946fbb086dSAndreas Boehler $R->tablecell_open(); 295f6f0bafeSAndreas Boehler $R->doc .= hsc($event['description']); 2966fbb086dSAndreas Boehler $R->tablecell_close(); 2976fbb086dSAndreas Boehler $R->tablerow_close(); 2986fbb086dSAndreas Boehler } 2996fbb086dSAndreas Boehler $R->table_close(); 3006fbb086dSAndreas Boehler } 3016fbb086dSAndreas Boehler 3026fbb086dSAndreas Boehler 3036fbb086dSAndreas Boehler 3046fbb086dSAndreas Boehler} 3056fbb086dSAndreas Boehler 3066fbb086dSAndreas Boehler// vim:ts=4:sw=4:et:enc=utf-8: 307