diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php index 817cfdf9..e44b2c6a 100644 --- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php +++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php @@ -819,6 +819,59 @@ class tasklist_kolab_driver extends tasklist_driver $config->save_tags($uid, $tags); } + /** + * Find messages linked with a task record + */ + private function get_links($uid) + { + $config = kolab_storage_config::get_instance(); + return array_map(array($this, '_convert_message_uri'), $config->get_object_links($uid)); + } + + /** + * + */ + private function save_links($uid, $links) + { + // make sure we have a valid array + if (empty($links)) { + $links = array(); + } + + // convert the given (simplified) message links into absolute IMAP URIs + $links = array_map(function($link) { + $url = parse_url(substr($link, 8)); + parse_str($url['query'], $linkref); + + $path = explode('/', $url['path']); + $linkref['uid'] = array_pop($path); + $linkref['folder'] = join('/', array_map('rawurldecode', $path)); + + return kolab_storage_config::build_member_url($linkref); + }, $links); + + $config = kolab_storage_config::get_instance(); + $remove = array_diff($config->get_object_links($uid), $links); + return $config->save_object_links($uid, $links, $remove); + } + + /** + * Simplify the given message URI by converting the mailbox + * part into a relative IMAP path valid for the current user. + */ + protected function _convert_message_uri($uri) + { + if (strpos($uri, 'imap:///') === 0) { + $linkref = kolab_storage_config::parse_member_url($uri); + + return 'imap:///' . implode('/', array_map('rawurlencode', explode('/', $linkref['folder']))) . + '/' . $linkref['uid'] . + '?' . http_build_query($linkref['params'], '', '&'); + } + + return $uri; + } + /** * Convert from Kolab_Format to internal representation */ @@ -839,6 +892,7 @@ class tasklist_kolab_driver extends tasklist_driver 'organizer' => $record['organizer'], 'sequence' => $record['sequence'], 'tags' => $record['tags'], + 'links' => $this->get_links($record['uid']), ); // convert from DateTime to internal date format @@ -1013,9 +1067,10 @@ class tasklist_kolab_driver extends tasklist_driver if (!$list_id || !($folder = $this->get_folder($list_id))) return false; - // tags are stored separately + // email links and tags are stored separately + $links = $task['links']; $tags = $task['tags']; - unset($task['tags']); + unset($task['tags'], $task['links']); // moved from another folder if ($task['_fromlist'] && ($fromfolder = $this->get_folder($task['_fromlist']))) { @@ -1049,6 +1104,8 @@ class tasklist_kolab_driver extends tasklist_driver $saved = false; } else { + // save links in configuration.relation object + $this->save_links($object['uid'], $links); // save tags in configuration.relation object $this->save_tags($object['uid'], $tags); @@ -1169,6 +1226,17 @@ class tasklist_kolab_driver extends tasklist_driver return false; } + /** + * Build a URI representing the given message reference + * + * @see tasklist_driver::get_message_uri() + */ + public function get_message_uri($headers, $folder) + { + $uri = kolab_storage_config::get_message_uri($headers, $folder); + return $this->_convert_message_uri($uri); + } + /** * */ diff --git a/plugins/tasklist/drivers/tasklist_driver.php b/plugins/tasklist/drivers/tasklist_driver.php index cdaa76ba..2102d219 100644 --- a/plugins/tasklist/drivers/tasklist_driver.php +++ b/plugins/tasklist/drivers/tasklist_driver.php @@ -287,6 +287,20 @@ abstract class tasklist_driver */ public function get_attachment_body($id, $task) { } + /** + * Build a URI representing the given message reference + * + * @param object rcube_message_header Instance holding the message headers + * @param string IMAP folder the message resides in + * + * @return string An URI referencing the given IMAP message + */ + public function get_message_uri($headers, $folder) + { + // to be implemented by the derived classes + return false; + } + /** * Helper method to determine whether the given task is considered "complete" * diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc index 72759959..4563999b 100644 --- a/plugins/tasklist/localization/en_US.inc +++ b/plugins/tasklist/localization/en_US.inc @@ -37,6 +37,7 @@ $labels['start'] = 'Start'; $labels['starttime'] = 'Start time'; $labels['alarms'] = 'Reminder'; $labels['repeat'] = 'Repeat'; +$labels['links'] = 'References'; $labels['status'] = 'Status'; $labels['status-needs-action'] = 'Needs action'; $labels['status-in-process'] = 'In process'; @@ -61,6 +62,7 @@ $labels['mytasks'] = 'My tasks'; $labels['mytaskstitle'] = 'Tasks assigned to you'; $labels['nodate'] = 'no date'; $labels['removetag'] = 'Remove'; +$labels['removelink'] = 'Remove email reference'; $labels['auto'] = 'Auto'; $labels['taskdetails'] = 'Details'; diff --git a/plugins/tasklist/skins/larry/sprites.png b/plugins/tasklist/skins/larry/sprites.png index 7a9c89f4..3552b008 100644 Binary files a/plugins/tasklist/skins/larry/sprites.png and b/plugins/tasklist/skins/larry/sprites.png differ diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css index aafc9e80..bf53e6b8 100644 --- a/plugins/tasklist/skins/larry/tasklist.css +++ b/plugins/tasklist/skins/larry/tasklist.css @@ -1083,6 +1083,56 @@ label.block { -o-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9); } +#task-links { + margin-top: 0; + margin-bottom: 0.2em; +} + +#task-links label { + vertical-align: top; + margin-top: 0.3em; +} + +#task-links .attachmentslist { + display: inline-block; +} + +#task-links .attachmentslist li { + display: inline-block; + margin-right: 1em; +} + +#taskedit-links .attachmentslist li.message.eml, +#task-links .attachmentslist li.message.eml { + background-image: url(sprites.png); + background-position: -2px -388px; +} + +#taskedit-links .attachmentslist li.message a.messagelink, +#task-links .attachmentslist li.message a.messagelink { + padding: 0 0 0 24px; +} + +#taskedit-links .attachmentslist li.deleted a.messagelink, +#taskedit-links .attachmentslist li.deleted a.messagelink:hover { + text-decoration: line-through; +} + +#taskedit-links label { + float: left; + margin-top: 0.3em; +} + +#taskedit-links .task-text { + margin-left: 8em; + min-height: 22px; +} + +#taskedit-links .attachmentslist li a.delete { + top: 0; + background-position: -6px -378px; +} + #task-attachments .attachmentslist li { float: left; margin-right: 1em; diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html index f3fd5953..4d3b9c14 100644 --- a/plugins/tasklist/skins/larry/templates/mainview.html +++ b/plugins/tasklist/skins/larry/templates/mainview.html @@ -211,6 +211,10 @@ +