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