You are here

search_api_autocomplete.module in Search API Autocomplete 7

Same filename and directory in other branches
  1. 8 search_api_autocomplete.module

Adds autocomplete capabilities for Search API searches.

File

search_api_autocomplete.module
View source
<?php

/**
 * @file
 * Adds autocomplete capabilities for Search API searches.
 */

// Include the files with the module-specific implementations.
require_once 'search_api_autocomplete.search_api_page.inc';
require_once 'search_api_autocomplete.search_api_views.inc';

/**
 * Implements hook_search_api_autocomplete_types().
 *
 * Adds search types for search pages and views. The actual implementations lie
 * in the above include files.
 */
function search_api_autocomplete_search_api_autocomplete_types() {
  $types = array();
  if (module_exists('search_api_page')) {
    $types['search_api_page'] = array(
      'name' => t('Search pages'),
      'description' => t('Searches provided by the <em>Search pages</em> module.'),
      'list searches' => 'search_api_autocomplete_pages_searches',
      'create query' => 'search_api_autocomplete_pages_query',
    );
  }
  if (module_exists('search_api_views')) {
    $types['search_api_views'] = array(
      'name' => t('Search views'),
      'description' => t('Searches provided by the <em>Search views</em> module.'),
      'list searches' => 'search_api_autocomplete_views_searches',
      'create query' => 'search_api_autocomplete_views_query',
      'config form' => 'search_api_autocomplete_views_config_form',
    );
  }
  return $types;
}

/**
 * Implements hook_search_api_autocomplete_suggester_info().
 */
function search_api_autocomplete_search_api_autocomplete_suggester_info() {
  $suggesters['server'] = array(
    'label' => t('Retrieve from server'),
    'description' => t('For compatible servers, ask the server for autocomplete suggestions.'),
    'class' => 'SearchApiAutocompleteServerSuggester',
  );
  $suggesters['live_results'] = array(
    'label' => t('Retrieve live results'),
    'description' => t('Return Live results.'),
    'class' => 'SearchApiAutocompleteLiveResultsSuggester',
  );
  return $suggesters;
}

/**
 * Implements hook_menu().
 */
function search_api_autocomplete_menu() {

  // Autocompletion path
  $items['search_api_autocomplete/%search_api_autocomplete_search'] = array(
    'title' => 'Search API autocomplete',
    'page callback' => 'search_api_autocomplete_autocomplete',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'search_api_autocomplete_access',
    'access arguments' => array(
      1,
    ),
    'type' => MENU_CALLBACK,
    'file' => 'search_api_autocomplete.pages.inc',
  );

  // Admin UI
  $items['admin/config/search/search_api/index/%search_api_index/autocomplete'] = array(
    'title' => 'Autocomplete',
    'description' => 'Add autocompletion to searches for this index.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_autocomplete_admin_overview',
      5,
    ),
    'access arguments' => array(
      'administer search_api',
    ),
    'weight' => -1,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_INLINE | MENU_CONTEXT_PAGE,
    'file' => 'search_api_autocomplete.admin.inc',
  );
  $items['admin/config/search/search_api/index/%/autocomplete/%search_api_autocomplete_search/edit'] = array(
    'title' => 'Edit autocompletion settings',
    'description' => 'Edit the autocompletion settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_autocomplete_admin_search_edit',
      7,
    ),
    'access arguments' => array(
      'administer search_api',
    ),
    'file' => 'search_api_autocomplete.admin.inc',
  );
  $items['admin/config/search/search_api/index/%/autocomplete/%search_api_autocomplete_search/delete'] = array(
    'title' => 'Delete autocompletion settings',
    'description' => 'Delete the autocompletion settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_autocomplete_admin_search_delete',
      7,
    ),
    'access arguments' => array(
      'administer search_api',
    ),
    'file' => 'search_api_autocomplete.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function search_api_autocomplete_theme() {
  $themes['search_api_autocomplete_suggestion'] = array(
    'variables' => array(
      'keys' => NULL,
      'prefix' => NULL,
      'suggestion_prefix' => '',
      'user_input' => '',
      'suggestion_suffix' => '',
      'results' => NULL,
    ),
    'file' => 'search_api_autocomplete.pages.inc',
  );
  return $themes;
}

/**
 * Implements hook_entity_info().
 */
function search_api_autocomplete_entity_info() {
  $info['search_api_autocomplete_search'] = array(
    'label' => t('Autocomplete search'),
    'controller class' => 'EntityAPIControllerExportable',
    'entity class' => 'SearchApiAutocompleteSearch',
    'base table' => 'search_api_autocomplete_search',
    'uri callback' => 'search_api_autocomplete_search_url',
    'module' => 'search_api_autocomplete',
    'exportable' => TRUE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'machine_name',
      'label' => 'name',
    ),
  );
  return $info;
}

/**
* Implements hook_entity_info_alter().
*/
function search_api_autocomplete_entity_info_alter(&$entity_info) {
  foreach ($entity_info as $entity_type => $info) {
    if (!empty($info['view modes'])) {
      $entity_info[$entity_type]['view modes']['live_results_search'] = array(
        'label' => t('Live results search'),
        'custom settings' => TRUE,
      );
    }
  }
}

/**
 * Implements hook_permission().
 */
function search_api_autocomplete_permission() {
  $perms = array();
  foreach (search_api_autocomplete_search_load_multiple() as $id => $search) {
    $perms['use search_api_autocomplete for ' . $id] = array(
      'title' => t('Use autocomplete for the %search search', array(
        '%search' => $search->name,
      )),
    );
  }
  return $perms;
}

/**
 * Access callback for search autocompletion.
 *
 * @param SearchApiAutocompleteSearch $search
 *   The autocomplete search which is being accessed.
 * @param object|null $account
 *   (optional) The account to check, if not given use currently logged in user.
 *
 * @return bool
 *   TRUE, if the search is enabled, supports autocompletion and the user has
 *   the necessary permission. FALSE otherwise.
 */
function search_api_autocomplete_access(SearchApiAutocompleteSearch $search, $account = NULL) {
  return $search->enabled && user_access('use search_api_autocomplete for ' . $search->machine_name, $account) && $search
    ->supportsAutocompletion();
}

/**
 * Implements hook_search_api_index_delete().
 */
function search_api_autocomplete_search_api_index_delete(SearchApiIndex $index) {
  if (!$index
    ->hasStatus(ENTITY_IN_CODE)) {
    $ids = db_query('SELECT id FROM {search_api_autocomplete_search} WHERE index_id = :id', array(
      ':id' => $index->machine_name,
    ))
      ->fetchCol();
    if ($ids) {
      entity_delete_multiple('search_api_autocomplete_search', $ids);
    }
  }
}

/**
 * Retrieves information about all search types, or a specific one.
 *
 * @param $type
 *   (optional) The name of a type.
 *
 * @return array|null
 *   If $type was not given, an array containing information about all search
 *   types. Otherwise, either information about the specified type, or NULL if
 *   the type is not known.
 *
 * @see hook_search_api_autocomplete_types()
 */
function search_api_autocomplete_get_types($type = NULL) {
  $types =& drupal_static(__FUNCTION__);
  if (!isset($types)) {
    $types = module_invoke_all('search_api_autocomplete_types');
  }
  if (isset($type)) {
    return isset($types[$type]) ? $types[$type] : NULL;
  }
  return $types;
}

/**
 * Retrieves the definitions of all suggester plugins, or a specific one.
 *
 * @param string|null $suggester_id
 *   (optional) The ID of the suggester plugin whose definition should be
 *   retrieved. Or NULL to return all known definitions.
 *
 * @return array|null
 *   If $suggester_id was given, either the definition of the given suggester
 *   plugin, or NULL if it isn't known. Otherwise, an associative array of all
 *   known suggester plugin definitions, keyed by ID.
 */
function search_api_autocomplete_suggester_info($suggester_id = NULL) {
  $suggesters =& drupal_static(__FUNCTION__);
  if (!isset($suggesters)) {
    $suggesters = module_invoke_all('search_api_autocomplete_suggester_info');
    drupal_alter('search_api_autocomplete_suggester_info', $suggesters);
    foreach ($suggesters as $i => $definition) {
      if (empty($definition['class']) || !class_exists($definition['class']) || !in_array('SearchApiAutocompleteSuggesterInterface', class_implements($definition['class']))) {
        $variables['@suggester_id'] = $i;
        watchdog('search_api_autocomplete', 'Autocomplete suggester plugin with ID @suggester_id does not specify a valid plugin class.', $variables, WATCHDOG_ERROR);
        unset($suggesters[$i]);
      }
    }
  }
  if (!isset($suggester_id)) {
    return $suggesters;
  }
  return isset($suggesters[$suggester_id]) ? $suggesters[$suggester_id] : NULL;
}

/**
 * Retrieves all suggester plugin definitions that support the given index.
 *
 * @param SearchApiIndex $index
 *   The index for which to check.
 *
 * @return array|null
 *   If $suggester_id was given, either the definition of the given suggester
 *   plugin, or NULL if it isn't known. Otherwise, an associative array of all
 *   known suggester plugin definitions, keyed by ID.
 */
function search_api_autocomplete_suggesters_for_index(SearchApiIndex $index) {
  $suggesters = search_api_autocomplete_suggester_info();
  foreach ($suggesters as $suggester_id => $definition) {
    if (!call_user_func(array(
      $definition['class'],
      'supportsIndex',
    ), $index)) {
      unset($suggesters[$suggester_id]);
    }
  }
  return $suggesters;
}

/**
 * Loads the specified suggester plugin.
 *
 * @param string $suggester_id
 *   The ID of the suggester plugin to load.
 * @param SearchApiAutocompleteSearch $search
 *   The search for which to create a suggester.
 * @param array $configuration
 *   The configuration for the search.
 *
 * @return SearchApiAutocompleteSuggesterInterface|null
 *   The loaded suggester plugin, or NULL if it could not be loaded.
 */
function search_api_autocomplete_suggester_load($suggester_id, SearchApiAutocompleteSearch $search, array $configuration) {
  $definition = search_api_autocomplete_suggester_info($suggester_id);
  if (!$definition) {
    return NULL;
  }
  return call_user_func(array(
    $definition['class'],
    'create',
  ), $search, $configuration, $suggester_id, $definition);
}

/**
 * Loads an autocomplete search entity.
 *
 * @param int|string $id
 *   Either the ID or machine name of an autocomplete search.
 * @param bool $reset
 *   Whether to reset the internal cache.
 *
 * @return SearchApiAutocompleteSearch
 *   The specified autocomplete search entity, or FALSE if it doesn't exist.
 */
function search_api_autocomplete_search_load($id, $reset = FALSE) {
  $ret = search_api_autocomplete_search_load_multiple(array(
    $id,
  ), array(), $reset);
  return $ret ? reset($ret) : FALSE;
}

/**
 * Loads autocomplete search entities.
 *
 * @param array|false $ids
 *   (optional) An array of IDs or machine names, or FALSE to load all searches.
 * @param array $conditions
 *   (optional) An associative array of conditions on the
 *   {search_api_autocomplete_search} table.
 * @param bool $reset
 *   (optional) Whether to reset the internal cache.
 *
 * @return SearchApiAutocompleteSearch[]
 *   An array of all autocomplete search entities that meet the criteria.
 *
 * @see entity_load()
 */
function search_api_autocomplete_search_load_multiple($ids = FALSE, array $conditions = array(), $reset = FALSE) {
  $searches = entity_load('search_api_autocomplete_search', $ids, $conditions, $reset);
  return entity_key_array_by_property($searches, 'machine_name');
}

Functions