alecpl
2011-11-24 e4a4ca19480690193e36e14ef6b9d592e73e9e9c
commit | author | age
f11541 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/steps/addressbook/search.inc                                  |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
0501b6 8  | Copyright (C) 2005-2011, The Roundcube Dev Team                       |
e9a9f2 9  | Copyright (C) 2011, Kolab Systems AG                                  |
f11541 10  | Licensed under the GNU GPL                                            |
T 11  |                                                                       |
12  | PURPOSE:                                                              |
e9a9f2 13  |   Search action (and form) for address book contacts                  |
f11541 14  |                                                                       |
T 15  +-----------------------------------------------------------------------+
16  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
e9a9f2 17  | Author: Aleksander Machniak <machniak@kolabsys.com>                   |
f11541 18  +-----------------------------------------------------------------------+
T 19
20  $Id: search.inc 456 2007-01-10 12:34:33Z thomasb $
21
22 */
23
f8e48d 24 if ($RCMAIL->action == 'search-create') {
A 25     $id   = get_input_value('_search', RCUBE_INPUT_POST);
26     $name = get_input_value('_name', RCUBE_INPUT_POST, true);
27
28     if (($params = $_SESSION['search_params']) && $params['id'] == $id) {
29
30         $data = array(
31             'type' => rcube_user::SEARCH_ADDRESSBOOK,
32             'name' => $name,
33             'data' => array(
34                 'fields' => $params['data'][0],
35                 'search' => $params['data'][1],
36             ),
37         );
38
39         $plugin = $RCMAIL->plugins->exec_hook('saved_search_create', array('data' => $data));
40
41         if (!$plugin['abort'])
42             $result = $RCMAIL->user->insert_search($plugin['data']);
43         else
44             $result = $plugin['result'];
45     }
46
47     if ($result) {
48         $OUTPUT->show_message('savedsearchcreated', 'confirmation');
49         $OUTPUT->command('insert_saved_search', Q($name), Q($result));
50     }
51     else
52         $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'savedsearchcreateerror', 'error');
53
54     $OUTPUT->send();
55 }
56
57 if ($RCMAIL->action == 'search-delete') {
58     $id = get_input_value('_sid', RCUBE_INPUT_POST);
59
60     $plugin = $RCMAIL->plugins->exec_hook('saved_search_delete', array('id' => $id));
61
62     if (!$plugin['abort'])
63         $result = $RCMAIL->user->delete_search($id);
64     else
65         $result = $plugin['result'];
66
67     if ($result) {
68         $OUTPUT->show_message('savedsearchdeleted', 'confirmation');
69         $OUTPUT->command('remove_search_item', Q($id));
b104e3 70         // contact list will be cleared, clear also page counter
A 71         $OUTPUT->command('set_rowcount', rcube_label('nocontactsfound'));
72         $OUTPUT->set_env('pagecount', 0);
f8e48d 73     }
A 74     else
75         $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'savedsearchdeleteerror', 'error');
76
77     $OUTPUT->send();
78 }
79
80
e9a9f2 81 if (!isset($_GET['_form'])) {
A 82     rcmail_contact_search();
3cacf9 83 }
A 84
e9a9f2 85 $OUTPUT->add_handler('searchform', 'rcmail_contact_search_form');
A 86 $OUTPUT->send('contactsearch');
3cacf9 87
A 88
e9a9f2 89 function rcmail_contact_search()
A 90 {
ecf295 91     global $RCMAIL, $OUTPUT, $CONFIG, $SEARCH_MODS_DEFAULT;
e9a9f2 92
A 93     $adv = isset($_POST['_adv']);
f8e48d 94     $sid = get_input_value('_sid', RCUBE_INPUT_GET);
e9a9f2 95
f8e48d 96     // get search criteria from saved search
A 97     if ($sid && ($search = $RCMAIL->user->get_search($sid))) {
98         $fields = $search['data']['fields'];
99         $search = $search['data']['search'];
100     }
e9a9f2 101     // get fields/values from advanced search form
f8e48d 102     else if ($adv) {
ecf295 103         foreach (array_keys($_POST) as $key) {
A 104             $s = trim(get_input_value($key, RCUBE_INPUT_POST, true));
105             if (strlen($s) && preg_match('/^_search_([a-zA-Z0-9_-]+)$/', $key, $m)) {
e9a9f2 106                 $search[] = $s;
ecf295 107                 $fields[] = $m[1];
e9a9f2 108             }
A 109         }
110
111         if (empty($fields)) {
112             // do nothing, show the form again
113             return;
114         }
115     }
116     // quick-search
117     else {
118         $search = trim(get_input_value('_q', RCUBE_INPUT_GET, true));
119         $fields = explode(',', get_input_value('_headers', RCUBE_INPUT_GET));
120
121         if (empty($fields)) {
08b796 122             $fields = array_keys($SEARCH_MODS_DEFAULT);
A 123         }
124         else {
125             $fields = array_filter($fields);
e9a9f2 126         }
A 127
128         // update search_mods setting
129         $old_mods = $RCMAIL->config->get('addressbook_search_mods');
130         $search_mods = array_fill_keys($fields, 1);
131         if ($old_mods != $search_mods) {
132             $RCMAIL->user->save_prefs(array('addressbook_search_mods' => $search_mods));
133         }
134
08b796 135         if (in_array('*', $fields)) {
e9a9f2 136             $fields = '*';
A 137         }
138     }
139
f21a04 140     // Values matching mode
A 141     $mode = (int) $RCMAIL->config->get('addressbook_search_mode');
142
ecf295 143     // get sources list
A 144     $sources    = $RCMAIL->get_address_sources();
145     $search_set = array();
146     $records    = array();
147
148     foreach ($sources as $s) {
149         $source = $RCMAIL->get_address_book($s['id']);
150
08b796 151         // check if search fields are supported....
ecf295 152         if (is_array($fields)) {
A 153             $cols = $source->coltypes[0] ? array_flip($source->coltypes) : $source->coltypes;
154             $supported = 0;
155
156             foreach ($fields as $f) {
157                 if (array_key_exists($f, $cols)) {
158                     $supported ++;
159                 }
160             }
161
08b796 162             // in advanced search we require all fields (AND operator)
A 163             // in quick search we require at least one field (OR operator)
164             if (($adv && $supported < count($fields)) || (!$adv && !$supported)) {
ecf295 165                 continue;
A 166             }
167         }
168
169         // reset page
170         $source->set_page(1);
171         $source->set_pagesize(9999);
172
173         // get contacts count
f21a04 174         $result = $source->search($fields, $search, $mode, false);
ecf295 175
A 176         if (!$result->count) {
177             continue;
178         }
179
180         // get records
181         $result = $source->list_records(array('name', 'email'));
182
183         while ($row = $result->next()) {
184             $row['sourceid'] = $s['id'];
185             $key = $row['name'] . ':' . $row['sourceid'];
186             $records[$key] = $row;
187         }
188
189         unset($result);
190         $search_set[$s['id']] = $source->get_search_set();
191     }
192
193     // sort the records
194     ksort($records, SORT_LOCALE_STRING);
195
196     // create resultset object
197     $count  = count($records);
198     $result = new rcube_result_set($count);
199
200     // cut first-page records
201     if ($CONFIG['pagesize'] < $count) {
202         $records = array_slice($records, 0, $CONFIG['pagesize']);
203     }
204
205     $result->records = array_values($records);
206
e9a9f2 207     // search request ID
9382b6 208     $search_request = md5('addr'
A 209         .(is_array($fields) ? implode($fields, ',') : $fields)
e9a9f2 210         .(is_array($search) ? implode($search, ',') : $search));
A 211
212     // save search settings in session
ecf295 213     $_SESSION['search'][$search_request] = $search_set;
f8e48d 214     $_SESSION['search_params'] = array('id' => $search_request, 'data' => array($fields, $search));
ecf295 215     $_SESSION['page'] = 1;
e9a9f2 216
A 217     if ($adv)
218         $OUTPUT->command('list_contacts_clear');
219
220     if ($result->count > 0) {
221         // create javascript list
222         rcmail_js_contacts_list($result);
f8e48d 223         $OUTPUT->show_message('contactsearchsuccessful', 'confirmation', array('nr' => $result->count));
e9a9f2 224     }
A 225     else {
226         $OUTPUT->show_message('nocontactsfound', 'notice');
227     }
228
229     // update message count display
230     $OUTPUT->command('set_env', 'search_request', $search_request);
ecf295 231     $OUTPUT->command('set_env', 'pagecount', ceil($result->count / $CONFIG['pagesize']));
A 232     $OUTPUT->command('set_rowcount', rcmail_get_rowcount_text($result));
f8e48d 233     // Re-set current source
A 234     $OUTPUT->command('set_env', 'search_id', $sid);
235     $OUTPUT->command('set_env', 'source', '');
236     $OUTPUT->command('set_env', 'group', '');
ecf295 237
A 238     // unselect currently selected directory/group
f8e48d 239     if (!$sid)
A 240         $OUTPUT->command('unselect_directory');
62811c 241     $OUTPUT->command('update_group_commands');
e9a9f2 242
A 243     // send response
244     $OUTPUT->send($adv ? 'iframe' : null);
3cacf9 245 }
f11541 246
e9a9f2 247 function rcmail_contact_search_form($attrib)
A 248 {
ecf295 249     global $RCMAIL, $CONTACT_COLTYPES;
f11541 250
e9a9f2 251     $i_size = !empty($attrib['size']) ? $attrib['size'] : 30;
0501b6 252
e9a9f2 253     $form = array(
A 254         'main' => array(
255             'name'    => rcube_label('contactproperties'),
256             'content' => array(
257             ),
258         ),
259         'personal' => array(
260             'name'    => rcube_label('personalinfo'),
261             'content' => array(
262             ),
263         ),
264         'other' => array(
265             'name'    => rcube_label('other'),
266             'content' => array(
267             ),
268         ),
269     );
270
ecf295 271     // get supported coltypes from all address sources
A 272     $sources  = $RCMAIL->get_address_sources();
273     $coltypes = array();
274
275     foreach ($sources as $s) {
276         $CONTACTS = $RCMAIL->get_address_book($s['id']);
277
278         if (is_array($CONTACTS->coltypes)) {
279             $contact_cols = $CONTACTS->coltypes[0] ? array_flip($CONTACTS->coltypes) : $CONTACTS->coltypes;
280             $coltypes = array_merge($coltypes, $contact_cols);
281         }
282     }
283
284     // merge supported coltypes with $CONTACT_COLTYPES
285     foreach ($coltypes as $col => $colprop) {
286         $coltypes[$col] = $CONTACT_COLTYPES[$col] ? array_merge($CONTACT_COLTYPES[$col], (array)$colprop) : (array)$colprop;
287     }
288
289     // build form fields list
290     foreach ($coltypes as $col => $colprop)
e9a9f2 291     {
A 292         if ($colprop['type'] != 'image' && !$colprop['nosearch'])
293         {
294             $ftype    = $colprop['type'] == 'select' ? 'select' : 'text';
295             $label    = isset($colprop['label']) ? $colprop['label'] : rcube_label($col);
296             $category = $colprop['category'] ? $colprop['category'] : 'other';
297
298             if ($ftype == 'text')
299                 $colprop['size'] = $i_size;
300
301             $content  = html::div('row', html::div('contactfieldlabel label', Q($label))
ecf295 302                 . html::div('contactfieldcontent', rcmail_get_edit_field('search_'.$col, '', $colprop, $ftype)));
e9a9f2 303
A 304             $form[$category]['content'][] = $content;
305         }
306     }
307
ecf295 308     $hiddenfields = new html_hiddenfield();
e9a9f2 309     $hiddenfields->add(array('name' => '_adv', 'value' => 1));
A 310
311     $out = $RCMAIL->output->request_form(array(
312         'name' => 'form', 'method' => 'post',
313         'task' => $RCMAIL->task, 'action' => 'search',
314         'noclose' => true) + $attrib, $hiddenfields->show());
315
316     $RCMAIL->output->add_gui_object('editform', $attrib['id']);
317
318     unset($attrib['name']);
319     unset($attrib['id']);
320
321     foreach ($form as $f) {
322         if (!empty($f['content'])) {
323             $content = html::div('contactfieldgroup', join("\n", $f['content']));
324
325             $out .= html::tag('fieldset', $attrib,
326                 html::tag('legend', null, Q($f['name']))
327                 . $content) . "\n";
328         }
329     }
330
331     return $out . '</form>';
f11541 332 }