From 2965a981b7ec22866fbdf2d567d87e2d068d3617 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Fri, 31 Jul 2015 16:04:08 -0400
Subject: [PATCH] Allow to search and import missing PGP pubkeys from keyservers using Publickey.js
---
program/lib/Roundcube/rcube_imap.php | 149 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 102 insertions(+), 47 deletions(-)
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 78073ab..65e0950 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -56,6 +56,7 @@
*/
protected $icache = array();
+ protected $plugins;
protected $list_page = 1;
protected $delimiter;
protected $namespace;
@@ -82,6 +83,7 @@
public function __construct()
{
$this->conn = new rcube_imap_generic();
+ $this->plugins = rcube::get_instance()->plugins;
// Set namespace and delimiter from session,
// so some methods would work before connection
@@ -110,13 +112,13 @@
/**
* Connect to an IMAP server
*
- * @param string $host Host to connect
- * @param string $user Username for IMAP account
- * @param string $pass Password for IMAP account
- * @param integer $port Port to connect to
- * @param string $use_ssl SSL schema (either ssl or tls) or null if plain connection
+ * @param string $host Host to connect
+ * @param string $user Username for IMAP account
+ * @param string $pass Password for IMAP account
+ * @param integer $port Port to connect to
+ * @param string $use_ssl SSL schema (either ssl or tls) or null if plain connection
*
- * @return boolean TRUE on success, FALSE on failure
+ * @return boolean True on success, False on failure
*/
public function connect($host, $user, $pass, $port=143, $use_ssl=null)
{
@@ -147,7 +149,7 @@
$attempt = 0;
do {
- $data = rcube::get_instance()->plugins->exec_hook('storage_connect',
+ $data = $this->plugins->exec_hook('storage_connect',
array_merge($this->options, array('host' => $host, 'user' => $user,
'attempt' => ++$attempt)));
@@ -170,8 +172,20 @@
$this->connect_done = true;
if ($this->conn->connected()) {
+ // check for session identifier
+ $session = null;
+ if (preg_match('/\s+SESSIONID=([^=\s]+)/', $this->conn->result, $m)) {
+ $session = $m[1];
+ }
+
// get namespace and delimiter
$this->set_env();
+
+ // trigger post-connect hook
+ $this->plugins->exec_hook('storage_connected', array(
+ 'host' => $host, 'user' => $user, 'session' => $session
+ ));
+
return true;
}
// write error log
@@ -761,7 +775,7 @@
$page = $page ? $page : $this->list_page;
// use saved message set
- if ($this->search_string && $folder == $this->folder) {
+ if ($this->search_string) {
return $this->list_search_messages($folder, $page, $slice);
}
@@ -1370,7 +1384,7 @@
public function index_direct($folder, $sort_field = null, $sort_order = null, $search = null)
{
if (!empty($search)) {
- $search = $this->search_set->get_compressed();
+ $search = $search->get_compressed();
}
// use message index sort as default sorting
@@ -1506,7 +1520,7 @@
$folder = $this->folder;
}
- $plugin = rcube::get_instance()->plugins->exec_hook('imap_search_before', array(
+ $plugin = $this->plugins->exec_hook('imap_search_before', array(
'folder' => $folder,
'search' => $search,
'charset' => $charset,
@@ -1943,6 +1957,16 @@
for ($i=1; $i<count($part); $i++) {
if (!is_array($part[$i])) {
$struct->ctype_secondary = strtolower($part[$i]);
+
+ // read content type parameters
+ if (is_array($part[$i+1])) {
+ $struct->ctype_parameters = array();
+ for ($j=0; $j<count($part[$i+1]); $j+=2) {
+ $param = strtolower($part[$i+1][$j]);
+ $struct->ctype_parameters[$param] = $part[$i+1][$j+1];
+ }
+ }
+
break;
}
}
@@ -2350,36 +2374,38 @@
/**
* Returns the whole message source as string (or saves to a file)
*
- * @param int $uid Message UID
- * @param resource $fp File pointer to save the message
+ * @param int $uid Message UID
+ * @param resource $fp File pointer to save the message
+ * @param string $part Optional message part ID
*
* @return string Message source string
*/
- public function get_raw_body($uid, $fp=null)
+ public function get_raw_body($uid, $fp=null, $part = null)
{
if (!$this->check_connection()) {
return null;
}
return $this->conn->handlePartBody($this->folder, $uid,
- true, null, null, false, $fp);
+ true, $part, null, false, $fp);
}
/**
* Returns the message headers as string
*
- * @param int $uid Message UID
+ * @param int $uid Message UID
+ * @param string $part Optional message part ID
*
* @return string Message headers string
*/
- public function get_raw_headers($uid)
+ public function get_raw_headers($uid, $part = null)
{
if (!$this->check_connection()) {
return null;
}
- return $this->conn->fetchPartHeader($this->folder, $uid, true);
+ return $this->conn->fetchPartHeader($this->folder, $uid, true, $part);
}
@@ -2501,7 +2527,7 @@
// increase messagecount of the target folder
$this->set_messagecount($folder, 'ALL', 1);
- rcube::get_instance()->plugins->exec_hook('message_saved', array(
+ $this->plugins->exec_hook('message_saved', array(
'folder' => $folder,
'message' => $message,
'headers' => $headers,
@@ -2777,7 +2803,7 @@
}
// Give plugins a chance to provide a list of folders
- $data = rcube::get_instance()->plugins->exec_hook('storage_folders',
+ $data = $this->plugins->exec_hook('storage_folders',
array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB'));
if (isset($data['folders'])) {
@@ -2909,7 +2935,7 @@
}
// Give plugins a chance to provide a list of folders
- $data = rcube::get_instance()->plugins->exec_hook('storage_folders',
+ $data = $this->plugins->exec_hook('storage_folders',
array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST'));
if (isset($data['folders'])) {
@@ -2990,7 +3016,7 @@
* @param array $result Reference to folders list
* @param string $type Listing type (ext-subscribed, subscribed or all)
*/
- private function list_folders_update(&$result, $type = null)
+ protected function list_folders_update(&$result, $type = null)
{
$namespace = $this->get_namespace();
$search = array();
@@ -3067,14 +3093,15 @@
/**
* Get mailbox quota information
- * added by Nuny
+ *
+ * @param string $folder Folder name
*
* @return mixed Quota info or False if not supported
*/
- public function get_quota()
+ public function get_quota($folder = null)
{
if ($this->get_capability('QUOTA') && $this->check_connection()) {
- return $this->conn->getQuota();
+ return $this->conn->getQuota($folder);
}
return false;
@@ -3149,6 +3176,16 @@
}
$result = $this->conn->createFolder($folder, $type ? array("\\" . ucfirst($type)) : null);
+
+ // it's quite often situation that we're trying to create and subscribe
+ // a folder that already exist, but is unsubscribed
+ if (!$result) {
+ if ($this->get_response_code() == rcube_storage::ALREADYEXISTS
+ || preg_match('/already exists/i', $this->get_error_str())
+ ) {
+ $result = true;
+ }
+ }
// try to subscribe it
if ($result) {
@@ -3297,12 +3334,14 @@
// request \Subscribed flag in LIST response as performance improvement for folder_exists()
$folders = $this->conn->listMailboxes('', '*', array('SUBSCRIBED'), array('SPECIAL-USE'));
- foreach ($folders as $folder) {
- if ($flags = $this->conn->data['LIST'][$folder]) {
- foreach ($types as $type) {
- if (in_array($type, $flags)) {
- $type = strtolower(substr($type, 1));
- $special[$type] = $folder;
+ if (!empty($folders)) {
+ foreach ($folders as $folder) {
+ if ($flags = $this->conn->data['LIST'][$folder]) {
+ foreach ($types as $type) {
+ if (in_array($type, $flags)) {
+ $type = strtolower(substr($type, 1));
+ $special[$type] = $folder;
+ }
}
}
}
@@ -3924,8 +3963,16 @@
// @TODO: Honor MAXSIZE and DEPTH options
foreach ($queries as $attrib => $entry) {
- if ($result = $this->conn->getAnnotation($folder, $entry, $attrib)) {
- $res = array_merge_recursive($res, $result);
+ $result = $this->conn->getAnnotation($folder, $entry, $attrib);
+
+ // an error, invalidate any previous getAnnotation() results
+ if (!is_array($result)) {
+ return null;
+ }
+ else {
+ foreach ($result as $fldr => $data) {
+ $res[$fldr] = array_merge((array) $res[$fldr], $data);
+ }
}
}
}
@@ -4166,29 +4213,37 @@
// force the type of folder name variable (#1485527)
$folders = array_map('strval', $folders);
+ $out = array();
+
+ // finally we must put special folders on top and rebuild the list
+ // to move their subfolders where they belong...
$specials = array_unique(array_intersect($specials, $folders));
- $head = array();
+ $folders = array_merge($specials, array_diff($folders, $specials));
- // place default folders on top
- foreach ($specials as $special) {
- $prefix = $special . $this->delimiter;
+ $this->sort_folder_specials(null, $folders, $specials, $out);
- foreach ($folders as $idx => $folder) {
- if ($folder === $special) {
- $head[] = $special;
- unset($folders[$idx]);
- }
- // put subfolders of default folders on their place...
- else if (strpos($folder, $prefix) === 0) {
- $head[] = $folder;
- unset($folders[$idx]);
+ return $out;
+ }
+
+ /**
+ * Recursive function to put subfolders of special folders in place
+ */
+ protected function sort_folder_specials($folder, &$list, &$specials, &$out)
+ {
+ while (list($key, $name) = each($list)) {
+ if ($folder === null || strpos($name, $folder.$this->delimiter) === 0) {
+ $out[] = $name;
+ unset($list[$key]);
+
+ if (!empty($specials) && ($found = array_search($name, $specials)) !== false) {
+ unset($specials[$found]);
+ $this->sort_folder_specials($name, $list, $specials, $out);
}
}
}
- return array_merge($head, $folders);
+ reset($list);
}
-
/**
* Callback for uasort() that implements correct
--
Gitblit v1.9.1