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 Boehler// must be run within Dokuwiki 106fbb086dSAndreas Boehlerif(!defined('DOKU_INC')) die(); 116fbb086dSAndreas Boehler 126fbb086dSAndreas Boehlerif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 136fbb086dSAndreas Boehlerrequire_once(DOKU_PLUGIN.'syntax.php'); 146fbb086dSAndreas Boehler 156fbb086dSAndreas Boehlerclass syntax_plugin_davcal_table extends DokuWiki_Syntax_Plugin { 166fbb086dSAndreas Boehler 176fbb086dSAndreas Boehler protected $hlp = null; 186fbb086dSAndreas Boehler 196fbb086dSAndreas Boehler // Load the helper plugin 206fbb086dSAndreas Boehler public function syntax_plugin_davcal_table() { 216fbb086dSAndreas Boehler $this->hlp =& plugin_load('helper', 'davcal'); 226fbb086dSAndreas Boehler } 236fbb086dSAndreas Boehler 246fbb086dSAndreas Boehler 256fbb086dSAndreas Boehler /** 266fbb086dSAndreas Boehler * What kind of syntax are we? 276fbb086dSAndreas Boehler */ 286fbb086dSAndreas Boehler function getType(){ 296fbb086dSAndreas Boehler return 'substition'; 306fbb086dSAndreas Boehler } 316fbb086dSAndreas Boehler 326fbb086dSAndreas Boehler /** 336fbb086dSAndreas Boehler * What about paragraphs? 346fbb086dSAndreas Boehler */ 356fbb086dSAndreas Boehler function getPType(){ 366fbb086dSAndreas Boehler return 'normal'; 376fbb086dSAndreas Boehler } 386fbb086dSAndreas Boehler 396fbb086dSAndreas Boehler /** 406fbb086dSAndreas Boehler * Where to sort in? 416fbb086dSAndreas Boehler */ 426fbb086dSAndreas Boehler function getSort(){ 436fbb086dSAndreas Boehler return 165; 446fbb086dSAndreas Boehler } 456fbb086dSAndreas Boehler 466fbb086dSAndreas Boehler /** 476fbb086dSAndreas Boehler * Connect pattern to lexer 486fbb086dSAndreas Boehler */ 496fbb086dSAndreas Boehler function connectTo($mode) { 506fbb086dSAndreas Boehler $this->Lexer->addSpecialPattern('\{\{davcaltable>[^}]*\}\}',$mode,'plugin_davcal_table'); 516fbb086dSAndreas Boehler } 526fbb086dSAndreas Boehler 536fbb086dSAndreas Boehler /** 546fbb086dSAndreas Boehler * Handle the match 556fbb086dSAndreas Boehler */ 566fbb086dSAndreas Boehler function handle($match, $state, $pos, &$handler){ 576fbb086dSAndreas Boehler global $ID; 586fbb086dSAndreas Boehler $options = trim(substr($match,14,-2)); 596fbb086dSAndreas Boehler $options = explode(',', $options); 606fbb086dSAndreas Boehler 616fbb086dSAndreas Boehler $data = array('id' => array(), 626fbb086dSAndreas Boehler 'startdate' => 'today', 636fbb086dSAndreas Boehler 'numdays' => 30, 64*a469597cSAndreas Boehler 'startisend' => false, 656fbb086dSAndreas Boehler 'dateformat' => 'Y-m-d H:i', 667bbaf436SAndreas Boehler 'alldayformat' => 'Y-m-d', 676fbb086dSAndreas Boehler 'onlystart' => false, 6882a48dfbSAndreas Boehler 'sort' => 'desc', 6982a48dfbSAndreas Boehler 'timezone' => 'local' 706fbb086dSAndreas Boehler ); 716fbb086dSAndreas Boehler $lastid = $ID; 726fbb086dSAndreas Boehler 736fbb086dSAndreas Boehler foreach($options as $option) 746fbb086dSAndreas Boehler { 756fbb086dSAndreas Boehler list($key, $val) = explode('=', $option); 766fbb086dSAndreas Boehler $key = strtolower(trim($key)); 776fbb086dSAndreas Boehler $val = trim($val); 786fbb086dSAndreas Boehler switch($key) 796fbb086dSAndreas Boehler { 806fbb086dSAndreas Boehler case 'id': 816fbb086dSAndreas Boehler $lastid = $val; 826fbb086dSAndreas Boehler if(!in_array($val, $data['id'])) 836fbb086dSAndreas Boehler $data['id'][$val] = '#3a87ad'; 846fbb086dSAndreas Boehler break; 856fbb086dSAndreas Boehler case 'onlystart': 866fbb086dSAndreas Boehler if(($val === 'on') || ($val === 'true')) 876fbb086dSAndreas Boehler $data['onlystart'] = true; 886fbb086dSAndreas Boehler break; 89*a469597cSAndreas Boehler case 'startisend': 90*a469597cSAndreas Boehler if(($val === 'on') || ($val === 'true')) 91*a469597cSAndreas Boehler $data['startisend'] = true; 92*a469597cSAndreas Boehler break; 9382a48dfbSAndreas Boehler case 'timezone': 9482a48dfbSAndreas Boehler $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); 9582a48dfbSAndreas Boehler if(in_array($val, $tzlist) || $val === 'no') 9682a48dfbSAndreas Boehler $data['timezone'] = $val; 9782a48dfbSAndreas Boehler else 9882a48dfbSAndreas Boehler msg($this->getLang('error_timezone_not_in_list'), -1); 9982a48dfbSAndreas Boehler break; 1006fbb086dSAndreas Boehler default: 1016fbb086dSAndreas Boehler $data[$key] = $val; 1026fbb086dSAndreas Boehler } 1036fbb086dSAndreas Boehler } 1046fbb086dSAndreas Boehler 1056fbb086dSAndreas Boehler // Handle the default case when the user didn't enter a different ID 1066fbb086dSAndreas Boehler if(empty($data['id'])) 1076fbb086dSAndreas Boehler { 1086fbb086dSAndreas Boehler $data['id'] = array($ID => '#3a87ad'); 1096fbb086dSAndreas Boehler } 1106fbb086dSAndreas Boehler 1116fbb086dSAndreas Boehler return $data; 1126fbb086dSAndreas Boehler } 1136fbb086dSAndreas Boehler 1146fbb086dSAndreas Boehler private static function sort_events_asc($a, $b) 1156fbb086dSAndreas Boehler { 1166fbb086dSAndreas Boehler $from1 = new \DateTime($a['start']); 1176fbb086dSAndreas Boehler $from2 = new \DateTime($b['start']); 1186fbb086dSAndreas Boehler return $from2 < $from1; 1196fbb086dSAndreas Boehler } 1206fbb086dSAndreas Boehler 1216fbb086dSAndreas Boehler private static function sort_events_desc($a, $b) 1226fbb086dSAndreas Boehler { 1236fbb086dSAndreas Boehler $from1 = new \DateTime($a['start']); 1246fbb086dSAndreas Boehler $from2 = new \DateTime($b['start']); 1256fbb086dSAndreas Boehler return $from1 < $from2; 1266fbb086dSAndreas Boehler } 1276fbb086dSAndreas Boehler 1286fbb086dSAndreas Boehler /** 1296fbb086dSAndreas Boehler * Create output 1306fbb086dSAndreas Boehler */ 1316fbb086dSAndreas Boehler function render($format, &$R, $data) { 1326fbb086dSAndreas Boehler if($format == 'metadata') 1336fbb086dSAndreas Boehler { 1346fbb086dSAndreas Boehler $R->meta['plugin_davcal']['table'] = true; 1356fbb086dSAndreas Boehler return true; 1366fbb086dSAndreas Boehler } 1376fbb086dSAndreas Boehler if(($format != 'xhtml') && ($format != 'odt')) return false; 1386fbb086dSAndreas Boehler global $ID; 1396fbb086dSAndreas Boehler 1406fbb086dSAndreas Boehler $events = array(); 1416fbb086dSAndreas Boehler $from = $data['startdate']; 142*a469597cSAndreas Boehler $toStr = null; 143*a469597cSAndreas Boehler 144*a469597cSAndreas Boehler // Handle the various options to 'startDate' 1456fbb086dSAndreas Boehler if($from === 'today') 1467bbaf436SAndreas Boehler { 1476fbb086dSAndreas Boehler $from = new \DateTime(); 1487bbaf436SAndreas Boehler } 1497bbaf436SAndreas Boehler elseif(strpos($from, 'today-') === 0) 1507bbaf436SAndreas Boehler { 151*a469597cSAndreas Boehler $days = intval(str_replace('today-', '', $from)); 1527bbaf436SAndreas Boehler $from = new \DateTime(); 1537bbaf436SAndreas Boehler $from->sub(new \DateInterval('P'.$days.'D')); 1547bbaf436SAndreas Boehler } 155*a469597cSAndreas Boehler elseif(strpos($from, 'today+') === 0) 156*a469597cSAndreas Boehler { 157*a469597cSAndreas Boehler $days = intval(str_replace('today+', '', $from)); 158*a469597cSAndreas Boehler $from = new \DateTime(); 159*a469597cSAndreas Boehler $from->add(new \DateInterval('P'.$days.'D')); 160*a469597cSAndreas Boehler } 1616fbb086dSAndreas Boehler else 1627bbaf436SAndreas Boehler { 1636fbb086dSAndreas Boehler $from = new \DateTime($from); 1647bbaf436SAndreas Boehler } 165*a469597cSAndreas Boehler 166*a469597cSAndreas Boehler // Handle the option 'startisend' 167*a469597cSAndreas Boehler if($data['startisend'] === true) 168*a469597cSAndreas Boehler { 169*a469597cSAndreas Boehler if($data['numdays'] > 0) 170*a469597cSAndreas Boehler { 171*a469597cSAndreas Boehler $to = clone $from; 172*a469597cSAndreas Boehler $to->sub(new \DateInterval('P'.$data['numdays'].'D')); 173*a469597cSAndreas Boehler $fromStr = $to->format('Y-m-d'); 174*a469597cSAndreas Boehler } 175*a469597cSAndreas Boehler else 176*a469597cSAndreas Boehler { 177*a469597cSAndreas Boehler $fromStr = null; 178*a469597cSAndreas Boehler } 179*a469597cSAndreas Boehler $toStr = $from->format('Y-m-d'); 180*a469597cSAndreas Boehler } 181*a469597cSAndreas Boehler else 182*a469597cSAndreas Boehler { 183*a469597cSAndreas Boehler if($data['numdays'] > 0) 184*a469597cSAndreas Boehler { 1856fbb086dSAndreas Boehler $to = clone $from; 1866fbb086dSAndreas Boehler $to->add(new \DateInterval('P'.$data['numdays'].'D')); 187*a469597cSAndreas Boehler $toStr = $to->format('Y-m-d'); 188*a469597cSAndreas Boehler } 189*a469597cSAndreas Boehler else 190*a469597cSAndreas Boehler { 191*a469597cSAndreas Boehler $toStr = null; 192*a469597cSAndreas Boehler } 193*a469597cSAndreas Boehler $fromStr = $from->format('Y-m-d'); 194*a469597cSAndreas Boehler } 195*a469597cSAndreas Boehler 196*a469597cSAndreas Boehler // Support for timezone 19782a48dfbSAndreas Boehler $timezone = $data['timezone']; 198*a469597cSAndreas Boehler 199*a469597cSAndreas Boehler // Fetch the events 2006fbb086dSAndreas Boehler foreach($data['id'] as $calPage => $color) 2016fbb086dSAndreas Boehler { 2026fbb086dSAndreas Boehler $events = array_merge($events, $this->hlp->getEventsWithinDateRange($calPage, 203*a469597cSAndreas Boehler $user, $fromStr, $toStr, $timezone)); 204*a469597cSAndreas Boehler 2056fbb086dSAndreas Boehler } 206*a469597cSAndreas Boehler // Sort the events 2076fbb086dSAndreas Boehler if($data['sort'] === 'desc') 2086fbb086dSAndreas Boehler usort($events, array("syntax_plugin_davcal_table", "sort_events_desc")); 2096fbb086dSAndreas Boehler else 2106fbb086dSAndreas Boehler usort($events, array("syntax_plugin_davcal_table", "sort_events_asc")); 2116fbb086dSAndreas Boehler 212*a469597cSAndreas Boehler // Create tabular output 2136fbb086dSAndreas Boehler $R->table_open(); 2146fbb086dSAndreas Boehler $R->tablethead_open(); 2156fbb086dSAndreas Boehler $R->tableheader_open(); 2166fbb086dSAndreas Boehler $R->doc .= $data['onlystart'] ? $this->getLang('at') : $this->getLang('from'); 2176fbb086dSAndreas Boehler $R->tableheader_close(); 2186fbb086dSAndreas Boehler if(!$data['onlystart']) 2196fbb086dSAndreas Boehler { 2206fbb086dSAndreas Boehler $R->tableheader_open(); 2216fbb086dSAndreas Boehler $R->doc .= $this->getLang('to'); 2226fbb086dSAndreas Boehler $R->tableheader_close(); 2236fbb086dSAndreas Boehler } 2246fbb086dSAndreas Boehler $R->tableheader_open(); 2256fbb086dSAndreas Boehler $R->doc .= $this->getLang('title'); 2266fbb086dSAndreas Boehler $R->tableheader_close(); 2276fbb086dSAndreas Boehler $R->tableheader_open(); 2286fbb086dSAndreas Boehler $R->doc .= $this->getLang('description'); 2296fbb086dSAndreas Boehler $R->tableheader_close(); 2306fbb086dSAndreas Boehler $R->tablethead_close(); 2316fbb086dSAndreas Boehler foreach($events as $event) 2326fbb086dSAndreas Boehler { 2336fbb086dSAndreas Boehler $R->tablerow_open(); 2346fbb086dSAndreas Boehler $R->tablecell_open(); 2356fbb086dSAndreas Boehler $from = new \DateTime($event['start']); 23632cad826SAndreas Boehler if($timezone !== 'local') 23732cad826SAndreas Boehler { 23832cad826SAndreas Boehler $from->setTimezone($timezone); 23932cad826SAndreas Boehler $to->setTimezone($timezone); 24032cad826SAndreas Boehler } 2417bbaf436SAndreas Boehler if($event['allDay'] === true) 2427bbaf436SAndreas Boehler $R->doc .= $from->format($data['alldayformat']); 2437bbaf436SAndreas Boehler else 2446fbb086dSAndreas Boehler $R->doc .= $from->format($data['dateformat']); 2456fbb086dSAndreas Boehler $R->tablecell_close(); 2466fbb086dSAndreas Boehler if(!$data['onlystart']) 2476fbb086dSAndreas Boehler { 24806f3ffd9SAndreas Boehler $to = new \DateTime($event['end']); 24906f3ffd9SAndreas Boehler // Fixup all day events, which have one day in excess 25006f3ffd9SAndreas Boehler if($event['allDay'] === true) 25106f3ffd9SAndreas Boehler { 25206f3ffd9SAndreas Boehler $to->sub(new \DateInterval('P1D')); 25306f3ffd9SAndreas Boehler } 2546fbb086dSAndreas Boehler $R->tablecell_open(); 2557bbaf436SAndreas Boehler if($event['allDay'] === true) 2567bbaf436SAndreas Boehler $R->doc .= $to->format($data['alldayformat']); 2577bbaf436SAndreas Boehler else 2586fbb086dSAndreas Boehler $R->doc .= $to->format($data['dateformat']); 2596fbb086dSAndreas Boehler $R->tablecell_close(); 2606fbb086dSAndreas Boehler } 2616fbb086dSAndreas Boehler $R->tablecell_open(); 2626fbb086dSAndreas Boehler $R->doc .= $event['title']; 2636fbb086dSAndreas Boehler $R->tablecell_close(); 2646fbb086dSAndreas Boehler $R->tablecell_open(); 2656fbb086dSAndreas Boehler $R->doc .= $event['description']; 2666fbb086dSAndreas Boehler $R->tablecell_close(); 2676fbb086dSAndreas Boehler $R->tablerow_close(); 2686fbb086dSAndreas Boehler } 2696fbb086dSAndreas Boehler $R->table_close(); 2706fbb086dSAndreas Boehler } 2716fbb086dSAndreas Boehler 2726fbb086dSAndreas Boehler 2736fbb086dSAndreas Boehler 2746fbb086dSAndreas Boehler} 2756fbb086dSAndreas Boehler 2766fbb086dSAndreas Boehler// vim:ts=4:sw=4:et:enc=utf-8: 277