You are here

fuzzysearch.admin.inc in Fuzzy Search 6

Admin settings and related functions

File

fuzzysearch.admin.inc
View source
<?php

/**
 * @file
 * Admin settings and related functions
 */

/**
 * Build the administration settings panel.
 */
function fuzzysearch_admin() {
  $total = db_result(db_query("SELECT COUNT(*) FROM {node}"));
  $remaining = db_result(db_query("SELECT COUNT(*) FROM {fuzzysearch_index_queue}"));
  $count = format_plural($remaining, 'There is 1 item left to index.', 'There are @count items left to index.');
  $percentage = (int) min(100, 100 * ($total - $remaining) / max(1, $total)) . '%';
  $status = '<p><strong>' . t('%percentage of the site has been indexed.', array(
    '%percentage' => $percentage,
  )) . ' ' . $count . '</strong></p>';
  $output .= $status;
  $output .= drupal_get_form('fuzzysearch_admin_form');
  $output .= drupal_get_form('fuzzysearch_scoring');
  return $output;
}

/**
 * Module Administration (clear index).
 */
function fuzzysearch_admin_form() {
  $form['index'] = array(
    '#title' => t('Index settings'),
    '#type' => 'fieldset',
    '#description' => t('This section configures how Fuzzysearch indexes your site content. You must reindex your site for changes made in this section to take effect.'),
  );
  $form['index']['fuzzysearch_ngram_length'] = array(
    '#type' => 'textfield',
    '#title' => t('Ngram length'),
    '#size' => 1,
    '#maxlength' => 1,
    '#description' => t('Fuzzysearch breaks down words into ngrams, or pieces of text this long, for indexing and searching. Default value is 3.'),
    '#default_value' => variable_get('fuzzysearch_ngram_length', 3),
  );
  $form['index']['fuzzysearch_index_cron'] = array(
    '#type' => 'textfield',
    '#title' => t('Nodes to index per cron run'),
    '#size' => 4,
    '#maxlength' => 4,
    '#description' => t('This sets the number of nodes to index per cron run. A high number may cause PHP to timeout.'),
    '#default_value' => variable_get('fuzzysearch_index_cron', 150),
  );
  $tags = fuzzysearch_get_index_tags();
  $tag_options = array_keys(array_fill(0, 100, 1));
  $form['index']['tags'] = array(
    '#title' => t('HTML tag scoring settings'),
    '#description' => t('Search terms located within some tags can raise the score of a matching node and move it up in the results list. You can set how important the tags are here. Tags set to 0 have no influence.'),
    '#type' => 'fieldset',
    '#collapsed' => TRUE,
    '#collapsible' => TRUE,
  );
  foreach ($tags as $tag => $value) {
    $form['index']['tags']['fuzzysearch_tag_' . $tag] = array(
      '#type' => 'select',
      '#title' => '&lt;' . $tag . '&gt;',
      '#description' => t('Set the indexing score for words inside the @tag tag', array(
        '@tag' => $tag,
      )),
      '#options' => $tag_options,
      '#default_value' => variable_get('fuzzysearch_tag_' . $tag, $tags[$tag]),
    );
  }
  $form['index']['fuzzysearch_reindex'] = array(
    '#type' => 'checkbox',
    '#title' => t('Rebuild index'),
    '#description' => t('Check the box and click submit to re-index all nodes on the site. Re-indexing will begin with the the next cron run. This does not clear the index.'),
    '#default_value' => FALSE,
  );
  $form['index']['fuzzysearch_clear_index'] = array(
    '#type' => 'checkbox',
    '#title' => t('Clear and rebuild index'),
    '#description' => t('Check the box and click submit to clear the index and re-index all nodes on the site. Re-indexing will begin with the the next cron run. Searching will be incomplete until all nodes are indexed.'),
    '#default_value' => FALSE,
  );
  $form['search'] = array(
    '#title' => t('Search settings'),
    '#description' => t('This section configures how Fuzzysearch queries indexed content.'),
    '#type' => 'fieldset',
  );
  $form['search']['fuzzysearch_missing_letters'] = array(
    '#type' => 'textfield',
    '#title' => t('Assume missing letters in search terms'),
    '#size' => 1,
    '#maxlength' => 1,
    '#description' => t('A search term as entered by a user may be missing letters. Up to how many missing letters in the term do you want to assume? 0 means the term will not return longer words in the results. 1 means a 4 letter search term will also check 5 letters words in the index.'),
    '#default_value' => variable_get('fuzzysearch_missing_letters', 1),
  );
  $form['search']['fuzzysearch_extra_letters'] = array(
    '#type' => 'textfield',
    '#title' => t('Assume extra letters in search terms'),
    '#size' => 1,
    '#maxlength' => 1,
    '#description' => t('A search term as entered by a user may have extra letters. Up to how many extra letters in the term do you want to assume? 0 means the term will not return shorter words in the results. 1 means a 4 letter search term will also check 3 letters words in the index.'),
    '#default_value' => variable_get('fuzzysearch_extra_letters', 1),
  );
  $form['search']['fuzzysearch_completeness'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum completeness'),
    '#size' => 3,
    '#maxlength' => 3,
    '#description' => t('Enter a value between 0 and 100 to set the minimum match completeness required in the returned results.'),
    '#default_value' => variable_get('fuzzysearch_completeness', 40),
  );
  $options = node_get_types('names');
  $form['search']['fuzzysearch_nodetypes'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Check any node types you want to exclude from search results'),
    '#description' => t('This does not affect how Fuzzy Search indexes your content types.'),
    '#default_value' => variable_get('fuzzysearch_nodetypes', array(
      '',
    )),
    '#options' => $options,
  );
  $form['search']['fuzzysearch_debug_search'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display debuging information'),
    '#description' => t('If selected, various search information will be displayed that may help tune fuzzysearch settings.'),
    '#default_value' => variable_get('fuzzysearch_debug_search', FALSE),
  );
  $form['display'] = array(
    '#title' => t('Display settings'),
    '#description' => t('This section configures how Fuzzysearch displays the search results.'),
    '#type' => 'fieldset',
  );
  $form['display']['fuzzysearch_path_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Search results path'),
    '#maxlength' => 32,
    '#required' => TRUE,
    '#description' => t('Choose the search results path, for example: search/results. Do not use leading or trailing slashes.'),
    '#default_value' => variable_get('fuzzysearch_path_name', 'fuzzysearch/results'),
  );
  $form['display']['fuzzysearch_sort_score'] = array(
    '#type' => 'checkbox',
    '#title' => t('Sort by score'),
    '#description' => t('If selected, the results will be sorted by score first and completeness second, which can make tag scores even more important. The default is to sort by completeness first.'),
    '#default_value' => variable_get('fuzzysearch_sort_score', FALSE),
  );
  $form['display']['fuzzysearch_debug_score'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display scoring'),
    '#description' => t('If selected, the completeness and score of the results will be shown below each result, which may be helpful for debugging.'),
    '#default_value' => variable_get('fuzzysearch_debug_score', FALSE),
  );
  $form['display']['fuzzysearch_excerpt'] = array(
    '#type' => 'textfield',
    '#title' => t('Result excerpt length'),
    '#size' => 3,
    '#maxlength' => 3,
    '#description' => t('Set the length of the displayed text excerpt containing a found search term. Applies per found term.'),
    '#default_value' => variable_get('fuzzysearch_excerpt', 200),
  );
  $form['display']['fuzzysearch_max_result'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum result length'),
    '#size' => 4,
    '#maxlength' => 4,
    '#description' => t('Set the maximum length of the displayed result. Set to 0 for unlimited length. Applies per result.'),
    '#default_value' => variable_get('fuzzysearch_max_result', 0),
  );
  $form['display']['fuzzysearch_spelling'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum spelling score'),
    '#size' => 3,
    '#maxlength' => 3,
    '#description' => t('Fuzzysearch tries to highlight search terms that may be misspelled. You can set the minimum threshold, which is calculated as a ratio of ngram hits to misses in a term. 0 may cause a misspelling to highlight everything, and 100 will only highlight exact terms. Enter value between 0 and 100. Changing this setting does not require reindexing.'),
    '#default_value' => variable_get('fuzzysearch_spelling', 30),
  );
  $form['#submit'][] = 'fuzzysearch_admin_form_submit';
  return system_settings_form($form);
}
function fuzzysearch_admin_form_validate($form, &$form_state) {
  if (!is_numeric($form_state['values']['fuzzysearch_ngram_length'])) {
    form_set_error('fuzzysearch_ngram_length', t('Ngram length must be an integer.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_index_cron'])) {
    form_set_error('fuzzysearch_index_cron', t('Cron index number must be an integer.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_completeness'])) {
    form_set_error('fuzzysearch_completeness', t('Minimum match completeness must be an integer.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_missing_letters']) || $form_state['values']['missing_letters'] < 0 || $form_state['values']['missing_letters'] > 9) {
    form_set_error('fuzzysearch_missing_letters', t('Assumed missing letters value must be an integer between 0 and 9 inclusive.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_extra_letters']) || $form_state['values']['extra_letters'] < 0 || $form_state['values']['extra_letters'] > 9) {
    form_set_error('fuzzysearch_extra_letters', t('Assumed extra letters value match completeness must be an integer between 0 and 9 inclusive.'));
  }
  $path = _menu_find_router_path($form_state['values']['fuzzysearch_path_name']);
  if (!empty($path) && $path != 'fuzzysearch/results' && $path != variable_get('fuzzysearch_path_name', 'fuzzysearch/results')) {
    form_set_error('fuzzysearch_path_name', t('The search results path is already in use.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_excerpt'])) {
    form_set_error('fuzzysearch_spelling', t('Excerpt length must be an integer.'));
  }
  if (!is_numeric($form_state['values']['fuzzysearch_max_result'])) {
    form_set_error('fuzzysearch_max_result', t('Maximum result length must be an integer.'));
  }
  if ($form_state['values']['fuzzysearch_excerpt'] > $form_state['values']['fuzzysearch_max_result'] && $form_state['values']['fuzzysearch_max_result'] != 0) {
    drupal_set_message(t('The maximum result length has been set smaller than the excerpt length. Any results will display the result\'s teaser instead of the found excerpt.'), 'warning');
  }
  if (!is_numeric($form_state['values']['fuzzysearch_spelling'])) {
    form_set_error('spelling', t('Minimum spelling score must be an integer.'));
  }
}
function fuzzysearch_admin_form_submit($form, &$form_state) {
  if ($form_state['values']['fuzzysearch_reindex'] || $form_state['values']['fuzzysearch_clear_index']) {

    // Refresh the index queue.
    db_query("TRUNCATE {fuzzysearch_index_queue}");

    // Empty the index.
    if ($form_state['values']['fuzzysearch_clear_index']) {
      db_query("TRUNCATE {fuzzysearch_index}");
      drupal_set_message(t('Fuzzy Search indexed cleared.'));
    }
    $query = db_query("SELECT nid FROM {node}");
    while ($row = db_fetch_object($query)) {
      fuzzysearch_reindex($row->nid, 'fuzzysearch');
    }
    drupal_set_message(t('Nodes ready for reindexing, please run cron to update the index.'));
  }

  // Rebuild the menu in case the results path changes.
  if ($form_state['values']['fuzzysearch_path_name'] != variable_get('fuzzysearch_path_name', 'fuzzysearch/results')) {
    module_invoke('menu', 'rebuild');
  }
}

/**
 * Set factors for scores returned by modules implementing hook_search_score().
 */
function fuzzysearch_scoring() {
  $form['scoring'] = array(
    '#title' => t('Scoring adjustment'),
    '#description' => t('Choose a multiplier for each of the score factors. Changing these settings will require all content to be reindexed.'),
    '#type' => 'fieldset',
  );

  // Allow multipliers to range from 10 = max impact on score, to 0 = no impact on score.
  $select_values = array(
    10 => 10,
    9 => 9,
    8 => 8,
    7 => 7,
    6 => 6,
    5 => 5,
    4 => 4,
    3 => 3,
    2 => 2,
    1 => 1,
    0 => 0,
  );

  // Return all the score modifiers using hook_search_score
  // expects each score modifier to return an array defining the title and
  // description of the modifier.
  $scores = module_invoke_all('fuzzysearch_score', 'settings', NULL);
  if (count($scores)) {
    foreach ($scores as $key => $score) {
      $form_index = $score['id'];
      $form['scoring'][$form_index] = array(
        '#title' => $score['title'],
        '#description' => $score['description'],
        '#type' => 'select',
        '#options' => $select_values,
        '#default_value' => variable_get('fuzzysearch_scoring_' . $score['id'], 5),
      );
    }
    $form['scoring']['submit'] = array(
      '#value' => t('Update score factors'),
      '#type' => 'submit',
    );
    return $form;
  }
  else {
    $form['scoring']['no_modifiers'] = array(
      '#value' => t('No enabled modules provide scoring multipliers.'),
    );
    return $form;
  }
}

/**
 * Save the score modifiers as set in the administrative form.
 */
function fuzzysearch_scoring_submit($form, &$form_state) {
  foreach ($form_state['values'] as $key => $value) {
    if ($key != 'op' || $key != 'submit' || $key != 'form_token' || $key != 'form_id') {
      variable_set('fuzzysearch_scoring_' . $key, $value);
    }
  }
  drupal_set_message(t('Score factor multipliers have been updated'));
}

Functions

Namesort descending Description
fuzzysearch_admin Build the administration settings panel.
fuzzysearch_admin_form Module Administration (clear index).
fuzzysearch_admin_form_submit
fuzzysearch_admin_form_validate
fuzzysearch_scoring Set factors for scores returned by modules implementing hook_search_score().
fuzzysearch_scoring_submit Save the score modifiers as set in the administrative form.