You are here

search_api_elasticsearch_elastica.module in Search API Elasticsearch 7

Provides an elasticsearch-based service class for the Search API.

File

modules/elastica/search_api_elasticsearch_elastica.module
View source
<?php

/**
 * @file
 * Provides an elasticsearch-based service class for the Search API.
 */

/**
 * Implements hook_search_api_service_info().
 */
function search_api_elasticsearch_elastica_search_api_service_info() {
  $services['search_api_elasticsearch_elastica_service'] = array(
    'name' => t('Elasticsearch (via Elastica)'),
    'description' => t('
    <p>Index items using a !url_elasticsearch search server.</p>
    <ul>
    <li>All field types are supported.</li>
    <li>Search API facets are supported.</li>
    <li>More Like This searches are supported.</li>
    <li>Will use internal elasticsearch preprocessors, so Search API preprocessors should for the most part be deactivated.</li>
    <li>See the README.txt file provided with this module for details.</li>
    </ul>', array(
      '!url_elasticsearch' => '<a href="http://www.elasticsearch.org/">' . t('Elasticsearch') . '</a>',
    )),
    'class' => 'SearchApiElasticsearchElastica',
  );
  return $services;
}

/**
 * Check if the Elastica library is loaded.
 *
 * @return bool
 *   Returns TRUE if loaded.
 */
function search_api_elasticsearch_elastica_loaded() {
  $loaded =& drupal_static(__FUNCTION__);
  if (!isset($loaded)) {
    if (!class_exists('\\Elastica\\Client') && module_exists('composer_manager')) {
      drupal_load('module', 'composer_manager');
      composer_manager_register_autoloader();
    }
    elseif (!class_exists('\\Elastica\\Client')) {
      spl_autoload_register('_search_api_elasticsearch_elastica_autoload');
    }
    $loaded = class_exists('\\Elastica\\Client');
  }
  return $loaded;
}

/**
 * Return path to Elastica library path, or FALSE if not found.
 */
function _search_api_elasticsearch_elastica_path($reset = FALSE) {
  static $path = NULL;
  if ($reset === TRUE) {
    $path = NULL;
  }
  if (!isset($path)) {
    $path = FALSE;

    // If Libraries API is installed, we first use that to try and find the
    // library. Otherwise we manually check a few locations.
    $search_dirs = array();
    if (function_exists('libraries_get_path')) {
      $dir = libraries_get_path('Elastica');

      // Confusingly, Libraries API 1.x will return sites/all/libraries/NAME on
      // failure, while Libraries API 2.x returns FALSE in that case.
      if (!empty($dir)) {
        $search_dirs[] = $dir;
      }
    }
    else {
      $search_dirs[] = 'sites/all/libraries/Elastica';
    }
    $search_dirs[] = drupal_get_path('module', 'search_api_elasticsearch') . '/Elastica';
    foreach ($search_dirs as $dir) {
      $dir = DRUPAL_ROOT . '/' . $dir . '/lib';
      if (is_dir($dir)) {
        $path = $dir;
        break;
      }
    }
  }
  return $path;
}

/**
 * Autoloader for the Elastica classes.
 */
function _search_api_elasticsearch_elastica_autoload($name) {
  static $lookup_cache = array();
  if (isset($lookup_cache[$name])) {
    return $lookup_cache[$name];
  }
  elseif (drupal_substr($name, 0, 8) == 'Elastica') {
    $path = _search_api_elasticsearch_elastica_path();
    if (file_exists($file_path = $path . '/' . str_replace('\\', '/', $name) . '.php')) {
      require_once $file_path;
      $lookup_cache[$name] = TRUE;
      return TRUE;
    }
  }
  $lookup_cache[$name] = FALSE;
  return FALSE;
}

/**
 * Implements hook_form_alter().
 */
function search_api_elasticsearch_elastica_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'search_api_admin_add_index') {
    search_api_elasticsearch_attach_ajax_callback($form);
    if (isset($form_state['values']) && !empty($form_state['values'])) {
      $add_options = search_api_elasticsearch_elastica_add_options($form_state['values']['server']);
      if ($add_options != FALSE) {
        search_api_elasticsearch_elastica_return_form_options($form, $form_state, array(), 'add');
      }
    }
  }
  elseif ($form_id == 'search_api_admin_index_edit') {
    $default_values = $form_state['index']->options;
    search_api_elasticsearch_attach_ajax_callback($form);
    if (!isset($form_state['values'])) {
      if (isset($form_state['build_info']['args']) && !empty($form_state['build_info']['args'])) {
        $index_obj = reset($form_state['build_info']['args']);
        $add_options = search_api_elasticsearch_elastica_add_options($index_obj->server);
        if ($add_options != FALSE) {
          search_api_elasticsearch_elastica_return_form_options($form, $form_state, $default_values, 'edit');
        }
      }
    }
    else {
      $add_options = search_api_elasticsearch_elastica_add_options($form_state['values']['server']);
      if ($add_options != FALSE) {
        search_api_elasticsearch_elastica_return_form_options($form, $form_state, $default_values, 'edit');
      }
    }
  }
}

/**
 * The form options for add/edit index.
 *
 * @param array $form
 * @param array $default_values
 */
function search_api_elasticsearch_elastica_return_form_options(&$form, &$form_state, $default_values = array(), $flag) {
  $default_options = $default_values + array(
    'number_of_shards' => 1,
    'number_of_replicas' => 0,
  );
  $form['options']['number_of_shards'] = array(
    '#type' => 'textfield',
    '#default_value' => $default_options['number_of_shards'],
    '#size' => 4,
    '#title' => t('Number of shards'),
  );
  $form['options']['number_of_replicas'] = array(
    '#type' => 'textfield',
    '#default_value' => $default_options['number_of_replicas'],
    '#size' => 4,
    '#title' => t('Number of replicas'),
  );
  if ($flag == 'edit') {
    $form['#submit'][] = 'search_api_elasticsearch_edit_index_submit';
  }
  else {
    array_unshift($form['#submit'], 'search_api_elasticsearch_add_index_submit');
  }
}

/**
 * Add options common function.
 *
 * @param integer $server_machine_name
 */
function search_api_elasticsearch_elastica_add_options($server_machine_name) {
  if (isset($server_machine_name) && !empty($server_machine_name)) {
    $server_id = search_api_elasticsearch_get_server_id_by_name($server_machine_name);
    if ($server_id != FALSE) {
      $server_obj = search_api_server_load($server_id);
      if (isset($server_obj) && !empty($server_obj)) {
        if ($server_obj->class == 'search_api_elasticsearch_elastica_service') {
          return TRUE;
        }
      }
    }
  }
  return FALSE;
}

/**
 * Implements hook_search_api_index_reindex.
 * Since there is no way to put a mapping and settings on an index simultaneously,
 * we allow users to delete and remap an index by using the clear index feature.
 * This approximates the ElasticSearch recommendation to destroy and recreate
 * indices to update their configuration.
 */
function search_api_elasticsearch_elastica_search_api_index_reindex(SearchApiIndex $index, $clear = FALSE) {
  $server = search_api_index_get_server($index);

  // Only act on index provided by search_api_elasticsearch
  if ($clear && $server->class == "search_api_elasticsearch_elastica_service") {
    $server
      ->removeIndex($index);
    $server
      ->addIndex($index);
  }
}

Functions

Namesort descending Description
search_api_elasticsearch_elastica_add_options Add options common function.
search_api_elasticsearch_elastica_form_alter Implements hook_form_alter().
search_api_elasticsearch_elastica_loaded Check if the Elastica library is loaded.
search_api_elasticsearch_elastica_return_form_options The form options for add/edit index.
search_api_elasticsearch_elastica_search_api_index_reindex Implements hook_search_api_index_reindex. Since there is no way to put a mapping and settings on an index simultaneously, we allow users to delete and remap an index by using the clear index feature. This approximates the ElasticSearch recommendation…
search_api_elasticsearch_elastica_search_api_service_info Implements hook_search_api_service_info().
_search_api_elasticsearch_elastica_autoload Autoloader for the Elastica classes.
_search_api_elasticsearch_elastica_path Return path to Elastica library path, or FALSE if not found.