Merge branch 'master' of github.com:roundcube/roundcubemail
| | |
| | | - 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 |
| | |
| | | }; |
| | | |
| | | // 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, |
| | |
| | | if (search) { |
| | | url._q = search; |
| | | |
| | | if (!smods && mods && this.message_list) |
| | | if (mods && this.message_list) |
| | | mods = mods[mbox] || mods['*']; |
| | | |
| | | if (mods) { |
| | |
| | | * 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(); |
| | | |
| | |
| | | $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; |
| | | } |
| | |
| | | { |
| | | public $options = array(); |
| | | |
| | | protected $jobs = array(); |
| | | protected $jobs = array(); |
| | | protected $timelimit = 0; |
| | | protected $results; |
| | | protected $conn; |
| | |
| | | public function __construct($options, $conn) |
| | | { |
| | | $this->options = $options; |
| | | $this->conn = $conn; |
| | | $this->conn = $conn; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | 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 |
| | |
| | | $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; |
| | | } |
| | |
| | | |
| | | 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; |
| | |
| | | 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); |
| | |
| | | { |
| | | return $this->result; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | 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'; |
| | | |
| | | |
| | | /** |
| | |
| | | public function __construct($folders = array()) |
| | | { |
| | | $this->folders = $folders; |
| | | $this->meta = array('count' => 0); |
| | | $this->meta = array('count' => 0); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | // 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); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | $this->sorting = $sort_field; |
| | | $this->order = $sort_order; |
| | | $this->order = $sort_order; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | if (!empty($this->folder)) { |
| | | $msgid .= '-' . $this->folder; |
| | | } |
| | | |
| | | return array_search($msgid, $this->index); |
| | | } |
| | | |
| | |
| | | if ($set->get_parameters('MAILBOX') == $folder) { |
| | | $set->filter($ids); |
| | | } |
| | | |
| | | $this->meta['count'] += $set->count(); |
| | | } |
| | | } |
| | |
| | | public function get_parameters($param=null) |
| | | { |
| | | $params = array( |
| | | 'SORT' => $this->sorting, |
| | | 'ORDER' => $this->order, |
| | | 'SORT' => $this->sorting, |
| | | 'ORDER' => $this->order, |
| | | 'MAILBOX' => $this->folders, |
| | | ); |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |