View source  
  <?php
define('SEARCH_API_LIVE_RESULTS_METHOD_OR', 1);
define('SEARCH_API_LIVE_RESULTS_METHOD_AND', 2);
define('SEARCH_API_LIVE_RESULTS_METHOD_KEYWORD', 3);
require_once 'search_api_live_results.search_api_page.inc';
require_once 'search_api_live_results.search_api_views.inc';
function search_api_live_results_menu() {
  $path = drupal_get_path('module', 'search_api_live_results');
  
  $items['search_api_live_results/%search_api_live_results_search'] = array(
    'title' => 'Search API live results',
    'page callback' => 'search_api_live_results_json',
    'page arguments' => array(
      1,
    ),
    'access arguments' => array(
      'use_search_api_live_results',
    ),
    'type' => MENU_CALLBACK,
    'file' => 'search_api_live_results.pages.inc',
    'file path' => $path . '/includes',
  );
  
  $items['admin/config/search/search_api/index/%search_api_index/live-results'] = array(
    'title' => 'Live results',
    'description' => 'Add live results to searches for this index.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_live_results_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_live_results.admin.inc',
    'file path' => $path . '/includes',
  );
  $items['admin/config/search/search_api/index/%/live-results/%search_api_live_results_search/edit'] = array(
    'title' => 'Edit live results settings',
    'description' => 'Edit the live results settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_live_results_admin_search_edit',
      7,
    ),
    'access arguments' => array(
      'administer search_api',
    ),
    'file' => 'search_api_live_results.admin.inc',
    'file path' => $path . '/includes',
  );
  $items['admin/config/search/search_api/index/%/live-results/%search_api_live_results_search/delete'] = array(
    'title' => 'Delete live results settings',
    'description' => 'Delete the live results settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'search_api_live_results_admin_search_delete',
      7,
    ),
    'access arguments' => array(
      'administer search_api',
    ),
    'file' => 'search_api_live_results.admin.inc',
    'file path' => $path . '/includes',
  );
  return $items;
}
function search_api_live_results_entity_info() {
  $info['search_api_live_results_search'] = array(
    'label' => t('Live results search'),
    'controller class' => 'EntityAPIControllerExportable',
    'entity class' => 'SearchApiLiveResultsSearch',
    'base table' => 'search_api_live_results_search',
    'uri callback' => 'search_api_live_results_search_url',
    'module' => 'search_api_live_results',
    'exportable' => TRUE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'machine_name',
      'label' => 'name',
    ),
  );
  return $info;
}
function search_api_live_results_permission() {
  return array(
    'use_search_api_live_results' => array(
      'title' => t('Use live result search'),
    ),
  );
}
function search_api_live_results_theme($existing, $type, $theme, $path) {
  return array(
    'live_results_search' => array(
      'render element' => 'element',
    ),
  );
}
function theme_live_results_search($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'text';
  element_set_attributes($element, array(
    'id',
    'name',
    'value',
    'size',
    'maxlength',
  ));
  _form_set_class($element, array(
    'form-text',
  ));
  $extra = '';
  if ($element['#autocomplete_path']) {
    $parts = explode("/", $element['#autocomplete_path']);
    
    $search = search_api_live_results_search_load(array_pop($parts));
    drupal_add_library('system', 'drupal.autocomplete');
    drupal_add_js(drupal_get_path('module', 'search_api_live_results') . '/js/search_api_live_results.js');
    drupal_add_js(array(
      'search_api_live_results' => array(
        'min_length' => $search->options['min_length'] != NULL ? intval($search->options['min_length']) : 3,
        'auto_hide' => isset($search->options['auto_hide']) && $search->options['auto_hide'] == 0 ? FALSE : TRUE,
      ),
    ), 'setting');
    $element['#attributes']['class'][] = 'form-autocomplete';
    $element['#attributes']['class'][] = 'live-results-search-textfield';
    $attributes = array();
    $attributes['type'] = 'hidden';
    $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
    $query = array();
    if (isset($element['#autocomplete_query'])) {
      $query = $element['#autocomplete_query'];
      $element['#attributes']['class'][] = 'caching-method-enabled';
    }
    $attributes['value'] = url($element['#autocomplete_path'], array(
      'absolute' => TRUE,
      'query' => $query,
    ));
    $attributes['disabled'] = 'disabled';
    $attributes['class'][] = 'live-result-autocomplete';
    $extra = '<input' . drupal_attributes($attributes) . ' />';
  }
  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
  return $output . $extra;
}
function search_api_live_results_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['live_results_search'] = array(
    'label' => t('Live results search'),
    'custom settings' => TRUE,
  );
  
}
function search_api_live_results_element_info() {
  return array(
    'live_results_search' => array(
      '#input' => TRUE,
      '#size' => 60,
      '#maxlength' => 128,
      '#autocomplete_path' => FALSE,
      '#process' => array(
        'ajax_process_form',
      ),
      '#theme' => 'live_results_search',
    ),
  );
}
function search_api_live_results_search_api_index_delete(SearchApiIndex $index) {
  if (!$index
    ->hasStatus(ENTITY_IN_CODE)) {
    $ids = db_query('SELECT id FROM {search_api_live_results_search} WHERE index_id = :id', array(
      ':id' => $index->machine_name,
    ))
      ->fetchCol();
    if ($ids) {
      entity_delete_multiple('search_api_live_results_search', $ids);
    }
  }
}
function search_api_live_results_search_api_live_results_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_live_results_pages_searches',
      'create query' => 'search_api_live_results_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_live_results_views_searches',
      'create query' => 'search_api_live_results_views_query',
    );
  }
  return $types;
}
function search_api_live_results_get_types($type = NULL) {
  $types =& drupal_static(__FUNCTION__);
  if (!isset($types)) {
    $types = module_invoke_all('search_api_live_results_types');
    drupal_alter('search_api_live_results_types', $types);
  }
  if (isset($type)) {
    return isset($types[$type]) ? $types[$type] : NULL;
  }
  return $types;
}
function search_api_live_results_search_load($id, $reset = FALSE) {
  $ret = search_api_live_results_search_load_multiple(array(
    $id,
  ), array(), $reset);
  return $ret ? reset($ret) : FALSE;
}
function search_api_live_results_search_load_multiple($ids = FALSE, array $conditions = array(), $reset = FALSE) {
  return entity_load_multiple_by_name('search_api_live_results_search', $ids, $conditions, $reset);
}
class SearchApiLiveResultsSearch extends Entity {
  
  
  public $id;
  
  public $machine_name;
  
  public $name;
  
  public $index_id;
  
  public $type;
  
  public $enabled;
  
  public $options = array();
  
  
  protected $index;
  
  protected $server;
  
  public function __construct(array $values = array()) {
    parent::__construct($values, 'search_api_live_results_search');
  }
  
  public function index() {
    if (!isset($this->index)) {
      $this->index = search_api_index_load($this->index_id);
      if (!$this->index) {
        $this->index = FALSE;
      }
    }
    return $this->index;
  }
  
  public function server() {
    if (!isset($this->server)) {
      if (!$this
        ->index() || !$this
        ->index()->server) {
        $this->server = FALSE;
      }
      else {
        $this->server = $this
          ->index()
          ->server();
        if (!$this->server) {
          $this->server = FALSE;
        }
      }
    }
    return $this->server;
  }
  
  public function alterElement(array &$element) {
    if (user_access('use_search_api_live_results')) {
      $element['#type'] = 'live_results_search';
      if (isset($this->options['caching']) && $this->options['caching']) {
        $element['#autocomplete_path'] = drupal_get_path('module', 'search_api_live_results') . '/search_api_live_results.results.php';
        $element['#autocomplete_query'] = array(
          'search' => $this->machine_name,
        );
      }
      else {
        $element['#autocomplete_path'] = 'search_api_live_results/' . $this->machine_name;
      }
    }
  }
  
  public function getQuery($keys) {
    $info = search_api_live_results_get_types($this->type);
    if (empty($info['create query'])) {
      return NULL;
    }
    $query = $info['create query']($this, $keys);
    return $query;
  }
}