You are here

function apachesolr_multilingual_apachesolr_query_alter in Apache Solr Multilingual 6.3

Same name and namespace in other branches
  1. 7 apachesolr_multilingual.module \apachesolr_multilingual_apachesolr_query_alter()

Implements hook_apachesolr_modify_query().

File

./apachesolr_multilingual.module, line 481
Multilingual search using Apache Solr.

Code

function apachesolr_multilingual_apachesolr_query_alter($query) {
  global $language;
  $context = $query
    ->getContext();
  $environment = apachesolr_multilingual_environment_load($context['env_id']);
  $settings = $environment['conf']['apachesolr_multilingual_index_settings'];
  if ($settings['apachesolr_multilingual_index']) {
    $custom_settings = array();
    if ('apachesolr_search_mlt' == $context['search_type']) {

      // Add multilingual settings to mlt blocks like we do for search pages.
      // @see https://drupal.org/node/2056055
      $mlt_block_settings = apachesolr_search_mlt_block_load($context['block_id']);
      if ($mlt_block_settings && array_key_exists('apachesolr_multilingual_query_settings', $mlt_block_settings)) {
        $custom_settings = $mlt_block_settings['apachesolr_multilingual_query_settings'];
      }

      // Use mlt block is as page id later in this function.
      $context['page_id'] = $context['block_id'];
    }
    elseif (!empty($context['page_id'])) {

      // Load multilingual custom settings assigned to this search page.
      $search_page = apachesolr_search_page_load($context['page_id']);
      $custom_settings = $search_page['settings'];
    }
    else {

      // A custom query has been created by a third party module.
      // Assume default multilingual settings.
      // TODO This behavior should be somehow configurable.
    }

    // Add defaults for required settings to not yet saved multilingual custom settings.
    apachesolr_multilingual_search_page_settings_add_defaults($custom_settings);
    $filter_languages =& variable_static('apachesolr_multilingual_filter_languages_' . $context['page_id']);
    $filter_languages = apachesolr_multilingual_get_language_filters_by_query($query);
    $languages = apachesolr_multilingual_language_list();
    if (empty($filter_languages) && $custom_settings['apachesolr_multilingual_auto_language_filter'] && (!$custom_settings['apachesolr_multilingual_auto_language_filter_detachable'] || $custom_settings['apachesolr_multilingual_auto_language_filter_detachable'] && empty($_GET['detach-auto-language-filter']))) {
      if (!empty($language->language)) {
        $filter_languages[] = $language->language;
        if ($custom_settings['apachesolr_multilingual_show_language_undefined_results']) {
          $subquery = apachesolr_drupal_query('Multilingual Language Limit');
          $subquery
            ->addFilter('ss_language', $language->language);
          $subquery
            ->addFilter('ss_language', APACHESOLR_MULTILINGUAL_LANGUAGE_UND);
          $subquery->operator = 'OR';

          // that's the default, but this way it's readable
          $query
            ->addFilterSubQuery($subquery);
        }
        else {
          $query
            ->addFilter('ss_language', $language->language);
        }
      }
    }

    // When CLIR is activated we want to search all language specific fields
    if (!$settings['apachesolr_multilingual_clir']['apachesolr_multilingual_index_translations']) {

      // Per default the 'query fields' contain all language un-specific and
      // specific fields.
      // If the query filters by language we have to remove all unnecessary
      // language specific fields.
      // For the remaining language specific fields we have to apply the boosts as
      // apachesolr_search_add_boost_params() will do for the unspecific ones.
      $qf = $query
        ->getParam('qf');
      foreach ($qf as $index => $field) {
        if (strpos($field, 'i18n_') === 0) {
          if (!empty($filter_languages)) {
            $remove = TRUE;
            foreach ($filter_languages as $filter_language) {
              if (preg_match('@_' . $filter_language . '(\\^|_)@', $field)) {
                $remove = FALSE;
                break;
              }
            }
            if ($remove) {
              unset($qf[$index]);
              continue;
            }
          }

          // Because apachesolr_search_add_boost_params() does not recognize the
          // the i18n_* prefix we have to apply the same logic here to add the
          // extra boost to language specific normed fields.
          if (strpos($field, 'i18n_content') === 0 || strpos($field, 'i18n_ts_') === 0 || strpos($field, 'i18n_tm_') === 0) {
            list($field_name, $boost) = explode('^', $field);

            // Normed fields tend to have a lower score. Multiplying by 40 is
            // a rough attempt to bring the score in line with fields that are
            // not normed.
            $qf[$index] = $field_name . '^' . sprintf('%.1F', 40.0 * $boost);
          }
        }
      }
      $query
        ->replaceParam('qf', $qf);
    }

    // Add the teaser to the result fields, because apachesolr_search_run()
    // won't do it anymore if highlighting parameters are set here.
    $query
      ->addParam('fl', 'teaser');
    $hl_fl_removed = FALSE;
    foreach (array_keys($languages) as $language_id) {
      if (!empty($filter_languages) && !in_array($language_id, $filter_languages)) {
        continue;
      }
      if (!$hl_fl_removed) {

        // Remove all language un-specific fields from highlighting before
        // adding language specific ones.
        $query
          ->removeParam('hl.fl');
        $hl_fl_removed = TRUE;
      }

      // TODO avoid snippets in case of CLIR because these might come from machine translation which should be hidden.
      $query
        ->addParam('hl.fl', 'i18n_content_' . $language_id);
      $query
        ->addParam('f.i18n_content_' . $language_id . '.hl.alternateField', 'i18n_teaser_' . $language_id);
      $query
        ->addParam('hl.fl', 'i18n_ts_' . $language_id . '_comments');
    }
  }
}