PageRenderTime 43ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/roundcubemail-0.7.2-dep/program/steps/addressbook/search.inc

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