1<?php
2/**
3 * DokuWiki Plugin DAVCal (Calendar 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_calendar extends DokuWiki_Syntax_Plugin {
16
17    protected $hlp = null;
18
19    // Load the helper plugin
20    public function syntax_plugin_davcal_calendar() {
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('\{\{davcal>[^}]*\}\}',$mode,'plugin_davcal_calendar');
51        $this->Lexer->addSpecialPattern('\{\{davcalclient>[^}]*\}\}',$mode,'plugin_davcal_calendar');
52    }
53
54    /**
55     * Handle the match
56     */
57    function handle($match, $state, $pos, Doku_Handler $handler){
58        global $ID;
59        $data = array('name' => $ID,
60                      'description' => $this->getLang('created_by_davcal'),
61                      'id' => array(),
62                      'settings' => 'show',
63                      'view' => 'month',
64                      'forcetimezone' => 'no',
65                      'forcetimeformat' => 'no',
66                      'fcoptions' => array(),
67                      );
68        if(strpos($match, '{{davcalclient') === 0)
69        {
70            $options = trim(substr($match,15,-2));
71            $defaultId = $this->getConf('default_client_id');
72            if(isset($defaultId) && ($defaultId != ''))
73            {
74                $data['id'][$defaultId] = null;
75                $lastid = $defaultId;
76            }
77        }
78        else
79        {
80            $options = trim(substr($match,9,-2));
81            $lastid = $ID;
82        }
83        $options = explode(',', $options);
84
85        foreach($options as $option)
86        {
87            list($key, $val) = explode('=', $option);
88            $key = strtolower(trim($key));
89            $val = trim($val);
90            switch($key)
91            {
92                case 'id':
93                    $lastid = $val;
94                    if(!in_array($val, $data['id']))
95                        $data['id'][$val] = null;
96                break;
97                case 'color':
98                    $data['id'][$lastid] = $val;
99                break;
100                case 'view':
101                    if(in_array($val, array('month', 'basicDay', 'basicWeek', 'agendaWeek', 'agendaDay', 'listWeek', 'listDay', 'listMonth', 'listYear')))
102                        $data['view'] = $val;
103                    else
104                        $data['view'] = 'month';
105                break;
106                case 'fcoptions':
107                    $fcoptions = explode(';', $val);
108                    foreach($fcoptions as $opt)
109                    {
110                        list($o, $v) = explode(':', $opt, 2);
111                        $data['fcoptions'][$o] = $v;
112                    }
113                break;
114                case 'forcetimezone':
115                    $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL);
116                    if(in_array($val, $tzlist) || $val === 'no')
117                        $data['forcetimezone'] = $val;
118                    else
119                        msg($this->getLang('error_timezone_not_in_list'), -1);
120                break;
121                case 'forcetimeformat':
122                    $tfopt = array('lang', '24h', '12h');
123                    if(in_array($val, $tfopt) || $val === 'no')
124                        $data['forcetimeformat'] = $val;
125                    else
126                        msg($this->getLang('error_option_error'), -1);
127                break;
128                default:
129                    $data[$key] = $val;
130            }
131        }
132        // Handle the default case when the user didn't enter a different ID
133        if(empty($data['id']))
134        {
135            $data['id'] = array($ID => null);
136        }
137
138        // Fix up the colors, if no color information is given
139        foreach($data['id'] as $id => $color)
140        {
141            if(is_null($color))
142            {
143                // If this is the current calendar or a WebDAV calendar, use the
144                // default color
145                if(($id === $ID) || (strpos($id, 'webdav://') === 0))
146                {
147                    $data['id'][$id] = '#3a87ad';
148                }
149                // Otherwise, retrieve the color information from the calendar settings
150                else
151                {
152                    $calid = $this->hlp->getCalendarIdForPage($ID);
153                    $settings = $this->hlp->getCalendarSettings($calid);
154                    $color = $settings['calendarcolor'];
155                    $data['id'][$id] = $color;
156                }
157            }
158        }
159
160        // Only update the calendar name/description if the ID matches the page ID.
161        // Otherwise, the calendar is included in another page and we don't want
162        // to interfere with its data.
163        if(in_array($ID, array_keys($data['id'])))
164        {
165            if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
166                $username = $_SERVER['REMOTE_USER'];
167            else
168                $username = uniqid('davcal-');
169            $this->hlp->setCalendarNameForPage($data['name'], $data['description'], $ID, $username);
170            $this->hlp->setCalendarColorForPage($data['id'][$ID], $ID);
171            $this->hlp->enableCalendarForPage($ID);
172        }
173
174        p_set_metadata($ID, array('plugin_davcal' => $data));
175
176        return $data;
177    }
178
179    /**
180     * Create output
181     */
182    function render($format, Doku_Renderer $R, $data) {
183        if($format != 'xhtml') return false;
184        global $ID;
185        $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL);
186
187        // Render the Calendar. Timezone list is within a hidden div,
188        // the calendar ID is in a data-calendarid tag.
189        if($data['forcetimezone'] !== 'no')
190            $R->doc .= '<div id="fullCalendarTimezoneWarning">'.sprintf($this->getLang('this_calendar_uses_timezone'), $data['forcetimezone']).'</div>';
191        $R->doc .= '<div id="fullCalendar" data-calendarpage="'.$ID.'"></div>';
192        $R->doc .= '<div id="fullCalendarTimezoneList" class="fullCalendarTimezoneList" style="display:none">';
193        $R->doc .= '<select id="fullCalendarTimezoneDropdown">';
194        $R->doc .= '<option value="local">'.$this->getLang('local_time').'</option>';
195        foreach($tzlist as $tz)
196        {
197            $R->doc .= '<option value="'.$tz.'">'.$tz.'</option>';
198        }
199        $R->doc .= '</select></div>';
200        if(($this->getConf('hide_settings') !== 1) && ($data['settings'] !== 'hide'))
201        {
202            $R->doc .= '<div class="fullCalendarSettings"><a href="#" class="fullCalendarSettings"><img src="'.DOKU_URL.'lib/plugins/davcal/images/settings.png'.'">'.$this->getLang('settings').'</a></div>';
203        }
204
205    }
206
207
208
209}
210
211// vim:ts=4:sw=4:et:enc=utf-8:
212