You are here

search_api_federated_solr.module in Search API Federated Solr 8.3

Contains hook implementations for the Federated Solr Search API Module.

File

search_api_federated_solr.module
View source
<?php

/**
 * @file
 * Contains hook implementations for the Federated Solr Search API Module.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\search_api\IndexInterface;

/**
 * Implements hook_help().
 */
function search_api_federated_solr_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the search_api_federated_solr module.
    case 'help.page.search_api_federated_solr':
      $text = '<p>' . t('This help text uses Markdown. Install the <a href="@markdown">Markdown module</a> or <a href="@readme">view it online</a> for easier reading', [
        '@markdown' => 'https://www.drupal.org/project/markdown',
        '@readme' => 'https://git.drupalcode.org/project/search_api_federated_solr',
      ]) . '</p>';
      $text .= file_get_contents(dirname(__FILE__) . '/README.md');
      if (!\Drupal::moduleHandler()
        ->moduleExists('markdown')) {
        return search_api_federated_solr_parse_help($text);
      }
      else {

        // Use the Markdown filter to render the README.
        $filter_manager = \Drupal::service('plugin.manager.filter');
        $settings = \Drupal::configFactory()
          ->get('markdown.settings')
          ->getRawData();
        $config = [
          'settings' => $settings,
        ];
        $filter = $filter_manager
          ->createInstance('markdown', $config);
        return $filter
          ->process($text, 'en');
      }
  }
  return NULL;
}

/**
 * Implements hook_theme().
 */
function search_api_federated_solr_theme($existing, $type, $theme, $path) {
  return [
    'search_app' => [
      'variables' => [
        'federated_search_app_config' => NULL,
      ],
    ],
    'search_api_federated_solr_block' => [
      'variables' => [
        'search_form' => NULL,
      ],
    ],
    'search_api_federated_solr_block_form' => [
      'render element' => 'form',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function search_api_federated_solr_theme_suggestions_input_alter(&$suggestions, array $variables) {
  $element = $variables['element'];
  if (isset($element['#provider']) && $element['#provider'] == 'search_api_federated_solr') {
    $suggestions[] = 'input__' . $element['#provider'] . '__' . $element['#type'];
  }
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function search_api_federated_solr_theme_suggestions_form_element_alter(&$suggestions, array $variables) {
  $element = $variables['element'];
  if (isset($element['#provider']) && $element['#provider'] == 'search_api_federated_solr') {
    $suggestions[] = 'form_element__' . $element['#provider'] . '__' . $element['#type'];
  }
}

/**
 * Change the way the index's field names are mapped to Solr field names.
 *
 * @param \Drupal\search_api\IndexInterface $index
 *   The index whose field mappings are altered.
 * @param array $fields
 *   An associative array containing the index field names mapped to their Solr
 *   counterparts. The special fields 'search_api_id' and 'search_api_relevance'
 *   are also included.
 */
function search_api_federated_solr_search_api_solr_field_mapping_alter(IndexInterface $index, array &$fields) {
  $singleFieldsMap = [
    // Field name => new single value for solr.
    "url" => "ss_url",
  ];

  // Iterate through the index fields and remap solr values where necessary.
  foreach (array_keys($fields) as $key) {

    // If this field is in our singleFieldsMap, remap it to its single value.
    if (array_key_exists($key, $singleFieldsMap)) {
      $fields[$key] = $singleFieldsMap[$key];
    }

    // Map all "mapped_field" property fields to their single value in solr.
    $field = $index
      ->getField($key);
    if (method_exists($field, 'getPropertyPath') && 'mapped_field' == $field
      ->getPropertyPath()) {
      $fields[$key] = preg_replace("/^(\\w)m_/", "\$1s_", $fields[$key], 1);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for the federated_search_page_block_form form.
 *
 * Since the exposed form is a GET form, we don't want it to send the form
 * tokens. However, you cannot make this happen in the form builder function
 * itself, because the tokens are added to the form after the builder function
 * is called. So, we have to do it in a form_alter.
 *
 * @see \Drupal\search_api_federated_solr\Form\FederatedSearchPageBlockForm
 */
function search_api_federated_solr_form_federated_search_page_block_form_alter(&$form, FormStateInterface $form_state) {
  $form['form_build_id']['#access'] = FALSE;
  $form['form_token']['#access'] = FALSE;
  $form['form_id']['#access'] = FALSE;
}

/**
 * Simplified display of help text without markdown module.
 *
 * @param $text
 *   The help text markdown.
 *
 * @return HTML
 */
function search_api_federated_solr_parse_help($text) {
  $find = "```\n\n";
  $replace = '</pre>';
  $text = str_replace($find, $replace, $text);
  $find = "```";
  $replace = '<pre>';
  $text = str_replace($find, $replace, $text);
  $find = [
    "\n",
  ];
  $replace = [
    '<br />',
  ];
  $text = str_replace($find, $replace, $text);
  return $text;
}

/**
 * Alter Solr documents before they are sent to Solr for indexing.
 *
 * @param \Solarium\QueryType\Update\Query\Document[] $documents
 *   An array of \Solarium\QueryType\Update\Query\Document\Document objects
 *   ready to be indexed, generated from $items array.
 * @param \Drupal\search_api\IndexInterface $index
 *   The search index for which items are being indexed.
 * @param \Drupal\search_api\Item\ItemInterface[] $items
 *   An array of items to be indexed, keyed by their item IDs.
 */
function search_api_federated_solr_search_api_solr_documents_alter(array &$documents, \Drupal\search_api\IndexInterface $index, array $items) {

  // The 8.x-3.x version of Search API Solr behaves differently from 7.x-1.x.
  // Notably, it uses Hungarian notation for fulltext fields, such that
  // "tm_rendered_item" is indexed as "tm_X3b_en_rendered_item". We rely on consistent
  // field naming, so have to coerce that field and the "content" field, which
  // are used by the schema from Drupal 7.
  foreach ($documents as $document) {
    $fields = $document
      ->getFields();
    foreach ($fields as $field_id => $field) {

      // The Drupal 8 schema passes 'sort_', so ignore that. We only index the
      // default language, and Drupal 8 is language-sensitive. So we find items
      // that are named 'tm_*_LANGCODE_rendered_item' and use those.
      $default_language_id = \Drupal::languageManager()
        ->getDefaultLanguage()
        ->getId();
      $string = $default_language_id . '_rendered_item';
      if (substr_count($field_id, $string) > 0 && substr_count($field_id, 'sort_') === 0) {
        $boost = $document
          ->getFieldBoost($field_id);
        $modifier = $document
          ->getFieldModifier($field_id);

        // The 'content' field is the generic handler for the Drupal 7 schema version.
        if (is_array($field)) {
          $string = implode(" ", $field);
          if (!is_null($string)) {
            $document
              ->setField('content', $string, $boost, $modifier);
          }
        }

        // The 'tm_rendered_item' field is required by the application.
        $document
          ->setField('tm_rendered_item', $field, $boost, $modifier);
      }
    }
  }
}

Functions