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