Changeset View
Changeset View
Standalone View
Standalone View
plugins/calendar/lib/calendar_ui.php
Show All 19 Lines | |||||
* | * | ||||
* You should have received a copy of the GNU Affero General Public License | * You should have received a copy of the GNU Affero General Public License | ||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
class calendar_ui | class calendar_ui | ||||
{ | { | ||||
private $rc; | private $rc; | ||||
private $cal; | private $cal; | ||||
private $ready = false; | private $ready = false; | ||||
public $screen; | public $screen; | ||||
function __construct($cal) | function __construct($cal) | ||||
{ | { | ||||
$this->cal = $cal; | $this->cal = $cal; | ||||
$this->rc = $cal->rc; | $this->rc = $cal->rc; | ||||
$this->screen = $this->rc->task == 'calendar' ? ($this->rc->action ? $this->rc->action: 'calendar') : 'other'; | $this->screen = $this->rc->task == 'calendar' ? ($this->rc->action ?: 'calendar') : 'other'; | ||||
} | } | ||||
/** | /** | ||||
* Calendar UI initialization and requests handlers | * Calendar UI initialization and requests handlers | ||||
*/ | */ | ||||
public function init() | public function init() | ||||
{ | { | ||||
if ($this->ready) // already done | if ($this->ready) { | ||||
// already done | |||||
return; | return; | ||||
} | |||||
// add taskbar button | // add taskbar button | ||||
$this->cal->add_button(array( | $this->cal->add_button([ | ||||
'command' => 'calendar', | 'command' => 'calendar', | ||||
'class' => 'button-calendar', | 'class' => 'button-calendar', | ||||
'classsel' => 'button-calendar button-selected', | 'classsel' => 'button-calendar button-selected', | ||||
'innerclass' => 'button-inner', | 'innerclass' => 'button-inner', | ||||
'label' => 'calendar.calendar', | 'label' => 'calendar.calendar', | ||||
'type' => 'link' | 'type' => 'link' | ||||
), 'taskbar'); | ], | ||||
'taskbar' | |||||
); | |||||
// load basic client script | // load basic client script | ||||
if ($this->rc->action != 'print') { | if ($this->rc->action != 'print') { | ||||
$this->cal->include_script('calendar_base.js'); | $this->cal->include_script('calendar_base.js'); | ||||
} | } | ||||
$this->addCSS(); | $this->addCSS(); | ||||
$this->ready = true; | $this->ready = true; | ||||
} | } | ||||
/** | /** | ||||
* Register handler methods for the template engine | * Register handler methods for the template engine | ||||
*/ | */ | ||||
public function init_templates() | public function init_templates() | ||||
{ | { | ||||
$this->cal->register_handler('plugin.calendar_css', array($this, 'calendar_css')); | $this->cal->register_handler('plugin.calendar_css', [$this, 'calendar_css']); | ||||
$this->cal->register_handler('plugin.calendar_list', array($this, 'calendar_list')); | $this->cal->register_handler('plugin.calendar_list', [$this, 'calendar_list']); | ||||
$this->cal->register_handler('plugin.calendar_select', array($this, 'calendar_select')); | $this->cal->register_handler('plugin.calendar_select', [$this, 'calendar_select']); | ||||
$this->cal->register_handler('plugin.identity_select', array($this, 'identity_select')); | $this->cal->register_handler('plugin.identity_select', [$this, 'identity_select']); | ||||
$this->cal->register_handler('plugin.category_select', array($this, 'category_select')); | $this->cal->register_handler('plugin.category_select', [$this, 'category_select']); | ||||
$this->cal->register_handler('plugin.status_select', array($this, 'status_select')); | $this->cal->register_handler('plugin.status_select', [$this, 'status_select']); | ||||
$this->cal->register_handler('plugin.freebusy_select', array($this, 'freebusy_select')); | $this->cal->register_handler('plugin.freebusy_select', [$this, 'freebusy_select']); | ||||
$this->cal->register_handler('plugin.priority_select', array($this, 'priority_select')); | $this->cal->register_handler('plugin.priority_select', [$this, 'priority_select']); | ||||
$this->cal->register_handler('plugin.sensitivity_select', array($this, 'sensitivity_select')); | $this->cal->register_handler('plugin.sensitivity_select', [$this, 'sensitivity_select']); | ||||
$this->cal->register_handler('plugin.alarm_select', array($this, 'alarm_select')); | $this->cal->register_handler('plugin.alarm_select', [$this, 'alarm_select']); | ||||
$this->cal->register_handler('plugin.recurrence_form', array($this->cal->lib, 'recurrence_form')); | $this->cal->register_handler('plugin.recurrence_form', [$this->cal->lib, 'recurrence_form']); | ||||
$this->cal->register_handler('plugin.attendees_list', array($this, 'attendees_list')); | $this->cal->register_handler('plugin.attendees_list', [$this, 'attendees_list']); | ||||
$this->cal->register_handler('plugin.attendees_form', array($this, 'attendees_form')); | $this->cal->register_handler('plugin.attendees_form', [$this, 'attendees_form']); | ||||
$this->cal->register_handler('plugin.resources_form', array($this, 'resources_form')); | $this->cal->register_handler('plugin.resources_form', [$this, 'resources_form']); | ||||
$this->cal->register_handler('plugin.resources_list', array($this, 'resources_list')); | $this->cal->register_handler('plugin.resources_list', [$this, 'resources_list']); | ||||
$this->cal->register_handler('plugin.resources_searchform', array($this, 'resources_search_form')); | $this->cal->register_handler('plugin.resources_searchform', [$this, 'resources_search_form']); | ||||
$this->cal->register_handler('plugin.resource_info', array($this, 'resource_info')); | $this->cal->register_handler('plugin.resource_info', [$this, 'resource_info']); | ||||
$this->cal->register_handler('plugin.resource_calendar', array($this, 'resource_calendar')); | $this->cal->register_handler('plugin.resource_calendar', [$this, 'resource_calendar']); | ||||
$this->cal->register_handler('plugin.attendees_freebusy_table', array($this, 'attendees_freebusy_table')); | $this->cal->register_handler('plugin.attendees_freebusy_table', [$this, 'attendees_freebusy_table']); | ||||
$this->cal->register_handler('plugin.edit_attendees_notify', array($this, 'edit_attendees_notify')); | $this->cal->register_handler('plugin.edit_attendees_notify', [$this, 'edit_attendees_notify']); | ||||
$this->cal->register_handler('plugin.edit_recurrence_sync', array($this, 'edit_recurrence_sync')); | $this->cal->register_handler('plugin.edit_recurrence_sync', [$this, 'edit_recurrence_sync']); | ||||
$this->cal->register_handler('plugin.edit_recurring_warning', array($this, 'recurring_event_warning')); | $this->cal->register_handler('plugin.edit_recurring_warning', [$this, 'recurring_event_warning']); | ||||
$this->cal->register_handler('plugin.event_rsvp_buttons', array($this, 'event_rsvp_buttons')); | $this->cal->register_handler('plugin.event_rsvp_buttons', [$this, 'event_rsvp_buttons']); | ||||
$this->cal->register_handler('plugin.agenda_options', array($this, 'agenda_options')); | $this->cal->register_handler('plugin.agenda_options', [$this, 'agenda_options']); | ||||
$this->cal->register_handler('plugin.events_import_form', array($this, 'events_import_form')); | $this->cal->register_handler('plugin.events_import_form', [$this, 'events_import_form']); | ||||
$this->cal->register_handler('plugin.events_export_form', array($this, 'events_export_form')); | $this->cal->register_handler('plugin.events_export_form', [$this, 'events_export_form']); | ||||
$this->cal->register_handler('plugin.object_changelog_table', array('libkolab', 'object_changelog_table')); | $this->cal->register_handler('plugin.object_changelog_table', ['libkolab', 'object_changelog_table']); | ||||
$this->cal->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template | $this->cal->register_handler('plugin.searchform', [$this->rc->output, 'search_form']); | ||||
kolab_attachments_handler::ui(); | kolab_attachments_handler::ui(); | ||||
} | } | ||||
/** | /** | ||||
* Adds CSS stylesheets to the page header | * Adds CSS stylesheets to the page header | ||||
*/ | */ | ||||
public function addCSS() | public function addCSS() | ||||
{ | { | ||||
$skin_path = $this->cal->local_skin_path(); | $skin_path = $this->cal->local_skin_path(); | ||||
if ($this->rc->task == 'calendar' && (!$this->rc->action || in_array($this->rc->action, array('index', 'print')))) { | if ( | ||||
$this->rc->task == 'calendar' | |||||
&& (!$this->rc->action || in_array($this->rc->action, ['index', 'print'])) | |||||
) { | |||||
// Include fullCalendar style before skin file for simpler style overriding | // Include fullCalendar style before skin file for simpler style overriding | ||||
$this->cal->include_stylesheet($skin_path . '/fullcalendar.css'); | $this->cal->include_stylesheet($skin_path . '/fullcalendar.css'); | ||||
} | } | ||||
$this->cal->include_stylesheet($skin_path . '/calendar.css'); | $this->cal->include_stylesheet($skin_path . '/calendar.css'); | ||||
if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { | if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { | ||||
$this->cal->include_stylesheet($skin_path . '/print.css'); | $this->cal->include_stylesheet($skin_path . '/print.css'); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Adds JS files to the page header | * Adds JS files to the page header | ||||
*/ | */ | ||||
public function addJS() | public function addJS() | ||||
{ | { | ||||
$this->cal->include_script('lib/js/moment.js'); | $this->cal->include_script('lib/js/moment.js'); | ||||
$this->cal->include_script('lib/js/fullcalendar.js'); | $this->cal->include_script('lib/js/fullcalendar.js'); | ||||
if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { | if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { | ||||
$this->cal->include_script('print.js'); | $this->cal->include_script('print.js'); | ||||
} | } | ||||
else { | else { | ||||
$this->rc->output->include_script('treelist.js'); | $this->rc->output->include_script('treelist.js'); | ||||
$this->cal->api->include_script('libkolab/libkolab.js'); | $this->cal->api->include_script('libkolab/libkolab.js'); | ||||
$this->cal->include_script('calendar_ui.js'); | $this->cal->include_script('calendar_ui.js'); | ||||
jqueryui::miniColors(); | jqueryui::miniColors(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* | * Add custom style for the calendar UI | ||||
*/ | */ | ||||
function calendar_css($attrib = array()) | function calendar_css($attrib = []) | ||||
{ | { | ||||
$categories = $this->cal->driver->list_categories(); | $categories = $this->cal->driver->list_categories(); | ||||
$js_categories = array(); | $calendars = $this->cal->driver->list_calendars(); | ||||
$js_categories = []; | |||||
$mode = $this->rc->config->get('calendar_event_coloring', $this->cal->defaults['calendar_event_coloring']); | $mode = $this->rc->config->get('calendar_event_coloring', $this->cal->defaults['calendar_event_coloring']); | ||||
$css = "\n"; | $css = "\n"; | ||||
foreach ((array)$categories as $class => $color) { | foreach ((array) $categories as $class => $color) { | ||||
if (!empty($color)) { | if (!empty($color)) { | ||||
$js_categories[$class] = $color; | $js_categories[$class] = $color; | ||||
$color = ltrim($color, '#'); | $color = ltrim($color, '#'); | ||||
$class = 'cat-' . asciiwords(strtolower($class), true); | $class = 'cat-' . asciiwords(strtolower($class), true); | ||||
$css .= ".$class { color: #$color; }\n"; | $css .= ".$class { color: #$color; }\n"; | ||||
} | } | ||||
} | } | ||||
$this->rc->output->set_env('calendar_categories', $js_categories); | $this->rc->output->set_env('calendar_categories', $js_categories); | ||||
$calendars = $this->cal->driver->list_calendars(); | |||||
foreach ((array)$calendars as $id => $prop) { | foreach ((array) $calendars as $id => $prop) { | ||||
if ($prop['color']) { | if (!empty($prop['color'])) { | ||||
$css .= $this->calendar_css_classes($id, $prop, $mode, $attrib); | $css .= $this->calendar_css_classes($id, $prop, $mode, $attrib); | ||||
} | } | ||||
} | } | ||||
return html::tag('style', array('type' => 'text/css'), $css); | return html::tag('style', ['type' => 'text/css'], $css); | ||||
} | } | ||||
/** | /** | ||||
* | * Calendar folder specific CSS classes | ||||
*/ | */ | ||||
public function calendar_css_classes($id, $prop, $mode, $attrib = array()) | public function calendar_css_classes($id, $prop, $mode, $attrib = []) | ||||
{ | { | ||||
$color = $folder_color = $prop['color']; | $color = $folder_color = $prop['color']; | ||||
// replace white with skin-defined color | // replace white with skin-defined color | ||||
if (!empty($attrib['folder-fallback-color']) && preg_match('/^f+$/i', $folder_color)) { | if (!empty($attrib['folder-fallback-color']) && preg_match('/^f+$/i', $folder_color)) { | ||||
$folder_color = ltrim($attrib['folder-fallback-color'], '#'); | $folder_color = ltrim($attrib['folder-fallback-color'], '#'); | ||||
} | } | ||||
$class = 'cal-' . asciiwords($id, true); | $class = 'cal-' . asciiwords($id, true); | ||||
$css = str_replace('$class', $class, $attrib['folder-class']) ?: "li .$class"; | $css = "li .$class"; | ||||
if (!empty($attrib['folder-class'])) { | |||||
$css = str_replace('$class', $class, $attrib['folder-class']); | |||||
} | |||||
$css .= " { color: #$folder_color; }\n"; | $css .= " { color: #$folder_color; }\n"; | ||||
return $css . ".$class .handle { background-color: #$color; }\n"; | return $css . ".$class .handle { background-color: #$color; }\n"; | ||||
} | } | ||||
/** | /** | ||||
* | * Generate HTML content of the calendars list (or metadata only) | ||||
*/ | */ | ||||
function calendar_list($attrib = array(), $js_only = false) | function calendar_list($attrib = [], $js_only = false) | ||||
{ | { | ||||
$html = ''; | $html = ''; | ||||
$jsenv = array(); | $jsenv = []; | ||||
$tree = true; | $tree = true; | ||||
$calendars = $this->cal->driver->list_calendars(0, $tree); | $calendars = $this->cal->driver->list_calendars(0, $tree); | ||||
// walk folder tree | // walk folder tree | ||||
if (is_object($tree)) { | if (is_object($tree)) { | ||||
$html = $this->list_tree_html($tree, $calendars, $jsenv, $attrib); | $html = $this->list_tree_html($tree, $calendars, $jsenv, $attrib); | ||||
// append birthdays calendar which isn't part of $tree | // append birthdays calendar which isn't part of $tree | ||||
if ($bdaycal = $calendars[calendar_driver::BIRTHDAY_CALENDAR_ID]) { | if (!empty($calendars[calendar_driver::BIRTHDAY_CALENDAR_ID])) { | ||||
$calendars = array(calendar_driver::BIRTHDAY_CALENDAR_ID => $bdaycal); | $bdaycal = $calendars[calendar_driver::BIRTHDAY_CALENDAR_ID]; | ||||
$calendars = [calendar_driver::BIRTHDAY_CALENDAR_ID => $bdaycal]; | |||||
} | } | ||||
else { | else { | ||||
$calendars = array(); // clear array for flat listing | $calendars = []; // clear array for flat listing | ||||
} | } | ||||
} | } | ||||
else { | else if (isset($attrib['class'])) { | ||||
// fall-back to flat folder listing | // fall-back to flat folder listing | ||||
$attrib['class'] .= ' flat'; | $attrib['class'] .= ' flat'; | ||||
} | } | ||||
foreach ((array)$calendars as $id => $prop) { | foreach ((array) $calendars as $id => $prop) { | ||||
if ($attrib['activeonly'] && !$prop['active']) | if (!empty($attrib['activeonly']) && empty($prop['active'])) { | ||||
continue; | continue; | ||||
} | |||||
$html .= html::tag('li', array('id' => 'rcmlical' . $id, 'class' => $prop['group']), | $li_content = $this->calendar_list_item($id, $prop, $jsenv, !empty($attrib['activeonly'])); | ||||
$content = $this->calendar_list_item($id, $prop, $jsenv, $attrib['activeonly']) | $li_attr = [ | ||||
); | 'id' => 'rcmlical' . $id, | ||||
'class' => isset($prop['group']) ? $prop['group'] : null, | |||||
]; | |||||
$html .= html::tag('li', $li_attr, $li_content); | |||||
} | } | ||||
$this->rc->output->set_env('calendars', $jsenv); | $this->rc->output->set_env('calendars', $jsenv); | ||||
if ($js_only) { | if ($js_only) { | ||||
return; | return; | ||||
} | } | ||||
$this->rc->output->set_env('source', rcube_utils::get_input_value('source', rcube_utils::INPUT_GET)); | $this->rc->output->set_env('source', rcube_utils::get_input_value('source', rcube_utils::INPUT_GET)); | ||||
$this->rc->output->add_gui_object('calendarslist', $attrib['id'] ?: 'unknown'); | $this->rc->output->add_gui_object('calendarslist', !empty($attrib['id']) ? $attrib['id'] : 'rccalendarlist'); | ||||
return html::tag('ul', $attrib, $html, html::$common_attrib); | return html::tag('ul', $attrib, $html, html::$common_attrib); | ||||
} | } | ||||
/** | /** | ||||
* Return html for a structured list <ul> for the folder tree | * Return html for a structured list <ul> for the folder tree | ||||
*/ | */ | ||||
public function list_tree_html($node, $data, &$jsenv, $attrib) | public function list_tree_html($node, $data, &$jsenv, $attrib) | ||||
{ | { | ||||
$out = ''; | $out = ''; | ||||
foreach ($node->children as $folder) { | foreach ($node->children as $folder) { | ||||
$id = $folder->id; | $id = $folder->id; | ||||
$prop = $data[$id]; | $prop = $data[$id]; | ||||
$is_collapsed = false; // TODO: determine this somehow? | $is_collapsed = false; // TODO: determine this somehow? | ||||
$content = $this->calendar_list_item($id, $prop, $jsenv, $attrib['activeonly']); | $content = $this->calendar_list_item($id, $prop, $jsenv, !empty($attrib['activeonly'])); | ||||
if (!empty($folder->children)) { | if (!empty($folder->children)) { | ||||
$content .= html::tag('ul', array('style' => ($is_collapsed ? "display:none;" : null)), | $content .= html::tag('ul', ['style' => $is_collapsed ? "display:none;" : null], | ||||
$this->list_tree_html($folder, $data, $jsenv, $attrib)); | $this->list_tree_html($folder, $data, $jsenv, $attrib) | ||||
); | |||||
} | } | ||||
if (strlen($content)) { | if (strlen($content)) { | ||||
$out .= html::tag('li', array( | $li_attr = [ | ||||
'id' => 'rcmlical' . rcube_utils::html_identifier($id), | 'id' => 'rcmlical' . rcube_utils::html_identifier($id), | ||||
'class' => $prop['group'] . ($prop['virtual'] ? ' virtual' : ''), | 'class' => $prop['group'] . (!empty($prop['virtual']) ? ' virtual' : ''), | ||||
), | ]; | ||||
$content); | $out .= html::tag('li', $li_attr, $content); | ||||
} | } | ||||
} | } | ||||
return $out; | return $out; | ||||
} | } | ||||
/** | /** | ||||
* Helper method to build a calendar list item (HTML content and js data) | * Helper method to build a calendar list item (HTML content and js data) | ||||
*/ | */ | ||||
public function calendar_list_item($id, $prop, &$jsenv, $activeonly = false) | public function calendar_list_item($id, $prop, &$jsenv, $activeonly = false) | ||||
{ | { | ||||
// enrich calendar properties with settings from the driver | // enrich calendar properties with settings from the driver | ||||
if (!$prop['virtual']) { | if (empty($prop['virtual'])) { | ||||
unset($prop['user_id']); | unset($prop['user_id']); | ||||
$prop['alarms'] = $this->cal->driver->alarms; | $prop['alarms'] = $this->cal->driver->alarms; | ||||
$prop['attendees'] = $this->cal->driver->attendees; | $prop['attendees'] = $this->cal->driver->attendees; | ||||
$prop['freebusy'] = $this->cal->driver->freebusy; | $prop['freebusy'] = $this->cal->driver->freebusy; | ||||
$prop['attachments'] = $this->cal->driver->attachments; | $prop['attachments'] = $this->cal->driver->attachments; | ||||
$prop['undelete'] = $this->cal->driver->undelete; | $prop['undelete'] = $this->cal->driver->undelete; | ||||
$prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed')); | $prop['feedurl'] = $this->cal->get_url([ | ||||
'_cal' => $this->cal->ical_feed_hash($id) . '.ics', | |||||
'action' => 'feed' | |||||
] | |||||
); | |||||
$jsenv[$id] = $prop; | $jsenv[$id] = $prop; | ||||
} | } | ||||
$classes = array('calendar', 'cal-' . asciiwords($id, true)); | if (!empty($prop['title'])) { | ||||
$title = $prop['title'] ?: ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25 ? | $title = $prop['title']; | ||||
html_entity_decode($prop['name'], ENT_COMPAT, RCUBE_CHARSET) : ''); | } | ||||
else if ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25) { | |||||
$title = html_entity_decode($prop['name'], ENT_COMPAT, RCUBE_CHARSET); | |||||
} | |||||
else { | |||||
$title = ''; | |||||
} | |||||
$classes = ['calendar', 'cal-' . asciiwords($id, true)]; | |||||
if ($prop['virtual']) | if (!empty($prop['virtual'])) { | ||||
$classes[] = 'virtual'; | $classes[] = 'virtual'; | ||||
else if (!$prop['editable']) | } | ||||
else if (empty($prop['editable'])) { | |||||
$classes[] = 'readonly'; | $classes[] = 'readonly'; | ||||
if ($prop['subscribed']) | } | ||||
if (!empty($prop['subscribed'])) { | |||||
$classes[] = 'subscribed'; | $classes[] = 'subscribed'; | ||||
if ($prop['subscribed'] === 2) | |||||
if ($prop['subscribed'] === 2) { | |||||
$classes[] = 'partial'; | $classes[] = 'partial'; | ||||
if ($prop['class']) | } | ||||
} | |||||
if (!empty($prop['class'])) { | |||||
$classes[] = $prop['class']; | $classes[] = $prop['class']; | ||||
} | |||||
$content = ''; | $content = ''; | ||||
if (!$activeonly || $prop['active']) { | |||||
if (!$activeonly || !empty($prop['active'])) { | |||||
$label_id = 'cl:' . $id; | $label_id = 'cl:' . $id; | ||||
$content = html::div(join(' ', $classes), | $content = html::a( | ||||
html::a(array('class' => 'calname', 'id' => $label_id, 'title' => $title, 'href' => '#'), rcube::Q($prop['editname'] ?: $prop['listname'])) | ['class' => 'calname', 'id' => $label_id, 'title' => $title, 'href' => '#'], | ||||
. ($prop['virtual'] ? '' : | rcube::Q(!empty($prop['editname']) ? $prop['editname'] : $prop['listname']) | ||||
html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id)) . | ); | ||||
html::span('actions', | |||||
($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->cal->gettext('removelist')), ' ') : '') . | if (empty($prop['virtual'])) { | ||||
html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'checkbox', 'aria-checked' => 'false'), '') . | $color = !empty($prop['color']) ? $prop['color'] : 'f00'; | ||||
(isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '') | $actions = ''; | ||||
) . | |||||
html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' ') | if (!EMPTY($prop['removable'])) { | ||||
) | $actions .= html::a([ | ||||
'href' => '#', | |||||
'class' => 'remove', | |||||
'title' => $this->cal->gettext('removelist') | |||||
], ' ' | |||||
); | |||||
} | |||||
$actions .= html::a([ | |||||
'href' => '#', | |||||
'class' => 'quickview', | |||||
'title' => $this->cal->gettext('quickview'), | |||||
'role' => 'checkbox', | |||||
'aria-checked' => 'false' | |||||
], '' | |||||
); | |||||
if (!empty($prop['subscribed'])) { | |||||
$actions .= html::a([ | |||||
'href' => '#', | |||||
'class' => 'subscribed', | |||||
'title' => $this->cal->gettext('calendarsubscribe'), | |||||
'role' => 'checkbox', | |||||
'aria-checked' => !empty($prop['subscribed']) ? 'true' : 'false' | |||||
], ' ' | |||||
); | ); | ||||
} | } | ||||
$content .= html::tag('input', [ | |||||
'type' => 'checkbox', | |||||
'name' => '_cal[]', | |||||
'value' => $id, | |||||
'checked' => !empty($prop['active']), | |||||
'aria-labelledby' => $label_id | |||||
]) | |||||
. html::span('actions', $actions) | |||||
. html::span(['class' => 'handle', 'style' => "background-color: #$color"], ' '); | |||||
} | |||||
$content = html::div(join(' ', $classes), $content); | |||||
} | |||||
return $content; | return $content; | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML for agenda options form | * Render a HTML for agenda options form | ||||
*/ | */ | ||||
function agenda_options($attrib = array()) | function agenda_options($attrib = []) | ||||
{ | { | ||||
$attrib += array('id' => 'agendaoptions'); | $attrib += ['id' => 'agendaoptions']; | ||||
$attrib['style'] .= 'display:none'; | $attrib['style'] = 'display:none'; | ||||
$select_range = new html_select(['name' => 'listrange', 'id' => 'agenda-listrange', 'class' => 'form-control custom-select']); | |||||
$select_range->add(1 . ' ' . preg_replace('/\(.+\)/', '', $this->cal->lib->gettext('days')), ''); | |||||
$select_range = new html_select(array('name' => 'listrange', 'id' => 'agenda-listrange', 'class' => 'form-control custom-select')); | foreach ([2,5,7,14,30,60,90,180,365] as $days) { | ||||
$select_range->add(1 . ' ' . preg_replace('/\(.+\)/', '', $this->cal->lib->gettext('days')), $days); | |||||
foreach (array(2,5,7,14,30,60,90,180,365) as $days) | |||||
$select_range->add($days . ' ' . preg_replace('/\(|\)/', '', $this->cal->lib->gettext('days')), $days); | $select_range->add($days . ' ' . preg_replace('/\(|\)/', '', $this->cal->lib->gettext('days')), $days); | ||||
} | |||||
$html = html::span('input-group', | $html = html::span('input-group', | ||||
html::label(array('for' => 'agenda-listrange', 'class' => 'input-group-prepend'), | html::label(['for' => 'agenda-listrange', 'class' => 'input-group-prepend'], | ||||
html::span('input-group-text', $this->cal->gettext('listrange'))) | html::span('input-group-text', $this->cal->gettext('listrange')) | ||||
) | |||||
. $select_range->show($this->rc->config->get('calendar_agenda_range', $this->cal->defaults['calendar_agenda_range'])) | . $select_range->show($this->rc->config->get('calendar_agenda_range', $this->cal->defaults['calendar_agenda_range'])) | ||||
); | ); | ||||
return html::div($attrib, $html); | return html::div($attrib, $html); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select box for calendar selection | * Render a HTML select box for calendar selection | ||||
*/ | */ | ||||
function calendar_select($attrib = array()) | function calendar_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'calendar'; | $attrib['name'] = 'calendar'; | ||||
$attrib['is_escaped'] = true; | $attrib['is_escaped'] = true; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
foreach ((array)$this->cal->driver->list_calendars() as $id => $prop) { | foreach ((array) $this->cal->driver->list_calendars() as $id => $prop) { | ||||
if ($prop['editable'] || strpos($prop['rights'], 'i') !== false) | if ( | ||||
!empty($prop['editable']) | |||||
|| (!empty($prop['rights']) && strpos($prop['rights'], 'i') !== false) | |||||
) { | |||||
$select->add($prop['name'], $id); | $select->add($prop['name'], $id); | ||||
} | } | ||||
} | |||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select box for user identity selection | * Render a HTML select box for user identity selection | ||||
*/ | */ | ||||
function identity_select($attrib = array()) | function identity_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'identity'; | $attrib['name'] = 'identity'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$identities = $this->rc->user->list_emails(); | $identities = $this->rc->user->list_emails(); | ||||
foreach ($identities as $ident) { | foreach ($identities as $ident) { | ||||
$select->add(format_email_recipient($ident['email'], $ident['name']), $ident['identity_id']); | $select->add(format_email_recipient($ident['email'], $ident['name']), $ident['identity_id']); | ||||
} | } | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select box to select an event category | * Render a HTML select box to select an event category | ||||
*/ | */ | ||||
function category_select($attrib = array()) | function category_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'categories'; | $attrib['name'] = 'categories'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$select->add('---', ''); | $select->add('---', ''); | ||||
foreach (array_keys((array)$this->cal->driver->list_categories()) as $cat) { | foreach (array_keys((array) $this->cal->driver->list_categories()) as $cat) { | ||||
$select->add($cat, $cat); | $select->add($cat, $cat); | ||||
} | } | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select box for status property | * Render a HTML select box for status property | ||||
*/ | */ | ||||
function status_select($attrib = array()) | function status_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'status'; | $attrib['name'] = 'status'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$select->add('---', ''); | $select->add('---', ''); | ||||
$select->add($this->cal->gettext('status-confirmed'), 'CONFIRMED'); | $select->add($this->cal->gettext('status-confirmed'), 'CONFIRMED'); | ||||
$select->add($this->cal->gettext('status-cancelled'), 'CANCELLED'); | $select->add($this->cal->gettext('status-cancelled'), 'CANCELLED'); | ||||
$select->add($this->cal->gettext('status-tentative'), 'TENTATIVE'); | $select->add($this->cal->gettext('status-tentative'), 'TENTATIVE'); | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select box for free/busy/out-of-office property | * Render a HTML select box for free/busy/out-of-office property | ||||
*/ | */ | ||||
function freebusy_select($attrib = array()) | function freebusy_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'freebusy'; | $attrib['name'] = 'freebusy'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$select->add($this->cal->gettext('free'), 'free'); | $select->add($this->cal->gettext('free'), 'free'); | ||||
$select->add($this->cal->gettext('busy'), 'busy'); | $select->add($this->cal->gettext('busy'), 'busy'); | ||||
// out-of-office is not supported by libkolabxml (#3220) | // out-of-office is not supported by libkolabxml (#3220) | ||||
// $select->add($this->cal->gettext('outofoffice'), 'outofoffice'); | // $select->add($this->cal->gettext('outofoffice'), 'outofoffice'); | ||||
$select->add($this->cal->gettext('tentative'), 'tentative'); | $select->add($this->cal->gettext('tentative'), 'tentative'); | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render a HTML select for event priorities | * Render a HTML select for event priorities | ||||
*/ | */ | ||||
function priority_select($attrib = array()) | function priority_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'priority'; | $attrib['name'] = 'priority'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$select->add('---', '0'); | $select->add('---', '0'); | ||||
$select->add('1 '.$this->cal->gettext('highest'), '1'); | $select->add('1 ' . $this->cal->gettext('highest'), '1'); | ||||
$select->add('2 '.$this->cal->gettext('high'), '2'); | $select->add('2 ' . $this->cal->gettext('high'), '2'); | ||||
$select->add('3 ', '3'); | $select->add('3 ', '3'); | ||||
$select->add('4 ', '4'); | $select->add('4 ', '4'); | ||||
$select->add('5 '.$this->cal->gettext('normal'), '5'); | $select->add('5 ' . $this->cal->gettext('normal'), '5'); | ||||
$select->add('6 ', '6'); | $select->add('6 ', '6'); | ||||
$select->add('7 ', '7'); | $select->add('7 ', '7'); | ||||
$select->add('8 '.$this->cal->gettext('low'), '8'); | $select->add('8 ' . $this->cal->gettext('low'), '8'); | ||||
$select->add('9 '.$this->cal->gettext('lowest'), '9'); | $select->add('9 ' . $this->cal->gettext('lowest'), '9'); | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render HTML input for sensitivity selection | * Render HTML input for sensitivity selection | ||||
*/ | */ | ||||
function sensitivity_select($attrib = array()) | function sensitivity_select($attrib = []) | ||||
{ | { | ||||
$attrib['name'] = 'sensitivity'; | $attrib['name'] = 'sensitivity'; | ||||
$select = new html_select($attrib); | $select = new html_select($attrib); | ||||
$select->add($this->cal->gettext('public'), 'public'); | $select->add($this->cal->gettext('public'), 'public'); | ||||
$select->add($this->cal->gettext('private'), 'private'); | $select->add($this->cal->gettext('private'), 'private'); | ||||
$select->add($this->cal->gettext('confidential'), 'confidential'); | $select->add($this->cal->gettext('confidential'), 'confidential'); | ||||
return $select->show(null); | return $select->show(null); | ||||
} | } | ||||
/** | /** | ||||
* Render HTML form for alarm configuration | * Render HTML form for alarm configuration | ||||
*/ | */ | ||||
function alarm_select($attrib = array()) | function alarm_select($attrib = []) | ||||
{ | { | ||||
return $this->cal->lib->alarm_select($attrib, $this->cal->driver->alarm_types, $this->cal->driver->alarm_absolute); | return $this->cal->lib->alarm_select($attrib, $this->cal->driver->alarm_types, $this->cal->driver->alarm_absolute); | ||||
} | } | ||||
/** | /** | ||||
* Render HTML for attendee notification warning | * Render HTML for attendee notification warning | ||||
*/ | */ | ||||
function edit_attendees_notify($attrib = array()) | function edit_attendees_notify($attrib = []) | ||||
{ | { | ||||
$checkbox = new html_checkbox(array('name' => '_notify', 'id' => 'edit-attendees-donotify', 'value' => 1, 'class' => 'pretty-checkbox')); | $checkbox = new html_checkbox(['name' => '_notify', 'id' => 'edit-attendees-donotify', 'value' => 1, 'class' => 'pretty-checkbox']); | ||||
return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('sendnotifications'))); | return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('sendnotifications'))); | ||||
} | } | ||||
/** | /** | ||||
* Render HTML for recurrence option to align start date with the recurrence rule | * Render HTML for recurrence option to align start date with the recurrence rule | ||||
*/ | */ | ||||
function edit_recurrence_sync($attrib = array()) | function edit_recurrence_sync($attrib = []) | ||||
{ | { | ||||
$checkbox = new html_checkbox(array('name' => '_start_sync', 'value' => 1, 'class' => 'pretty-checkbox')); | $checkbox = new html_checkbox(['name' => '_start_sync', 'value' => 1, 'class' => 'pretty-checkbox']); | ||||
return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('eventstartsync'))); | return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('eventstartsync'))); | ||||
} | } | ||||
/** | /** | ||||
* Generate the form for recurrence settings | * Generate the form for recurrence settings | ||||
*/ | */ | ||||
function recurring_event_warning($attrib = array()) | function recurring_event_warning($attrib = []) | ||||
{ | { | ||||
$attrib['id'] = 'edit-recurring-warning'; | $attrib['id'] = 'edit-recurring-warning'; | ||||
$radio = new html_radiobutton(array('name' => '_savemode', 'class' => 'edit-recurring-savemode')); | $radio = new html_radiobutton(['name' => '_savemode', 'class' => 'edit-recurring-savemode']); | ||||
$form = html::label(null, $radio->show('', array('value' => 'current')) . $this->cal->gettext('currentevent')) . ' ' . | |||||
html::label(null, $radio->show('', array('value' => 'future')) . $this->cal->gettext('futurevents')) . ' ' . | |||||
html::label(null, $radio->show('all', array('value' => 'all')) . $this->cal->gettext('allevents')) . ' ' . | |||||
html::label(null, $radio->show('', array('value' => 'new')) . $this->cal->gettext('saveasnew')); | |||||
return html::div($attrib, html::div('message', $this->cal->gettext('changerecurringeventwarning')) . html::div('savemode', $form)); | $form = html::label(null, $radio->show('', ['value' => 'current']) . $this->cal->gettext('currentevent')) . ' ' | ||||
. html::label(null, $radio->show('', ['value' => 'future']) . $this->cal->gettext('futurevents')) . ' ' | |||||
. html::label(null, $radio->show('all', ['value' => 'all']) . $this->cal->gettext('allevents')) . ' ' | |||||
. html::label(null, $radio->show('', ['value' => 'new']) . $this->cal->gettext('saveasnew')); | |||||
return html::div($attrib, | |||||
html::div('message', $this->cal->gettext('changerecurringeventwarning')) | |||||
. html::div('savemode', $form) | |||||
); | |||||
} | } | ||||
/** | /** | ||||
* Form for uploading and importing events | * Form for uploading and importing events | ||||
*/ | */ | ||||
function events_import_form($attrib = array()) | function events_import_form($attrib = []) | ||||
{ | { | ||||
if (!$attrib['id']) | if (empty($attrib['id'])) { | ||||
$attrib['id'] = 'rcmImportForm'; | $attrib['id'] = 'rcmImportForm'; | ||||
} | |||||
// Get max filesize, enable upload progress bar | // Get max filesize, enable upload progress bar | ||||
$max_filesize = $this->rc->upload_init(); | $max_filesize = $this->rc->upload_init(); | ||||
$accept = '.ics, text/calendar, text/x-vcalendar, application/ics'; | $accept = '.ics, text/calendar, text/x-vcalendar, application/ics'; | ||||
if (class_exists('ZipArchive', false)) { | if (class_exists('ZipArchive', false)) { | ||||
$accept .= ', .zip, application/zip'; | $accept .= ', .zip, application/zip'; | ||||
} | } | ||||
$input = new html_inputfield(array( | $input = new html_inputfield([ | ||||
'id' => 'importfile', | 'id' => 'importfile', | ||||
'type' => 'file', | 'type' => 'file', | ||||
'name' => '_data', | 'name' => '_data', | ||||
'size' => $attrib['uploadfieldsize'], | 'size' => !empty($attrib['uploadfieldsize']) ? $attrib['uploadfieldsize'] : null, | ||||
'accept' => $accept | 'accept' => $accept | ||||
)); | ]); | ||||
$select = new html_select(array('name' => '_range', 'id' => 'event-import-range')); | $select = new html_select(['name' => '_range', 'id' => 'event-import-range']); | ||||
$select->add(array( | $select->add([ | ||||
$this->cal->gettext('onemonthback'), | $this->cal->gettext('onemonthback'), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>2))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>2]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>3))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>3]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>6))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>6]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>12))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr'=>12]]), | ||||
$this->cal->gettext('all'), | $this->cal->gettext('all'), | ||||
), | ], | ||||
array('1','2','3','6','12',0)); | ['1','2','3','6','12',0] | ||||
); | |||||
$html = html::div('form-section form-group row', | $html = html::div('form-section form-group row', | ||||
html::label(array('class' => 'col-sm-4 col-form-label', 'for' => 'importfile'), rcube::Q($this->rc->gettext('importfromfile'))) | html::label(['class' => 'col-sm-4 col-form-label', 'for' => 'importfile'], | ||||
rcube::Q($this->rc->gettext('importfromfile')) | |||||
) | |||||
. html::div('col-sm-8', $input->show() | . html::div('col-sm-8', $input->show() | ||||
. html::div('hint', $this->rc->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))) | . html::div('hint', $this->rc->gettext(['name' => 'maxuploadsize', 'vars' => ['size' => $max_filesize]])) | ||||
) | |||||
); | ); | ||||
$html .= html::div('form-section form-group row', | $html .= html::div('form-section form-group row', | ||||
html::label(array('for' => 'event-import-calendar', 'class' => 'col-form-label col-sm-4'), $this->cal->gettext('calendar')) | html::label(['for' => 'event-import-calendar', 'class' => 'col-form-label col-sm-4'], | ||||
. html::div('col-sm-8', $this->calendar_select(array('name' => 'calendar', 'id' => 'event-import-calendar'))) | $this->cal->gettext('calendar') | ||||
) | |||||
. html::div('col-sm-8', $this->calendar_select(['name' => 'calendar', 'id' => 'event-import-calendar'])) | |||||
); | ); | ||||
$html .= html::div('form-section form-group row', | $html .= html::div('form-section form-group row', | ||||
html::label(array('for' => 'event-import-range', 'class' => 'col-form-label col-sm-4'), $this->cal->gettext('importrange')) | html::label(['for' => 'event-import-range', 'class' => 'col-form-label col-sm-4'], | ||||
$this->cal->gettext('importrange') | |||||
) | |||||
. html::div('col-sm-8', $select->show(1)) | . html::div('col-sm-8', $select->show(1)) | ||||
); | ); | ||||
$this->rc->output->add_gui_object('importform', $attrib['id']); | $this->rc->output->add_gui_object('importform', $attrib['id']); | ||||
$this->rc->output->add_label('import'); | $this->rc->output->add_label('import'); | ||||
return html::tag('p', null, $this->cal->gettext('importtext')) | return html::tag('p', null, $this->cal->gettext('importtext')) | ||||
. html::tag('form', array( | . html::tag('form', [ | ||||
'action' => $this->rc->url(array('task' => 'calendar', 'action' => 'import_events')), | 'action' => $this->rc->url(['task' => 'calendar', 'action' => 'import_events']), | ||||
'method' => 'post', | 'method' => 'post', | ||||
'enctype' => 'multipart/form-data', | 'enctype' => 'multipart/form-data', | ||||
'id' => $attrib['id'] | 'id' => $attrib['id'] | ||||
), $html); | ], $html | ||||
); | |||||
} | } | ||||
/** | /** | ||||
* Form to select options for exporting events | * Form to select options for exporting events | ||||
*/ | */ | ||||
function events_export_form($attrib = array()) | function events_export_form($attrib = []) | ||||
{ | { | ||||
if (!$attrib['id']) | if (empty($attrib['id'])) { | ||||
$attrib['id'] = 'rcmExportForm'; | $attrib['id'] = 'rcmExportForm'; | ||||
} | |||||
$html = html::div('form-section form-group row', | $html = html::div('form-section form-group row', | ||||
html::label(array('for' => 'event-export-calendar', 'class' => 'col-sm-4 col-form-label'), $this->cal->gettext('calendar')) | html::label(['for' => 'event-export-calendar', 'class' => 'col-sm-4 col-form-label'], | ||||
. html::div('col-sm-8', $this->calendar_select(array('name' => 'calendar', 'id' => 'event-export-calendar', 'class' => 'form-control custom-select')))); | $this->cal->gettext('calendar') | ||||
) | |||||
. html::div('col-sm-8', $this->calendar_select(['name' => 'calendar', 'id' => 'event-export-calendar', 'class' => 'form-control custom-select'])) | |||||
); | |||||
$select = new html_select([ | |||||
'name' => 'range', | |||||
'id' => 'event-export-range', | |||||
'class' => 'form-control custom-select rounded-right' | |||||
]); | |||||
$select = new html_select(array('name' => 'range', 'id' => 'event-export-range', 'class' => 'form-control custom-select rounded-right')); | $select->add([ | ||||
$select->add(array( | |||||
$this->cal->gettext('all'), | $this->cal->gettext('all'), | ||||
$this->cal->gettext('onemonthback'), | $this->cal->gettext('onemonthback'), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>2))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 2]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>3))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 3]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>6))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 6]]), | ||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>12))), | $this->cal->gettext(['name' => 'nmonthsback', 'vars' => ['nr' => 12]]), | ||||
$this->cal->gettext('customdate'), | $this->cal->gettext('customdate'), | ||||
), | ], | ||||
array(0,'1','2','3','6','12','custom')); | [0,'1','2','3','6','12','custom'] | ||||
); | |||||
$startdate = new html_inputfield(array('name' => 'start', 'size' => 11, 'id' => 'event-export-startdate', 'style' => 'display:none')); | $startdate = new html_inputfield([ | ||||
'name' => 'start', | |||||
'size' => 11, | |||||
'id' => 'event-export-startdate', | |||||
'style' => 'display:none' | |||||
]); | |||||
$html .= html::div('form-section form-group row', | $html .= html::div('form-section form-group row', | ||||
html::label(array('for' => 'event-export-range', 'class' => 'col-sm-4 col-form-label'), $this->cal->gettext('exportrange')) | html::label(['for' => 'event-export-range', 'class' => 'col-sm-4 col-form-label'], | ||||
. html::div('col-sm-8 input-group', $select->show(0) . $startdate->show())); | $this->cal->gettext('exportrange') | ||||
) | |||||
. html::div('col-sm-8 input-group', $select->show(0) . $startdate->show()) | |||||
); | |||||
$checkbox = new html_checkbox([ | |||||
'name' => 'attachments', | |||||
'id' => 'event-export-attachments', | |||||
'value' => 1, | |||||
'class' => 'form-check-input pretty-checkbox' | |||||
]); | |||||
$checkbox = new html_checkbox(array('name' => 'attachments', 'id' => 'event-export-attachments', 'value' => 1, 'class' => 'form-check-input pretty-checkbox')); | |||||
$html .= html::div('form-section form-check row', | $html .= html::div('form-section form-check row', | ||||
html::label(array('for' => 'event-export-attachments', 'class' => 'col-sm-4 col-form-label'), $this->cal->gettext('exportattachments')) | html::label(['for' => 'event-export-attachments', 'class' => 'col-sm-4 col-form-label'], | ||||
. html::div('col-sm-8', $checkbox->show(1))); | $this->cal->gettext('exportattachments') | ||||
) | |||||
. html::div('col-sm-8', $checkbox->show(1)) | |||||
); | |||||
$this->rc->output->add_gui_object('exportform', $attrib['id']); | $this->rc->output->add_gui_object('exportform', $attrib['id']); | ||||
return html::tag('form', $attrib + array( | return html::tag('form', $attrib + [ | ||||
'action' => $this->rc->url(array('task' => 'calendar', 'action' => 'export_events')), | 'action' => $this->rc->url(['task' => 'calendar', 'action' => 'export_events']), | ||||
'method' => "post", | 'method' => 'post', | ||||
'id' => $attrib['id'] | 'id' => $attrib['id'] | ||||
), | ], | ||||
$html | $html | ||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* Handler for calendar form template. | * Handler for calendar form template. | ||||
* The form content could be overriden by the driver | * The form content could be overriden by the driver | ||||
*/ | */ | ||||
function calendar_editform($action, $calendar = array()) | function calendar_editform($action, $calendar = []) | ||||
{ | { | ||||
$this->action = $action; | $this->action = $action; | ||||
$this->calendar = $calendar; | $this->calendar = $calendar; | ||||
// load miniColors js/css files | // load miniColors js/css files | ||||
jqueryui::miniColors(); | jqueryui::miniColors(); | ||||
$this->rc->output->set_env('pagetitle', $this->cal->gettext('calendarprops')); | $this->rc->output->set_env('pagetitle', $this->cal->gettext('calendarprops')); | ||||
$this->rc->output->add_handler('folderform', array($this, 'calendarform')); | $this->rc->output->add_handler('folderform', [$this, 'calendarform']); | ||||
$this->rc->output->send('libkolab.folderform'); | $this->rc->output->send('libkolab.folderform'); | ||||
} | } | ||||
/** | /** | ||||
* Handler for calendar form template. | * Handler for calendar form template. | ||||
* The form content could be overriden by the driver | * The form content could be overriden by the driver | ||||
*/ | */ | ||||
function calendarform($attrib) | function calendarform($attrib) | ||||
{ | { | ||||
// compose default calendar form fields | // compose default calendar form fields | ||||
$input_name = new html_inputfield(array('name' => 'name', 'id' => 'calendar-name', 'size' => 20)); | $input_name = new html_inputfield(['name' => 'name', 'id' => 'calendar-name', 'size' => 20]); | ||||
$input_color = new html_inputfield(array('name' => 'color', 'id' => 'calendar-color', 'size' => 7, 'class' => 'colors')); | $input_color = new html_inputfield(['name' => 'color', 'id' => 'calendar-color', 'size' => 7, 'class' => 'colors']); | ||||
$formfields = array( | $formfields = [ | ||||
'name' => array( | 'name' => [ | ||||
'label' => $this->cal->gettext('name'), | 'label' => $this->cal->gettext('name'), | ||||
'value' => $input_name->show($calendar['name']), | 'value' => $input_name->show(isset($this->calendar['name']) ? $this->calendar['name'] : ''), | ||||
'id' => 'calendar-name', | 'id' => 'calendar-name', | ||||
), | ], | ||||
'color' => array( | 'color' => [ | ||||
'label' => $this->cal->gettext('color'), | 'label' => $this->cal->gettext('color'), | ||||
'value' => $input_color->show($calendar['color']), | 'value' => $input_color->show(isset($this->calendar['color']) ? $this->calendar['color'] : ''), | ||||
'id' => 'calendar-color', | 'id' => 'calendar-color', | ||||
), | ], | ||||
); | ]; | ||||
if (!empty($this->cal->driver->alarms)) { | |||||
$checkbox = new html_checkbox(['name' => 'showalarms', 'id' => 'calendar-showalarms', 'value' => 1]); | |||||
if ($this->cal->driver->alarms) { | $formfields['showalarms'] = [ | ||||
$checkbox = new html_checkbox(array('name' => 'showalarms', 'id' => 'calendar-showalarms', 'value' => 1)); | |||||
$formfields['showalarms'] = array( | |||||
'label' => $this->cal->gettext('showalarms'), | 'label' => $this->cal->gettext('showalarms'), | ||||
'value' => $checkbox->show($this->calendar['showalarms'] ? 1 :0), | 'value' => $checkbox->show(!empty($this->calendar['showalarms']) ? 1 : 0), | ||||
'id' => 'calendar-showalarms', | 'id' => 'calendar-showalarms', | ||||
); | ]; | ||||
} | } | ||||
// allow driver to extend or replace the form content | // allow driver to extend or replace the form content | ||||
return html::tag('form', $attrib + array('action' => "#", 'method' => "get", 'id' => 'calendarpropform'), | return html::tag('form', $attrib + ['action' => '#', 'method' => 'get', 'id' => 'calendarpropform'], | ||||
$this->cal->driver->calendar_form($this->action, $this->calendar, $formfields) | $this->cal->driver->calendar_form($this->action, $this->calendar, $formfields) | ||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* | * Render HTML for attendees table | ||||
*/ | */ | ||||
function attendees_list($attrib = array()) | function attendees_list($attrib = []) | ||||
{ | { | ||||
// add "noreply" checkbox to attendees table only | // add "noreply" checkbox to attendees table only | ||||
$invitations = strpos($attrib['id'], 'attend') !== false; | $invitations = strpos($attrib['id'], 'attend') !== false; | ||||
$invite = new html_checkbox(array('value' => 1, 'id' => 'edit-attendees-invite')); | $invite = new html_checkbox(['value' => 1, 'id' => 'edit-attendees-invite']); | ||||
$table = new html_table(array('cols' => 5 + intval($invitations), 'border' => 0, 'cellpadding' => 0, 'class' => 'rectable')); | $table = new html_table(['cols' => 5 + intval($invitations), 'border' => 0, 'cellpadding' => 0, 'class' => 'rectable']); | ||||
$table->add_header('role', $this->cal->gettext('role')); | $table->add_header('role', $this->cal->gettext('role')); | ||||
$table->add_header('name', $this->cal->gettext($attrib['coltitle'] ?: 'attendee')); | $table->add_header('name', $this->cal->gettext(!empty($attrib['coltitle']) ? $attrib['coltitle'] : 'attendee')); | ||||
$table->add_header('availability', $this->cal->gettext('availability')); | $table->add_header('availability', $this->cal->gettext('availability')); | ||||
$table->add_header('confirmstate', $this->cal->gettext('confirmstate')); | $table->add_header('confirmstate', $this->cal->gettext('confirmstate')); | ||||
if ($invitations) { | if ($invitations) { | ||||
$table->add_header(array('class' => 'invite', 'title' => $this->cal->gettext('sendinvitations')), | $table->add_header(['class' => 'invite', 'title' => $this->cal->gettext('sendinvitations')], | ||||
$invite->show(1) . html::label('edit-attendees-invite', html::span('inner', $this->cal->gettext('sendinvitations')))); | $invite->show(1) | ||||
. html::label('edit-attendees-invite', html::span('inner', $this->cal->gettext('sendinvitations'))) | |||||
); | |||||
} | } | ||||
$table->add_header('options', ''); | $table->add_header('options', ''); | ||||
// hide invite column if disabled by config | // hide invite column if disabled by config | ||||
$itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', $this->cal->defaults['calendar_itip_send_option']); | $itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', $this->cal->defaults['calendar_itip_send_option']); | ||||
if ($invitations && !($itip_notify & 2)) { | if ($invitations && !($itip_notify & 2)) { | ||||
$css = sprintf('#%s td.invite, #%s th.invite { display:none !important }', $attrib['id'], $attrib['id']); | $css = sprintf('#%s td.invite, #%s th.invite { display:none !important }', $attrib['id'], $attrib['id']); | ||||
$this->rc->output->add_footer(html::tag('style', array('type' => 'text/css'), $css)); | $this->rc->output->add_footer(html::tag('style', ['type' => 'text/css'], $css)); | ||||
} | } | ||||
return $table->show($attrib); | return $table->show($attrib); | ||||
} | } | ||||
/** | /** | ||||
* | * Render HTML for attendees adding form | ||||
*/ | */ | ||||
function attendees_form($attrib = array()) | function attendees_form($attrib = []) | ||||
{ | { | ||||
$input = new html_inputfield(array('name' => 'participant', 'id' => 'edit-attendee-name', 'class' => 'form-control')); | $input = new html_inputfield([ | ||||
$textarea = new html_textarea(array('name' => 'comment', 'id' => 'edit-attendees-comment', 'class' => 'form-control', | 'name' => 'participant', | ||||
'rows' => 4, 'cols' => 55, 'title' => $this->cal->gettext('itipcommenttitle'))); | 'id' => 'edit-attendee-name', | ||||
'class' => 'form-control' | |||||
]); | |||||
$textarea = new html_textarea([ | |||||
'name' => 'comment', | |||||
'id' => 'edit-attendees-comment', | |||||
'class' => 'form-control', | |||||
'rows' => 4, | |||||
'cols' => 55, | |||||
'title' => $this->cal->gettext('itipcommenttitle') | |||||
]); | |||||
return html::div($attrib, | return html::div($attrib, | ||||
html::div('form-searchbar', $input->show() . " " . | html::div('form-searchbar', | ||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-attendee-add', 'value' => $this->cal->gettext('addattendee'))) . " " . | $input->show() | ||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-attendee-schedule', 'value' => $this->cal->gettext('scheduletime').'...'))) . | . ' ' . | ||||
html::p('attendees-commentbox', html::label('edit-attendees-comment', $this->cal->gettext('itipcomment')) . $textarea->show()) | html::tag('input', [ | ||||
'type' => 'button', | |||||
'class' => 'button', | |||||
'id' => 'edit-attendee-add', | |||||
'value' => $this->cal->gettext('addattendee') | |||||
]) | |||||
. ' ' . | |||||
html::tag('input', [ | |||||
'type' => 'button', | |||||
'class' => 'button', | |||||
'id' => 'edit-attendee-schedule', | |||||
'value' => $this->cal->gettext('scheduletime') . '...' | |||||
]) | |||||
) | |||||
. html::p('attendees-commentbox', html::label('edit-attendees-comment', $this->cal->gettext('itipcomment')) . $textarea->show()) | |||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* | * Render HTML for resources adding form | ||||
*/ | */ | ||||
function resources_form($attrib = array()) | function resources_form($attrib = []) | ||||
{ | { | ||||
$input = new html_inputfield(array('name' => 'resource', 'id' => 'edit-resource-name', 'class' => 'form-control')); | $input = new html_inputfield(['name' => 'resource', 'id' => 'edit-resource-name', 'class' => 'form-control']); | ||||
return html::div($attrib, | return html::div($attrib, | ||||
html::div('form-searchbar', $input->show() . " " . | html::div('form-searchbar', | ||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-resource-add', 'value' => $this->cal->gettext('addresource'))) . " " . | $input->show() | ||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-resource-find', 'value' => $this->cal->gettext('findresources').'...'))) | . ' ' . | ||||
html::tag('input', [ | |||||
'type' => 'button', | |||||
'class' => 'button', | |||||
'id' => 'edit-resource-add', | |||||
'value' => $this->cal->gettext('addresource') | |||||
]) | |||||
. ' ' . | |||||
html::tag('input', [ | |||||
'type' => 'button', | |||||
'class' => 'button', | |||||
'id' => 'edit-resource-find', | |||||
'value' => $this->cal->gettext('findresources') . '...' | |||||
]) | |||||
) | |||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* | * Render HTML for resources list | ||||
*/ | */ | ||||
function resources_list($attrib = array()) | function resources_list($attrib = []) | ||||
{ | { | ||||
$attrib += array('id' => 'calendar-resources-list'); | $attrib += ['id' => 'calendar-resources-list']; | ||||
$this->rc->output->add_gui_object('resourceslist', $attrib['id']); | $this->rc->output->add_gui_object('resourceslist', $attrib['id']); | ||||
return html::tag('ul', $attrib, '', html::$common_attrib); | return html::tag('ul', $attrib, '', html::$common_attrib); | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
public function resource_info($attrib = array()) | public function resource_info($attrib = []) | ||||
{ | { | ||||
$attrib += array('id' => 'calendar-resources-info'); | $attrib += ['id' => 'calendar-resources-info']; | ||||
$this->rc->output->add_gui_object('resourceinfo', $attrib['id']); | $this->rc->output->add_gui_object('resourceinfo', $attrib['id']); | ||||
$this->rc->output->add_gui_object('resourceownerinfo', $attrib['id'] . '-owner'); | $this->rc->output->add_gui_object('resourceownerinfo', $attrib['id'] . '-owner'); | ||||
// copy address book labels for owner details to client | // copy address book labels for owner details to client | ||||
$this->rc->output->add_label('name','firstname','surname','department','jobtitle','email','phone','address'); | $this->rc->output->add_label('name','firstname','surname','department','jobtitle','email','phone','address'); | ||||
$table_attrib = array('id','class','style','width','summary','cellpadding','cellspacing','border'); | $table_attrib = ['id','class','style','width','summary','cellpadding','cellspacing','border']; | ||||
return html::tag('table', $attrib, | return html::tag('table', $attrib, html::tag('tbody', null, ''), $table_attrib) | ||||
html::tag('tbody', null, ''), $table_attrib) . | . html::tag('table', ['id' => $attrib['id'] . '-owner', 'style' => 'display:none'] + $attrib, | ||||
html::tag('table', array('id' => $attrib['id'] . '-owner', 'style' => 'display:none') + $attrib, | |||||
html::tag('thead', null, | html::tag('thead', null, | ||||
html::tag('tr', null, | html::tag('tr', null, | ||||
html::tag('td', array('colspan' => 2), rcube::Q($this->cal->gettext('resourceowner'))) | html::tag('td', ['colspan' => 2], rcube::Q($this->cal->gettext('resourceowner'))) | ||||
) | |||||
) | ) | ||||
) . | . html::tag('tbody', null, ''), | ||||
html::tag('tbody', null, ''), | $table_attrib | ||||
$table_attrib); | ); | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
public function resource_calendar($attrib = array()) | public function resource_calendar($attrib = []) | ||||
{ | { | ||||
$attrib += array('id' => 'calendar-resources-calendar'); | $attrib += ['id' => 'calendar-resources-calendar']; | ||||
$this->rc->output->add_gui_object('resourceinfocalendar', $attrib['id']); | $this->rc->output->add_gui_object('resourceinfocalendar', $attrib['id']); | ||||
return html::div($attrib, ''); | return html::div($attrib, ''); | ||||
} | } | ||||
/** | /** | ||||
* GUI object 'searchform' for the resource finder dialog | * GUI object 'searchform' for the resource finder dialog | ||||
* | * | ||||
* @param array Named parameters | * @param array $attrib Named parameters | ||||
* | |||||
* @return string HTML code for the gui object | * @return string HTML code for the gui object | ||||
*/ | */ | ||||
function resources_search_form($attrib) | function resources_search_form($attrib) | ||||
{ | { | ||||
$attrib += array( | $attrib += [ | ||||
'command' => 'search-resource', | 'command' => 'search-resource', | ||||
'reset-command' => 'reset-resource-search', | 'reset-command' => 'reset-resource-search', | ||||
'id' => 'rcmcalresqsearchbox', | 'id' => 'rcmcalresqsearchbox', | ||||
'autocomplete' => 'off', | 'autocomplete' => 'off', | ||||
'form-name' => 'rcmcalresoursqsearchform', | 'form-name' => 'rcmcalresoursqsearchform', | ||||
'gui-object' => 'resourcesearchform', | 'gui-object' => 'resourcesearchform', | ||||
); | ]; | ||||
// add form tag around text field | // add form tag around text field | ||||
return $this->rc->output->search_form($attrib); | return $this->rc->output->search_form($attrib); | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
function attendees_freebusy_table($attrib = array()) | function attendees_freebusy_table($attrib = []) | ||||
{ | { | ||||
$table = new html_table(array('cols' => 2, 'border' => 0, 'cellspacing' => 0)); | $table = new html_table(['cols' => 2, 'border' => 0, 'cellspacing' => 0]); | ||||
$table->add('attendees', | $table->add('attendees', | ||||
html::tag('h3', 'boxtitle', $this->cal->gettext('tabattendees')) . | html::tag('h3', 'boxtitle', $this->cal->gettext('tabattendees')) | ||||
html::div('timesheader', ' ') . | . html::div('timesheader', ' ') | ||||
html::div(array('id' => 'schedule-attendees-list', 'class' => 'attendees-list'), '') | . html::div(['id' => 'schedule-attendees-list', 'class' => 'attendees-list'], '') | ||||
); | ); | ||||
$table->add('times', | $table->add('times', | ||||
html::div('scroll', | html::div('scroll', | ||||
html::tag('table', array('id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0), html::tag('thead') . html::tag('tbody')) . | html::tag('table', ['id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0], | ||||
html::div(array('id' => 'schedule-event-time', 'style' => 'display:none'), ' ') | html::tag('thead') . html::tag('tbody') | ||||
) | |||||
. html::div(['id' => 'schedule-event-time', 'style' => 'display:none'], ' ') | |||||
) | ) | ||||
); | ); | ||||
return $table->show($attrib); | return $table->show($attrib); | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
function event_invitebox($attrib = array()) | function event_invitebox($attrib = []) | ||||
{ | { | ||||
if ($this->cal->event) { | if (!empty($this->cal->event)) { | ||||
return html::div($attrib, | return html::div($attrib, | ||||
$this->cal->itip->itip_object_details_table($this->cal->event, $this->cal->itip->gettext('itipinvitation')) . | $this->cal->itip->itip_object_details_table($this->cal->event, $this->cal->itip->gettext('itipinvitation')) | ||||
$this->cal->invitestatus | . $this->cal->invitestatus | ||||
); | ); | ||||
} | } | ||||
return ''; | return ''; | ||||
} | } | ||||
function event_rsvp_buttons($attrib = array()) | function event_rsvp_buttons($attrib = []) | ||||
{ | { | ||||
$actions = array('accepted','tentative','declined'); | $actions = ['accepted', 'tentative', 'declined']; | ||||
if ($attrib['delegate'] !== 'false') | |||||
if (empty($attrib['delegate']) || $attrib['delegate'] !== 'false') { | |||||
$actions[] = 'delegated'; | $actions[] = 'delegated'; | ||||
} | |||||
return $this->cal->itip->itip_rsvp_buttons($attrib, $actions); | return $this->cal->itip->itip_rsvp_buttons($attrib, $actions); | ||||
} | } | ||||
} | } |