xref: /plugin/davcal/syntax/table.php (revision 32cad826f2b0eae7aa98994745948c6bd5fc3e48)
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