t('Search pages'), 'description' => t('Searches provided by the Search pages 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 Search views 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', ); 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_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'); }