apachesolr_multilingual.module in Apache Solr Multilingual 6
Same filename and directory in other branches
Multilingual search using Apache Solr.
@author Markus Kalkbrenner (mkalkbrenner) | Cocomore AG
File
apachesolr_multilingual.moduleView source
<?php
/**
* @file
* Multilingual search using Apache Solr.
*
* @see apachesolr.module
*
* @author Markus Kalkbrenner (mkalkbrenner) | Cocomore AG
* @see http://drupal.org/user/124705
* @see http://drupal.cocomore.com
*/
/**
* Implements hook_nodeapi().
*
* @param $node
* @param $op
* @param $a3
* @param $a4
* @return mixed
*/
function apachesolr_multilingual_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'delete':
case 'insert':
case 'update':
if (variable_get('apachesolr_multilingual_index_translations', 0) && !empty($node->tnid)) {
$translations = translation_node_get_translations($node->tnid);
foreach ($translations as $language => $translation) {
if ($translation->nid != $node->nid) {
if ($translation_node = node_load($translation->nid)) {
_apachesolr_nodeapi_update($translation_node);
}
}
}
}
break;
}
}
/**
* Implements hook_apachesolr_update_index().
*
* @param $document
* @param $node
* @param $namespace
* @return mixed
*/
function apachesolr_multilingual_apachesolr_update_index(&$document, $node, $namespace) {
static $reentrance = FALSE;
if (!$reentrance) {
$reentrance = TRUE;
$language = $node->language;
if (!$language) {
// Language neutral
$language = variable_get('apachesolr_multilingual_map_language_neutral', '');
if ($language) {
$document->language = $node->language = $language;
}
}
if ($language) {
if (is_array($document->vid)) {
// vid is vocabulary id in this case
$term_languages = array(
$language,
);
if (module_exists('i18ntaxonomy') && variable_get('apachesolr_multilingual_index_term_translations', 0)) {
$term_languages = variable_get('apachesolr_multilingual_languages', array());
}
foreach ($term_languages as $term_language) {
if ($term_language) {
$vids = array_unique($document->vid);
$terms = array();
foreach ($vids as $vid) {
if (module_exists('i18ntaxonomy')) {
$tmp = '';
foreach ($document->{'im_vid_' . $vid} as $tid) {
$term = i18nstrings("taxonomy:term:{$tid}:name", '', $term_language);
if (!empty($term)) {
$tmp .= $term . ' ';
}
}
if (!empty($tmp)) {
$terms[] = $tmp;
}
}
else {
// module i18ntaxonomy isn't installed
// in this case we simply copy the terms
$terms[] = $document->{'ts_vid_' . $vid . '_names'};
// REVIEW see http://drupal.org/node/783924
}
}
if ($terms) {
$document->{'taxonomy_names_' . $term_language} = $terms;
}
}
}
}
// use language specific stemming and so on ..
$document->{'title_' . $language} = $document->title;
$document->{'body_' . $language} = $document->body;
$document->{'tags_h1_' . $language} = $document->tags_h1;
$document->{'tags_h2_h3_' . $language} = $document->tags_h2_h3;
$document->{'tags_h4_h5_h6_' . $language} = $document->tags_h4_h5_h6;
$document->{'tags_a_' . $language} = $document->tags_a;
$document->{'tags_inline_' . $language} = $document->tags_inline;
$solr = apachesolr_get_solr();
$fields = $solr
->getFields();
foreach ($fields as $field_name => $field) {
if (strpos($field_name, 'ts_') === 0 && !empty($document->{$field_name})) {
// deal with fields like cck using dynamic ts_* fields
// search for existing language identifier at second position
$tmp = explode('_', $field_name);
if ($language != $tmp[1]) {
$document->{'ts_' . $language . drupal_substr($field_name, 2)} = $document->{$field_name};
}
}
}
if (variable_get('apachesolr_multilingual_index_translations', 0) && $node->tnid) {
$translations = translation_node_get_translations($node->tnid);
foreach ($translations as $translation_language => $translation) {
if ($translation->nid != $node->nid) {
if ($translation_document = apachesolr_node_to_document($translation->nid, $namespace)) {
$document->{'title_' . $translation_language} = $translation_document->title;
$document->{'body_' . $translation_language} = $translation_document->body;
$document->{'tags_h1_' . $translation_language} = $translation_document->tags_h1;
$document->{'tags_h2_h3_' . $translation_language} = $translation_document->tags_h2_h3;
$document->{'tags_h4_h5_h6_' . $translation_language} = $translation_document->tags_h4_h5_h6;
$document->{'tags_a_' . $translation_language} = $translation_document->tags_a;
$document->{'tags_inline_' . $translation_language} = $translation_document->tags_inline;
foreach ($fields as $field_name => $field) {
if (strpos($field_name, 'ts_') === 0 && !empty($translation_document->{$field_name})) {
// deal with fields like cck using dynamic ts_* fields
// search for existing language identifier at second position
$tmp = explode('_', $field_name);
if ($translation_language != $tmp[1]) {
$document->{'ts_' . $translation_language . drupal_substr($field_name, 2)} = $translation_document->{$field_name};
}
}
}
}
}
}
}
}
$reentrance = FALSE;
}
}
/**
* Implements hook_form_alter().
*
* By default we only show text fields. Use hook_form_alter to change.
*
* @param $form
* @param $state
* @param $form_id
* @return mixed
*/
function apachesolr_multilingual_form_alter(&$form, $form_state, $form_id) {
if ('apachesolr_search_settings_form' == $form_id) {
$active_languages = locale_language_list();
$solr = apachesolr_get_solr();
$fields = $solr
->getFields();
$form['apachesolr_search_query_fields']['#description'] .= '<br />' . t('<b>Note:</b> If you are missing some language specific fields here you have to index some corresponding content first.');
$qf = variable_get('apachesolr_search_query_fields', array());
// Note - we have default values set in solrconfig.xml, which will operate
// when none are set. That's the preferred state.
$defaults = array(
'body' => '1.0',
'title' => '5.0',
'name' => '3.0',
'taxonomy_names' => '2.0',
'tags_h1' => '5.0',
'tags_h2_h3' => '3.0',
'tags_h4_h5_h6' => '2.0',
'tags_inline' => '1.0',
'tags_a' => '0',
);
if (!$qf) {
$qf = $defaults;
}
foreach ($fields as $field_name => $field) {
// Only indexed fields are searchable.
if ($field->schema[0] == 'I') {
if ('text' != $field->type && strpos($field->type, 'text') === 0 && strpos($field->type, 'textSpell') !== 0) {
// search for language identifier at last or second position
$tmp = explode('_', $field_name);
$lang = array_pop($tmp);
if (empty($active_languages[$lang])) {
$tmp[] = $lang;
if (!empty($active_languages[$tmp[1]])) {
$lang = $tmp[1];
unset($tmp[1]);
}
}
if (!empty($active_languages[$lang])) {
$base_field_name = implode('_', $tmp);
$form['apachesolr_search_query_fields'][$base_field_name]['#description'] = t('Recommended to "Omit". Use language specific fields instead.');
$form['apachesolr_search_query_fields'][$field_name]['#access'] = TRUE;
if (!array_key_exists($field_name, $qf)) {
$form['apachesolr_search_query_fields'][$field_name]['#default_value'] = isset($qf[$base_field_name]) ? $qf[$base_field_name] : '0';
}
}
}
}
}
}
}
/**
* Implements hook_apachesolr_field_name_map_alter().
*/
function apachesolr_multilingual_apachesolr_field_name_map_alter(&$map) {
$active_languages = locale_language_list();
$solr = apachesolr_get_solr();
$fields = $solr
->getFields();
foreach ($fields as $field_name => $field) {
// Only indexed fields are searchable.
if ($field->schema[0] == 'I') {
if ('text' != $field->type && strpos($field->type, 'text') === 0 && strpos($field->type, 'textSpell') !== 0) {
// serach for language identifier at last or second position within the field name
$tmp = explode('_', $field_name);
$lang = array_pop($tmp);
if (empty($active_languages[$lang])) {
$tmp[] = $lang;
if (!empty($active_languages[$tmp[1]])) {
$lang = $tmp[1];
unset($tmp[1]);
}
}
$base_field_name = implode('_', $tmp);
if (!empty($active_languages[$lang])) {
$map[$field_name] = '<em>' . $active_languages[$lang] . '</em> - ' . $map[$base_field_name];
}
}
}
}
}
/**
* Implements hook_menu().
*/
function apachesolr_multilingual_menu() {
$items = array();
$items['admin/settings/apachesolr/multilingual'] = array(
'title' => 'Multilingual',
'weight' => 0,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_multilingual_admin_form',
),
'file' => 'apachesolr_multilingual.admin.inc',
'access arguments' => array(
'administer search',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/settings/apachesolr/schema_generator'] = array(
'title' => 'Config files',
'weight' => 10,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_multilingual_schema_generator_form',
),
'file' => 'apachesolr_multilingual.schema_generator.inc',
'access arguments' => array(
'administer search',
),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Helper funktion that returns the name of a stemmer
* if available
*
* @param string
* the language id
*
* @return string
* the name of the stemmer
*/
function apachesolr_multilingual_get_stemmer($language_id) {
static $available_stemmers = array(
'da' => 'Danish',
'nl' => 'Dutch',
'en' => 'English',
'fi' => 'Finnish',
'fr' => 'French',
'de' => 'German',
'it' => 'Italian',
'nn' => 'Norwegian',
'nb' => 'Norwegian',
'pt-br' => 'Portuguese',
'pt-pt' => 'Portuguese',
'ro' => 'Romanian',
'ru' => 'Russian',
'es' => 'Spanish',
'sv' => 'Swedish',
'tr' => 'Turkish',
);
if (array_key_exists($language_id, $available_stemmers)) {
return $available_stemmers[$language_id];
}
return FALSE;
}
/**
* Implements hook_apachesolr_modify_query().
*/
function apachesolr_multilingual_apachesolr_modify_query(&$query, &$params, $caller) {
global $language;
$filter_language = '';
// We assume that a user is not able to select two different languages as filter
$language_filters = $query
->get_filters('language');
if (!empty($language_filters)) {
$filter_language = $language_filters[0]['#value'];
}
$languages = variable_get('apachesolr_multilingual_languages', array());
if (!$filter_language && variable_get('apachesolr_multilingual_auto_language_filter', 0) && (!variable_get('apachesolr_multilingual_auto_language_filter_detachable', 0) || variable_get('apachesolr_multilingual_auto_language_filter_detachable', 0) && empty($_GET['detach-auto-language-filter']))) {
if (!empty($language->language)) {
if (in_array($language->language, $languages)) {
$filter_language = $language->language;
$query
->add_filter('language', $filter_language);
}
}
elseif (variable_get('apachesolr_multilingual_map_language_neutral', '')) {
$filter_language = variable_get('apachesolr_multilingual_map_language_neutral', '');
if ($filter_language) {
$query
->add_filter('language', $filter_language);
}
}
}
if (empty($params['hl.fl'])) {
$params['hl.fl'] = 'body';
}
if ($filter_language && in_array($filter_language, $languages)) {
$solr = apachesolr_get_solr();
$fields = $solr
->getFields();
$highlighted_fields = explode(',', $params['hl.fl']);
foreach ($highlighted_fields as $key => $highlighted_field) {
if (array_key_exists($highlighted_field . '_' . $filter_language, $fields)) {
// title, body, spell
$highlighted_fields[$key] .= '_' . $filter_language;
}
elseif (strpos('ts_', $highlighted_field) === 0 && strpos('ts_' . $filter_language, $highlighted_field) !== 0) {
$highlighted_fields[$key] = 'ts_' . $filter_language . substr($highlighted_field, 2);
}
elseif (strpos('tm_', $highlighted_field) === 0 && strpos('tm_' . $filter_language, $highlighted_field) !== 0) {
$highlighted_fields[$key] = 'tm_' . $filter_language . substr($highlighted_field, 2);
}
}
$params['hl.fl'] = implode(',', $highlighted_fields);
if (variable_get('apachesolr_search_spellcheck', FALSE) && array_key_exists('spell_' . $filter_language, $fields)) {
$params['spellcheck.dictionary'] = 'spellchecker_' . $filter_language;
}
}
}
/**
* Implements hook_form_search_form_alter().
*
* @param $form
* @param $form_state
*/
function apachesolr_multilingual_form_search_form_alter(&$form, $form_state) {
if ($form['module']['#value'] == 'apachesolr_search') {
if (variable_get('apachesolr_multilingual_auto_language_filter', 0) && variable_get('apachesolr_multilingual_auto_language_filter_detachable', 0)) {
$lang_filter = !empty($_GET['filters']) && strpos($_GET['filters'], 'language:') !== FALSE;
$form['basic']['apachesolr_search']['detach_auto_language_filter'] = array(
'#type' => $lang_filter ? 'hidden' : 'checkbox',
'#title' => t('Search all languages'),
'#default_value' => isset($_GET['detach-auto-language-filter']),
);
$form['#submit'] = array_merge(array(
'apachesolr_multilingual_form_search_submit',
), $form['#submit']);
}
}
}
/**
* @see apachesolr_multilingual_form_search_form_alter()
*/
function apachesolr_multilingual_form_search_submit($form, &$form_state) {
$fv = $form_state['values'];
if (!empty($fv['apachesolr_search']['get'])) {
$get = json_decode($fv['apachesolr_search']['get'], TRUE);
if (!empty($fv['apachesolr_search']['detach_auto_language_filter'])) {
$get['detach-auto-language-filter'] = '1';
}
elseif (isset($get['detach-auto-language-filter'])) {
unset($get['detach-auto-language-filter']);
}
$form_state['values']['apachesolr_search']['get'] = json_encode($get);
}
}
/**
* Implements hook_apachesolr_facets().
*/
function apachesolr_multilingual_apachesolr_facets() {
$facets['apachesolr_multilingual_language'] = array(
'info' => t('Apache Solr Multilingual: Filter by Language'),
'facet_field' => 'language',
);
return $facets;
}
/**
* Implements hook_block().
*/
function apachesolr_multilingual_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$enabled_facets = apachesolr_get_enabled_facets('apachesolr_multilingual');
$facets = apachesolr_multilingual_apachesolr_facets();
// Add the blocks
$blocks = array();
foreach ($enabled_facets as $delta => $facet_field) {
if (isset($facets[$delta])) {
$blocks[$delta] = $facets[$delta] + array(
'cache' => BLOCK_CACHE_PER_PAGE,
);
}
}
return $blocks;
case 'view':
if (apachesolr_has_searched()) {
$response = apachesolr_static_response_cache();
if (empty($response)) {
return;
}
$query = apachesolr_current_query();
$facets = apachesolr_multilingual_apachesolr_facets();
switch ($delta) {
case 'apachesolr_multilingual_language':
if (!variable_get('apachesolr_multilingual_auto_language_filter', 0) || variable_get('apachesolr_multilingual_auto_language_filter', 0) && variable_get('apachesolr_multilingual_auto_language_filter_detachable', 0) && (count((array) $response->facet_counts->facet_fields->{$facets}[$delta]['facet_field']) > 1 || !empty($_GET['filters']) && strpos($_GET['filters'], 'language:') !== FALSE)) {
return apachesolr_facet_block($response, $query, 'apachesolr_multilingual', $delta, $facets[$delta]['facet_field'], t('Filter by language'), 'apachesolr_search_language_name');
}
break;
}
}
break;
case 'configure':
return apachesolr_facetcount_form('apachesolr_multilingual', $delta);
case 'save':
apachesolr_facetcount_save($edit);
break;
}
}
Functions
Name | Description |
---|---|
apachesolr_multilingual_apachesolr_facets | Implements hook_apachesolr_facets(). |
apachesolr_multilingual_apachesolr_field_name_map_alter | Implements hook_apachesolr_field_name_map_alter(). |
apachesolr_multilingual_apachesolr_modify_query | Implements hook_apachesolr_modify_query(). |
apachesolr_multilingual_apachesolr_update_index | Implements hook_apachesolr_update_index(). |
apachesolr_multilingual_block | Implements hook_block(). |
apachesolr_multilingual_form_alter | Implements hook_form_alter(). |
apachesolr_multilingual_form_search_form_alter | Implements hook_form_search_form_alter(). |
apachesolr_multilingual_form_search_submit | |
apachesolr_multilingual_get_stemmer | Helper funktion that returns the name of a stemmer if available |
apachesolr_multilingual_menu | Implements hook_menu(). |
apachesolr_multilingual_nodeapi | Implements hook_nodeapi(). |