1<?php 2/** 3 * DokuWiki Plugin DAVCal (Table Syntax Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Böhler <dev@aboehler.at> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13require_once(DOKU_PLUGIN.'syntax.php'); 14 15class syntax_plugin_davcal_table extends DokuWiki_Syntax_Plugin { 16 17 protected $hlp = null; 18 19 // Load the helper plugin 20 public function syntax_plugin_davcal_table() { 21 $this->hlp =& plugin_load('helper', 'davcal'); 22 } 23 24 25 /** 26 * What kind of syntax are we? 27 */ 28 function getType(){ 29 return 'substition'; 30 } 31 32 /** 33 * What about paragraphs? 34 */ 35 function getPType(){ 36 return 'normal'; 37 } 38 39 /** 40 * Where to sort in? 41 */ 42 function getSort(){ 43 return 165; 44 } 45 46 /** 47 * Connect pattern to lexer 48 */ 49 function connectTo($mode) { 50 $this->Lexer->addSpecialPattern('\{\{davcaltable>[^}]*\}\}',$mode,'plugin_davcal_table'); 51 } 52 53 /** 54 * Handle the match 55 */ 56 function handle($match, $state, $pos, &$handler){ 57 global $ID; 58 $options = trim(substr($match,14,-2)); 59 $options = explode(',', $options); 60 61 $data = array('id' => array(), 62 'startdate' => 'today', 63 'numdays' => 30, 64 'dateformat' => 'Y-m-d H:i', 65 'alldayformat' => 'Y-m-d', 66 'onlystart' => false, 67 'sort' => 'desc', 68 'timezone' => 'local' 69 ); 70 $lastid = $ID; 71 72 foreach($options as $option) 73 { 74 list($key, $val) = explode('=', $option); 75 $key = strtolower(trim($key)); 76 $val = trim($val); 77 switch($key) 78 { 79 case 'id': 80 $lastid = $val; 81 if(!in_array($val, $data['id'])) 82 $data['id'][$val] = '#3a87ad'; 83 break; 84 case 'onlystart': 85 if(($val === 'on') || ($val === 'true')) 86 $data['onlystart'] = true; 87 break; 88 case 'timezone': 89 $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); 90 if(in_array($val, $tzlist) || $val === 'no') 91 $data['timezone'] = $val; 92 else 93 msg($this->getLang('error_timezone_not_in_list'), -1); 94 break; 95 default: 96 $data[$key] = $val; 97 } 98 } 99 100 // Handle the default case when the user didn't enter a different ID 101 if(empty($data['id'])) 102 { 103 $data['id'] = array($ID => '#3a87ad'); 104 } 105 106 return $data; 107 } 108 109 private static function sort_events_asc($a, $b) 110 { 111 $from1 = new \DateTime($a['start']); 112 $from2 = new \DateTime($b['start']); 113 return $from2 < $from1; 114 } 115 116 private static function sort_events_desc($a, $b) 117 { 118 $from1 = new \DateTime($a['start']); 119 $from2 = new \DateTime($b['start']); 120 return $from1 < $from2; 121 } 122 123 /** 124 * Create output 125 */ 126 function render($format, &$R, $data) { 127 if($format == 'metadata') 128 { 129 $R->meta['plugin_davcal']['table'] = true; 130 return true; 131 } 132 if(($format != 'xhtml') && ($format != 'odt')) return false; 133 global $ID; 134 135 $events = array(); 136 $from = $data['startdate']; 137 if($from === 'today') 138 { 139 $from = new \DateTime(); 140 } 141 elseif(strpos($from, 'today-') === 0) 142 { 143 $days = intval(str_replace('today-', '', str_replace(' ', '', $from))); 144 $from = new \DateTime(); 145 $from->sub(new \DateInterval('P'.$days.'D')); 146 } 147 else 148 { 149 $from = new \DateTime($from); 150 } 151 $to = clone $from; 152 $to->add(new \DateInterval('P'.$data['numdays'].'D')); 153 $timezone = $data['timezone']; 154 foreach($data['id'] as $calPage => $color) 155 { 156 $events = array_merge($events, $this->hlp->getEventsWithinDateRange($calPage, 157 $user, $from->format('Y-m-d'), $to->format('Y-m-d'), 158 $timezone)); 159 } 160 if($data['sort'] === 'desc') 161 usort($events, array("syntax_plugin_davcal_table", "sort_events_desc")); 162 else 163 usort($events, array("syntax_plugin_davcal_table", "sort_events_asc")); 164 165 $R->table_open(); 166 $R->tablethead_open(); 167 $R->tableheader_open(); 168 $R->doc .= $data['onlystart'] ? $this->getLang('at') : $this->getLang('from'); 169 $R->tableheader_close(); 170 if(!$data['onlystart']) 171 { 172 $R->tableheader_open(); 173 $R->doc .= $this->getLang('to'); 174 $R->tableheader_close(); 175 } 176 $R->tableheader_open(); 177 $R->doc .= $this->getLang('title'); 178 $R->tableheader_close(); 179 $R->tableheader_open(); 180 $R->doc .= $this->getLang('description'); 181 $R->tableheader_close(); 182 $R->tablethead_close(); 183 foreach($events as $event) 184 { 185 $R->tablerow_open(); 186 $R->tablecell_open(); 187 $from = new \DateTime($event['start']); 188 if($timezone !== 'local') 189 { 190 $from->setTimezone($timezone); 191 $to->setTimezone($timezone); 192 } 193 if($event['allDay'] === true) 194 $R->doc .= $from->format($data['alldayformat']); 195 else 196 $R->doc .= $from->format($data['dateformat']); 197 $R->tablecell_close(); 198 if(!$data['onlystart']) 199 { 200 $to = new \DateTime($event['end']); 201 // Fixup all day events, which have one day in excess 202 if($event['allDay'] === true) 203 { 204 $to->sub(new \DateInterval('P1D')); 205 } 206 $R->tablecell_open(); 207 if($event['allDay'] === true) 208 $R->doc .= $to->format($data['alldayformat']); 209 else 210 $R->doc .= $to->format($data['dateformat']); 211 $R->tablecell_close(); 212 } 213 $R->tablecell_open(); 214 $R->doc .= $event['title']; 215 $R->tablecell_close(); 216 $R->tablecell_open(); 217 $R->doc .= $event['description']; 218 $R->tablecell_close(); 219 $R->tablerow_close(); 220 } 221 $R->table_close(); 222 } 223 224 225 226} 227 228// vim:ts=4:sw=4:et:enc=utf-8: 229