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