diff --git a/search_api_autocomplete.info b/search_api_autocomplete.info index 0d6ab24..c72391b 100644 --- a/search_api_autocomplete.info +++ b/search_api_autocomplete.info @@ -8,3 +8,4 @@ files[] = search_api_autocomplete.entity.php files[] = src/SearchApiAutocompleteSuggesterInterface.php files[] = src/SearchApiAutocompleteSuggesterPluginBase.php files[] = src/SearchApiAutocompleteServerSuggester.php +files[] = src/SearchApiAutocompleteLiveResultsSuggester.php diff --git a/search_api_autocomplete.module b/search_api_autocomplete.module index d107552..2957685 100644 --- a/search_api_autocomplete.module +++ b/search_api_autocomplete.module @@ -47,6 +47,12 @@ function search_api_autocomplete_search_api_autocomplete_suggester_info() { '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; } @@ -140,6 +146,20 @@ function search_api_autocomplete_entity_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() { diff --git a/search_api_autocomplete.pages.inc b/search_api_autocomplete.pages.inc index 3cb2821..13c1e21 100644 --- a/search_api_autocomplete.pages.inc +++ b/search_api_autocomplete.pages.inc @@ -36,54 +36,59 @@ function search_api_autocomplete_autocomplete(SearchApiAutocompleteSearch $searc $query->preExecute(); $suggestions = $search->getSuggester()->getAutocompleteSuggestions($query, $incomplete, $keys); if ($suggestions) { - foreach ($suggestions as $suggestion) { + foreach ($suggestions as $suggestion) { + // If we want to render the suggestion. + if(isset($suggestion['render'])) { + $ret[] = $suggestion; // Convert suggestion strings into an array. - if (is_string($suggestion)) { - $pos = strpos($suggestion, $keys); - if ($pos === FALSE) { - $suggestion = array( - 'user_input' => '', - 'suggestion_suffix' => $suggestion, - ); + } else { + if (is_string($suggestion)) { + $pos = strpos($suggestion, $keys); + if ($pos === FALSE) { + $suggestion = array( + 'user_input' => '', + 'suggestion_suffix' => $suggestion, + ); + } + else { + $suggestion = array( + 'suggestion_prefix' => substr($suggestion, 0, $pos), + 'user_input' => $keys, + 'suggestion_suffix' => substr($suggestion, $pos + strlen($keys)), + ); + } } - else { - $suggestion = array( - 'suggestion_prefix' => substr($suggestion, 0, $pos), - 'user_input' => $keys, - 'suggestion_suffix' => substr($suggestion, $pos + strlen($keys)), - ); + // Add defaults. + $suggestion += array( + 'url' => NULL, + 'keys' => NULL, + 'prefix' => NULL, + 'suggestion_prefix' => '', + 'user_input' => $keys, + 'suggestion_suffix' => '', + 'results' => NULL, + ); + if (empty($search->options['results'])) { + unset($suggestion['results']); } - } - // Add defaults. - $suggestion += array( - 'url' => NULL, - 'keys' => NULL, - 'prefix' => NULL, - 'suggestion_prefix' => '', - 'user_input' => $keys, - 'suggestion_suffix' => '', - 'results' => NULL, - ); - if (empty($search->options['results'])) { - unset($suggestion['results']); - } - // Decide what the action of the suggestion is – entering specific - // search terms or redirecting to a URL. - if (isset($suggestion['url'])) { - $key = ' ' . $suggestion['url']; - } - else { - // Also set the "keys" key so it will always be available in alter - // hooks and the theme function. - if (!isset($suggestion['keys'])) { - $suggestion['keys'] = $suggestion['suggestion_prefix'] . $suggestion['user_input'] . $suggestion['suggestion_suffix']; + // Decide what the action of the suggestion is – entering specific + // search terms or redirecting to a URL. + if (isset($suggestion['url'])) { + $key = ' ' . $suggestion['url']; + } + else { + // Also set the "keys" key so it will always be available in alter + // hooks and the theme function. + if (!isset($suggestion['keys'])) { + $suggestion['keys'] = $suggestion['suggestion_prefix'] . $suggestion['user_input'] . $suggestion['suggestion_suffix']; + } + $key = trim($suggestion['keys']); } - $key = trim($suggestion['keys']); - } - if (!isset($ret[$key])) { - $ret[$key] = $suggestion; + if (!isset($ret[$key])) { + $ret[$key] = $suggestion; + } } } diff --git a/src/SearchApiAutocompleteLiveResultsSuggester.php b/src/SearchApiAutocompleteLiveResultsSuggester.php new file mode 100644 index 0000000..63956b3 --- /dev/null +++ b/src/SearchApiAutocompleteLiveResultsSuggester.php @@ -0,0 +1,129 @@ +server() && $index->server()->supportsFeature('search_api_autocomplete'); + } + catch (SearchApiException $e) { + return FALSE; + } + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array( + 'fields' => array(), + ); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, array &$form_state) { + // Add a list of fields to include for autocomplete searches. + $search = $this->getSearch(); + $fields = $search->index()->getFields(); + $fulltext_fields = $search->index()->getFulltextFields(); + $options = array(); + + foreach ($fulltext_fields as $field) { + $options[$field] = check_plain($fields[$field]['name']); + } + + $form['display'] = array( + '#type' => 'radios', + '#title' => t('Display method'), + '#description' => t('The way the results should be displayed.'), + '#default_value' => !empty($this->configuration['display']), + '#options' => array( + 'view_mode' => t("Use view mode: 'Live result search' to display results"), + 'title' => t("Only show title (linked to node)"), + ), + '#default_value' => (!empty($this->configuration['display'])) ? $this->configuration['display'] : 'title', + ); + + $form['fields'] = array( + '#type' => 'checkboxes', + '#title' => t('Override used fields'), + '#description' => t('Select the fields which should be searched for matches when looking for autocompletion suggestions. Leave blank to use the same fields as the underlying search.'), + '#options' => $options, + '#default_value' => drupal_map_assoc($this->configuration['fields']), + '#attributes' => array('class' => array('search-api-checkboxes-list')), + ); + $form['#attached']['css'][] = drupal_get_path('module', 'search_api') . '/search_api.admin.css'; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array $form, array &$form_state) { + $values = $form_state['values']; + $values['fields'] = array_keys(array_filter($values['fields'])); + $this->setConfiguration($values); + } + + /** + * {@inheritdoc} + */ + public function getAutocompleteSuggestions(SearchApiQueryInterface $query, $incomplete_key, $user_input) { + $search = $this->getSearch(); + + if ($this->configuration['fields']) { + $query->fields($this->configuration['fields']); + } + + $results = $query->execute(); + $ret = array(); + $ids = array(); + foreach ((array) $results['results'] as $result) { + $ids[] = $result['id']; + } + $render = NULL; + if(!empty($ids)) { + // Load all searched suggested entities. + $entity_type = $search->index()->item_type; + $entities = entity_load($entity_type, $ids); + + if ($this->configuration['display'] == 'view_mode') { + $entity_view = entity_view($entity_type, $entities, 'live_results_search'); + } + + foreach($entities as $id => $entity) { + if ($entity_view) { + $render = drupal_render($entity_view[$entity_type][$id]); + } + else { + $url = entity_uri($entity_type, $entity); + $render = l($entity->title, $url['path']); + } + $ret[] = array( + 'entity' => $entity, + 'render' => $render, + ); + } + } + + return $ret; + } + +}