123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- <?php
- /**
- * @file
- * Hooks provided by the Search API autocomplete module.
- */
- /**
- * @addtogroup hooks
- * @{
- */
- /**
- * Inform the module about types of searches for which autocompletion is available.
- *
- * The implementation has to take care of altering the search form accordingly
- * itself. This should be done by loading the appropriate
- * SearchApiAutocompleteSearch entity and calling its alterElement() method with
- * the textfield element to which autocompletion should be added. See
- * example_form_example_search_form_alter() for an example.
- *
- * @return array
- * An array with search types as the keys, mapped to arrays containing the
- * following entries:
- * - name: The category name for searches of this type.
- * - description: A short description of this type (may contain HTML).
- * - list searches: Callback function that returns a list of all known
- * searches of this type for a given index. See
- * example_list_autocomplete_searches() for the expected function signature.
- * - create query: Callback function to create a search query for a search of
- * this type and some user input. See example_create_autocomplete_query()
- * for the expected function signature.
- * - config form: (optional) Callback function for adding a form for
- * type-specific options to a search's autocomplete settings form. See
- * example_autocomplete_config_form() for the expected function signature.
- * This function name will also be the base for custom validation and submit
- * callbacks, with "_validate" or "_submit" appended, respectively.
- *
- * @see example_list_autocomplete_searches()
- * @see example_create_autocomplete_query()
- * @see example_autocomplete_config_form()
- * @see example_autocomplete_config_form_validate()
- * @see example_autocomplete_config_form_submit()
- * @see example_form_example_search_form_alter()
- */
- function hook_search_api_autocomplete_types() {
- $types['example'] = array(
- 'name' => t('Example searches'),
- 'description' => t('Searches provided by the <em>Example</em> module.'),
- 'list searches' => 'example_list_autocomplete_searches',
- 'create query' => 'example_create_autocomplete_query',
- 'config form' => 'example_autocomplete_config_form',
- );
- return $types;
- }
- /**
- * Acts on searches being loaded from the database.
- *
- * This hook is invoked during search loading, which is handled by
- * entity_load(), via the EntityCRUDController.
- *
- * @param array $searches
- * An array of search entities being loaded, keyed by machine name.
- *
- * @see hook_entity_load()
- */
- function hook_search_api_autocomplete_search_load(array $searches) {
- $result = db_query('SELECT pid, foo FROM {mytable} WHERE pid IN(:ids)', array(':ids' => array_keys($entities)));
- foreach ($result as $record) {
- $entities[$record->pid]->foo = $record->foo;
- }
- }
- /**
- * Responds when a search is inserted.
- *
- * This hook is invoked after the search is inserted into the database.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search that is being inserted.
- *
- * @see hook_entity_insert()
- */
- function hook_search_api_autocomplete_search_insert(SearchApiAutocompleteSearch $search) {
- db_insert('mytable')
- ->fields(array(
- 'id' => entity_id('search_api_autocomplete_search', $search),
- 'extra' => print_r($search, TRUE),
- ))
- ->execute();
- }
- /**
- * Acts on a search being inserted or updated.
- *
- * This hook is invoked before the search is saved to the database.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search that is being inserted or updated.
- *
- * @see hook_entity_presave()
- */
- function hook_search_api_autocomplete_search_presave(SearchApiAutocompleteSearch $search) {
- $search->name = 'foo';
- }
- /**
- * Responds to a search being updated.
- *
- * This hook is invoked after the search has been updated in the database.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search that is being updated.
- *
- * @see hook_entity_update()
- */
- function hook_search_api_autocomplete_search_update(SearchApiAutocompleteSearch $search) {
- db_update('mytable')
- ->fields(array('extra' => print_r($search, TRUE)))
- ->condition('id', entity_id('search_api_autocomplete_search', $search))
- ->execute();
- }
- /**
- * Responds to search deletion.
- *
- * This hook is invoked after the search has been removed from the database.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search that is being deleted.
- *
- * @see hook_entity_delete()
- */
- function hook_search_api_autocomplete_search_delete(SearchApiAutocompleteSearch $search) {
- db_delete('mytable')
- ->condition('pid', entity_id('search_api_autocomplete_search', $search))
- ->execute();
- }
- /**
- * Define default search configurations.
- *
- * @return
- * An array of default searches, keyed by machine names.
- *
- * @see hook_default_search_api_autocomplete_search_alter()
- */
- function hook_default_search_api_autocomplete_search() {
- $defaults['main'] = entity_create('search_api_autocomplete_search', array(
- // …
- ));
- return $defaults;
- }
- /**
- * Alter default search configurations.
- *
- * @param array $defaults
- * An array of default searches, keyed by machine names.
- *
- * @see hook_default_search_api_autocomplete_search()
- */
- function hook_default_search_api_autocomplete_search_alter(array &$defaults) {
- $defaults['main']->name = 'custom name';
- }
- /**
- * @} End of "addtogroup hooks".
- */
- /**
- * Returns a list of searches for the given index.
- *
- * All searches returned must have a unique and well-defined machine name. The
- * implementing module for this type is responsible for being able to map a
- * specific search always to the same distinct machine name.
- * Since the machine names have to be globally unique, they should be prefixed
- * with the search type / module name.
- *
- * Also, name and machine name have to respect the length constraints from
- * search_api_autocomplete_schema().
- *
- * @param SearchApiIndex $index
- * The index whose searches should be returned.
- *
- * @return array
- * An array of searches, keyed by their machine name. The values are arrays
- * with the following keys:
- * - name: A human-readable name for this search.
- * - options: (optional) An array of options to use for this search.
- * Type-specific options should go into the "custom" nested key in these
- * options.
- */
- function example_list_autocomplete_searches(SearchApiIndex $index) {
- $ret = array();
- $result = db_query('SELECT name, machine_name, extra FROM {example_searches} WHERE index_id = :id', array($index->machine_name));
- foreach ($result as $row) {
- $id = 'example_' . $row->machine_name;
- $ret[$id] = array(
- 'name' => $row->name,
- );
- if ($row->extra) {
- $ret[$id]['options']['custom']['extra'] = $row->extra;
- }
- }
- return $ret;
- }
- /**
- * Create the query that would be issued for the given search for the complete keys.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search for which to create the query.
- * @param $complete
- * A string containing the complete search keys.
- * @param $incomplete
- * A string containing the incomplete last search key.
- *
- * @return SearchApiQueryInterface
- * The query that would normally be executed when only $complete was entered
- * as the search keys for the given search.
- */
- function example_create_autocomplete_query(SearchApiAutocompleteSearch $search, $complete, $incomplete) {
- $query = search_api_query($search->index_id);
- if ($complete) {
- $query->keys($complete);
- }
- if (!empty($search->options['custom']['extra'])) {
- list($f, $v) = explode('=', $search->options['custom']['extra'], 2);
- $query->condition($f, $v);
- }
- if (!empty($search->options['custom']['user_filters'])) {
- foreach (explode("\n", $search->options['custom']['user_filters']) as $line) {
- list($f, $v) = explode('=', $line, 2);
- $query->condition($f, $v);
- }
- }
- return $query;
- }
- /**
- * Form callback for configuring autocompletion for searches of the "example" type.
- *
- * The returned form array will be nested into an outer form, so you should not
- * rely on knowing the array structure (like the elements' parents) and should
- * not set "#tree" to FALSE for any element.
- *
- * @param SearchApiAutocompleteSearch $search
- * The search whose config form should be presented.
- *
- * @see example_autocomplete_config_form_validate()
- * @see example_autocomplete_config_form_submit()
- */
- function example_autocomplete_config_form(array $form, array &$form_state, SearchApiAutocompleteSearch $search) {
- $form['user_filters'] = array(
- '#type' => 'textarea',
- '#title' => t('Custom filters'),
- '#description' => t('Enter additional filters set on the autocompletion search. ' .
- 'Write one filter on each line, the field and its value separated by an equals sign (=).'),
- '#default_value' => empty($search->options['custom']['user_filters']) ? '' : $search->options['custom']['user_filters'],
- );
- return $form;
- }
- /**
- * Validation callback for example_autocomplete_config_form().
- *
- * The configured SearchApiAutocompleteSearch object can be found in
- * $form_state['search'].
- *
- * @param array $form
- * The type-specific config form, as returned by the "config form" callback.
- * @param array $form_state
- * The complete form state of the form.
- * @param array $values
- * The portion of $form_state['values'] that corresponds to the type-specific
- * config form.
- *
- * @see example_autocomplete_config_form()
- * @see example_autocomplete_config_form_submit()
- */
- function example_autocomplete_config_form_validate(array $form, array &$form_state, array &$values) {
- $f = array();
- foreach (explode("\n", $values['user_filters']) as $line) {
- if (preg_match('/^\s*([a-z0-9_:]+)\s*=\s*(.*\S)\s*$/i', $line, $m)) {
- $f[] = $m[1] . '=' . $m[2];
- }
- else {
- form_error($form, t('Write one filter on each line, the field and its value separated by an equals sign (=).'));
- }
- }
- $values['user_filters'] = $f;
- }
- /**
- * Submit callback for example_autocomplete_config_form().
- *
- * After calling this function, the value of $values (if set) will automatically
- * be written to $search->options['custom']. This function just has to take care
- * of sanitizing the data as necessary. Also, values already present in
- * $search->options['custom'], but not in the form, will automatically be
- * protected from being overwritten.
- *
- * The configured SearchApiAutocompleteSearch object can be found in
- * $form_state['search'].
- *
- * @param array $form
- * The type-specific config form, as returned by the "config form" callback.
- * @param array $form_state
- * The complete form state of the form.
- * @param array $values
- * The portion of $form_state['values'] that corresponds to the type-specific
- * config form.
- *
- * @see example_autocomplete_config_form()
- * @see example_autocomplete_config_form_validate()
- */
- function example_autocomplete_config_form_submit(array $form, array &$form_state, array &$values) {
- $values['user_filters'] = implode("\n", $values['user_filters']);
- }
- /**
- * Implements hook_form_FORM_ID_alter().
- *
- * Alters the example_search_form form to add autocompletion, if enabled by the
- * user.
- */
- function example_form_example_search_form_alter(array &$form, array &$form_state) {
- // Compute the machine name that would be generated for this search in the
- // 'list searches' callback.
- $search_id = 'example_' . $form_state['search id'];
- // Look up the corresponding autocompletion configuration, if it exists.
- $search = search_api_autocomplete_search_load($search_id);
- // Check whether autocompletion for the search is enabled.
- // (This is also checked automatically later, so could be skipped here.)
- if (!empty($search->enabled)) {
- // If it is, pass the textfield for the search keywords to the
- // alterElement() method of the search object.
- $search->alterElement($form['keys']);
- }
- }
- /**
- * Implements hook_search_api_query_alter().
- *
- * This example hook implementation shows how a custom module could fix the
- * problem with Views contextual filters in a specific context.
- */
- function example_search_api_query_alter(SearchApiQueryInterface $query) {
- // Check whether this is an appropriate automcomplete query.
- if ($query->getOption('search id') === 'search_api_autocomplete:example') {
- // If it is, add the necessary filters that would otherwise be added by
- // contextual filters. This is easy if the argument comes from the global
- // user or a similar global source. If the argument comes from the URL or
- // some other page-specific source, however, you would need to somehow pass
- // that information along to this function.
- global $user;
- $query->condition('group', $user->data['group']);
- }
- }
|