/[drupal]/contributions/modules/keyword_autocomplete/keyword_autocomplete.module
ViewVC logotype

Contents of /contributions/modules/keyword_autocomplete/keyword_autocomplete.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Mon Feb 16 15:11:09 2009 UTC (9 months, 1 week ago) by rszrama
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-BETA1, HEAD
Branch point for: DRUPAL-6--1
Changes since 1.2: +97 -98 lines
File MIME type: text/x-php
Applying patch for D6 conversion.
1 <?php
2 // $Id: keyword_autocomplete.module,v 1.2 2009/02/16 14:23:56 rszrama Exp $
3
4 /**
5 * @file
6 * Adds an autocomplete feature to search forms so prior search keywords appear
7 * in a list weighted by number of searches.
8 */
9
10
11 /**
12 * Implementation of hook_menu().
13 */
14 function keyword_autocomplete_menu() {
15 $items = array();
16
17 $items['search/keyword-autocomplete'] = array(
18 'page callback' => 'keyword_autocomplete_keywords',
19 'access arguments' => array('view keyword autocomplete'),
20 'type' => MENU_CALLBACK,
21 );
22 $items['admin/settings/keyword-autocomplete'] = array(
23 'title' => 'Keyword autocomplete',
24 'description' => 'Administer searched keywords and settings.',
25 'page callback' => 'keyword_autocomplete_admin',
26 'access arguments' => array('administer keyword autocomplete'),
27 'type' => MENU_NORMAL_ITEM,
28 );
29 $items['admin/settings/keyword-autocomplete/keywords'] = array(
30 'title' => 'Keywords',
31 'type' => MENU_DEFAULT_LOCAL_TASK,
32 'weight' => -10,
33 );
34 $items['admin/settings/keyword-autocomplete/add'] = array(
35 'title' => 'Add keywords',
36 'description' => 'Add keywords to the autocomplete table.',
37 'page callback' => 'drupal_get_form',
38 'page arguments' => array('keyword_autocomplete_edit_form', '0'),
39 'access arguments' => array('administer keyword autocomplete'),
40 'type' => MENU_LOCAL_TASK,
41 'weight' => -5,
42 );
43 $items['admin/settings/keyword-autocomplete/settings'] = array(
44 'title' => 'Settings',
45 'description' => 'Adjust the settings for the keyword autocomplete module.',
46 'page callback' => 'drupal_get_form',
47 'page arguments' => array('keyword_autocomplete_settings_form'),
48 'access arguments' => array('administer keyword autocomplete'),
49 'type' => MENU_LOCAL_TASK,
50 'weight' => 0,
51 );
52 $items['admin/settings/keyword-autocomplete/%/edit'] = array(
53 'title' => 'Edit keywords',
54 'description' => 'Update keywords in the autocomplete table.',
55 'page callback' => 'drupal_get_form',
56 'page arguments' => array('keyword_autocomplete_edit_form', 3),
57 'access arguments' => array('administer keyword autocomplete'),
58 'type' => MENU_CALLBACK,
59 );
60 $items['admin/settings/keyword-autocomplete/%/delete'] = array(
61 'title' => 'Delete keywords',
62 'description' => 'Delete keywords from the autocomplete table.',
63 'page callback' => 'drupal_get_form',
64 'page arguments' => array('keyword_autocomplete_delete_form', 3),
65 'access arguments' => array('administer keyword autocomplete'),
66 'type' => MENU_CALLBACK,
67 );
68
69 return $items;
70 }
71
72 /**
73 * Implementation of hook_perm().
74 */
75 function keyword_autocomplete_perm() {
76 return array('administer keyword autocomplete', 'view keyword autocomplete');
77 }
78
79 /**
80 * Implementation of hook_form_alter().
81 */
82 function keyword_autocomplete_form_alter(&$form, &$form_state, $form_id) {
83 // Act only on search forms...
84 if ($form_id == 'search_form' || $form_id == 'search_theme_form' || $form_id = 'search_block_form') {
85 // Add the autocomplete path to the various keyword textfields.
86 if (user_access('view keyword autocomplete')) {
87 // Load an array of forms to apply the keyword autocomplete to.
88 $forms = variable_get('keyword_autocomplete_forms', array());
89
90 // The normal search form.
91 if ($form_id == 'search_form' && $forms['search_form'] === 'search_form' && arg(0) != 'admin' && arg(1) != 'user') {
92 $form['basic']['inline']['keys']['#autocomplete_path'] = 'search/keyword-autocomplete';
93 }
94
95 // The search form embedded in the theme.
96 if ($form_id == 'search_theme_form' && $forms['search_theme_form'] === 'search_theme_form') {
97 $form['search_theme_form']['#autocomplete_path'] = 'search/keyword-autocomplete';
98 }
99
100 // The form in the search block.
101 if ($form_id == 'search_block_form' && $forms['search_block_form'] === 'search_block_form') {
102 $form['search_block_form']['#autocomplete_path'] = 'search/keyword-autocomplete';
103 }
104 }
105
106 // Set a custom submit handler to store the keywords in the database.
107 $form['#submit'][] = 'keyword_autocomplete_search_form_submit';
108 }
109 }
110
111 /**
112 * Implementation of hook_theme().
113 */
114 function keyword_autocomplete_theme() {
115 return array(
116 'total_keyword' => array(
117 'arguments' => array('count' => 0),
118 ),
119 );
120 }
121
122 // Stores keyword information in the database.
123 function keyword_autocomplete_search_form_submit($form, &$form_state) {
124 $keywords = '';
125
126 // Get the search keywords based on the form.
127 if ($form_state['values']['form_id'] == 'search_form') {
128 $keywords = trim($form_state['values']['keys']);
129 }
130 elseif ($form_state['values']['form_id'] == 'search_theme_form') {
131 $keywords = trim($form_state['values']['search_theme_form']);
132 }
133 elseif ($form_state['values']['form_id'] == 'search_block_form') {
134 $keywords = trim($form_state['values']['search_block_form']);
135 }
136
137 // Save the keywords to the database if they're valid.
138 if (!empty($keywords) && keyword_autocomplete_validate_keywords($keywords)) {
139 keyword_autocomplete_save_keywords($keywords, $form_id);
140 }
141 }
142
143 // Validates a keywords string and returns TRUE if the keywords were valid.
144 function keyword_autocomplete_validate_keywords($keywords) {
145 // Parse the keywords like do_search().
146 $query = search_parse_query($keywords);
147
148 // Only save the keywords if we had good keywords.
149 if ($query === NULL || $query[0] == '' || $query[2] == '') {
150 return FALSE;
151 }
152 else {
153 return TRUE;
154 }
155 }
156
157 /**
158 * Saves a keywords string to the database.
159 *
160 * @param $keywords
161 * The keywords string from the search.
162 * @param $source
163 * The source of the search; usually the form_id of the search form.
164 * @param $count
165 * When saving a new row, the initial value to insert for search_count.
166 */
167 function keyword_autocomplete_save_keywords($keywords, $source = NULL, $count = 1) {
168 // Grab the existing data for the keywords.
169 $result = db_query("SELECT * FROM {keyword_autocomplete_keywords} WHERE search_keywords = '%s'", $keywords);
170
171 // If we found it, then update the row with some new data.
172 if ($data = db_fetch_array($result)) {
173 // Unpack the sources array.
174 $sources = unserialize($data['sources']);
175
176 // If a source is specified...
177 if (!empty($source)) {
178 // Increment the source count if it already exists.
179 if (isset($sources[$source])) {
180 $sources[$source]++;
181 }
182 else {
183 // Otherwise set it to 1.
184 $sources[$source] = 1;
185 }
186 }
187
188 // Update the database with the new information.
189 db_query("UPDATE {keyword_autocomplete_keywords} SET search_count = search_count + 1, last_search = %d, sources = '%s' WHERE keyword_id = %d", time(), serialize($sources), $data['keyword_id']);
190 }
191 else {
192 // Otherwise save a new row!
193 $sources = array();
194
195 // Set the source if one is specified.
196 if (!empty($source)) {
197 $sources[$source] = 1;
198 }
199
200 // Save the row to the database.
201 db_query("INSERT INTO {keyword_autocomplete_keywords} (search_keywords, search_count, sources, last_search) VALUES ('%s', %d, '%d', %d)",
202 $keywords, $count, serialize($sources), time());
203 }
204 }
205
206 /**
207 * Loads the data for a set of search keywords by the keyword ID.
208 *
209 * @param $keyword_id
210 * The numeric ID of the keywords string in the database.
211 * @return
212 * An array of data for the keywords from the database.
213 */
214 function keyword_autocomplete_load_data($keyword_id) {
215 // Take care of the ID 0 which represents a new row in the table.
216 if ($keyword_id == 0) {
217 return array();
218 }
219
220 // Load any appropriate data from the database.
221 $result = db_query("SELECT * FROM {keyword_autocomplete_keywords} WHERE keyword_id = %d", $keyword_id);
222
223 // If we found a row...
224 if ($data = db_fetch_array($result)) {
225 // Then return the data array.
226 return $data;
227 }
228 else {
229 // Otherwise return an empty array.
230 return array();
231 }
232 }
233
234 // Returns an autocomplete list for search keywords on various search forms.
235 function keyword_autocomplete_keywords($string = '') {
236 $matches = array();
237
238 // If the user has started typing something...
239 if ($string) {
240 // Pull up relevant results from the database.
241 $result = db_query_range("SELECT search_keywords FROM {keyword_autocomplete_keywords} WHERE LOWER(search_keywords) LIKE LOWER('%s%%') ORDER BY search_count DESC, last_search DESC", $string, 0, variable_get('keyword_autocomplete_matches', 10));
242 while ($data = db_fetch_object($result)) {
243 $matches[$data->search_keywords] = check_plain($data->search_keywords);
244 }
245 }
246
247 // Print out the matches in the format expected by autocomplete.js.
248 drupal_json($matches);
249 }
250
251 // Displays a table for viewing and administering saved keywords.
252 function keyword_autocomplete_admin($filter = '') {
253 $args = array();
254 $rows = array();
255
256 // Build the header for the admin table.
257 $header = array(
258 array('data' => t('Keywords'), 'field' => 'search_keywords', 'sort' => 'asc'),
259 array('data' => t('Count'), 'field' => 'search_count'),
260 array('data' => t('Last search'), 'field' => 'last_search'),
261 t('Operations'),
262 );
263
264 // Build the appropriate query to load keyword data.
265 if (empty($filter)) {
266 $query = "SELECT * FROM {keyword_autocomplete_keywords}";
267 }
268 else {
269 $query = "SELECT * FROM {keyword_autocomplete_keywords} WHERE LOWER(search_keywords) LIKE LOWER('%s')";
270 $args = array(str_replace('*', '%%', $filter));
271 }
272
273 // Grab the keywords from the database.
274 $result = pager_query($query . tablesort_sql($header), variable_get('keyword_table_size', 30), 0, NULL, $args);
275
276 // Loop through the results and build the table rows.
277 while ($data = db_fetch_array($result)) {
278 // Build the operations links for the row.
279 $ops = array(
280 l(t('edit'), 'admin/settings/keyword-autocomplete/'. $data['keyword_id'] .'/edit'),
281 l(t('delete'), 'admin/settings/keyword-autocomplete/'. $data['keyword_id'] .'/delete'),
282 );
283
284 // Add the search keywords row to the table.
285 $rows[] = array(
286 check_plain($data['search_keywords']),
287 $data['search_count'],
288 format_date($data['last_search'], 'small'),
289 implode(' ', $ops),
290 );
291 }
292
293 // Account for an empty table.
294 if (empty($rows)) {
295 $rows[] = array(
296 array('data' => t('No keywords found.'), 'colspan' => 4),
297 );
298 }
299 else {
300 // Count how many keywords have been saved.
301 $count = db_result(db_query("SELECT COUNT(keyword_id) FROM {keyword_autocomplete_keywords}"));
302 }
303
304 return drupal_get_form('keyword_autocomplete_admin_filter_form', $filter)
305 . theme('total_keywords', $count) . theme('table', $header, $rows) . theme('pager');
306 }
307
308 // Themes the total number of keywords for display above the admin table.
309 function theme_total_keywords($count) {
310 return '<div class="total-keywords">'. t('Total rows: !count', array('!count' => $count)) .'</div>';
311 }
312
313 // Displays a form to filter keywords displayed in the admin table.
314 function keyword_autocomplete_admin_filter_form($form_state, $filter = '') {
315 $form['filter'] = array(
316 '#type' => 'fieldset',
317 '#title' => t('Keywords filter'),
318 '#description' => t('Enter a search filter for the displayed keywords. Use * as a wildcard.'),
319 '#collapsible' => TRUE,
320 '#collapsed' => empty($filter),
321 );
322
323 $form['filter']['filter_text'] = array(
324 '#type' => 'textfield',
325 '#title' => t('Filter'),
326 '#default_value' => $filter,
327 );
328
329 $form['filter']['submit'] = array(
330 '#type' => 'submit',
331 '#value' => t('Apply filter'),
332 '#suffix' => empty($filter) ? '' : l(t('Remove filter'), 'admin/settings/keyword-autocomplete'),
333 );
334
335 return $form;
336 }
337
338 function keyword_autocomplete_admin_filter_form_submit($form, &$form_state) {
339 // Trim the input for the filter text.
340 $filter = trim($form_state['values']['filter_text']);
341
342 // Redirect to the filtered URL.
343 if (!empty($filter)) {
344 return 'admin/settings/keyword-autocomplete/'. $filter;
345 }
346 }
347
348 // Displays the search keywords edit form.
349 function keyword_autocomplete_edit_form($form_state, $keyword_id) {
350 $data = keyword_autocomplete_load_data($keyword_id);
351
352 $form['keyword_id'] = array(
353 '#type' => 'value',
354 '#value' => $data['keyword_id'],
355 );
356
357 $form['search_keywords'] = array(
358 '#type' => 'textfield',
359 '#title' => t('Search keywords'),
360 '#description' => t('The keywords to match on in autocomplete results.'),
361 '#maxlength' => 255,
362 '#default_value' => $data['search_keywords'],
363 '#disabled' => !empty($data['search_keywords']),
364 '#required' => TRUE,
365 );
366
367 $form['search_count'] = array(
368 '#type' => 'textfield',
369 '#title' => t('Search count'),
370 '#description' => t('The search counter for these terms. Higher counts display first.'),
371 '#default_value' => empty($data['search_count']) ? 1 : $data['search_count'],
372 '#required' => TRUE,
373 );
374
375 $form['submit'] = array(
376 '#type' => 'submit',
377 '#value' => t('Submit'),
378 '#suffix' => l(t('Cancel'), 'admin/settings/keyword-autocomplete'),
379 );
380
381 return $form;
382 }
383
384 function keyword_autocomplete_edit_form_validate($form, &$form_state) {
385 if (!is_numeric($form_state['values']['search_count']) || intval($form_state['values']['search_count']) <= 0) {
386 form_set_error('search_count', t('Search count must be a positive whole number.'));
387 }
388 }
389
390 function keyword_autocomplete_edit_form_submit($form, &$form_state) {
391 // If the submission was for a new set of keywords...
392 if ($form_state['values']['keyword_id'] == 0) {
393 $keywords = $form_state['values']['search_keywords'];
394
395 // Grab the keyword ID for the keyword string if it's already saved.
396 $result = db_result(db_query("SELECT keyword_id FROM {keyword_autocomplete_keywords} WHERE search_keywords = '%s'", $keywords));
397
398 // If we found an ID, display a message and redirect to its edit form.
399 if ($result > 0) {
400 drupal_set_message(t('Those keywords have already been saved. You have been redirected to the edit form and may update its values accordingly.'));
401 $form_state['redirect'] = 'admin/settings/keyword-autocomplete/'. $result .'/edit';
402 }
403
404 // Otherwise save the new keyword string.
405 keyword_autocomplete_save_keywords($keywords, NULL, $form_state['values']['search_count']);
406
407 drupal_set_message(t('%keywords saved to the autocomplete table.', array('%keywords' => $keywords)));
408 $form_state['redirect'] = 'admin/settings/keyword-autocomplete';
409 }
410
411 // Update values for an existing keywords row.
412 db_query("UPDATE {keyword_autocomplete_keywords} SET search_count = %d, last_search = %d WHERE keyword_id = %d",
413 intval($form_state['values']['search_count']), time(), $form_state['values']['keyword_id']);
414
415 drupal_set_message(t('%keywords values have been updated.', array('%keywords' => $form_state['values']['search_keywords'])));
416 $form_state['redirect'] = 'admin/settings/keyword-autocomplete';
417 }
418
419 // Displays the delete confirmation form.
420 function keyword_autocomplete_delete_form($form_state, $keyword_id) {
421 // Load the keywords data from the database.
422 $data = keyword_autocomplete_load_data($keyword_id);
423
424 // Fail out if an invalid keyword ID was entered.
425 if (empty($data)) {
426 drupal_set_message(t('No keywords have been saved with that ID.'), 'error');
427 drupal_goto('admin/settings/keyword-autocomplete');
428 }
429
430 $form['keyword_id'] = array(
431 '#type' => 'value',
432 '#value' => $keyword_id,
433 );
434
435 return confirm_form($form, t('Are you sure you want to delete the data for %keywords?', array('%keywords' => $data['search_keywords'])), 'admin/settings/keyword-autocomplete', NULL, t('Delete'));
436 }
437
438 function keyword_autocomplete_delete_form_submit($form, &$form_state) {
439 // Load the keywords data from the database.
440 $data = keyword_autocomplete_load_data($form_state['values']['keyword_id']);
441
442 // Delete the data from the table and display a confirmation message.
443 db_query("DELETE FROM {keyword_autocomplete_keywords} WHERE keyword_id = %d", $data['keyword_id']);
444 drupal_set_message(t('%keywords data deleted from the autocomplete table.', array('%keywords' => $data['search_keywords'])));
445
446 $form_state['redirect'] = 'admin/settings/keyword-autocomplete';
447 }
448
449 // Displays the module settings form.
450 function keyword_autocomplete_settings_form() {
451 $form = array();
452
453 $form['keyword_table_size'] = array(
454 '#type' => 'select',
455 '#title' => t('Keyword admin table size'),
456 '#description' => t('Adjusts the number of rows in the table on the Keywords tab.'),
457 '#options' => drupal_map_assoc(array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)),
458 '#default_value' => variable_get('keyword_table_size', 30),
459 );
460
461 $form['keyword_autocomplete_forms'] = array(
462 '#type' => 'checkboxes',
463 '#title' => t('Add keyword autocomplete to these forms'),
464 '#description' => t('Keywords will only appear for users with %perm access.', array('%perm' => 'view keyword autocomplete')),
465 '#options' => array(
466 'search_form' => t('The normal search form.'),
467 'search_theme_form' => t('The search form embedded in the theme.'),
468 'search_block_form' => t('The form in the search block.'),
469 ),
470 '#default_value' => variable_get('keyword_autocomplete_forms', array()),
471 );
472
473 $form['keyword_autocomplete_matches'] = array(
474 '#type' => 'select',
475 '#title' => t('Number of autocomplete matches'),
476 '#description' => t('Adjusts the number of keywords that pops up on autocomplete textfields.'),
477 '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25)),
478 '#default_value' => variable_get('keyword_autocomplete_matches', 10),
479 );
480
481 return system_settings_form($form);
482 }
483

  ViewVC Help
Powered by ViewVC 1.1.2