diff options
-rw-r--r-- | lib/kolab/plugins/kolab_auth/kolab_auth.php | 3 | ||||
-rw-r--r-- | lib/kolab/plugins/kolab_folders/config.inc.php.dist | 4 | ||||
-rw-r--r-- | lib/kolab/plugins/kolab_folders/kolab_folders.php | 109 | ||||
-rw-r--r-- | lib/kolab/plugins/kolab_folders/localization/en_US.inc | 2 | ||||
-rw-r--r-- | lib/kolab/plugins/kolab_folders/localization/pl_PL.inc | 2 | ||||
-rw-r--r-- | lib/kolab/plugins/kolab_folders/package.xml | 4 | ||||
-rw-r--r-- | lib/kolab/plugins/libkolab/lib/kolab_storage_folder.php | 74 | ||||
-rw-r--r-- | temp/.htaccess | 2 |
8 files changed, 105 insertions, 95 deletions
diff --git a/lib/kolab/plugins/kolab_auth/kolab_auth.php b/lib/kolab/plugins/kolab_auth/kolab_auth.php index 620def5..28caca3 100644 --- a/lib/kolab/plugins/kolab_auth/kolab_auth.php +++ b/lib/kolab/plugins/kolab_auth/kolab_auth.php @@ -271,7 +271,7 @@ class kolab_auth extends rcube_plugin $email_attr = $rcmail->config->get('kolab_auth_email'); // get username and host - $host = rcube_utils::parse_host($args['host']); + $host = $args['host']; $user = $args['user']; $pass = $args['pass']; $loginas = trim(rcube_utils::get_input_value('_loginas', rcube_utils::INPUT_POST)); @@ -302,6 +302,7 @@ class kolab_auth extends rcube_plugin $result = $this->ldap->bind($dn, $pass); if (!$result) { + $args['abort'] = true; return $args; } diff --git a/lib/kolab/plugins/kolab_folders/config.inc.php.dist b/lib/kolab/plugins/kolab_folders/config.inc.php.dist index e393684..ffa1e15 100644 --- a/lib/kolab/plugins/kolab_folders/config.inc.php.dist +++ b/lib/kolab/plugins/kolab_folders/config.inc.php.dist @@ -18,6 +18,10 @@ $rcmail_config['kolab_folders_task_default'] = ''; $rcmail_config['kolab_folders_note_default'] = ''; // Default Journal folder $rcmail_config['kolab_folders_journal_default'] = ''; +// Default Files folder +$rcmail_config['kolab_folders_file_default'] = ''; +// Default FreeBusy folder +$rcmail_config['kolab_folders_freebusy_default'] = ''; // INBOX folder $rcmail_config['kolab_folders_mail_inbox'] = ''; diff --git a/lib/kolab/plugins/kolab_folders/kolab_folders.php b/lib/kolab/plugins/kolab_folders/kolab_folders.php index ed05122..80389f6 100644 --- a/lib/kolab/plugins/kolab_folders/kolab_folders.php +++ b/lib/kolab/plugins/kolab_folders/kolab_folders.php @@ -26,7 +26,7 @@ class kolab_folders extends rcube_plugin { public $task = '?(?!login).*'; - public $types = array('mail', 'event', 'journal', 'task', 'note', 'contact', 'configuration'); + public $types = array('mail', 'event', 'journal', 'task', 'note', 'contact', 'configuration', 'file', 'freebusy'); public $mail_types = array('inbox', 'drafts', 'sentitems', 'outbox', 'wastebasket', 'junkemail'); private $rc; @@ -337,14 +337,7 @@ class kolab_folders extends rcube_plugin */ function get_folder_type($folder) { - $storage = $this->rc->get_storage(); - $folderdata = $storage->get_metadata($folder, array(kolab_storage::CTYPE_KEY_PRIVATE, kolab_storage::CTYPE_KEY)); - - if (!($ctype = $folderdata[$folder][kolab_storage::CTYPE_KEY_PRIVATE])) { - $ctype = $folderdata[$folder][kolab_storage::CTYPE_KEY]; - } - - return explode('.', $ctype); + return explode('.', (string)kolab_storage::folder_type($folder)); } /** @@ -355,7 +348,7 @@ class kolab_folders extends rcube_plugin * * @return boolean True on success */ - function set_folder_type($folder, $type='mail') + function set_folder_type($folder, $type = 'mail') { return kolab_storage::set_folder_type($folder, $type); } @@ -376,38 +369,11 @@ class kolab_folders extends rcube_plugin return null; } - $type .= '.default'; - $namespace = $storage->get_namespace(); - // get all folders of specified type - $folderdata = array_map(array($this, 'folder_select_metadata'), $folderdata); - $folderdata = array_intersect($folderdata, array($type)); - - foreach ($folderdata as $folder => $data) { - // check if folder is in personal namespace - foreach (array('shared', 'other') as $nskey) { - if (!empty($namespace[$nskey])) { - foreach ($namespace[$nskey] as $ns) { - if ($ns[0] && substr($folder, 0, strlen($ns[0])) == $ns[0]) { - continue 3; - } - } - } - } + $folderdata = array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata); + $folderdata = array_intersect($folderdata, array($type.'.default')); - // There can be only one default folder of specified type - return $folder; - } - - return null; - } - - /** - * Callback for array_map to select the correct annotation value - */ - private function folder_select_metadata($types) - { - return $types[kolab_storage::CTYPE_KEY_PRIVATE] ?: $types[kolab_storage::CTYPE_KEY]; + return key($folderdata); } /** @@ -438,25 +404,12 @@ class kolab_folders extends rcube_plugin $namespace = $storage->get_namespace(); $defaults = array(); $need_update = false; - - if (!is_array($folderdata)) { - $folderdata = $storage->get_metadata('*', kolab_storage::CTYPE_KEY); - - if (!is_array($folderdata)) { - return; - } - - // "Flattenize" metadata array to become a name->type hash - $folderdata = array_map('implode', $folderdata); - } + $prefix = ''; // Find personal namespace prefix if (is_array($namespace['personal']) && count($namespace['personal']) == 1) { $prefix = $namespace['personal'][0][0]; } - else { - $prefix = ''; - } $this->load_config(); @@ -477,45 +430,35 @@ class kolab_folders extends rcube_plugin } } - // find default folders - foreach ($defaults as $type => $foldername) { - // folder exists, do nothing - if (!empty($folderdata[$foldername])) { - continue; - } + if (empty($defaults)) { + return; + } - // special case, need to set type only - if ($foldername == 'INBOX' || $type == 'mail.inbox') { - $this->set_folder_type($foldername, 'mail.inbox'); - continue; + if (!is_array($folderdata)) { + $folderdata = $storage->get_metadata('*', array(kolab_storage::CTYPE_KEY_PRIVATE, kolab_storage::CTYPE_KEY)); + + if (!is_array($folderdata)) { + return; } + $folderdata = array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata); + } + + // find default folders + foreach ($defaults as $type => $foldername) { // get all folders of specified type - $folders = array_intersect($folderdata, array($type)); - unset($folders[0]); - - // find folders in personal namespace - foreach ($folders as $folder) { - if ($folder) { - foreach (array('shared', 'other') as $nskey) { - if (!empty($namespace[$nskey])) { - foreach ($namespace[$nskey] as $ns) { - if ($ns[0] && substr($folder, 0, strlen($ns[0])) == $ns[0]) { - continue 3; - } - } - } - } - } + $_folders = array_intersect($folderdata, array($type)); - // got folder in personal namespace - continue 2; + // default folder found + if (!empty($_folders)) { + continue; } list($type1, $type2) = explode('.', $type); + $exists = !empty($folderdata[$foldername]) || $foldername == 'INBOX'; // create folder - if ($type1 != 'mail' || !$storage->folder_exists($foldername)) { + if (!$exists && !$storage->folder_exists($foldername)) { $storage->create_folder($foldername, $type1 == 'mail'); } diff --git a/lib/kolab/plugins/kolab_folders/localization/en_US.inc b/lib/kolab/plugins/kolab_folders/localization/en_US.inc index 70867bc..856f59d 100644 --- a/lib/kolab/plugins/kolab_folders/localization/en_US.inc +++ b/lib/kolab/plugins/kolab_folders/localization/en_US.inc @@ -10,6 +10,8 @@ $labels['foldertypetask'] = 'Tasks'; $labels['foldertypenote'] = 'Notes'; $labels['foldertypecontact'] = 'Contacts'; $labels['foldertypeconfiguration'] = 'Configuration'; +$labels['foldertypefile'] = 'Files'; +$labels['foldertypefreebusy'] = 'Free-Busy'; $labels['default'] = 'Default'; $labels['inbox'] = 'Inbox'; diff --git a/lib/kolab/plugins/kolab_folders/localization/pl_PL.inc b/lib/kolab/plugins/kolab_folders/localization/pl_PL.inc index 95177cd..4520dac 100644 --- a/lib/kolab/plugins/kolab_folders/localization/pl_PL.inc +++ b/lib/kolab/plugins/kolab_folders/localization/pl_PL.inc @@ -9,6 +9,8 @@ $labels['foldertypetask'] = 'Zadania'; $labels['foldertypenote'] = 'Notatki'; $labels['foldertypecontact'] = 'Kontakty'; $labels['foldertypeconfiguration'] = 'Konfiguracja'; +$labels['foldertypefile'] = 'Pliki'; +$labels['foldertypefreebusy'] = 'Free-Busy'; $labels['default'] = 'Domyślny'; $labels['inbox'] = 'Odebrane'; $labels['drafts'] = 'Szkice'; diff --git a/lib/kolab/plugins/kolab_folders/package.xml b/lib/kolab/plugins/kolab_folders/package.xml index 875d614..b40acab 100644 --- a/lib/kolab/plugins/kolab_folders/package.xml +++ b/lib/kolab/plugins/kolab_folders/package.xml @@ -21,9 +21,9 @@ <email>machniak@kolabsys.com</email> <active>yes</active> </lead> - <date>2012-05-14</date> + <date>2012-10.25</date> <version> - <release>2.0</release> + <release>2.1</release> <api>2.0</api> </version> <stability> diff --git a/lib/kolab/plugins/libkolab/lib/kolab_storage_folder.php b/lib/kolab/plugins/libkolab/lib/kolab_storage_folder.php index 2c58973..89b2b99 100644 --- a/lib/kolab/plugins/libkolab/lib/kolab_storage_folder.php +++ b/lib/kolab/plugins/libkolab/lib/kolab_storage_folder.php @@ -602,7 +602,13 @@ class kolab_storage_folder } if ($raw_msg = $this->build_message($object, $type)) { - $result = $this->imap->save_message($this->name, $raw_msg, '', false); + if (is_array($raw_msg)) { + $result = $this->imap->save_message($this->name, $raw_msg[0], $raw_msg[1], true); + @unlink($raw_msg[0]); + } + else { + $result = $this->imap->save_message($this->name, $raw_msg); + } // delete old message if ($result && !empty($object['_msguid']) && !empty($object['_mailbox'])) { @@ -620,7 +626,7 @@ class kolab_storage_folder $this->cache->insert($result, $object); } } - + return $result; } @@ -710,6 +716,9 @@ class kolab_storage_folder /** * Creates source of the configuration object message + * + * @return mixed Message as string or array with two elements + * (one for message file path, second for message headers) */ private function build_message(&$object, $type) { @@ -735,8 +744,8 @@ class kolab_storage_folder return false; } - $mime = new Mail_mime("\r\n"); - $rcmail = rcube::get_instance(); + $mime = new Mail_mime("\r\n"); + $rcmail = rcube::get_instance(); $headers = array(); $part_id = 1; @@ -751,12 +760,33 @@ class kolab_storage_folder // $headers['Message-ID'] = $rcmail->gen_message_id(); $headers['User-Agent'] = $rcmail->config->get('useragent'); + // Check if we have enough memory to handle the message in it + // It's faster than using files, so we'll do this if we only can + if (!empty($object['_attachments']) && ($mem_limit = parse_bytes(ini_get('memory_limit'))) > 0) { + $memory = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB + + foreach ($object['_attachments'] as $id => $attachment) { + $memory += $attachment['size']; + } + + // 1.33 is for base64, we need at least 2x more memory than the message size + if ($memory * 1.33 * 2 > $mem_limit) { + $is_file = true; + $temp_dir = unslashify($rcmail->config->get('temp_dir')); + $mime->setParam('delay_file_io', true); + } + } + $mime->headers($headers); - $mime->setTXTBody('This is a Kolab Groupware object. ' - . 'To view this object you will need an email client that understands the Kolab Groupware format. ' + $mime->setTXTBody("This is a Kolab Groupware object. " + . "To view this object you will need an email client that understands the Kolab Groupware format. " . "For a list of such email clients please visit http://www.kolab.org/\n\n"); $ctype = kolab_storage::$version == 2.0 ? $format->CTYPEv2 : $format->CTYPE; + // Convert new lines to \r\n, to wrokaround "NO Message contains bare newlines" + // when APPENDing from temp file + $xml = preg_replace('/\r?\n/', "\r\n", $xml); + $mime->addAttachment($xml, // file $ctype, // content-type 'kolab.xml', // filename @@ -768,11 +798,21 @@ class kolab_storage_folder $part_id++; // save object attachments as separate parts - // TODO: optimize memory consumption by using tempfiles for transfer foreach ((array)$object['_attachments'] as $key => $att) { if (empty($att['content']) && !empty($att['id'])) { $msguid = !empty($object['_msguid']) ? $object['_msguid'] : $object['uid']; - $att['content'] = $this->get_attachment($msguid, $att['id'], $object['_mailbox']); + if ($is_file) { + $att['path'] = tempnam($temp_dir, 'rcmAttmnt'); + if (($fp = fopen($att['path'], 'w')) && $this->get_attachment($msguid, $att['id'], $object['_mailbox'], false, $fp)) { + fclose($fp); + } + else { + return false; + } + } + else { + $att['content'] = $this->get_attachment($msguid, $att['id'], $object['_mailbox']); + } } $headers = array('Content-ID' => Mail_mimePart::encodeHeader('Content-ID', '<' . $key . '>', RCMAIL_CHARSET, 'quoted-printable')); @@ -790,7 +830,23 @@ class kolab_storage_folder $object['_attachments'][$key]['id'] = $part_id; } - return $mime->getMessage(); + if ($is_file) { + // use common temp dir + $body_file = tempnam($temp_dir, 'rcmMsg'); + + if (PEAR::isError($mime_result = $mime->saveMessageBody($body_file))) { + self::raise_error(array('code' => 650, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not create message: ".$mime_result->getMessage()), + true, false); + return false; + } + + return array($body_file, $mime->txtHeaders()); + } + else { + return $mime->getMessage(); + } } diff --git a/temp/.htaccess b/temp/.htaccess new file mode 100644 index 0000000..93169e4 --- /dev/null +++ b/temp/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all |