summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--program/js/app.js4
-rw-r--r--program/lib/Roundcube/rcube_imap.php51
-rw-r--r--program/lib/Roundcube/rcube_imap_search.php25
-rw-r--r--program/lib/Roundcube/rcube_result_multifolder.php27
-rw-r--r--program/lib/Roundcube/rcube_storage.php13
6 files changed, 76 insertions, 45 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6335f8842..d38b97e64 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@ CHANGELOG Roundcube Webmail
- Make identity name field optional (#1489510)
- Utility script to remove user records from the local database
- Plugin API: Added message_saved hook (#1489752)
+- Plugin API: Added imap_search_before hook
- Support messages import from zip archives
- Zipdownload: Added mbox format support (#1486069)
- Drop support for IE6, move IE7/IE8 support to legacy_browser plugin
diff --git a/program/js/app.js b/program/js/app.js
index 9aa0942f1..21595570a 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -4225,7 +4225,7 @@ function rcube_webmail()
};
// build URL params for search
- this.search_params = function(search, filter, smods)
+ this.search_params = function(search, filter)
{
var n, url = {}, mods_arr = [],
mods = this.env.search_mods,
@@ -4244,7 +4244,7 @@ function rcube_webmail()
if (search) {
url._q = search;
- if (!smods && mods && this.message_list)
+ if (mods && this.message_list)
mods = mods[mbox] || mods['*'];
if (mods) {
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 4204354b3..4b32c466b 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -1489,23 +1489,39 @@ class rcube_imap extends rcube_storage
* Invoke search request to IMAP server
*
* @param string $folder Folder name to search in
- * @param string $str Search criteria
+ * @param string $search Search criteria
* @param string $charset Search charset
* @param string $sort_field Header field to sort by
+ *
* @return rcube_result_index Search result object
* @todo: Search criteria should be provided in non-IMAP format, eg. array
*/
- public function search($folder='', $str='ALL', $charset=NULL, $sort_field=NULL)
+ public function search($folder = '', $search = 'ALL', $charset = null, $sort_field = null)
{
- if (!$str) {
- $str = 'ALL';
+ if (!$search) {
+ $search = 'ALL';
}
- // multi-folder search
- if (is_array($folder) && count($folder) > 1 && $str != 'ALL') {
- new rcube_result_index; // trigger autoloader and make these classes available for threaded context
- new rcube_result_thread;
+ if ((is_array($folder) && empty($folder)) || (!is_array($folder) && !strlen($folder))) {
+ $folder = $this->folder;
+ }
+
+ $plugin = rcube::get_instance()->plugins->exec_hook('imap_search_before', array(
+ 'folder' => $folder,
+ 'search' => $search,
+ 'charset' => $charset,
+ 'sort_field' => $sort_field,
+ 'threading' => $this->threading,
+ ));
+
+ $folder = $plugin['folder'];
+ $search = $plugin['search'];
+ $charset = $plugin['charset'];
+ $sort_field = $plugin['sort_field'];
+ $results = $plugin['result'];
+ // multi-folder search
+ if (!$results && is_array($folder) && count($folder) > 1 && $search != 'ALL') {
// connect IMAP to have all the required classes and settings loaded
$this->check_connection();
@@ -1518,29 +1534,28 @@ class rcube_imap extends rcube_storage
$searcher->set_timelimit(60);
// continue existing incomplete search
- if (!empty($this->search_set) && $this->search_set->incomplete && $str == $this->search_string) {
+ if (!empty($this->search_set) && $this->search_set->incomplete && $search == $this->search_string) {
$searcher->set_results($this->search_set);
}
// execute the search
$results = $searcher->exec(
$folder,
- $str,
+ $search,
$charset ? $charset : $this->default_charset,
$sort_field && $this->get_capability('SORT') ? $sort_field : null,
$this->threading
);
}
- else {
- $folder = is_array($folder) ? $folder[0] : $folder;
- if (!strlen($folder)) {
- $folder = $this->folder;
- }
- $results = $this->search_index($folder, $str, $charset, $sort_field);
+ else if (!$results) {
+ $folder = is_array($folder) ? $folder[0] : $folder;
+ $search = is_array($search) ? $search[$folder] : $search;
+ $results = $this->search_index($folder, $search, $charset, $sort_field);
}
- $this->set_search_set(array($str, $results, $charset, $sort_field,
- $this->threading || $this->search_sorted ? true : false));
+ $sorted = $this->threading || $this->search_sorted || $plugin['search_sorted'] ? true : false;
+
+ $this->set_search_set(array($search, $results, $charset, $sort_field, $sorted));
return $results;
}
diff --git a/program/lib/Roundcube/rcube_imap_search.php b/program/lib/Roundcube/rcube_imap_search.php
index 0c44daf1b..365d78f76 100644
--- a/program/lib/Roundcube/rcube_imap_search.php
+++ b/program/lib/Roundcube/rcube_imap_search.php
@@ -29,7 +29,7 @@ class rcube_imap_search
{
public $options = array();
- protected $jobs = array();
+ protected $jobs = array();
protected $timelimit = 0;
protected $results;
protected $conn;
@@ -40,7 +40,7 @@ class rcube_imap_search
public function __construct($options, $conn)
{
$this->options = $options;
- $this->conn = $conn;
+ $this->conn = $conn;
}
/**
@@ -54,7 +54,7 @@ class rcube_imap_search
*/
public function exec($folders, $str, $charset = null, $sort_field = null, $threading=null)
{
- $start = floor(microtime(true));
+ $start = floor(microtime(true));
$results = new rcube_result_multifolder($folders);
// start a search job for every folder to search in
@@ -65,7 +65,8 @@ class rcube_imap_search
$results->add($result);
}
else {
- $job = new rcube_imap_search_job($folder, $str, $charset, $sort_field, $threading);
+ $search = is_array($str) && $str[$folder] ? $str[$folder] : $str;
+ $job = new rcube_imap_search_job($folder, $search, $charset, $sort_field, $threading);
$job->worker = $this;
$this->jobs[] = $job;
}
@@ -129,11 +130,11 @@ class rcube_imap_search_job /* extends Stackable */
public function __construct($folder, $str, $charset = null, $sort_field = null, $threading=false)
{
- $this->folder = $folder;
- $this->search = $str;
- $this->charset = $charset;
+ $this->folder = $folder;
+ $this->search = $str;
+ $this->charset = $charset;
$this->sort_field = $sort_field;
- $this->threading = $threading;
+ $this->threading = $threading;
$this->result = new rcube_result_index($folder);
$this->result->incomplete = true;
@@ -150,9 +151,8 @@ class rcube_imap_search_job /* extends Stackable */
protected function search_index()
{
$criteria = $this->search;
- $charset = $this->charset;
-
- $imap = $this->worker->get_imap();
+ $charset = $this->charset;
+ $imap = $this->worker->get_imap();
if (!$imap->connected()) {
trigger_error("No IMAP connection for $this->folder", E_USER_WARNING);
@@ -228,7 +228,4 @@ class rcube_imap_search_job /* extends Stackable */
{
return $this->result;
}
-
}
-
-
diff --git a/program/lib/Roundcube/rcube_result_multifolder.php b/program/lib/Roundcube/rcube_result_multifolder.php
index 4bbd2188d..786ee85f6 100644
--- a/program/lib/Roundcube/rcube_result_multifolder.php
+++ b/program/lib/Roundcube/rcube_result_multifolder.php
@@ -26,16 +26,16 @@
*/
class rcube_result_multifolder
{
- public $multi = true;
- public $sets = array();
+ public $multi = true;
+ public $sets = array();
public $incomplete = false;
public $folder;
- protected $meta = array();
- protected $index = array();
+ protected $meta = array();
+ protected $index = array();
protected $folders = array();
+ protected $order = 'ASC';
protected $sorting;
- protected $order = 'ASC';
/**
@@ -44,7 +44,7 @@ class rcube_result_multifolder
public function __construct($folders = array())
{
$this->folders = $folders;
- $this->meta = array('count' => 0);
+ $this->meta = array('count' => 0);
}
@@ -74,7 +74,8 @@ class rcube_result_multifolder
// append UIDs to global index
$folder = $result->get_parameters('MAILBOX');
- $index = array_map(function($uid) use ($folder) { return $uid . '-' . $folder; }, $result->get());
+ $index = array_map(function($uid) use ($folder) { return $uid . '-' . $folder; }, $result->get());
+
$this->index = array_merge($this->index, $index);
}
@@ -89,7 +90,7 @@ class rcube_result_multifolder
}
$this->sorting = $sort_field;
- $this->order = $sort_order;
+ $this->order = $sort_order;
}
/**
@@ -150,8 +151,10 @@ class rcube_result_multifolder
if ($this->order != $set->get_parameters('ORDER')) {
$set->revert();
}
+
$folder = $set->get_parameters('MAILBOX');
- $index = array_map(function($uid) use ($folder) { return $uid . '-' . $folder; }, $set->get());
+ $index = array_map(function($uid) use ($folder) { return $uid . '-' . $folder; }, $set->get());
+
$this->index = array_merge($this->index, $index);
}
}
@@ -171,6 +174,7 @@ class rcube_result_multifolder
if (!empty($this->folder)) {
$msgid .= '-' . $this->folder;
}
+
return array_search($msgid, $this->index);
}
@@ -188,6 +192,7 @@ class rcube_result_multifolder
if ($set->get_parameters('MAILBOX') == $folder) {
$set->filter($ids);
}
+
$this->meta['count'] += $set->count();
}
}
@@ -267,8 +272,8 @@ class rcube_result_multifolder
public function get_parameters($param=null)
{
$params = array(
- 'SORT' => $this->sorting,
- 'ORDER' => $this->order,
+ 'SORT' => $this->sorting,
+ 'ORDER' => $this->order,
'MAILBOX' => $this->folders,
);
diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php
index 69d6d2fae..c1293961c 100644
--- a/program/lib/Roundcube/rcube_storage.php
+++ b/program/lib/Roundcube/rcube_storage.php
@@ -152,6 +152,19 @@ abstract class rcube_storage
/**
+ * Get connection/class option
+ *
+ * @param string $name Option name
+ *
+ * @param mixed Option value
+ */
+ public function get_option($name)
+ {
+ return $this->options[$name];
+ }
+
+
+ /**
* Activate/deactivate debug mode.
*
* @param boolean $dbg True if conversation with the server should be logged