diff --git a/script.js b/script.js --- a/script.js +++ b/script.js @@ -1,866 +1,955 @@ /* DOKUWIKI:include_once fullcalendar-3.7.0/moment.js */ /* DOKUWIKI:include_once fullcalendar-3.7.0/fullcalendar.js */ /* DOKUWIKI:include_once fullcalendar-3.7.0/locale/de.js */ /* DOKUWIKI:include_once fullcalendar-3.7.0/locale/en.js */ /* DOKUWIKI:include_once fullcalendar-3.7.0/locale/fr.js */ /* DOKUWIKI:include_once fullcalendar-3.7.0/locale/nl.js */ /* DOKUWIKI:include_once datetimepicker-2.4.5/jquery.datetimepicker.js */ /* DOKUWIKI:include_once jstz.js */ /** * Initialize the DAVCal script, attaching some event handlers and triggering * the initial load of the fullcalendar JS */ jQuery(function() { // Redefine functions for using moment.js with datetimepicker Date.parseDate = function( input, format ){ return moment(input,format).toDate(); }; Date.prototype.dateFormat = function( format ){ return moment(this).format(format); }; // Attach to event links - var calendarpage = jQuery('#fullCalendar').data('calendarpage'); - if(!calendarpage) return; - dw_davcal__modals.page = calendarpage; + var calendarpage1 = jQuery('#fullCalendar').data('calendarpage'); + if(calendarpage1) + { + dw_davcal__modals.page = calendarpage1; + + jQuery('div.fullCalendarSettings a').each(function() { + var $link = jQuery(this); + var href = $link.attr('href'); + if (!href) return; - jQuery('div.fullCalendarSettings a').each(function() { - var $link = jQuery(this); - var href = $link.attr('href'); - if (!href) return; - - $link.click( - function(e) { - dw_davcal__modals.showSettingsDialog(); - e.preventDefault(); - return ''; + $link.click( + function(e) { + dw_davcal__modals.showSettingsDialog(); + e.preventDefault(); + return ''; + } + ); } ); + } + + // Attach to event view links + var calendarpage2 = jQuery('div.davcalevents').data('calendarpage'); + if(calendarpage2) + { + dw_davcal__modals.page = calendarpage2; + + jQuery('a.davcalEventsAddNew').each(function() { + var $link = jQuery(this); + var href = $link.attr('href'); + if (!href) return; + + $link.click( + function(e) { + dw_davcal__modals.showEditEventDialog(null, dw_davcal__modals.reasonParams.CreateEvent); + e.preventDefault(); + return ''; + } + ); } - ); + ); + } + + if(!calendarpage1 && !calendarpage2) + return; // First, retrieve the current settings. // Upon success, initialize fullcalendar. var postArray = { }; jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_davcal', id: dw_davcal__modals.page, page: dw_davcal__modals.page, action: 'getSettings', params: postArray, sectok: JSINFO.plugin.davcal['sectok'] }, function(data) { var result = data['result']; if(result === true) { dw_davcal__modals.settings = data['settings']; var tz = false; if(data['settings']['timezone'] !== '') tz = data['settings']['timezone']; // Force-overwrite thhe timezone setting if requested if(data['settings']['meta']['forcetimezone'] !== 'no') tz = data['settings']['meta']['forcetimezone']; var fcOptions = { dayClick: function(date, jsEvent, view) { - dw_davcal__modals.showEditEventDialog(date, false); + dw_davcal__modals.showEditEventDialog(date, dw_davcal__modals.reasonParams.EditEntry); }, eventClick: function(calEvent, jsEvent, view) { - dw_davcal__modals.showEditEventDialog(calEvent, true); + dw_davcal__modals.showEditEventDialog(calEvent, dw_davcal__modals.reasonParams.CreateEntry); }, events: { url: DOKU_BASE + 'lib/exe/ajax.php', type: 'POST', data: { call: 'plugin_davcal', action: 'getEvents', id: dw_davcal__modals.page, page: dw_davcal__modals.page, sectok: JSINFO.plugin.davcal['sectok'] }, error: function() { dw_davcal__modals.msg = LANG.plugins.davcal['error_retrieving_data']; dw_davcal__modals.showDialog(false); } }, header: { left: 'title', center: 'today prev,next', right: 'month,agendaWeek,agendaDay,listWeek' }, locale: JSINFO.plugin.davcal['language'], weekNumbers: (data['settings']['weeknumbers'] == 1) ? true : false, timezone: tz, weekends: (data['settings']['workweek'] == 1) ? false : true, firstDay: (data['settings']['monday'] == 1) ? 1 : 0, defaultView: data['settings']['meta']['view'], }; var timeformat = data['settings']['timeformat']; // Force-overwrite the user's timezone setting if requested by the calendar if(data['settings']['meta']['forcetimeformat'] !== 'no') timeformat = data['settings']['meta']['forcetimeformat']; if(timeformat !== 'lang') { // If the time format is language-based, we don't need to pass // the timeFormat option to fullCalendar if(timeformat == '24h') { fcOptions.timeFormat = 'H:mm'; } if(timeformat == '12h') { fcOptions.timeFormat = 'h:mmt'; } } for (var key in data['settings']['meta']['fcoptions']) { if(!data['settings']['meta']['fcoptions'].hasOwnProperty(key)) continue; var val = data['settings']['meta']['fcoptions'][key]; fcOptions[key] = val; } var detectedTz = jstz.determine().name(); dw_davcal__modals.detectedTz = detectedTz; // The current TZ value holds either the uers's selection or // the force timezone value dw_davcal__modals.currentTz = (tz === false) ? '' : tz; // Initialize the davcal popup var res = jQuery('#fullCalendar').fullCalendar(fcOptions); } } ); }); /** * This holds all modal windows that DAVCal uses. */ var dw_davcal__modals = { $editEventDialog: null, $dialog: null, $settingsDialog: null, $inputDialog: null, msg: null, completeCb: null, action: null, uid: null, settings: null, page: null, detectedTz: null, currentTz: null, + reasonParams : { + EditEntry : 0, + CreateEntry : 1, + EditEvent : 2, + CreateEvent : 3, + }, /** * Show the settings dialog */ // FIXME: Hide URLs for multi-calendar showSettingsDialog : function() { if(dw_davcal__modals.$settingsDialog) return; // Dialog buttons are language-dependent and defined here. // Attach event handlers for save and cancel. var dialogButtons = {}; if(!JSINFO.plugin.davcal['disable_settings']) { dialogButtons[LANG.plugins.davcal['save']] = function() { var postArray = { }; jQuery("input[class=dw_davcal__settings], select[class=dw_davcal__settings]").each(function() { if(jQuery(this).attr('type') == 'checkbox') { postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0; } else { postArray[jQuery(this).prop('name')] = jQuery(this).val(); } }); jQuery('#dw_davcal__ajaxsettings').html(''); jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_davcal', id: dw_davcal__modals.page, page: dw_davcal__modals.page, action: 'saveSettings', params: postArray, sectok: JSINFO.plugin.davcal['sectok'] }, function(data) { var result = data['result']; var html = data['html']; jQuery('#dw_davcal__ajaxsettings').html(html); if(result === true) { location.reload(); } } ); }; } dialogButtons[LANG.plugins.davcal['cancel']] = function () { dw_davcal__modals.hideSettingsDialog(); }; var settingsHtml = '
'; if(JSINFO.plugin.davcal['disable_settings'] && JSINFO.plugin.davcal['disable_sync'] && JSINFO.plugin.davcal['disable_ics']) { settingsHtml += LANG.plugins.davcal['nothing_to_show']; } if(!JSINFO.plugin.davcal['disable_settings']) { settingsHtml += '' + '' + '' + '' + ''; } if(!JSINFO.plugin.davcal['disable_sync']) { settingsHtml += ''; settingsHtml += ''; } if(!JSINFO.plugin.davcal['disable_ics']) { settingsHtml += ''; } settingsHtml += '
' + LANG.plugins.davcal['timezone'] + '
' + LANG.plugins.davcal['timeformat'] + '
' + LANG.plugins.davcal['weeknumbers'] + '
' + LANG.plugins.davcal['only_workweek'] + '
' + LANG.plugins.davcal['start_monday'] + '
' + LANG.plugins.davcal['sync_url'] + '
' + LANG.plugins.davcal['sync_ical'] + '
' + LANG.plugins.davcal['private_url'] + '
' + '
' + '
'; dw_davcal__modals.$settingsDialog = jQuery(document.createElement('div')) .dialog({ autoOpen: false, draggable: true, // fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues drag: function(event, ui) { var fixPix = jQuery(document).scrollTop(); iObj = ui.position; iObj.top = iObj.top - fixPix; jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); }, title: LANG.plugins.davcal['settings'], resizable: true, buttons: dialogButtons, }) .html( settingsHtml ) .parent() .attr('id','dw_davcal__settings') .show() .appendTo('.dokuwiki:first'); jQuery('#dw_davcal__settings').position({ my: "center", at: "center", of: window }); // Initialize current settings if(!JSINFO.plugin.davcal['disable_settings']) { var $tzdropdown = jQuery('#dw_davcal__settings_timezone'); jQuery('#fullCalendarTimezoneList option').each(function() { jQuery(''); } - if(edit || (dw_davcal__modals.settings['calids'].length < 1)) + if((action == "editEvent") || (action == "editEntry") || (dw_davcal__modals.settings['calids'].length < 1)) { $dropdown.prop('disabled', true); } // Set up existing/predefined values jQuery('#dw_davcal__tz_edit').val(dw_davcal__modals.detectedTz); jQuery('#dw_davcal__currenttz_edit').val(dw_davcal__modals.currentTz); jQuery('#dw_davcal__uid_edit').val(calEvent.id); jQuery('#dw_davcal__eventname_edit').val(calEvent.title); jQuery('#dw_davcal__eventlocation_edit').val(calEvent.location); jQuery('#dw_davcal__eventfrom_edit').val(calEvent.start.format('YYYY-MM-DD')); jQuery('#dw_davcal__eventfromtime_edit').val(calEvent.start.format('HH:mm')); jQuery('#dw_davcal__eventdescription_edit').val(calEvent.description); if(calEvent.attachments && (calEvent.attachments !== null)) { for(var i=0; i' + url + '' + LANG.plugins.davcal['delete'] + ''; jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); } } dw_davcal__modals.attachAttachmentDeleteHandlers(); jQuery('#dw_davcal__editevent_attach').on("click", function(e) { e.preventDefault(); var url = jQuery('#dw_davcal__editevent_attachment').val(); if(url == '') return false; jQuery('#dw_davcal__editevent_attachment').val('http://'); var row = '' + url + '' + LANG.plugins.davcal['delete'] + ''; jQuery('#dw_davcal__editevent_attachments > tbody:last').append(row); dw_davcal__modals.attachAttachmentDeleteHandlers(); return false; }); if(calEvent.allDay && (calEvent.end === null)) { jQuery('#dw_davcal__eventto_edit').val(calEvent.start.format('YYYY-MM-DD')); jQuery('#dw_davcal__eventtotime_edit').val(calEvent.start.format('HH:mm')); } else if(calEvent.allDay) { endEvent = moment(calEvent.end); endEvent.subtract(1, 'days'); jQuery('#dw_davcal__eventto_edit').val(endEvent.format('YYYY-MM-DD')); jQuery('#dw_davcal__eventotime_edit').val(endEvent.format('HH:mm')); } else { jQuery('#dw_davcal__eventto_edit').val(calEvent.end.format('YYYY-MM-DD')); jQuery('#dw_davcal__eventtotime_edit').val(calEvent.end.format('HH:mm')); } jQuery('#dw_davcal__allday_edit').prop('checked', calEvent.allDay); // attach event handlers jQuery('#dw_davcal__edit .ui-dialog-titlebar-close').click(function(){ dw_davcal__modals.hideEditEventDialog(); }); jQuery('#dw_davcal__eventfrom_edit').datetimepicker({format:'YYYY-MM-DD', formatDate:'YYYY-MM-DD', datepicker: true, timepicker: false, lang: JSINFO.plugin.davcal['language'], }); jQuery('#dw_davcal__eventfromtime_edit').datetimepicker({format:'HH:mm', formatTime:'HH:mm', datepicker: false, timepicker: true, lang: JSINFO.plugin.davcal['language'], step: 15}); jQuery('#dw_davcal__eventto_edit').datetimepicker({format:'YYYY-MM-DD', formatDate:'YYYY-MM-DD', datepicker: true, timepicker: false, lang: JSINFO.plugin.davcal['language'], }); jQuery('#dw_davcal__eventtotime_edit').datetimepicker({format:'HH:mm', formatTime:'HH:mm', datepicker: false, timepicker: true, lang: JSINFO.plugin.davcal['language'], step:15}); jQuery('#dw_davcal__allday_edit').change(function() { if(jQuery(this).is(":checked")) { jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', true); jQuery('#dw_davcal__eventtotime_edit').prop('readonly', true); } else { jQuery('#dw_davcal__eventfromtime_edit').prop('readonly', false); jQuery('#dw_davcal__eventtotime_edit').prop('readonly', false); } }); jQuery('#dw_davcal__allday_edit').change(); }, /** * Attach handles to delete the attachments to all 'delete' links */ attachAttachmentDeleteHandlers: function() { jQuery("#dw_davcal__editevent_attachments .deleteLink").on("click", function(e) { e.preventDefault(); var tr = jQuery(this).closest('tr'); tr.css("background-color", "#FF3700"); tr.fadeOut(400, function() { tr.remove(); }); return false; }); }, /** * Show an info/confirmation dialog * @param {Object} confirm Whether a confirmation dialog (true) or an info dialog (false) is requested */ showDialog : function(confirm) { if(dw_davcal__modals.$confirmDialog) return; var dialogButtons = {}; var title = ''; if(confirm) { title = LANG.plugins.davcal['confirmation']; var pageid = jQuery("#dw_davcal__editevent_calendar option:selected").val(); dialogButtons[LANG.plugins.davcal['yes']] = function() { jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_davcal', id: pageid, page: dw_davcal__modals.page, action: dw_davcal__modals.action, params: { uid: dw_davcal__modals.uid }, sectok: JSINFO.plugin.davcal['sectok'] }, function(data) { dw_davcal__modals.completeCb(data); } ); dw_davcal__modals.hideDialog(); }; dialogButtons[LANG.plugins.davcal['cancel']] = function() { dw_davcal__modals.hideDialog(); }; } else { title = LANG.plugins.davcal['info']; dialogButtons[LANG.plugins.davcal['ok']] = function() { dw_davcal__modals.hideDialog(); }; } dw_davcal__modals.$dialog = jQuery(document.createElement('div')) .dialog({ autoOpen: false, draggable: true, //fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues drag: function(event, ui) { var fixPix = jQuery(document).scrollTop(); iObj = ui.position; iObj.top = iObj.top - fixPix; jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px"); }, title: title, resizable: true, buttons: dialogButtons, }) .html( '
' + dw_davcal__modals.msg + '
' ) .parent() .attr('id','dw_davcal__confirm') .show() .appendTo('.dokuwiki:first'); jQuery('#dw_davcal__confirm').position({ my: "center", at: "center", of: window }); // attach event handlers jQuery('#dw_davcal__confirm .ui-dialog-titlebar-close').click(function(){ dw_davcal__modals.hideDialog(); }); }, /** * Hide the edit event dialog */ hideEditEventDialog : function() { dw_davcal__modals.$editEventDialog.empty(); dw_davcal__modals.$editEventDialog.remove(); dw_davcal__modals.$editEventDialog = null; }, /** * Hide the confirm/info dialog */ hideDialog: function() { dw_davcal__modals.$dialog.empty(); dw_davcal__modals.$dialog.remove(); dw_davcal__modals.$dialog = null; }, /** * Hide the settings dialog */ hideSettingsDialog: function() { dw_davcal__modals.$settingsDialog.empty(); dw_davcal__modals.$settingsDialog.remove(); dw_davcal__modals.$settingsDialog = null; } }; diff --git a/syntax/calendar.php b/syntax/calendar.php --- a/syntax/calendar.php +++ b/syntax/calendar.php @@ -1,211 +1,229 @@ */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_davcal_calendar extends DokuWiki_Syntax_Plugin { protected $hlp = null; // Load the helper plugin public function syntax_plugin_davcal_calendar() { $this->hlp =& plugin_load('helper', 'davcal'); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } /** * What about paragraphs? */ function getPType(){ return 'normal'; } /** * Where to sort in? */ function getSort(){ return 165; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{davcal>[^}]*\}\}',$mode,'plugin_davcal_calendar'); $this->Lexer->addSpecialPattern('\{\{davcalclient>[^}]*\}\}',$mode,'plugin_davcal_calendar'); } /** * Handle the match */ function handle($match, $state, $pos, Doku_Handler $handler){ global $ID; $data = array('name' => $ID, 'description' => $this->getLang('created_by_davcal'), 'id' => array(), 'settings' => 'show', 'view' => 'month', 'forcetimezone' => 'no', 'forcetimeformat' => 'no', 'fcoptions' => array(), ); if(strpos($match, '{{davcalclient') === 0) { $options = trim(substr($match,15,-2)); $defaultId = $this->getConf('default_client_id'); if(isset($defaultId) && ($defaultId != '')) { $data['id'][$defaultId] = null; $lastid = $defaultId; } } else { $options = trim(substr($match,9,-2)); $lastid = $ID; } $options = explode(',', $options); foreach($options as $option) { list($key, $val) = explode('=', $option); $key = strtolower(trim($key)); $val = trim($val); switch($key) { case 'id': $lastid = $val; if(!in_array($val, $data['id'])) $data['id'][$val] = null; break; case 'color': $data['id'][$lastid] = $val; break; case 'view': if(in_array($val, array('month', 'basicDay', 'basicWeek', 'agendaWeek', 'agendaDay', 'listWeek', 'listDay', 'listMonth', 'listYear'))) $data['view'] = $val; else $data['view'] = 'month'; break; case 'fcoptions': $fcoptions = explode(';', $val); foreach($fcoptions as $opt) { list($o, $v) = explode(':', $opt, 2); $data['fcoptions'][$o] = $v; } break; case 'forcetimezone': $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); if(in_array($val, $tzlist) || $val === 'no') $data['forcetimezone'] = $val; else msg($this->getLang('error_timezone_not_in_list'), -1); break; case 'forcetimeformat': $tfopt = array('lang', '24h', '12h'); if(in_array($val, $tfopt) || $val === 'no') $data['forcetimeformat'] = $val; else msg($this->getLang('error_option_error'), -1); break; default: $data[$key] = $val; } } // Handle the default case when the user didn't enter a different ID if(empty($data['id'])) { $data['id'] = array($ID => null); } // Fix up the colors, if no color information is given foreach($data['id'] as $id => $color) { if(is_null($color)) { // If this is the current calendar or a WebDAV calendar, use the // default color if(($id === $ID) || (strpos($id, 'webdav://') === 0)) { $data['id'][$id] = '#3a87ad'; } // Otherwise, retrieve the color information from the calendar settings else { $calid = $this->hlp->getCalendarIdForPage($ID); $settings = $this->hlp->getCalendarSettings($calid); $color = $settings['calendarcolor']; $data['id'][$id] = $color; } } } // Only update the calendar name/description if the ID matches the page ID. // Otherwise, the calendar is included in another page and we don't want // to interfere with its data. if(in_array($ID, array_keys($data['id']))) { if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) $username = $_SERVER['REMOTE_USER']; else $username = uniqid('davcal-'); $this->hlp->setCalendarNameForPage($data['name'], $data['description'], $ID, $username); $this->hlp->setCalendarColorForPage($data['id'][$ID], $ID); $this->hlp->enableCalendarForPage($ID); } - p_set_metadata($ID, array('plugin_davcal' => $data)); + // FIXME + //p_set_metadata($ID, array('plugin_davcal' => $data)); return $data; } /** * Create output */ function render($format, Doku_Renderer $R, $data) { + if($format == 'metadata') + { + if(isset($R->persistent['plugin_davcal'])) + { + unset($R->persistent['plugin_davcal']); + $R->meta['plugin_davcal'] = array(); + } + + if(isset($R->meta['plugin_davcal'])) + { + $R->meta['plugin_davcal'] = array_merge_recursive($R->meta['plugin_davcal'], $data); + } + else + { + $R->meta['plugin_davcal'] = $data; + } + } if($format != 'xhtml') return false; global $ID; $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); // Render the Calendar. Timezone list is within a hidden div, // the calendar ID is in a data-calendarid tag. if($data['forcetimezone'] !== 'no') $R->doc .= '
'.sprintf($this->getLang('this_calendar_uses_timezone'), $data['forcetimezone']).'
'; $R->doc .= '
'; $R->doc .= ''; if(($this->getConf('hide_settings') !== 1) && ($data['settings'] !== 'hide')) { $R->doc .= '
'.$this->getLang('settings').'
'; } } } // vim:ts=4:sw=4:et:enc=utf-8: diff --git a/syntax/events.php b/syntax/events.php --- a/syntax/events.php +++ b/syntax/events.php @@ -1,309 +1,309 @@ */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_davcal_events extends DokuWiki_Syntax_Plugin { protected $hlp = null; // Load the helper plugin public function syntax_plugin_davcal_events() { $this->hlp =& plugin_load('helper', 'davcal'); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } /** * What about paragraphs? */ function getPType(){ return 'normal'; } /** * Where to sort in? */ function getSort(){ return 165; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{davcalevents>[^}]*\}\}',$mode,'plugin_davcal_events'); } /** * Handle the match */ function handle($match, $state, $pos, Doku_Handler $handler){ global $ID; $data = array('id' => array(), 'startdate' => 'today', 'numdays' => 30, 'startisend' => false, 'dateformat' => 'Y-m-d H:i', 'alldayformat' => 'Y-m-d', 'onlystart' => false, 'sort' => 'desc', 'timezone' => 'local', 'timeformat' => null, ); $lastid = $ID; $options = trim(substr($match,15,-2)); $options = explode(',', $options); foreach($options as $option) { list($key, $val) = explode('=', $option); $key = strtolower(trim($key)); $val = trim($val); switch($key) { case 'id': $lastid = $val; if(!in_array($val, $data['id'])) $data['id'][$val] = null; break; case 'color': $data['id'][$lastid] = $val; break; case 'onlystart': if(($val === 'on') || ($val === 'true')) $data['onlystart'] = true; break; case 'startisend': if(($val === 'on') || ($val === 'true')) $data['startisend'] = true; break; case 'timezone': $tzlist = \DateTimeZone::listIdentifiers(DateTimeZone::ALL); if(in_array($val, $tzlist) || $val === 'no') $data['timezone'] = $val; else msg($this->getLang('error_timezone_not_in_list'), -1); break; default: $data[$key] = $val; } } // Handle the default case when the user didn't enter a different ID if(empty($data['id'])) { $data['id'] = array($ID => '#3a87ad'); } // Fix up the colors, if no color information is given foreach($data['id'] as $id => $color) { if(is_null($color)) { // If this is the current calendar or a WebDAV calendar, use the // default color if(($id === $ID) || (strpos($id, 'webdav://') === 0)) { $data['id'][$id] = '#3a87ad'; } // Otherwise, retrieve the color information from the calendar settings else { $calid = $this->hlp->getCalendarIdForPage($ID); $settings = $this->hlp->getCalendarSettings($calid); $color = $settings['calendarcolor']; $data['id'][$id] = $color; } } } return $data; } private static function sort_events_asc($a, $b) { $from1 = new \DateTime($a['start']); $from2 = new \DateTime($b['start']); return $from2 < $from1; } private static function sort_events_desc($a, $b) { $from1 = new \DateTime($a['start']); $from2 = new \DateTime($b['start']); return $from1 < $from2; } /** * Create output */ function render($format, Doku_Renderer $R, $data) { if($format == 'metadata') { $R->meta['plugin_davcal']['events'] = true; - return true; + $R->meta['plugin_davcal'] = array_merge_recursive($R->meta['plugin_davcal'], $data); } if(($format != 'xhtml') && ($format != 'odt')) return false; global $ID; $events = array(); $from = $data['startdate']; $toStr = null; // Handle the various options to 'startDate' if($from === 'today') { $from = new \DateTime(); } elseif(strpos($from, 'today-') === 0) { $days = intval(str_replace('today-', '', $from)); $from = new \DateTime(); $from->sub(new \DateInterval('P'.$days.'D')); } elseif(strpos($from, 'today+') === 0) { $days = intval(str_replace('today+', '', $from)); $from = new \DateTime(); $from->add(new \DateInterval('P'.$days.'D')); } else { $from = new \DateTime($from); } // Handle the option 'startisend' if($data['startisend'] === true) { if($data['numdays'] > 0) { $to = clone $from; $to->sub(new \DateInterval('P'.$data['numdays'].'D')); $fromStr = $to->format('Y-m-d'); } else { $fromStr = null; } $toStr = $from->format('Y-m-d'); } else { if($data['numdays'] > 0) { $to = clone $from; $to->add(new \DateInterval('P'.$data['numdays'].'D')); $toStr = $to->format('Y-m-d'); } else { $toStr = null; } $fromStr = $from->format('Y-m-d'); } // Support for timezone $timezone = $data['timezone']; // Filter events by user permissions $userEvents = $this->hlp->filterCalendarPagesByUserPermission($data['id']); $perms = array(); // Fetch the events foreach($userEvents as $calPage => $color) { $events = array_merge($events, $this->hlp->getEventsWithinDateRange($calPage, $user, $fromStr, $toStr, $timezone, null, array('URL', 'X-COST'))); $perms[$calPage] = $this->hlp->checkCalendarPermission($calPage); } // Sort the events if($data['sort'] === 'desc') usort($events, array("syntax_plugin_davcal_events", "sort_events_desc")); else usort($events, array("syntax_plugin_davcal_events", "sort_events_asc")); $R->doc .= '
'; foreach($perms as $page => $perm) { if($perm > AUTH_READ) { $R->doc .= ''.$this->getLang('add_new').'
'; break; } } foreach($events as $event) { $from = new \DateTime($event['start']); $color = $data['id'][$event['page']]; $R->doc .= '
'; $R->doc .= '
'; if($timezone !== 'local') { $from->setTimezone(new \DateTimeZone($timezone)); $to->setTimezone(new \DateTimeZone($timezone)); } if($event['allDay'] === true) $R->doc .= '

'.$from->format($data['alldayformat']).'

'; else $R->doc .= '

'.$from->format($data['dateformat']).'

'; if(!is_null($data['timeformat']) && $event['allDay'] != true) { $R->doc .= '

'.$from->format($data['timeformat']).'

'; } $R->doc .= hsc($event['title']).'
'; if(isset($event['X-COST']) && $event['X-COST'] !== '') { $R->doc .= ''.$this->getLang('costs').': '.hsc($event['X-COST']).''; } $R->doc .= '
'; $R->doc .= '
'; $R->doc .= ''; $R->doc .= ''; $R->doc .= ''; $R->doc .= '
'; if(isset($event['URL']) && $event['URL'] !== '') { $R->doc .= '
'; $R->doc .= ''.$this->getLang('more_info').''; $R->doc .= '
'; } if(isset($perms[$event['page']]) && ($perms[$event['page']] > AUTH_READ)) { $R->doc .= '
'; - $R->doc .= ''.$this->getLang('edit').''; + $R->doc .= ''.$this->getLang('edit').''; $R->doc .= '
'; } $R->doc .= '
'; } $R->doc .= '
'; } } // vim:ts=4:sw=4:et:enc=utf-8: