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
9class syntax_plugin_davcal_calendar extends DokuWiki_Syntax_Plugin {
10
11    protected $hlp = null;
12
13    // Load the helper plugin
14    public function __construct() {
15        $this->hlp =& plugin_load('helper', 'davcal');
16    }
17
18
19    /**
20     * What kind of syntax are we?
21     */
22    function getType(){
23        return 'substition';
24    }
25
26    /**
27     * What about paragraphs?
28     */
29    function getPType(){
30        return 'normal';
31    }
32
33    /**
34     * Where to sort in?
35     */
36    function getSort(){
37        return 165;
38    }
39
40    /**
41     * Connect pattern to lexer
42     */
43    function connectTo($mode) {
44        $this->Lexer->addSpecialPattern('\{\{davcal>[^}]*\}\}',$mode,'plugin_davcal_calendar');
45        $this->Lexer->addSpecialPattern('\{\{davcalclient>[^}]*\}\}',$mode,'plugin_davcal_calendar');
46    }
47
48    /**
49     * Handle the match
50     */
51    function handle($match, $state, $pos, Doku_Handler $handler){
52        global $ID;
53        $data = array('name' => $ID,
54                      'description' => $this->getLang('created_by_davcal'),
55                      'id' => array(),
56                      'settings' => 'show',
57                      'view' => 'month',
58                      'forcetimezone' => 'no',
59                      'forcetimeformat' => 'no',
60                      'fcoptions' => array(),
61                      );
62        if(strpos($match, '{{davcalclient') === 0)
63        {
64            $options = trim(substr($match,15,-2));
65            $defaultId = $this->getConf('default_client_id');
66            if(isset($defaultId) && ($defaultId != ''))
67            {
68                $data['id'][$defaultId] = null;
69                $lastid = $defaultId;
70            }
71        }
72        else
73        {
74            $options = trim(substr($match,9,-2));
75            $lastid = $ID;
76        }
77        $options = explode(',', $options);
78
79        foreach($options as $option)
80        {
81            $option = trim($option);
82            if(empty($option)) continue;
83
84            $parts = explode('=', $option, 2);
85            if(count($parts) < 2) continue;
86
87            list($key, $val) = $parts;
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                        $opt = trim($opt);
111                        if(empty($opt)) continue;
112
113                        $parts = explode(':', $opt, 2);
114                        if(count($parts) < 2) continue;
115
116                        list($o, $v) = $parts;
117                        $data['fcoptions'][$o] = $v;
118                    }
119                break;
120                case 'forcetimezone':
121                    $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL);
122                    if(in_array($val, $tzlist) || $val === 'no')
123                        $data['forcetimezone'] = $val;
124                    else
125                        msg($this->getLang('error_timezone_not_in_list'), -1);
126                break;
127                case 'forcetimeformat':
128                    $tfopt = array('lang', '24h', '12h');
129                    if(in_array($val, $tfopt) || $val === 'no')
130                        $data['forcetimeformat'] = $val;
131                    else
132                        msg($this->getLang('error_option_error'), -1);
133                break;
134                default:
135                    $data[$key] = $val;
136            }
137        }
138        // Handle the default case when the user didn't enter a different ID
139        if(empty($data['id']))
140        {
141            $data['id'] = array($ID => null);
142        }
143
144        // Fix up the colors, if no color information is given
145        foreach($data['id'] as $id => $color)
146        {
147            if(is_null($color))
148            {
149                // If this is the current calendar or a WebDAV calendar, use the
150                // default color
151                if(($id === $ID) || (strpos($id, 'webdav://') === 0))
152                {
153                    $data['id'][$id] = '#3a87ad';
154                }
155                // Otherwise, retrieve the color information from the calendar settings
156                else
157                {
158                    $calid = $this->hlp->getCalendarIdForPage($ID);
159                    $settings = $this->hlp->getCalendarSettings($calid);
160                    if (is_array($settings) && isset($settings['calendarcolor'])) {
161                        $color = $settings['calendarcolor'];
162                    } else {
163                        $color = '#3a87ad'; // fallback color if settings are missing
164                    }
165                    $data['id'][$id] = $color;
166                }
167            }
168        }
169
170        // Only update the calendar name/description if the ID matches the page ID.
171        // Otherwise, the calendar is included in another page and we don't want
172        // to interfere with its data.
173        if(in_array($ID, array_keys($data['id'])))
174        {
175            if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
176                $username = $_SERVER['REMOTE_USER'];
177            else
178                $username = uniqid('davcal-');
179            $this->hlp->setCalendarNameForPage($data['name'], $data['description'], $ID, $username);
180            $this->hlp->setCalendarColorForPage($data['id'][$ID], $ID);
181            $this->hlp->enableCalendarForPage($ID);
182        }
183
184        p_set_metadata($ID, array('plugin_davcal' => $data));
185
186        return $data;
187    }
188
189    /**
190     * Create output
191     */
192    function render($format, Doku_Renderer $R, $data) {
193        if($format != 'xhtml') return false;
194        global $ID;
195        $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL);
196
197        // Render the Calendar. Timezone list is within a hidden div,
198        // the calendar ID is in a data-calendarid tag.
199        if($data['forcetimezone'] !== 'no')
200            $R->doc .= '<div id="fullCalendarTimezoneWarning">'.sprintf($this->getLang('this_calendar_uses_timezone'), $data['forcetimezone']).'</div>';
201        $R->doc .= '<div id="fullCalendar" data-calendarpage="'.$ID.'"></div>';
202        $R->doc .= '<div id="fullCalendarTimezoneList" class="fullCalendarTimezoneList" style="display:none">';
203        $R->doc .= '<select id="fullCalendarTimezoneDropdown">';
204        $R->doc .= '<option value="local">'.$this->getLang('local_time').'</option>';
205        foreach($tzlist as $tz)
206        {
207            $R->doc .= '<option value="'.$tz.'">'.$tz.'</option>';
208        }
209        $R->doc .= '</select></div>';
210        if(($this->getConf('hide_settings') !== 1) && ($data['settings'] !== 'hide'))
211        {
212            $R->doc .= '<div class="fullCalendarSettings"><a href="#" class="fullCalendarSettings"><img src="'.DOKU_URL.'lib/plugins/davcal/images/settings.png'.'">'.$this->getLang('settings').'</a></div>';
213        }
214
215    }
216
217
218
219}
220
221// vim:ts=4:sw=4:et:enc=utf-8:
222