1<?php 2/** 3 * DokuWiki Syntax Plugin WikiCalendar-ng 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Michael Klier <chi@chimeric.de> 7 * @edited Nick Spindler <n1ck@gmx.at> 8 */ 9 10if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 12require_once(DOKU_PLUGIN.'syntax.php'); 13 14/** 15 * All DokuWiki plugins to extend the parser/rendering mechanism 16 * need to inherit from this class 17 */ 18class syntax_plugin_wikicalendar extends DokuWiki_Syntax_Plugin { 19 20 /** 21 * namespace of the calendar 22 */ 23 var $calendar_ns = ''; 24 25 /** 26 * namespace of the current viewed month 27 */ 28 var $month_ns = ''; 29 30 /** 31 * indicator if first week of the month has been generated 32 */ 33 var $firstWeek = false; 34 35 /** 36 * array with localisations of weekdays 37 */ 38 var $langDays = array(); 39 40 /** 41 * array with localistaions of month 42 */ 43 var $langMonth = array(); 44 45 /** 46 * the current date 47 */ 48 var $curDate = array(); 49 50 /** 51 * the month to show 52 */ 53 var $showMonth = ''; 54 55 /** 56 * the year to show 57 */ 58 var $showYear = ''; 59 60 /** 61 * the global timestamp for date-operations 62 */ 63 var $gTimestamp = ''; 64 65 /** 66 * number days of the current month 67 */ 68 var $numDays = ''; 69 70 /** 71 * date-date to generate the calendar 72 */ 73 var $viewDate = array(); 74 75 /** 76 * return some info 77 */ 78 function getInfo(){ 79 return array( 80 'author' => 'Michael Klier (chi)', 81 'email' => 'chi@chimeric.de', 82 'date' => @file_get_contents(DOKU_PLUGIN.'wikicalendar/VERSION'), 83 'name' => 'WikiCalendar Plugin', 84 'desc' => 'Implements a simple Calendar with links to wikipages.', 85 'url' => 'http://dokuwiki.org/plugin:wikicalendar' 86 ); 87 } 88 89 /** 90 * Some Information first. 91 */ 92 function getType() { return 'substition'; } 93 function getPType() { return 'block'; } 94 function getSort() { return 125; } 95 96 /** 97 * Connect pattern to lexer 98 */ 99 function connectTo($mode) { 100 $this->Lexer->addSpecialPattern('{{cal>.+?}}',$mode,'plugin_wikicalendar'); 101 } 102 103 /** 104 * Handle the match 105 */ 106 function handle($match, $state, $pos, Doku_Handler $handler){ 107 $match = substr($match,6,-2); 108 return array($match); 109 } 110 111 /** 112 * Create output 113 */ 114 function render($mode, Doku_Renderer $renderer, $data) { 115 global $ID; 116 global $conf; 117 118 if($mode == 'xhtml'){ 119 120 $tz = date_default_timezone_get(); 121 if($this->getConf('timezone')) { 122 date_default_timezone_set($this->getConf('timezone')); 123 } 124 125 // define some variables first 126 $this->calendar_ns = ($data[0]) ? $data[0] : $ID; 127 $this->langDays = $this->getLang('days'); 128 $this->langMonth = $this->getLang('month'); 129 $this->curDate = getdate(time()); 130 $requestMonth = $_REQUEST['plugin_wikicalendar_month'] ?? null; 131 $requestYear = $_REQUEST['plugin_wikicalendar_year'] ?? null; 132 $this->showMonth = is_numeric($requestMonth) ? $requestMonth : $this->curDate['mon']; 133 $this->showYear = is_numeric($requestYear) ? $requestYear : $this->curDate['year']; 134 $this->gTimestamp = mktime(0,0,0,$this->showMonth,1,$this->showYear); 135 $this->numDays = date('t',$this->gTimestamp); 136 $this->viewDate = getdate($this->gTimestamp); 137 $this->today = ($this->viewDate['mon'] == $this->curDate['mon'] && 138 $this->viewDate['year'] == $this->curDate['year']) ? 139 $this->curDate['mday'] : null; 140 141 // if month directory exists we keep the old scheme 142 if(is_dir($conf['datadir'].'/'.str_replace(':','/',$this->calendar_ns.':'.$this->showYear.':'.$this->showMonth))) { 143 $this->month_ns = $this->calendar_ns.':'.$this->showYear.':'.$this->showMonth; 144 } else { 145 if($this->showMonth < 10) { 146 $this->month_ns = $this->calendar_ns.':'.$this->showYear.':0'.$this->showMonth; 147 } else { 148 $this->month_ns = $this->calendar_ns.':'.$this->showYear.':'.$this->showMonth; 149 } 150 } 151 152 $this->MonthStart = ($this->viewDate['wday'] == 0) ? 7 : $this->viewDate['wday']; 153 if($this->MonthStart == 7 && $this->getConf('weekstart') == 'Sunday') { 154 $this->MonthStart = 0; 155 } 156 157 // turn off caching 158 $renderer->info['cache'] = false; 159 160 $renderer->doc .= '<div class="plugin_wikicalendar">' . DOKU_LF; 161 $renderer->doc .= $this->_month_xhtml(); 162 $renderer->doc .= $this->_form_go2(); 163 $renderer->doc .= '</div>' . DOKU_LF; 164 165 date_default_timezone_set($tz); 166 return true; 167 } 168 169 return false; 170 } 171 172 /** 173 * Renders the Calendar (month-view) 174 * 175 * @author Michael Klier <chi@chimeric.de> 176 */ 177 function _month_xhtml() { 178 global $ID; 179 180 $out = ''; 181 $wd = 0; 182 $this->firstWeek = false; 183 184 $script = script(); 185 186 $prevMonth = ($this->showMonth-1 > 0) ? ($this->showMonth-1) : 12; 187 $nextMonth = ($this->showMonth+1 < 13) ? ($this->showMonth+1) : 1; 188 189 switch(true) { 190 case($prevMonth == 12): 191 $prevYear = ($this->showYear-1); 192 $nextYear = $this->showYear; 193 break; 194 case($nextMonth == 1): 195 $nextYear = ($this->showYear+1); 196 $prevYear = $this->showYear; 197 break; 198 default: 199 $prevYear = $this->showYear; 200 $nextYear = $this->showYear; 201 break; 202 } 203 204 // create calendar-header 205 $out .= <<<CALHEAD 206<table class="plugin_wikicalendar"> 207 <tr> 208 <th class="month"> 209 <form action="{$script}" method="post" class="prevnext"> 210 <input type="hidden" name="id" value="{$ID}" /> 211 <input type="hidden" name="plugin_wikicalendar_year" value="{$prevYear}" /> 212 <input type="hidden" name="plugin_wikicalendar_month" value="{$prevMonth}" /> 213 <input type="submit" class="btn_prev_month" name="submit" value="←" accesskey="P" title="{$this->langMonth[$prevMonth]} {$prevYear}" /> 214 </form> 215 </th> 216 <th class="blank"> </th> 217 <th class="blank"> </th> 218 <th class="month">{$this->langMonth[$this->viewDate['mon']]}<br />{$this->showYear}<br /></th> 219 <th class="blank"> </th> 220 <th class="blank"> </th> 221 <th class="month"> 222 <form action="{$script}" method="post" class="prevnext"> 223 <input type="hidden" name="id" value="{$ID}" /> 224 <input type="hidden" name="plugin_wikicalendar_year" value="{$nextYear}" /> 225 <input type="hidden" name="plugin_wikicalendar_month" value="{$nextMonth}" /> 226 <input type="submit" class="btn_next_month" name="submit" value="→" accesskey="N" title="{$this->langMonth[$nextMonth]} {$nextYear}" /> 227 </form> 228 </th> 229 </tr> 230CALHEAD; 231 232 // create calendar weekday-headers 233 $out .= "<tr>"; 234 if($this->getConf('weekstart') == 'Sunday') { 235 $last = array_pop($this->langDays); 236 array_unshift($this->langDays, $last); 237 } 238 foreach($this->langDays as $day) { 239 $out .= '<td class="weekday">'.$day.'</td>'; 240 } 241 $out .= "</tr>\n"; 242 243 // create calendar-body 244 for($i=1;$i<=$this->numDays;$i++) { 245 $day = $i; 246 //set day-wikipage - use leading zeros on new pages 247 if($day < 10) { 248 if(page_exists($this->month_ns.':'.$day)) { 249 $dayWP = $this->month_ns.':'.$day; 250 } else { 251 $dayWP = $this->month_ns.':0'.$day; 252 } 253 } else { 254 $dayWP = $this->month_ns.':'.$day; 255 } 256 // close row at end of week 257 if($wd == 7) $out .= '</tr>'; 258 // set weekday 259 if(!isset($wd) or $wd == 7) { $wd = 0; } 260 // start new row when new week starts 261 if($wd == 0) $out .= '<tr>'; 262 263 // create blank fields up to the first day of the month 264 $offset = ($this->getConf('weekstart') == 'Sunday') ? 0 : 1; 265 if(!$this->firstWeek) { 266 while($wd < ($this->MonthStart - $offset)) { 267 $out .= '<td class="blank"> </td>'; 268 $wd++; 269 } 270 // ok - first week is printet 271 $this->firstWeek = true; 272 } 273 274 // check for today 275 if($this->today == $day) { 276 $out .= '<td class="today">'.$this->_calendar_day($dayWP,$day).'</td>'; 277 } else { 278 $out .= '<td class="day">'.$this->_calendar_day($dayWP,$day).'</td>'; 279 } 280 281 // fill remaining days with blanks 282 if($i == $this->numDays && $wd < 7) { 283 while($wd<7) { 284 $out .= '<td class="blank"> </td>'; 285 $wd++; 286 } 287 $out .= '</tr>'; 288 } 289 290 // dont forget to count weekdays 291 $wd++; 292 } 293 294 // finally close the table 295 $out .= '</table>'; 296 297 return ($out); 298 } 299 300 /** 301 * Generates the content of each day in the calendar-table. 302 * 303 * @author Michael Klier <chi@chimeric.de> 304 */ 305 function _calendar_day($wp, $day) { 306 global $lang; 307 global $ID; 308 $out = ''; 309 310 if(file_exists(wikiFN($wp))) { 311 $out .= '<div class="isevent">'; 312 if(auth_quickaclcheck($wp) >= AUTH_READ) { 313 $out .= '<a href="' . wl($wp, array('do' => 'edit', 'plugin_wikicalendar_redirect_id' => $ID, 'plugin_wikicalendar_month' => $this->showMonth, 'plugin_wikicalendar_year' => $this->showYear)) . '" class="plugin_wikicalendar_btn" title="' . $lang['btn_edit'] . '"><img src="' . DOKU_BASE . 'lib/plugins/wikicalendar/img/edit01.png" alt="' . $lang['btn_edit'] . '" width="18" height="18" /></a>' . DOKU_LF; 314 } 315 $out .= '<div class="day_num"><a href="' . wl($wp) . '" class="wikilink1" title="' . $wp . '">'.$day.'</a></div>'; 316 $out .= '<div class="abstract">' . p_get_metadata($wp, 'description abstract') . '</div>' . DOKU_LF; 317 } else { 318 $out .= '<div class="noevent">'; 319 if(auth_quickaclcheck($wp) >= AUTH_CREATE) { 320 //$out .= $this->_btn_add_day($wp); 321 $out .= '<a href="' . wl($wp, array('do' => 'edit', 'plugin_wikicalendar_redirect_id' => $ID, 'plugin_wikicalendar_month' => $this->showMonth, 'plugin_wikicalendar_year' => $this->showYear)) . '" class="plugin_wikicalendar_btn" title="' . $lang['btn_create'] . '"><img src="' . DOKU_BASE . 'lib/plugins/wikicalendar/img/edit01.png" alt="' . $lang['btn_edit'] . '" width="18" height="18" /></a>' . DOKU_LF; 322 } 323 $out .= '<div class="day_num">'.$day.'</div>'; 324 } 325 $out .= '</div>'; 326 return ($out); 327 } 328 329 /** 330 * Generates a From to jump to selected dates 331 * 332 * @author Michael Klier <chi@chimeric.de> 333 */ 334 function _form_go2() { 335 $out = ''; 336 global $ID; 337 338 $out .= '<table class="inline plugin_wikicalendar_go2">' . DOKU_LF; 339 340 $out .= '<form action="'.script().'" method="post">' . DOKU_LF; 341 $out .= '<tr class="default">' . DOKU_LF; 342 $out .= '<td><label>'.$this->getLang('year').':</label></td>' . DOKU_LF; 343 $out .= '<td><div class="input">' . DOKU_LF; 344 $out .= '<select id="year" name="plugin_wikicalendar_year">' . DOKU_LF; 345 346 $year_start = ($this->showYear != $this->curDate['year']) ? $this->showYear - 10 : $this->curDate['year'] - 5; 347 $year_end = $this->showYear + 10; 348 349 for($i=$year_start;$i<=$year_end;$i++) { 350 if($i == $this->showYear || $i == $this->curDate['year']) { 351 $out .= '<option value="'.$i.'" selected="selected">'.$i.'</option>' . DOKU_LF; 352 } else { 353 $out .= '<option value="'.$i.'">'.$i.'</option>' . DOKU_LF; 354 } 355 } 356 357 $out .= '</select>' . DOKU_LF; 358 $out .= '</div>' . DOKU_LF; 359 $out .= '</td>' . DOKU_LF; 360 $out .= '<td><label>'.$this->getLang('mon').':</label></td>' . DOKU_LF; 361 $out .= '<td><div class="input">' . DOKU_LF; 362 $out .= '<select id="month" name="plugin_wikicalendar_month">' . DOKU_LF; 363 364 for($i=1;$i<=12;$i++) { 365 if($i == $this->showMonth) { 366 $out .= '<option value="'.$i.'" selected="selected">'.$this->langMonth[$i].'</option>' . DOKU_LF; 367 } else { 368 $out .= '<option value="'.$i.'">'.$this->langMonth[$i].'</option>' . DOKU_LF; 369 } 370 } 371 372 $out .= '</select>' . DOKU_LF; 373 $out .= '</div>' . DOKU_LF; 374 $out .= '</td>' . DOKU_LF; 375 $out .= '<td><input type="hidden" name="id" value="'.$ID.'" />' . DOKU_LF; 376 $out .= '<input type="submit" class="button" name="go2" value="'.$this->getLang('go').'" />' . DOKU_LF; 377 $out .= '</form>' . DOKU_LF; 378 379 if($this->showYear != $this->curDate['year'] or $this->showMonth != $this->curDate['mon']) { 380 $out .= '<form action="'.script().'" method="post" class="go2" onsubmit="">' . DOKU_LF; 381 $out .= '<input type="hidden" name="id" value="'.$ID.'" />' . DOKU_LF; 382 $out .= '<input type="submit" class="button" name="back2cur" value="'.$this->getLang('current').'" />' . DOKU_LF; 383 $out .= '</form>' . DOKU_LF; 384 } else { 385 $out .= '</td></tr>' . DOKU_LF; 386 } 387 388 $out .= '</table>' . DOKU_LF; 389 390 return ($out); 391 } 392} 393//Setup Vim: tabstop=4 enc=utf8 394