diff --git a/action/jsinfo.php b/action/jsinfo.php --- a/action/jsinfo.php +++ b/action/jsinfo.php @@ -1,54 +1,57 @@ register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'add_jsinfo_information'); } /** * Add the language variable to the JSINFO variable */ function add_jsinfo_information(&$event, $param) { global $conf; global $JSINFO; $lang = $conf['lang']; switch($lang) { case 'de': case 'de-informal': $lc = 'de'; break; case 'nl': $lc = 'nl'; break; case 'fr': $lc = 'fr'; break; + case 'ru': + $lc = 'ru'; + break; default: $lc = 'en'; } $JSINFO['plugin']['davcal']['sectok'] = getSecurityToken(); $JSINFO['plugin']['davcal']['language'] = $lc; if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) { $JSINFO['plugin']['davcal']['disable_sync'] = $this->getConf('disable_sync'); $JSINFO['plugin']['davcal']['disable_settings'] = $this->getConf('hide_settings'); } else { $JSINFO['plugin']['davcal']['disable_settings'] = 1; $JSINFO['plugin']['davcal']['disable_sync'] = 1; } $JSINFO['plugin']['davcal']['disable_ics'] = $this->getConf('disable_ics'); } } diff --git a/lang/ru/lang.php b/lang/ru/lang.php new file mode 100644 --- /dev/null +++ b/lang/ru/lang.php @@ -0,0 +1,65 @@ + + */ +$lang['created_by_davcal'] = 'Создано DAVCal для DokuWiki'; +$lang['unknown_error'] = 'Неизвестная ошибка'; +$lang['event_added'] = 'Событие добавлено'; +$lang['event_edited'] = 'Событие исправлено'; +$lang['event_deleted'] = 'Событие удалено'; +$lang['no_permission'] = 'У Вас нет прав изменять этот календарь'; +$lang['settings'] = 'Настройки/Синхронизация'; +$lang['settings_saved'] = 'Настройки сохранены'; +$lang['error_saving'] = 'Ошибка при сохранении настроек.'; +$lang['local_time'] = 'Местное время (по информации браузера)'; +$lang['from'] = 'Начало'; +$lang['to'] = 'Окончание'; +$lang['at'] = 'At'; +$lang['description'] = 'Описание'; +$lang['title'] = 'Заголовок'; +$lang['error_timezone_not_in_list'] = 'Выбранная временная зона не поддерживается PHP!'; +$lang['error_option_error'] = 'Ошибка в списке параметров'; +$lang['this_calendar_uses_timezone'] = 'Этот календарь показан во временной зоне %s.'; +$lang['location'] = 'Расположение'; +$lang['js']['create_new_event'] = 'Создать новое событие'; +$lang['js']['cancel'] = 'Отмена'; +$lang['js']['create'] = 'Создать'; +$lang['js']['save'] = 'Сохранить'; +$lang['js']['settings'] = 'Настройки'; +$lang['js']['edit'] = 'Редактировать'; +$lang['js']['delete'] = 'Удалить'; +$lang['js']['edit_event'] = 'Редактировать событие'; +$lang['js']['allday'] = 'Весь день'; +$lang['js']['title'] = 'Заголовок'; +$lang['js']['location'] = 'Расположение'; +$lang['js']['from'] = 'Начало'; +$lang['js']['to'] = 'Окончание'; +$lang['js']['yes'] = 'Да'; +$lang['js']['confirmation'] = 'Подтверждение'; +$lang['js']['ok'] = 'OK'; +$lang['js']['info'] = 'Информация'; +$lang['js']['really_delete_this_event'] = 'Удалить это событие?'; +$lang['js']['timezone'] = 'Временная зона'; +$lang['js']['weeknumbers'] = 'Номера недель'; +$lang['js']['use_lang_tz'] = 'Использовать временную зону из настроек языка'; +$lang['js']['only_workweek'] = 'Показывать только рабочую неделю'; +$lang['js']['sync_url'] = 'CalDAV URL'; +$lang['js']['error_retrieving_data'] = 'Ошибка при получении данных от сервера календаря.'; +$lang['js']['start_date_invalid'] = 'Дата/время начала неправильное.'; +$lang['js']['end_date_invalid'] = 'Дата/время окончания неправильное.'; +$lang['js']['end_date_before_start_date'] = 'Дата/время окончания раньше даты/врмени начала.'; +$lang['js']['end_date_is_same_as_start_date'] = 'Дата/время окончания совпадает с датой/временем начала.'; +$lang['js']['description'] = 'Описание'; +$lang['js']['private_url'] = 'Private URL'; +$lang['js']['recurring_cant_edit'] = 'Редактирование повторяющихся событий в настоящее время не поддерживается'; +$lang['js']['no_permission'] = 'У Вас нет прав изменять этот календарь'; +$lang['js']['calendar'] = 'Календарь'; +$lang['js']['start_monday'] = 'Начало недели в Пн'; +$lang['js']['nothing_to_show'] = 'Ничего нет для отображения'; +$lang['js']['add_attachment'] = 'Добавить ссылку'; +$lang['js']['attachments'] = 'Ссылки'; +$lang['js']['language_specific'] = 'По настройкам языка'; +$lang['js']['sync_ical'] = 'iCal Sync URL'; +$lang['js']['timeformat'] = 'Формат времени'; diff --git a/lang/ru/settings.php b/lang/ru/settings.php new file mode 100644 --- /dev/null +++ b/lang/ru/settings.php @@ -0,0 +1,15 @@ + + */ +$lang['hide_settings'] = 'Скрыть кнопку настроек у календаря'; +$lang['disable_sync'] = 'Отключить синхронизацию CalDAV (но оставить частные ICS URL)'; +$lang['disable_ics'] = 'Отключить синхронизацию частных ICS URL (но оставить CalDAV)'; +$lang['monday'] = 'Начинать неделю с Пн вместо Вс'; +$lang['timezone'] = 'Установить временную зону для календаря (например "Europe/Vienna" или "local" для использования данных браузера)'; +$lang['workweek'] = 'Показывать только рабочую неделю'; +$lang['weeknumbers'] = 'Показывать номера недель'; +$lang['timeformat'] = 'Формат времени, язык берётся по настройке языка'; +$lang['default_client_id'] = 'ID по умолчанию для указания в качестве davcal-клиента, например webdav://8'; diff --git a/plugin.info.txt b/plugin.info.txt --- a/plugin.info.txt +++ b/plugin.info.txt @@ -1,7 +1,7 @@ base davcal author Andreas Boehler email dev@aboehler.at -date 2019-01-22 +date 2019-04-30 name Calendar PlugIn with CalDAV sharing support desc Create one calendar per page and share/subscribe via CalDAV url http://www.dokuwiki.org/plugin:davcal diff --git a/script.js b/script.js --- a/script.js +++ b/script.js @@ -1,866 +1,867 @@ /* 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 fullcalendar-3.7.0/locale/ru.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; 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 ''; } ); } ); // 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); }, eventClick: function(calEvent, jsEvent, view) { dw_davcal__modals.showEditEventDialog(calEvent, true); }, 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, /** * 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)) { $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; } };