Changeset View
Changeset View
Standalone View
Standalone View
plugins/tasklist/tasklist.php
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | class tasklist extends rcube_plugin | ||||
// These are handled by __get() | // These are handled by __get() | ||||
// public $driver; | // public $driver; | ||||
// public $itip; | // public $itip; | ||||
// public $ical; | // public $ical; | ||||
private $collapsed_tasks = array(); | private $collapsed_tasks = array(); | ||||
private $message_tasks = array(); | private $message_tasks = array(); | ||||
private $task_titles = array(); | |||||
/** | /** | ||||
* Plugin initialization. | * Plugin initialization. | ||||
*/ | */ | ||||
function init() | function init() | ||||
{ | { | ||||
$this->require_plugin('libcalendaring'); | $this->require_plugin('libcalendaring'); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | public function startup($args) | ||||
if ($args['action'] == 'show' || $args['action'] == 'preview') { | if ($args['action'] == 'show' || $args['action'] == 'preview') { | ||||
if ($this->rc->config->get('tasklist_mail_embed', true)) { | if ($this->rc->config->get('tasklist_mail_embed', true)) { | ||||
$this->add_hook('message_load', array($this, 'mail_message_load')); | $this->add_hook('message_load', array($this, 'mail_message_load')); | ||||
} | } | ||||
$this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html')); | $this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html')); | ||||
} | } | ||||
// add 'Create event' item to message menu | // add 'Create event' item to message menu | ||||
if ($this->api->output->type == 'html' && $_GET['_rel'] != 'task') { | if ($this->api->output->type == 'html' && (empty($_GET['_rel']) || $_GET['_rel'] != 'task')) { | ||||
$this->api->add_content(html::tag('li', array('role' => 'menuitem'), | $this->api->add_content(html::tag('li', array('role' => 'menuitem'), | ||||
$this->api->output->button(array( | $this->api->output->button(array( | ||||
'command' => 'tasklist-create-from-mail', | 'command' => 'tasklist-create-from-mail', | ||||
'label' => 'tasklist.createfrommail', | 'label' => 'tasklist.createfrommail', | ||||
'type' => 'link', | 'type' => 'link', | ||||
'classact' => 'icon taskaddlink active', | 'classact' => 'icon taskaddlink active', | ||||
'class' => 'icon taskaddlink disabled', | 'class' => 'icon taskaddlink disabled', | ||||
'innerclass' => 'icon taskadd', | 'innerclass' => 'icon taskadd', | ||||
))), | ))), | ||||
'messagemenu'); | 'messagemenu'); | ||||
$this->api->output->add_label('tasklist.createfrommail'); | $this->api->output->add_label('tasklist.createfrommail'); | ||||
} | } | ||||
} | } | ||||
if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) { | if (!$this->rc->output->ajax_call && empty($this->rc->output->env['framed'])) { | ||||
$this->load_ui(); | $this->load_ui(); | ||||
$this->ui->init(); | $this->ui->init(); | ||||
} | } | ||||
// add hooks for alarms handling | // add hooks for alarms handling | ||||
$this->add_hook('pending_alarms', array($this, 'pending_alarms')); | $this->add_hook('pending_alarms', array($this, 'pending_alarms')); | ||||
$this->add_hook('dismiss_alarms', array($this, 'dismiss_alarms')); | $this->add_hook('dismiss_alarms', array($this, 'dismiss_alarms')); | ||||
} | } | ||||
Show All 9 Lines | private function load_ui() | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Helper method to load the backend driver according to local config | * Helper method to load the backend driver according to local config | ||||
*/ | */ | ||||
private function load_driver() | private function load_driver() | ||||
{ | { | ||||
if (is_object($this->driver)) { | if (!empty($this->driver)) { | ||||
return; | return; | ||||
} | } | ||||
$driver_name = $this->rc->config->get('tasklist_driver', 'database'); | $driver_name = $this->rc->config->get('tasklist_driver', 'database'); | ||||
$driver_class = 'tasklist_' . $driver_name . '_driver'; | $driver_class = 'tasklist_' . $driver_name . '_driver'; | ||||
require_once($this->home . '/drivers/tasklist_driver.php'); | require_once($this->home . '/drivers/tasklist_driver.php'); | ||||
require_once($this->home . '/drivers/' . $driver_name . '/' . $driver_class . '.php'); | require_once($this->home . '/drivers/' . $driver_name . '/' . $driver_class . '.php'); | ||||
Show All 11 Lines | public function task_action() | ||||
$filter = intval(rcube_utils::get_input_value('filter', rcube_utils::INPUT_GPC)); | $filter = intval(rcube_utils::get_input_value('filter', rcube_utils::INPUT_GPC)); | ||||
$action = rcube_utils::get_input_value('action', rcube_utils::INPUT_GPC); | $action = rcube_utils::get_input_value('action', rcube_utils::INPUT_GPC); | ||||
$rec = rcube_utils::get_input_value('t', rcube_utils::INPUT_POST, true); | $rec = rcube_utils::get_input_value('t', rcube_utils::INPUT_POST, true); | ||||
$oldrec = $rec; | $oldrec = $rec; | ||||
$success = $refresh = $got_msg = false; | $success = $refresh = $got_msg = false; | ||||
// force notify if hidden + active | // force notify if hidden + active | ||||
$itip_send_option = (int)$this->rc->config->get('calendar_itip_send_option', 3); | $itip_send_option = (int)$this->rc->config->get('calendar_itip_send_option', 3); | ||||
if ($itip_send_option === 1 && empty($rec['_reportpartstat'])) | if ($itip_send_option === 1 && empty($rec['_reportpartstat'])) { | ||||
$rec['_notify'] = 1; | $rec['_notify'] = 1; | ||||
} | |||||
switch ($action) { | switch ($action) { | ||||
case 'new': | case 'new': | ||||
$oldrec = null; | $oldrec = null; | ||||
$rec = $this->prepare_task($rec); | $rec = $this->prepare_task($rec); | ||||
$rec['uid'] = $this->generate_uid(); | $rec['uid'] = $this->generate_uid(); | ||||
$temp_id = $rec['tempid']; | $temp_id = !empty($rec['tempid']) ? $rec['tempid'] : null; | ||||
if ($success = $this->driver->create_task($rec)) { | if ($success = $this->driver->create_task($rec)) { | ||||
$refresh = $this->driver->get_task($rec); | $refresh = $this->driver->get_task($rec); | ||||
if ($temp_id) $refresh['tempid'] = $temp_id; | if ($temp_id) $refresh['tempid'] = $temp_id; | ||||
$this->cleanup_task($rec); | $this->cleanup_task($rec); | ||||
} | } | ||||
break; | break; | ||||
case 'complete': | case 'complete': | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | public function task_action() | ||||
$this->rc->output->show_message('successfullysaved', 'confirmation'); | $this->rc->output->show_message('successfullysaved', 'confirmation'); | ||||
$this->update_counts($oldrec, $refresh); | $this->update_counts($oldrec, $refresh); | ||||
} | } | ||||
else if (!$got_msg) { | else if (!$got_msg) { | ||||
$this->rc->output->show_message('tasklist.errorsaving', 'error'); | $this->rc->output->show_message('tasklist.errorsaving', 'error'); | ||||
} | } | ||||
// send out notifications | // send out notifications | ||||
if ($success && $rec['_notify'] && ($rec['attendees'] || $oldrec['attendees'])) { | if ($success && !empty($rec['_notify']) && ($rec['attendees'] || $oldrec['attendees'])) { | ||||
// make sure we have the complete record | // make sure we have the complete record | ||||
$task = $action == 'delete' ? $oldrec : $this->driver->get_task($rec); | $task = $action == 'delete' ? $oldrec : $this->driver->get_task($rec); | ||||
// only notify if data really changed (TODO: do diff check on client already) | // only notify if data really changed (TODO: do diff check on client already) | ||||
if (!$oldrec || $action == 'delete' || self::task_diff($task, $oldrec)) { | if (!$oldrec || $action == 'delete' || self::task_diff($task, $oldrec)) { | ||||
$sent = $this->notify_attendees($task, $oldrec, $action, $rec['_comment']); | $sent = $this->notify_attendees($task, $oldrec, $action, $rec['_comment']); | ||||
if ($sent > 0) | if ($sent > 0) | ||||
$this->rc->output->show_message('tasklist.itipsendsuccess', 'confirmation'); | $this->rc->output->show_message('tasklist.itipsendsuccess', 'confirmation'); | ||||
else if ($sent < 0) | else if ($sent < 0) | ||||
$this->rc->output->show_message('tasklist.errornotifying', 'error'); | $this->rc->output->show_message('tasklist.errornotifying', 'error'); | ||||
} | } | ||||
} | } | ||||
if ($success && $rec['_reportpartstat'] && $rec['_reportpartstat'] != 'NEEDS-ACTION') { | if ($success && !empty($rec['_reportpartstat']) && $rec['_reportpartstat'] != 'NEEDS-ACTION') { | ||||
// get the full record after update | // get the full record after update | ||||
if (!$task) { | if (!$task) { | ||||
$task = $this->driver->get_task($rec); | $task = $this->driver->get_task($rec); | ||||
} | } | ||||
// send iTip REPLY with the updated partstat | // send iTip REPLY with the updated partstat | ||||
if ($task['organizer'] && ($idx = $this->is_attendee($task)) !== false) { | if ($task['organizer'] && ($idx = $this->is_attendee($task)) !== false) { | ||||
$sender = $task['attendees'][$idx]; | $sender = $task['attendees'][$idx]; | ||||
Show All 11 Lines | public function task_action() | ||||
$this->rc->output->command('display_message', $this->gettext('itipresponseerror'), 'error'); | $this->rc->output->command('display_message', $this->gettext('itipresponseerror'), 'error'); | ||||
} | } | ||||
} | } | ||||
// unlock client | // unlock client | ||||
$this->rc->output->command('plugin.unlock_saving', $success); | $this->rc->output->command('plugin.unlock_saving', $success); | ||||
if ($refresh) { | if ($refresh) { | ||||
if ($refresh['id']) { | if (!empty($refresh['id'])) { | ||||
$this->encode_task($refresh); | $this->encode_task($refresh); | ||||
} | } | ||||
else if (is_array($refresh)) { | else if (is_array($refresh)) { | ||||
foreach ($refresh as $i => $r) | foreach ($refresh as $i => $r) | ||||
$this->encode_task($refresh[$i]); | $this->encode_task($refresh[$i]); | ||||
} | } | ||||
$this->rc->output->command('plugin.update_task', $refresh); | $this->rc->output->command('plugin.update_task', $refresh); | ||||
} | } | ||||
else if ($success && ($action == 'delete' || $action == 'undelete')) { | else if ($success && ($action == 'delete' || $action == 'undelete')) { | ||||
$this->rc->output->command('plugin.refresh_tagcloud'); | $this->rc->output->command('plugin.refresh_tagcloud'); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Load iTIP functions | * Load iTIP functions | ||||
*/ | */ | ||||
private function load_itip() | private function load_itip() | ||||
{ | { | ||||
if (!$this->itip) { | if (empty($this->itip)) { | ||||
require_once realpath(__DIR__ . '/../libcalendaring/lib/libcalendaring_itip.php'); | require_once __DIR__ . '/../libcalendaring/lib/libcalendaring_itip.php'; | ||||
$this->itip = new libcalendaring_itip($this, 'tasklist'); | $this->itip = new libcalendaring_itip($this, 'tasklist'); | ||||
$this->itip->set_rsvp_actions(array('accepted','declined','delegated')); | $this->itip->set_rsvp_actions(array('accepted','declined','delegated')); | ||||
$this->itip->set_rsvp_status(array('accepted','tentative','declined','delegated','in-process','completed')); | $this->itip->set_rsvp_status(array('accepted','tentative','declined','delegated','in-process','completed')); | ||||
} | } | ||||
return $this->itip; | return $this->itip; | ||||
} | } | ||||
/** | /** | ||||
* repares new/edited task properties before save | * repares new/edited task properties before save | ||||
*/ | */ | ||||
private function prepare_task($rec) | private function prepare_task($rec) | ||||
{ | { | ||||
// try to be smart and extract date from raw input | // try to be smart and extract date from raw input | ||||
if ($rec['raw']) { | if (!empty($rec['raw'])) { | ||||
foreach (array('today','tomorrow','sunday','monday','tuesday','wednesday','thursday','friday','saturday','sun','mon','tue','wed','thu','fri','sat') as $word) { | foreach (array('today','tomorrow','sunday','monday','tuesday','wednesday','thursday','friday','saturday','sun','mon','tue','wed','thu','fri','sat') as $word) { | ||||
$locwords[] = '/^' . preg_quote(mb_strtolower($this->gettext($word))) . '\b/i'; | $locwords[] = '/^' . preg_quote(mb_strtolower($this->gettext($word))) . '\b/i'; | ||||
$normwords[] = $word; | $normwords[] = $word; | ||||
$datewords[] = $word; | $datewords[] = $word; | ||||
} | } | ||||
foreach (array('jan','feb','mar','apr','may','jun','jul','aug','sep','oct','now','dec') as $month) { | foreach (array('jan','feb','mar','apr','may','jun','jul','aug','sep','oct','now','dec') as $month) { | ||||
$locwords[] = '/(' . preg_quote(mb_strtolower($this->gettext('long'.$month))) . '|' . preg_quote(mb_strtolower($this->gettext($month))) . ')\b/i'; | $locwords[] = '/(' . preg_quote(mb_strtolower($this->gettext('long'.$month))) . '|' . preg_quote(mb_strtolower($this->gettext($month))) . ')\b/i'; | ||||
$normwords[] = $month; | $normwords[] = $month; | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | private function prepare_task($rec) | ||||
} | } | ||||
// convert tags to array, filter out empty entries | // convert tags to array, filter out empty entries | ||||
if (isset($rec['tags']) && !is_array($rec['tags'])) { | if (isset($rec['tags']) && !is_array($rec['tags'])) { | ||||
$rec['tags'] = array_filter((array)$rec['tags']); | $rec['tags'] = array_filter((array)$rec['tags']); | ||||
} | } | ||||
// convert the submitted alarm values | // convert the submitted alarm values | ||||
if ($rec['valarms']) { | if (!empty($rec['valarms'])) { | ||||
$valarms = array(); | $valarms = array(); | ||||
foreach (libcalendaring::from_client_alarms($rec['valarms']) as $alarm) { | foreach (libcalendaring::from_client_alarms($rec['valarms']) as $alarm) { | ||||
// alarms can only work with a date (either task start, due or absolute alarm date) | // alarms can only work with a date (either task start, due or absolute alarm date) | ||||
if (is_a($alarm['trigger'], 'DateTime') || $rec['date'] || $rec['startdate']) | if (is_a($alarm['trigger'], 'DateTime') || $rec['date'] || $rec['startdate']) | ||||
$valarms[] = $alarm; | $valarms[] = $alarm; | ||||
} | } | ||||
$rec['valarms'] = $valarms; | $rec['valarms'] = $valarms; | ||||
} | } | ||||
Show All 9 Lines | private function prepare_task($rec) | ||||
} | } | ||||
if ($refdate) { | if ($refdate) { | ||||
$rec['recurrence'] = $this->lib->from_client_recurrence($rec['recurrence'], $refdate); | $rec['recurrence'] = $this->lib->from_client_recurrence($rec['recurrence'], $refdate); | ||||
// translate count into an absolute end date. | // translate count into an absolute end date. | ||||
// why? because when shifting completed tasks to the next recurrence, | // why? because when shifting completed tasks to the next recurrence, | ||||
// the initial start date to count from gets lost. | // the initial start date to count from gets lost. | ||||
if ($rec['recurrence']['COUNT']) { | if (!empty($rec['recurrence']['COUNT'])) { | ||||
$engine = libcalendaring::get_recurrence(); | $engine = libcalendaring::get_recurrence(); | ||||
$engine->init($rec['recurrence'], $refdate); | $engine->init($rec['recurrence'], $refdate); | ||||
if ($until = $engine->end()) { | if ($until = $engine->end()) { | ||||
$rec['recurrence']['UNTIL'] = $until; | $rec['recurrence']['UNTIL'] = $until; | ||||
unset($rec['recurrence']['COUNT']); | unset($rec['recurrence']['COUNT']); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
else { // recurrence requires a reference date | else { // recurrence requires a reference date | ||||
$rec['recurrence'] = ''; | $rec['recurrence'] = ''; | ||||
} | } | ||||
} | } | ||||
$attachments = array(); | $attachments = array(); | ||||
$taskid = $rec['id']; | $taskid = $rec['id']; | ||||
if (is_array($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY]['id'] == $taskid) { | if (!empty($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY]['id'] == $taskid) { | ||||
if (!empty($_SESSION[self::SESSION_KEY]['attachments'])) { | if (!empty($_SESSION[self::SESSION_KEY]['attachments'])) { | ||||
foreach ($_SESSION[self::SESSION_KEY]['attachments'] as $id => $attachment) { | foreach ($_SESSION[self::SESSION_KEY]['attachments'] as $id => $attachment) { | ||||
if (is_array($rec['attachments']) && in_array($id, $rec['attachments'])) { | if (is_array($rec['attachments']) && in_array($id, $rec['attachments'])) { | ||||
$attachments[$id] = $this->rc->plugins->exec_hook('attachment_get', $attachment); | $attachments[$id] = $this->rc->plugins->exec_hook('attachment_get', $attachment); | ||||
unset($attachments[$id]['abort'], $attachments[$id]['group']); | unset($attachments[$id]['abort'], $attachments[$id]['group']); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$rec['attachments'] = $attachments; | $rec['attachments'] = $attachments; | ||||
// convert link references into simple URIs | // convert link references into simple URIs | ||||
if (array_key_exists('links', $rec)) { | if (array_key_exists('links', $rec)) { | ||||
$rec['links'] = array_map(function($link) { return is_array($link) ? $link['uri'] : strval($link); }, (array)$rec['links']); | $rec['links'] = array_map(function($link) { return is_array($link) ? $link['uri'] : strval($link); }, (array)$rec['links']); | ||||
} | } | ||||
// convert invalid data | // convert invalid data | ||||
if (isset($rec['attendees']) && !is_array($rec['attendees'])) | if (isset($rec['attendees']) && !is_array($rec['attendees'])) { | ||||
$rec['attendees'] = array(); | $rec['attendees'] = array(); | ||||
} | |||||
if (!empty($rec['attendees'])) { | |||||
foreach ((array)$rec['attendees'] as $i => $attendee) { | foreach ((array) $rec['attendees'] as $i => $attendee) { | ||||
if (is_string($attendee['rsvp'])) { | if (is_string($attendee['rsvp'])) { | ||||
$rec['attendees'][$i]['rsvp'] = $attendee['rsvp'] == 'true' || $attendee['rsvp'] == '1'; | $rec['attendees'][$i]['rsvp'] = $attendee['rsvp'] == 'true' || $attendee['rsvp'] == '1'; | ||||
} | } | ||||
} | } | ||||
} | |||||
// copy the task status to my attendee partstat | // copy the task status to my attendee partstat | ||||
if (!empty($rec['_reportpartstat'])) { | if (!empty($rec['_reportpartstat'])) { | ||||
if (($idx = $this->is_attendee($rec)) !== false) { | if (($idx = $this->is_attendee($rec)) !== false) { | ||||
if (!($rec['_reportpartstat'] == 'NEEDS-ACTION' && $rec['attendees'][$idx]['status'] == 'ACCEPTED')) | if (!($rec['_reportpartstat'] == 'NEEDS-ACTION' && $rec['attendees'][$idx]['status'] == 'ACCEPTED')) | ||||
$rec['attendees'][$idx]['status'] = $rec['_reportpartstat']; | $rec['attendees'][$idx]['status'] = $rec['_reportpartstat']; | ||||
else | else | ||||
unset($rec['_reportpartstat']); | unset($rec['_reportpartstat']); | ||||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | public function tasklist_action() | ||||
$this->load_ui(); | $this->load_ui(); | ||||
echo $this->ui->tasklist_editform($action, $list); | echo $this->ui->tasklist_editform($action, $list); | ||||
exit; | exit; | ||||
case 'new': | case 'new': | ||||
$list += array('showalarms' => true, 'active' => true, 'editable' => true); | $list += array('showalarms' => true, 'active' => true, 'editable' => true); | ||||
if ($insert_id = $this->driver->create_list($list)) { | if ($insert_id = $this->driver->create_list($list)) { | ||||
$list['id'] = $insert_id; | $list['id'] = $insert_id; | ||||
if (!$list['_reload']) { | if (empty($list['_reload'])) { | ||||
$this->load_ui(); | $this->load_ui(); | ||||
$list['html'] = $this->ui->tasklist_list_item($insert_id, $list, $jsenv); | $list['html'] = $this->ui->tasklist_list_item($insert_id, $list, $jsenv); | ||||
$list += (array)$jsenv[$insert_id]; | $list += (array)$jsenv[$insert_id]; | ||||
} | } | ||||
$this->rc->output->command('plugin.insert_tasklist', $list); | $this->rc->output->command('plugin.insert_tasklist', $list); | ||||
$success = true; | $success = true; | ||||
} | } | ||||
break; | break; | ||||
Show All 31 Lines | public function tasklist_action() | ||||
$html = $this->ui->tasklist_list_item($id, $prop, $jsenv); | $html = $this->ui->tasklist_list_item($id, $prop, $jsenv); | ||||
$prop += (array)$jsenv[$id]; | $prop += (array)$jsenv[$id]; | ||||
$prop['editname'] = $editname; | $prop['editname'] = $editname; | ||||
$prop['html'] = $html; | $prop['html'] = $html; | ||||
$results[] = $prop; | $results[] = $prop; | ||||
} | } | ||||
// report more results available | // report more results available | ||||
if ($this->driver->search_more_results) { | if (!empty($this->driver->search_more_results)) { | ||||
$this->rc->output->show_message('autocompletemore', 'notice'); | $this->rc->output->show_message('autocompletemore', 'notice'); | ||||
} | } | ||||
$this->rc->output->command('multi_thread_http_response', $results, rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC)); | $this->rc->output->command('multi_thread_http_response', $results, rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC)); | ||||
return; | return; | ||||
} | } | ||||
if ($success) | if ($success) { | ||||
$this->rc->output->show_message('successfullysaved', 'confirmation'); | $this->rc->output->show_message('successfullysaved', 'confirmation'); | ||||
else | } | ||||
else { | |||||
$this->rc->output->show_message('tasklist.errorsaving', 'error'); | $this->rc->output->show_message('tasklist.errorsaving', 'error'); | ||||
} | |||||
$this->rc->output->command('plugin.unlock_saving'); | $this->rc->output->command('plugin.unlock_saving'); | ||||
} | } | ||||
/** | /** | ||||
* Get counts for active tasks divided into different selectors | * Get counts for active tasks divided into different selectors | ||||
*/ | */ | ||||
public function fetch_counts() | public function fetch_counts() | ||||
{ | { | ||||
if (isset($_REQUEST['lists'])) { | if (isset($_REQUEST['lists'])) { | ||||
$lists = rcube_utils::get_input_value('lists', rcube_utils::INPUT_GPC); | $lists = rcube_utils::get_input_value('lists', rcube_utils::INPUT_GPC); | ||||
} | } | ||||
else { | else { | ||||
foreach ($this->driver->get_lists() as $list) { | foreach ($this->driver->get_lists() as $list) { | ||||
if ($list['active']) | if (!empty($list['active'])) { | ||||
$lists[] = $list['id']; | $lists[] = $list['id']; | ||||
} | } | ||||
} | } | ||||
} | |||||
$counts = $this->driver->count_tasks($lists); | $counts = $this->driver->count_tasks($lists); | ||||
$this->rc->output->command('plugin.update_counts', $counts); | $this->rc->output->command('plugin.update_counts', $counts); | ||||
} | } | ||||
/** | /** | ||||
* Adjust the cached counts after changing a task | * Adjust the cached counts after changing a task | ||||
*/ | */ | ||||
public function update_counts($oldrec, $newrec) | public function update_counts($oldrec, $newrec) | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Prepare and sort the given task records to be sent to the client | * Prepare and sort the given task records to be sent to the client | ||||
*/ | */ | ||||
private function tasks_data($records) | private function tasks_data($records) | ||||
{ | { | ||||
$data = $this->task_tree = $this->task_titles = array(); | $data = $this->task_tree = $this->task_titles = array(); | ||||
foreach ($records as $rec) { | foreach ($records as $rec) { | ||||
if ($rec['parent_id']) { | if (!empty($rec['parent_id'])) { | ||||
$this->task_tree[$rec['id']] = $rec['parent_id']; | $this->task_tree[$rec['id']] = $rec['parent_id']; | ||||
} | } | ||||
$this->encode_task($rec); | $this->encode_task($rec); | ||||
$data[] = $rec; | $data[] = $rec; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | private function encode_task(&$rec) | ||||
$rec['startdatetime'] = intval($date->format('U')); | $rec['startdatetime'] = intval($date->format('U')); | ||||
$rec['startdate'] = $date->format($this->rc->config->get('date_format', 'Y-m-d')); | $rec['startdate'] = $date->format($this->rc->config->get('date_format', 'Y-m-d')); | ||||
} | } | ||||
catch (Exception $e) { | catch (Exception $e) { | ||||
$rec['startdate'] = $rec['startdatetime'] = null; | $rec['startdate'] = $rec['startdatetime'] = null; | ||||
} | } | ||||
} | } | ||||
if ($rec['valarms']) { | if (!empty($rec['valarms'])) { | ||||
$rec['alarms_text'] = libcalendaring::alarms_text($rec['valarms']); | $rec['alarms_text'] = libcalendaring::alarms_text($rec['valarms']); | ||||
$rec['valarms'] = libcalendaring::to_client_alarms($rec['valarms']); | $rec['valarms'] = libcalendaring::to_client_alarms($rec['valarms']); | ||||
} | } | ||||
if ($rec['recurrence']) { | if (!empty($rec['recurrence'])) { | ||||
$rec['recurrence_text'] = $this->lib->recurrence_text($rec['recurrence']); | $rec['recurrence_text'] = $this->lib->recurrence_text($rec['recurrence']); | ||||
$rec['recurrence'] = $this->lib->to_client_recurrence($rec['recurrence'], $rec['time'] || $rec['starttime']); | $rec['recurrence'] = $this->lib->to_client_recurrence($rec['recurrence'], $rec['time'] || $rec['starttime']); | ||||
} | } | ||||
if (!empty($rec['attachments'])) { | |||||
foreach ((array)$rec['attachments'] as $k => $attachment) { | foreach ((array) $rec['attachments'] as $k => $attachment) { | ||||
$rec['attachments'][$k]['classname'] = rcube_utils::file2class($attachment['mimetype'], $attachment['name']); | $rec['attachments'][$k]['classname'] = rcube_utils::file2class($attachment['mimetype'], $attachment['name']); | ||||
} | } | ||||
} | |||||
// convert link URIs references into structs | // convert link URIs references into structs | ||||
if (array_key_exists('links', $rec)) { | if (array_key_exists('links', $rec)) { | ||||
foreach ((array) $rec['links'] as $i => $link) { | foreach ((array) $rec['links'] as $i => $link) { | ||||
if (strpos($link, 'imap://') === 0 && ($msgref = $this->driver->get_message_reference($link, 'task'))) { | if (strpos($link, 'imap://') === 0 && ($msgref = $this->driver->get_message_reference($link, 'task'))) { | ||||
$rec['links'][$i] = $msgref; | $rec['links'][$i] = $msgref; | ||||
} | } | ||||
} | } | ||||
Show All 30 Lines | |||||
/** | /** | ||||
* Callback function for array_walk over all tasks. | * Callback function for array_walk over all tasks. | ||||
* Sets tree depth and parent titles | * Sets tree depth and parent titles | ||||
*/ | */ | ||||
private function task_walk_tree(&$rec) | private function task_walk_tree(&$rec) | ||||
{ | { | ||||
$rec['_depth'] = 0; | $rec['_depth'] = 0; | ||||
$parent_titles = array(); | $parent_titles = array(); | ||||
$parent_id = $this->task_tree[$rec['id']]; | $parent_id = isset($this->task_tree[$rec['id']]) ? $this->task_tree[$rec['id']] : null; | ||||
while ($parent_id) { | while ($parent_id) { | ||||
$rec['_depth']++; | $rec['_depth']++; | ||||
if (isset($this->task_titles[$parent_id])) { | |||||
array_unshift($parent_titles, $this->task_titles[$parent_id]); | array_unshift($parent_titles, $this->task_titles[$parent_id]); | ||||
$parent_id = $this->task_tree[$parent_id]; | } | ||||
$parent_id = isset($this->task_tree[$parent_id]) ? $this->task_tree[$parent_id] : null; | |||||
} | } | ||||
if (count($parent_titles)) { | if (count($parent_titles)) { | ||||
$rec['parent_title'] = join(' » ', array_filter($parent_titles)); | $rec['parent_title'] = join(' » ', array_filter($parent_titles)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 398 Lines • ▼ Show 20 Lines | function export_tasks() | ||||
$this->rc->output->nocacheing_headers(); | $this->rc->output->nocacheing_headers(); | ||||
// don't kill the connection if download takes more than 30 sec. | // don't kill the connection if download takes more than 30 sec. | ||||
@set_time_limit(0); | @set_time_limit(0); | ||||
header("Content-Type: text/calendar"); | header("Content-Type: text/calendar"); | ||||
header("Content-Disposition: inline; filename=\"". $plugin['filename'] ."\""); | header("Content-Disposition: inline; filename=\"". $plugin['filename'] ."\""); | ||||
$this->get_ical()->export($plugin['result'], '', true, | $this->get_ical()->export($plugin['result'], '', true, | ||||
$plugins['attachments'] ? array($this->driver, 'get_attachment_body') : null); | !empty($plugin['attachments']) ? array($this->driver, 'get_attachment_body') : null); | ||||
exit; | exit; | ||||
} | } | ||||
/******* Attachment handling *******/ | /******* Attachment handling *******/ | ||||
/** | /** | ||||
* Handler for attachments upload | * Handler for attachments upload | ||||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | public function mail_messagebody_html($p) | ||||
return $p; | return $p; | ||||
} | } | ||||
/** | /** | ||||
* Lookup backend storage and find notes associated with the given message | * Lookup backend storage and find notes associated with the given message | ||||
*/ | */ | ||||
public function mail_message_load($p) | public function mail_message_load($p) | ||||
{ | { | ||||
if (!$p['object']->headers->others['x-kolab-type']) { | if (empty($p['object']->headers->others['x-kolab-type'])) { | ||||
$this->load_driver(); | $this->load_driver(); | ||||
$this->message_tasks = $this->driver->get_message_related_tasks($p['object']->headers, $p['object']->folder); | $this->message_tasks = $this->driver->get_message_related_tasks($p['object']->headers, $p['object']->folder); | ||||
// sort message tasks by completeness and due date | // sort message tasks by completeness and due date | ||||
$driver = $this->driver; | $driver = $this->driver; | ||||
array_walk($this->message_tasks, array($this, 'encode_task')); | array_walk($this->message_tasks, array($this, 'encode_task')); | ||||
usort($this->message_tasks, function($a, $b) use ($driver) { | usort($this->message_tasks, function($a, $b) use ($driver) { | ||||
$a_complete = intval($driver->is_complete($a)); | $a_complete = intval($driver->is_complete($a)); | ||||
$b_complete = intval($driver->is_complete($b)); | $b_complete = intval($driver->is_complete($b)); | ||||
$d = $a_complete - $b_complete; | $d = $a_complete - $b_complete; | ||||
if (!$d) $d = $b['_hasdate'] - $a['_hasdate']; | if (!$d) $d = $b['_hasdate'] - $a['_hasdate']; | ||||
if (!$d) $d = $a['datetime'] - $b['datetime']; | if (!$d) $d = $a['datetime'] - $b['datetime']; | ||||
return $d; | return $d; | ||||
}); | }); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Load iCalendar functions | * Load iCalendar functions | ||||
*/ | */ | ||||
public function get_ical() | public function get_ical() | ||||
{ | { | ||||
if (!$this->ical) { | if (empty($this->ical)) { | ||||
$this->ical = libcalendaring::get_ical(); | $this->ical = libcalendaring::get_ical(); | ||||
} | } | ||||
return $this->ical; | return $this->ical; | ||||
} | } | ||||
/** | /** | ||||
* Get properties of the tasklist this user has specified as default | * Get properties of the tasklist this user has specified as default | ||||
▲ Show 20 Lines • Show All 475 Lines • ▼ Show 20 Lines | public function to_libcal($task) | ||||
$object['complete'] = $task['complete'] * 100; | $object['complete'] = $task['complete'] * 100; | ||||
if ($task['complete'] == 1.0 && empty($task['complete'])) { | if ($task['complete'] == 1.0 && empty($task['complete'])) { | ||||
$object['status'] = 'COMPLETED'; | $object['status'] = 'COMPLETED'; | ||||
} | } | ||||
if ($task['flagged']) { | if ($task['flagged']) { | ||||
$object['priority'] = 1; | $object['priority'] = 1; | ||||
} | } | ||||
else if (!$task['priority']) { | else if (empty($task['priority'])) { | ||||
$object['priority'] = 0; | $object['priority'] = 0; | ||||
} | } | ||||
return $object; | return $object; | ||||
} | } | ||||
/** | /** | ||||
* Convert task properties from ical parser to the internal format | * Convert task properties from ical parser to the internal format | ||||
▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines |