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