1<?php
2/**
3 * DokuWiki Syntax Plugin MiniCal
4 *
5 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Alexandre Bastien <alexandre.bastien@fsaa.ulaval.ca>
7 * Forked from WikiCalendar (Michael Klier <chi@chimeric.de>)
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_minical extends DokuWiki_Syntax_Plugin {
19
20     // namespace of the calendar
21    var $calendar_ns    = '';
22
23     // namespace of the current viewed month
24    var $month_ns       = '';
25
26     // indicator if first week of the month has been generated
27    var $firstWeek      = false;
28
29     // array with localisations of weekdays
30    var $langDays       = array();
31
32     // array with localistaions of month
33    var $langMonth      = array();
34
35     // the current date
36    var $curDate        = array();
37
38     // the month to show
39    var $showMonth      = '';
40
41     // the year to show
42    var $showYear       = '';
43
44     // the global timestamp for date-operations
45    var $gTimestamp     = '';
46
47     // number days of the current month
48    var $numDays        = '';
49
50     // date-date to generate the calendar
51    var $viewDate       = array();
52
53     // return some info
54    function getInfo(){
55        return array(
56            'author' => 'Alexandre Bastien',
57            'email'  => 'alexandre.bastien@fsaa.ulaval.ca',
58            'date'   => @file_get_contents(DOKU_PLUGIN.'minical/VERSION'),
59            'name'   => 'MiniCal Plugin',
60            'desc'   => 'Implements a simple Calendar with links to wikipages. Stripped down version forked from Michael Klier\'s minical',
61            'url'    => 'http://dokuwiki.org/plugin:minical'
62        );
63    }
64
65    /**
66     * Some Information first.
67     */
68    function getType() { return 'substition'; }
69    function getPType() { return 'block'; }
70    function getSort() { return 125; }
71
72    /**
73     * Connect pattern to lexer
74     */
75    function connectTo($mode) {
76        $this->Lexer->addSpecialPattern('{{minical>.+?}}',$mode,'plugin_minical');
77    }
78
79    /**
80     * Handle the match
81     */
82    function handle($match, $state, $pos, Doku_Handler $handler){
83        $match = substr($match,10,-2);
84        return array($match);
85    }
86
87    /**
88     * Create output
89     */
90    function render($mode, Doku_Renderer $renderer, $data) {
91        global $ID;
92        global $conf;
93
94        if($mode == 'xhtml'){
95
96            $tz = date_default_timezone_get();
97            if($this->getConf('timezone')) {
98                date_default_timezone_set($this->getConf('timezone'));
99            }
100
101            // define some variables first
102            $this->calendar_ns  = ($data[0]) ? $data[0] : $ID;
103            $this->langDays     = $this->getLang('days');
104            $this->langMonth    = $this->getLang('month');
105            $this->curDate      = getdate(time());
106            $this->showMonth    = (is_numeric($_REQUEST['plugin_minical_month'])) ? $_REQUEST['plugin_minical_month'] : $this->curDate['mon'];
107            $this->showYear     = (is_numeric($_REQUEST['plugin_minical_year']))  ? $_REQUEST['plugin_minical_year']  : $this->curDate['year'];
108            $this->gTimestamp   = mktime(0,0,0,$this->showMonth,1,$this->showYear);
109            $this->numDays      = date('t',$this->gTimestamp);
110            $this->viewDate     = getdate($this->gTimestamp);
111            $this->today        = ($this->viewDate['mon'] == $this->curDate['mon'] &&
112                                   $this->viewDate['year'] == $this->curDate['year']) ?
113                                   $this->curDate['mday'] : null;
114
115            // if month directory exists we keep the old scheme
116            if(is_dir($conf['datadir'].'/'.str_replace(':','/',$this->calendar_ns.':'.$this->showYear.':'.$this->showMonth))) {
117                $this->month_ns = $this->calendar_ns.':'.$this->showYear.':'.$this->showMonth;
118            } else {
119                if($this->showMonth < 10) {
120                    $this->month_ns = $this->calendar_ns.':'.$this->showYear.':0'.$this->showMonth;
121                } else {
122                    $this->month_ns = $this->calendar_ns.':'.$this->showYear.':'.$this->showMonth;
123                }
124            }
125/*
126            if($this->MonthStart == 7 && $this->getConf('weekstart') == 'Sunday') {
127                $this->MonthStart = 0;
128            } else {
129                $this->MonthStart = ($this->viewDate['wday'] == 0) ? 7 : $this->viewDate['wday'];
130            }
131*/
132	    $this->MonthStart = ($this->viewDate['wday'] == 0) ? 7 : $this->viewDate['wday'];
133            if($this->MonthStart == 7 && $this->getConf('weekstart') == 'Sunday') {
134                $this->MonthStart = 0;
135            }
136
137	// turn off caching
138            $renderer->info['cache'] = false;
139
140            $renderer->doc .= '<div class="plugin_minical">' . DOKU_LF;
141            $renderer->doc .= $this->_month_xhtml();
142           $renderer->doc .= '</div>' . DOKU_LF;
143
144            date_default_timezone_set($tz);
145            return true;
146        }
147
148        return false;
149    }
150
151     // Renders the Calendar (month-view)
152    function _month_xhtml() {
153        global $ID;
154
155        $script = script();
156
157        $prevMonth  = ($this->showMonth-1 > 0)  ? ($this->showMonth-1) : 12;
158        $nextMonth  = ($this->showMonth+1 < 13) ? ($this->showMonth+1) : 1;
159
160        switch(true) {
161            case($prevMonth == 12):
162                $prevYear = ($this->showYear-1);
163                $nextYear = $this->showYear;
164                break;
165            case($nextMonth == 1):
166                $nextYear = ($this->showYear+1);
167                $prevYear = $this->showYear;
168                break;
169            default:
170                $prevYear = $this->showYear;
171                $nextYear = $this->showYear;
172                break;
173        }
174
175        // create calendar-header
176        $out .= <<<CALHEAD
177<table class="plugin_minical">
178  <tr>
179    <td class="month">
180      <form action="{$script}" method="post" class="prevnext">
181        <input type="hidden" name="id" value="{$ID}" />
182        <input type="hidden" name="plugin_minical_year" value="{$prevYear}" />
183        <input type="hidden" name="plugin_minical_month" value="{$prevMonth}" />
184        <input type="submit" class="btn_prev_month" name="submit" value="&larr;" accesskey="P" title="{$this->langMonth[$prevMonth]} {$prevYear}" />
185      </form>
186    </td>
187    <td class="month" colspan="3">{$this->langMonth[$this->viewDate['mon']]}</td>
188	<td class="month" colspan="2">{$this->showYear}</td>
189    <td class="month">
190      <form action="{$script}" method="post" class="prevnext">
191        <input type="hidden" name="id" value="{$ID}" />
192        <input type="hidden" name="plugin_minical_year" value="{$nextYear}" />
193        <input type="hidden" name="plugin_minical_month" value="{$nextMonth}" />
194        <input type="submit" class="btn_next_month" name="submit" value="&rarr;" accesskey="N" title="{$this->langMonth[$nextMonth]} {$nextYear}" />
195      </form>
196    </td>
197  </tr>
198CALHEAD;
199
200        // create calendar weekday-headers
201        $out .= "<tr>";
202        if($this->getConf('weekstart') == 'Sunday') {
203            $last = array_pop($this->langDays);
204            array_unshift($this->langDays, $last);
205        }
206        foreach($this->langDays as $day) {
207            $out .= '<td class="weekday">'.$day.'</td>';
208        }
209        $out .= "</tr>\n";
210
211        // create calendar-body
212        for($i=1;$i<=$this->numDays;$i++) {
213            $day = $i;
214            //set day-wikipage - use leading zeros on new pages
215            if($day < 10) {
216                if(page_exists($this->month_ns.':'.$day)) {
217                    $dayWP = $this->month_ns.':'.$day;
218                } else {
219                    $dayWP = $this->month_ns.':0'.$day;
220                }
221            } else {
222                $dayWP = $this->month_ns.':'.$day;
223            }
224            // close row at end of week
225            if($wd == 7) $out .= '</tr>';
226            // set weekday
227            if(!isset($wd) or $wd == 7) { $wd = 0; }
228            // start new row when new week starts
229            if($wd == 0) $out .= '<tr>';
230
231            // create blank fields up to the first day of the month
232            $offset = ($this->getConf('weekstart') == 'Sunday') ? 0 : 1;
233            if(!$this->firstWeek) {
234                while($wd < ($this->MonthStart - $offset)) {
235                    $out .= '<td class="blank">&nbsp;</td>';
236                    $wd++;
237                }
238                // ok - first week is printet
239                $this->firstWeek = true;
240            }
241
242            // check for today
243            if($this->today == $day) {
244                $out .= '<td class="today">'.$this->_calendar_day($dayWP,$day).'</td>';
245            } else {
246                $out .= '<td class="day">'.$this->_calendar_day($dayWP,$day).'</td>';
247            }
248
249            // fill remaining days with blanks
250            if($i == $this->numDays && $wd < 7) {
251                while($wd<6) {
252                    $out .= '<td class="blank">&nbsp;</td>';
253                    $wd++;
254                }
255                $out .= '</tr>';
256            }
257
258            // dont forget to count weekdays
259            $wd++;
260        }
261
262        // finally close the table
263        $out .= '</table>';
264
265        return ($out);
266    }
267
268
269     // Generates the content of each day in the calendar-table.
270    function _calendar_day($wp, $day) {
271        global $lang;
272        global $ID;
273
274        if(file_exists(wikiFN($wp))) {
275            $out .= '<div class="isevent">';
276            if(auth_quickaclcheck($wp) >= AUTH_READ) {
277            }
278            $out .= '<div class="day_num"><a href="' . wl($wp) . '" class="wikilink1" title="' . $wp . '">'.$day.'</a></div>';
279            $out .= '<div class="abstract">' . p_get_metadata($wp, 'description abstract') . '</div>' . DOKU_LF;
280        } else {
281            $out .= '<div class="noevent">';
282            if(auth_quickaclcheck($wp) >= AUTH_CREATE) {
283				$out .= '<a href="' . wl($wp, array('do' => 'edit', 'plugin_minical_redirect_id' => $ID, 'plugin_minical_month' => $this->showMonth, 'plugin_minical_year' => $this->showYear)) . '" class="plugin_minical_btn" title="' . $lang['btn_create'] . '">'.$day.'</a>' . DOKU_LF;
284            } else {
285				if (auth_quickaclcheck($wp) >= AUTH_READ) {
286					$out .= '<span class="plugin_minical_btn">' . $day . '</span>' . DOKU_LF;
287				}
288			}
289        }
290        $out .= '</div>';
291        return ($out);
292    }
293 }
294