- Add popup with basic fields selection for addressbook search
| | |
| | | CHANGELOG Roundcube Webmail |
| | | =========================== |
| | | |
| | | - Add popup with basic fields selection for addressbook search |
| | | - Case-insensitive matching in autocompletion (#1487933) |
| | | - Added option to force spellchecking before sending a message (#1485458) |
| | | - Fix handling of "<" character in contact data, search fields and folder names (#1487864) |
| | |
| | | // Please note that folder names should to be in sync with $rcmail_config['default_imap_folders'] |
| | | $rcmail_config['search_mods'] = null; // Example: array('*' => array('subject'=>1, 'from'=>1), 'Sent' => array('subject'=>1, 'to'=>1)); |
| | | |
| | | // Defaults of the addressbook search field configuration. |
| | | $rcmail_config['addressbook_search_mods'] = null; // Example: array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1, '*'=>1); |
| | | |
| | | // 'Delete always' |
| | | // This setting reflects if mail should be always deleted |
| | | // when moving to Trash fails. This is necessary in some setups |
| | |
| | | $ids = $this->db->array2list($ids, 'integer'); |
| | | $where[] = 'c.' . $this->primary_key.' IN ('.$ids.')'; |
| | | } |
| | | else if ($strict) { |
| | | $where[] = $this->db->quoteIdentifier($col).' = '.$this->db->quote($value); |
| | | } |
| | | else if ($col == '*') { |
| | | $words = array(); |
| | | foreach(explode(" ", self::normalize_string($value)) as $word) |
| | | $words[] = $this->db->ilike('words', '%'.$word.'%'); |
| | | $where[] = '(' . join(' AND ', $words) . ')'; |
| | | } |
| | | else |
| | | else if ($strict) { |
| | | $where[] = $this->db->quoteIdentifier($col).' = '.$this->db->quote($value); |
| | | } |
| | | else if (in_array($col, $this->table_cols)) { |
| | | $where[] = $this->db->ilike($col, '%'.$value.'%'); |
| | | } |
| | | } |
| | | |
| | | foreach ($required as $col) { |
| | | $and_where[] = $this->db->quoteIdentifier($col).' <> '.$this->db->quote(''); |
| | |
| | | |
| | | $filter = '(|'; |
| | | $wc = !$strict && $this->prop['fuzzy_search'] ? '*' : ''; |
| | | if ($fields != '*') |
| | | if ($fields == '*') |
| | | { |
| | | // search_fields are required for fulltext search |
| | | if (!$this->prop['search_fields']) |
| | | if (empty($this->prop['search_fields'])) |
| | | { |
| | | $this->set_error(self::ERROR_SEARCH, 'nofulltextsearch'); |
| | | $this->result = new rcube_result_set(); |
| | | return $this->result; |
| | | } |
| | | } |
| | | |
| | | if (is_array($this->prop['search_fields'])) |
| | | { |
| | | foreach ($this->prop['search_fields'] as $k => $field) |
| | | $filter .= "($field=$wc" . $this->_quote_string($value) . "$wc)"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | foreach ((array)$fields as $field) |
| | |
| | | this.qsearch = function(value) |
| | | { |
| | | if (value != '') { |
| | | var addurl = ''; |
| | | var n, addurl = '', mods_arr = [], |
| | | mods = this.env.search_mods, |
| | | mbox = this.env.mailbox, |
| | | lock = this.set_busy(true, 'searching'); |
| | | |
| | | if (this.message_list) { |
| | | this.clear_message_list(); |
| | | if (this.env.search_mods) { |
| | | var mods = this.env.search_mods[this.env.mailbox] ? this.env.search_mods[this.env.mailbox] : this.env.search_mods['*']; |
| | | if (mods) { |
| | | var head_arr = []; |
| | | for (var n in mods) |
| | | head_arr.push(n); |
| | | addurl += '&_headers='+head_arr.join(','); |
| | | } |
| | | } |
| | | if (mods) |
| | | mods = mods[mbox] ? mods[mbox] : mods['*']; |
| | | } else if (this.contact_list) { |
| | | this.contact_list.clear(true); |
| | | this.show_contentframe(false); |
| | | } |
| | | |
| | | if (mods) { |
| | | for (n in mods) |
| | | mods_arr.push(n); |
| | | addurl += '&_headers='+mods_arr.join(','); |
| | | } |
| | | |
| | | if (this.gui_objects.search_filter) |
| | |
| | | |
| | | // reset vars |
| | | this.env.current_page = 1; |
| | | var lock = this.set_busy(true, 'searching'); |
| | | this.http_request('search', '_q='+urlencode(value) |
| | | + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '') |
| | | + (mbox ? '&_mbox='+urlencode(mbox) : '') |
| | | + (this.env.source ? '&_source='+urlencode(this.env.source) : '') |
| | | + (this.env.group ? '&_gid='+urlencode(this.env.group) : '') |
| | | + (addurl ? addurl : ''), lock); |
| | |
| | | $labels['manager'] = 'Manager'; |
| | | $labels['assistant'] = 'Assistant'; |
| | | $labels['spouse'] = 'Spouse'; |
| | | $labels['allfields'] = 'All fields'; |
| | | |
| | | $labels['typehome'] = 'Home'; |
| | | $labels['typework'] = 'Work'; |
| | |
| | | $labels['sharedfolder'] = 'Folder współdzielony'; |
| | | $labels['defaultaddressbook'] = 'Nowe kontakty dodawaj do wybranej książki adresowej'; |
| | | $labels['spellcheckbeforesend'] = 'Przed wysłaniem wiadomości sprawdzaj pisownię'; |
| | | $labels['allfields'] = 'Wszystkie pola'; |
| | | |
| | | ?> |
| | |
| | | |
| | | */ |
| | | |
| | | $SEARCH_MODS_DEFAULT = array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1, '*'=>1); |
| | | |
| | | // add list of address sources to client env |
| | | $js_list = $RCMAIL->get_address_sources(); |
| | | |
| | |
| | | $OUTPUT->set_env('source', $source ? $source : '0'); |
| | | $OUTPUT->set_env('readonly', $CONTACTS->readonly, false); |
| | | if (!$OUTPUT->ajax_call) { |
| | | $search_mods = $RCMAIL->config->get('addressbook_search_mods', $SEARCH_MODS_DEFAULT); |
| | | $OUTPUT->set_env('search_mods', $search_mods); |
| | | $OUTPUT->set_env('address_sources', $js_list); |
| | | $OUTPUT->set_pagetitle(rcube_label('addressbook')); |
| | | } |
| | |
| | | $CONTACTS->set_page(1); |
| | | $_SESSION['page'] = 1; |
| | | |
| | | // get input |
| | | $search = trim(get_input_value('_q', RCUBE_INPUT_GET, true)); |
| | | $search_request = md5('addr'.$search); |
| | | $fields = explode(',', get_input_value('_headers', RCUBE_INPUT_GET)); |
| | | |
| | | if (empty($fields)) { |
| | | $fields = $SEARCH_MODS_DEFAULT; |
| | | } |
| | | |
| | | $search_request = md5('addr'.$search.implode($fields, ',')); |
| | | |
| | | // update search_mods setting |
| | | $search_mods = array_fill_keys($fields, 1); |
| | | $RCMAIL->user->save_prefs(array('addressbook_search_mods' => $search_mods)); |
| | | |
| | | if ($fields['all'] || count($fields) == count($SEARCH_MODS_DEFAULT)) { |
| | | $fields = '*'; |
| | | } |
| | | |
| | | // get contacts for this user |
| | | $result = $CONTACTS->search('*', $search); |
| | | $result = $CONTACTS->search($fields, $search); |
| | | |
| | | // save search settings in session |
| | | $_SESSION['search'][$search_request] = $CONTACTS->get_search_set(); |
| | | |
| | | if ($result->count > 0) |
| | | { |
| | | if ($result->count > 0) { |
| | | // create javascript list |
| | | rcmail_js_contacts_list($result); |
| | | } |
| | | else |
| | | { |
| | | else { |
| | | $OUTPUT->show_message('nocontactsfound', 'notice'); |
| | | } |
| | | |
| | |
| | | border: none; |
| | | } |
| | | |
| | | |
| | | /***** roundcube webmail pre-defined classes *****/ |
| | | |
| | | #rcmversion |
| | |
| | | padding-top: 2px; |
| | | } |
| | | |
| | | #searchmenu |
| | | { |
| | | width: 160px; |
| | | } |
| | | |
| | | #searchmenu ul.toolbarmenu |
| | | { |
| | | margin: 0; |
| | | } |
| | | |
| | | #searchmenu ul.toolbarmenu li |
| | | { |
| | | margin: 1px 4px 1px; |
| | | } |
| | | |
| | | |
| | | /***** tabbed interface elements *****/ |
| | | |
| | |
| | | .find(':checked').prop('checked', false); |
| | | |
| | | if (rcmail.env.search_mods) { |
| | | var search_mods = rcmail.env.search_mods[rcmail.env.mailbox] ? rcmail.env.search_mods[rcmail.env.mailbox] : rcmail.env.search_mods['*']; |
| | | for (var n in search_mods) |
| | | var n, mbox = rcmail.env.mailbox, mods = rcmail.env.search_mods; |
| | | |
| | | if (rcmail.env.task != 'addressbook') { |
| | | mods = mods[mbox] ? mods[mbox] : mods['*']; |
| | | |
| | | for (n in mods) |
| | | $('#s_mod_' + n).prop('checked', true); |
| | | } |
| | | else { |
| | | if (mods['*']) |
| | | $('input:checkbox[name="s_mods[]"]').map(function() { |
| | | this.checked = true; |
| | | this.disabled = this.value != '*'; |
| | | }); |
| | | else { |
| | | for (n in mods) |
| | | $('#s_mod_' + n).prop('checked', true); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | obj[show?'show':'hide'](); |
| | |
| | | |
| | | set_searchmod: function(elem) |
| | | { |
| | | if (!rcmail.env.search_mods) |
| | | rcmail.env.search_mods = {}; |
| | | var task = rcmail.env.task, |
| | | mods = rcmail.env.search_mods, |
| | | mbox = rcmail.env.mailbox; |
| | | |
| | | if (!rcmail.env.search_mods[rcmail.env.mailbox]) |
| | | rcmail.env.search_mods[rcmail.env.mailbox] = rcube_clone_object(rcmail.env.search_mods['*']); |
| | | if (!mods) |
| | | mods = {}; |
| | | |
| | | if (task == 'mail') { |
| | | if (!mods[mbox]) |
| | | mods[mbox] = rcube_clone_object(mods['*']); |
| | | if (!elem.checked) |
| | | delete(rcmail.env.search_mods[rcmail.env.mailbox][elem.value]); |
| | | delete(mods[mbox][elem.value]); |
| | | else |
| | | rcmail.env.search_mods[rcmail.env.mailbox][elem.value] = elem.value; |
| | | mods[mbox][elem.value] = 1; |
| | | } |
| | | else { //addressbook |
| | | if (!elem.checked) |
| | | delete(mods[elem.value]); |
| | | else |
| | | mods[elem.value] = 1; |
| | | |
| | | // mark all fields |
| | | if (elem.value == '*') { |
| | | $('input:checkbox[name="s_mods[]"]').map(function() { |
| | | if (this == elem) |
| | | return; |
| | | |
| | | if (elem.checked) { |
| | | mods[this.value] = 1; |
| | | this.checked = true; |
| | | this.disabled = true; |
| | | } |
| | | else { |
| | | this.disabled = false; |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | rcmail.env.search_mods = mods; |
| | | }, |
| | | |
| | | listmenu: function(show) |
| | |
| | | padding-left: 2px; |
| | | } |
| | | |
| | | #searchmenu |
| | | { |
| | | width: 160px; |
| | | } |
| | | |
| | | #searchmenu ul.toolbarmenu |
| | | { |
| | | margin: 0; |
| | | } |
| | | |
| | | #searchmenu ul.toolbarmenu li |
| | | { |
| | | margin: 1px 4px 1px; |
| | | } |
| | | |
| | | #messagemenu li a.active:hover, |
| | | #markmessagemenu li a.active:hover |
| | | { |
| | |
| | | </div> |
| | | |
| | | <div id="quicksearchbar"> |
| | | <roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass.png" /> |
| | | <roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass_roll.png" onclick="rcmail_ui.show_popup('searchmenu');return false" title="searchmod" /> |
| | | <roundcube:object name="searchform" id="quicksearchbox" /> |
| | | <roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" /> |
| | | </div> |
| | | |
| | | <div id="searchmenu" class="popupmenu"> |
| | | <ul class="toolbarmenu"> |
| | | <li><input type="checkbox" name="s_mods[]" value="name" id="s_mod_name" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_name"><roundcube:label name="name" /></label></li> |
| | | <li><input type="checkbox" name="s_mods[]" value="firstname" id="s_mod_firstname" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_firstname"><roundcube:label name="firstname" /></label></li> |
| | | <li><input type="checkbox" name="s_mods[]" value="surname" id="s_mod_surname" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_surname"><roundcube:label name="surname" /></label></li> |
| | | <li><input type="checkbox" name="s_mods[]" value="email" id="s_mod_email" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_email"><roundcube:label name="email" /></label></li> |
| | | <li><input type="checkbox" name="s_mods[]" value="*" id="s_mod_all" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_all"><roundcube:label name="allfields" /></label></li> |
| | | <!-- |
| | | <li class="separator_below"> |
| | | <li><roundcube:button command="advsearch" type="link" label="advsearch" style="padding-left: 0" classAct="active" /></li> |
| | | --> |
| | | </ul> |
| | | </div> |
| | | |
| | | <div id="directorylistbox"> |
| | | <div id="directorylist-title" class="boxtitle"><roundcube:label name="groups" /></div> |
| | | <div class="boxlistcontent"> |