Changeset View
Changeset View
Standalone View
Standalone View
plugins/calendar/calendar.php
Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | else { | ||||
$this->rc->output->show_message($error_msg, 'error'); | $this->rc->output->show_message($error_msg, 'error'); | ||||
} | } | ||||
$this->rc->output->command('plugin.unlock_saving'); | $this->rc->output->command('plugin.unlock_saving'); | ||||
if ($success && $reload) | if ($success && $reload) | ||||
$this->rc->output->command('plugin.reload_view'); | $this->rc->output->command('plugin.reload_view'); | ||||
} | } | ||||
/** | /** | ||||
* Dispatcher for event actions initiated by the client | * Dispatcher for event actions initiated by the client | ||||
*/ | */ | ||||
function event_action() | function event_action() | ||||
{ | { | ||||
$action = rcube_utils::get_input_value('action', rcube_utils::INPUT_GPC); | $action = rcube_utils::get_input_value('action', rcube_utils::INPUT_GPC); | ||||
$event = rcube_utils::get_input_value('e', rcube_utils::INPUT_POST, true); | $event = rcube_utils::get_input_value('e', rcube_utils::INPUT_POST, true); | ||||
$success = $reload = $got_msg = false; | $success = $reload = $got_msg = false; | ||||
// force notify if hidden + active | // force notify if hidden + active | ||||
if ((int)$this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']) === 1) | if ((int)$this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']) === 1) | ||||
$event['_notify'] = 1; | $event['_notify'] = 1; | ||||
// read old event data in order to find changes | // read old event data in order to find changes | ||||
if (($event['_notify'] || $event['_decline']) && $action != 'new') { | if (($event['_notify'] || $event['_decline']) && $action != 'new') { | ||||
$old = $this->driver->get_event($event); | $old = $this->driver->get_event($event); | ||||
// load main event if savemode is 'all' or if deleting 'future' events | // load main event if savemode is 'all' or if deleting 'future' events | ||||
if (($event['_savemode'] == 'all' || ($event['_savemode'] == 'future' && $action == 'remove' && !$event['_decline'])) && $old['recurrence_id']) { | if (($event['_savemode'] == 'all' || ($event['_savemode'] == 'future' && $action == 'remove' && !$event['_decline'])) && $old['recurrence_id']) { | ||||
$old['id'] = $old['recurrence_id']; | $old['id'] = $old['recurrence_id']; | ||||
$old = $this->driver->get_event($old); | $old = $this->driver->get_event($old); | ||||
} | } | ||||
} | } | ||||
switch ($action) { | switch ($action) { | ||||
case "new": | case "new": | ||||
// create UID for new event | // create UID for new event | ||||
$event['uid'] = $this->generate_uid(); | $event['uid'] = $this->generate_uid(); | ||||
$this->write_preprocess($event, $action); | if (!$this->write_preprocess($event, $action)) { | ||||
if ($success = $this->driver->new_event($event)) { | $got_msg = true; | ||||
} | |||||
else if ($success = $this->driver->new_event($event)) { | |||||
$event['id'] = $event['uid']; | $event['id'] = $event['uid']; | ||||
$event['_savemode'] = 'all'; | $event['_savemode'] = 'all'; | ||||
$this->cleanup_event($event); | $this->cleanup_event($event); | ||||
$this->event_save_success($event, null, $action, true); | $this->event_save_success($event, null, $action, true); | ||||
} | } | ||||
$reload = $success && $event['recurrence'] ? 2 : 1; | $reload = $success && $event['recurrence'] ? 2 : 1; | ||||
break; | break; | ||||
case "edit": | case "edit": | ||||
$this->write_preprocess($event, $action); | if (!$this->write_preprocess($event, $action)) { | ||||
if ($success = $this->driver->edit_event($event)) { | $got_msg = true; | ||||
} | |||||
else if ($success = $this->driver->edit_event($event)) { | |||||
$this->cleanup_event($event); | $this->cleanup_event($event); | ||||
$this->event_save_success($event, $old, $action, $success); | $this->event_save_success($event, $old, $action, $success); | ||||
} | } | ||||
$reload = $success && ($event['recurrence'] || $event['_savemode'] || $event['_fromcalendar']) ? 2 : 1; | $reload = $success && ($event['recurrence'] || $event['_savemode'] || $event['_fromcalendar']) ? 2 : 1; | ||||
break; | break; | ||||
case "resize": | case "resize": | ||||
$this->write_preprocess($event, $action); | if (!$this->write_preprocess($event, $action)) { | ||||
if ($success = $this->driver->resize_event($event)) { | $got_msg = true; | ||||
} | |||||
else if ($success = $this->driver->resize_event($event)) { | |||||
$this->event_save_success($event, $old, $action, $success); | $this->event_save_success($event, $old, $action, $success); | ||||
} | } | ||||
$reload = $event['_savemode'] ? 2 : 1; | $reload = $event['_savemode'] ? 2 : 1; | ||||
break; | break; | ||||
case "move": | case "move": | ||||
$this->write_preprocess($event, $action); | if (!$this->write_preprocess($event, $action)) { | ||||
if ($success = $this->driver->move_event($event)) { | $got_msg = true; | ||||
} | |||||
else if ($success = $this->driver->move_event($event)) { | |||||
$this->event_save_success($event, $old, $action, $success); | $this->event_save_success($event, $old, $action, $success); | ||||
} | } | ||||
$reload = $success && $event['_savemode'] ? 2 : 1; | $reload = $success && $event['_savemode'] ? 2 : 1; | ||||
break; | break; | ||||
case "remove": | case "remove": | ||||
// remove previous deletes | // remove previous deletes | ||||
$undo_time = $this->driver->undelete ? $this->rc->config->get('undo_timeout', 0) : 0; | $undo_time = $this->driver->undelete ? $this->rc->config->get('undo_timeout', 0) : 0; | ||||
$this->rc->session->remove('calendar_event_undo'); | $this->rc->session->remove('calendar_event_undo'); | ||||
// search for event if only UID is given | // search for event if only UID is given | ||||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | if (!$got_msg) { | ||||
$this->rc->output->show_message('successfullysaved', 'confirmation'); | $this->rc->output->show_message('successfullysaved', 'confirmation'); | ||||
else | else | ||||
$this->rc->output->show_message('calendar.errorsaving', 'error'); | $this->rc->output->show_message('calendar.errorsaving', 'error'); | ||||
} | } | ||||
// unlock client | // unlock client | ||||
$this->rc->output->command('plugin.unlock_saving'); | $this->rc->output->command('plugin.unlock_saving'); | ||||
// update event object on the client or trigger a complete refretch if too complicated | // update event object on the client or trigger a complete refresh if too complicated | ||||
if ($reload) { | if ($reload) { | ||||
$args = array('source' => $event['calendar']); | $args = array('source' => $event['calendar']); | ||||
if ($reload > 1) | if ($reload > 1) | ||||
$args['refetch'] = true; | $args['refetch'] = true; | ||||
else if ($success && $action != 'remove') | else if ($success && $action != 'remove') | ||||
$args['update'] = $this->_client_event($this->driver->get_event($event), true); | $args['update'] = $this->_client_event($this->driver->get_event($event), true); | ||||
$this->rc->output->command('plugin.refresh_calendar', $args); | $this->rc->output->command('plugin.refresh_calendar', $args); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 792 Lines • ▼ Show 20 Lines | // $chars = "!# abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890"; | ||||
{ | { | ||||
// convert dates into DateTime objects in user's current timezone | // convert dates into DateTime objects in user's current timezone | ||||
$event['start'] = new DateTime($event['start'], $this->timezone); | $event['start'] = new DateTime($event['start'], $this->timezone); | ||||
$event['end'] = new DateTime($event['end'], $this->timezone); | $event['end'] = new DateTime($event['end'], $this->timezone); | ||||
$event['allday'] = (bool)$event['allday']; | $event['allday'] = (bool)$event['allday']; | ||||
// start/end is all we need for 'move' action (#1480) | // start/end is all we need for 'move' action (#1480) | ||||
if ($action == 'move') { | if ($action == 'move') { | ||||
return; | return true; | ||||
} | } | ||||
// convert the submitted recurrence settings | // convert the submitted recurrence settings | ||||
if (is_array($event['recurrence'])) { | if (is_array($event['recurrence'])) { | ||||
$event['recurrence'] = $this->lib->from_client_recurrence($event['recurrence'], $event['start']); | $event['recurrence'] = $this->lib->from_client_recurrence($event['recurrence'], $event['start']); | ||||
// align start date with the first occurrence | |||||
if (!empty($event['recurrence']) && !empty($event['syncstart']) | |||||
&& (empty($event['_savemode']) || $event['_savemode'] == 'all') | |||||
) { | |||||
$next = $this->find_first_occurrence($event); | |||||
if (!$next) { | |||||
$this->rc->output->show_message('calendar.recurrenceerror', 'error'); | |||||
return false; | |||||
} | |||||
else if ($event['start'] != $next) { | |||||
$diff = $event['start']->diff($event['end'], true); | |||||
$event['start'] = $next; | |||||
$event['end'] = clone $next; | |||||
$event['end']->add($diff); | |||||
} | |||||
} | |||||
} | } | ||||
// convert the submitted alarm values | // convert the submitted alarm values | ||||
if ($event['valarms']) { | if ($event['valarms']) { | ||||
$event['valarms'] = libcalendaring::from_client_alarms($event['valarms']); | $event['valarms'] = libcalendaring::from_client_alarms($event['valarms']); | ||||
} | } | ||||
$attachments = array(); | $attachments = array(); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if ($action == 'new' || $action == 'edit') { | ||||
} | } | ||||
} | } | ||||
// mapping url => vurl because of the fullcalendar client script | // mapping url => vurl because of the fullcalendar client script | ||||
if (array_key_exists('vurl', $event)) { | if (array_key_exists('vurl', $event)) { | ||||
$event['url'] = $event['vurl']; | $event['url'] = $event['vurl']; | ||||
unset($event['vurl']); | unset($event['vurl']); | ||||
} | } | ||||
return true; | |||||
} | } | ||||
/** | /** | ||||
* Releases some resources after successful event save | * Releases some resources after successful event save | ||||
*/ | */ | ||||
private function cleanup_event(&$event) | private function cleanup_event(&$event) | ||||
{ | { | ||||
// remove temp. attachment files | // remove temp. attachment files | ||||
▲ Show 20 Lines • Show All 1,357 Lines • ▼ Show 20 Lines | public function user_delete($args) | ||||
$db->query("DELETE FROM $table_itipinvitations WHERE `user_id` = ?", $args['user']->ID); | $db->query("DELETE FROM $table_itipinvitations WHERE `user_id` = ?", $args['user']->ID); | ||||
$this->setup(); | $this->setup(); | ||||
$this->load_driver(); | $this->load_driver(); | ||||
return $this->driver->user_delete($args); | return $this->driver->user_delete($args); | ||||
} | } | ||||
/** | /** | ||||
* Find first occurrence of a recurring event excluding start date | |||||
* | |||||
* @param array $event Event data (with 'start' and 'recurrence') | |||||
* | |||||
* @return DateTime Date of the first occurrence | |||||
*/ | |||||
public function find_first_occurrence($event) | |||||
{ | |||||
// Make sure libkolab plugin is loaded in case of Kolab driver | |||||
$this->load_driver(); | |||||
// Use libkolab to compute recurring events (and libkolab plugin) | |||||
// Horde-based fallback has many bugs | |||||
if (class_exists('kolabformat') && class_exists('kolabcalendaring') && class_exists('kolab_date_recurrence')) { | |||||
$object = kolab_format::factory('event', 3.0); | |||||
$object->set($event); | |||||
$recurrence = new kolab_date_recurrence($object); | |||||
} | |||||
else { | |||||
// fallback to libcalendaring (Horde-based) recurrence implementation | |||||
require_once(__DIR__ . '/lib/calendar_recurrence.php'); | |||||
$recurrence = new calendar_recurrence($this, $event); | |||||
} | |||||
return $recurrence->first_occurrence(); | |||||
} | |||||
/** | |||||
* Magic getter for public access to protected members | * Magic getter for public access to protected members | ||||
*/ | */ | ||||
public function __get($name) | public function __get($name) | ||||
{ | { | ||||
switch ($name) { | switch ($name) { | ||||
case 'ical': | case 'ical': | ||||
return $this->get_ical(); | return $this->get_ical(); | ||||
Show All 12 Lines |