first global commit

This commit is contained in:
2020-09-23 15:50:29 +02:00
commit 78adf3a099
6052 changed files with 1221183 additions and 0 deletions
@@ -0,0 +1,8 @@
This module differs from this one: http://drupal.org/project/search_api_et. It
uses an alternative way of getting language aware search with entity translation:
have one index per language. This has some drawbacks like scalability and site
building usability. But when used with Solr as indexing backend, it allows to set
a different configuration for each language (by declaring one Search API server
per language, matching to a different Solr core). This especially makes sense if
the website only has two or three languages.
For more info on these considerations, see http://drupal.org/node/1393058.
@@ -0,0 +1,6 @@
name = Entity translation search API
description = Allows to set several monolingual search indexes.
package = Search
core = 7.x
files[] = includes/datasource_translated_entity.inc
@@ -0,0 +1,61 @@
<?php
define('ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION', 'none');
/**
* Implements hook_search_api_search_api_item_type_info_alter().
*/
function entity_translation_search_api_search_api_item_type_info_alter(array &$infos) {
foreach ($infos as $type => $info) {
if (entity_get_info($type)) {
$infos[$type]['datasource controller'] = 'EntityTranslationDataSourceController';
}
}
}
/**
* Implements hook_form_alter().
*/
function entity_translation_search_api_form_alter(&$form, &$form_state, $form_id) {
if (in_array($form_id, array(
'search_api_admin_add_index',
'search_api_admin_index_edit',
))) {
if ($form_id == 'search_api_admin_index_edit') {
$index = $form_state['index'];
$default = isset($index->options['entity_translation_language']) ? $index->options['entity_translation_language'] : ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION;
}
else {
$default = ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION;
}
$languages = language_list('enabled');
$languages = $languages[1];
$names = array(ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION => t('No translation'));
foreach ($languages as $langcode => $item) {
$name = t($item->name);
$names[$langcode] = $name . ($item->native != $name ? ' (' . $item->native . ')' : '');
}
$form['options']['entity_translation_language'] = array(
'#type' => (count($names) <= 5 ? 'radios' : 'select'),
'#title' => t('Entity translation language'),
'#description' => t('To which language the entities should be translated before indexing.'),
'#default_value' => $default,
'#options' => $names,
);
}
}
/**
* Implements hook_search_api_index_items_alter().
* For compatibility with language control data alteration.
*/
function entity_translation_search_api_search_api_index_items_alter(array &$items, SearchApiIndex $index) {
$target_language = $index->options['entity_translation_language'];
if ($target_language != ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION) {
foreach ($items as $id => $item) {
if (isset($item->translations->data[$target_language])) {
$item->language = $target_language;
}
}
}
}
@@ -0,0 +1,43 @@
<?php
class EntityTranslationDataSourceController extends SearchApiEntityDataSourceController {
/**
* Get a metadata wrapper for the item type of this data source controller.
*
* @param $item
* Unless NULL, an item of the item type for this controller to be wrapped.
* @param array $info
* Optionally, additional information that should be used for creating the
* wrapper. Uses the same format as entity_metadata_wrapper().
*
* @return EntityMetadataWrapper
* A wrapper for the item type of this data source controller, according to
* the info array, and optionally loaded with the given data.
*
* @see entity_metadata_wrapper()
*/
public function getMetadataWrapper($item = NULL, array $info = array()) {
if (is_array($info['property info alter'])) {
$index = reset($info['property info alter']);
$target_language = $index->options['entity_translation_language'];
if ($target_language != ENTITY_TRANSLATION_SEARCH_API_NO_TRANSLATION) {
// This may not be really needed.
$info['langcode'] = $target_language;
$wrapper = parent::getMetadataWrapper($item, $info);
$wrapper->language($target_language);
$properties = $wrapper->getPropertyInfo();
foreach ($properties as $key=>$property) {
if (isset($property['type']) && $property['type'] == 'taxonomy_term') {
$wrapper->$key->language($target_language);
}
}
return $wrapper;
}
}
return parent::getMetadataWrapper($item, $info);
}
}
@@ -0,0 +1,156 @@
<?php
/**
* Search API data alteration callback that filters out items based on their
* bundle.
*/
class SearchAPIBaseLanguage extends SearchApiAbstractAlterCallback {
/**
* Construct a data-alter callback.
*
* @param SearchApiIndex $index
* The index whose items will be altered.
* @param array $options
* The callback options set for this index.
*/
public function __construct(SearchApiIndex $index, array $options = array()) {
$options += array(
'lang_field' => '',
'languages' => array(),
);
parent::__construct($index, $options);
}
/**
* Check whether this data-alter callback is applicable for a certain index.
*
* Only returns TRUE if the system is multilingual.
*
* @param SearchApiIndex $index
* The index to check for.
*
* @return boolean
* TRUE if the callback can run on the given index; FALSE otherwise.
*
* @see drupal_multilingual()
*/
public function supportsIndex(SearchApiIndex $index) {
return drupal_multilingual();
}
/**
* Display a form for configuring this data alteration.
*
* @return array
* A form array for configuring this data alteration.
*/
public function configurationForm() {
$form = array();
$wrapper = $this->index->entityWrapper();
$fields[''] = t('- Use default -');
foreach ($wrapper as $key => $property) {
if ($key == 'search_api_language') {
continue;
}
$type = $property->type();
// Only single-valued string properties make sense here. Also, nested
// properties probably don't make sense.
if ($type == 'text' || $type == 'token') {
$info = $property->info();
$fields[$key] = $info['label'];
}
}
if (count($fields) > 1) {
$form['lang_field'] = array(
'#type' => 'select',
'#title' => t('Language field'),
'#description' => t("Select the field which should be used to determine an item's language."),
'#options' => $fields,
'#default_value' => $this->options['lang_field'],
);
}
$languages[LANGUAGE_NONE] = t('Language neutral');
$list = language_list('enabled') + array(array(), array());
foreach (array($list[1], $list[0]) as $list) {
foreach ($list as $lang) {
$name = t($lang->name);
$native = $lang->native;
$languages[$lang->language] = ($name == $native) ? $name : "$name ($native)";
if (!$lang->enabled) {
$languages[$lang->language] .= ' [' . t('disabled') . ']';
}
}
}
$form['language'] = array(
'#type' => 'radios',
'#title' => t('Index language'),
'#description' => t('Index items in this language.'),
'#options' => $languages,
'#default_value' => $this->options['language'],
);
return $form;
}
/**
* Submit callback for the form returned by configurationForm().
*
* This method should both return the new options and set them internally.
*
* @param array $form
* The form returned by configurationForm().
* @param array $values
* The part of the $form_state['values'] array corresponding to this form.
* @param array $form_state
* The complete form state.
*
* @return array
* The new options array for this callback.
*/
public function configurationFormSubmit(array $form, array &$values, array &$form_state) {
$values['language'] = $values['language'];
return parent::configurationFormSubmit($form, $values, $form_state);
}
/**
* Alter items before indexing.
*
* Items which are removed from the array won't be indexed, but will be marked
* as clean for future indexing. This could for instance be used to implement
* some sort of access filter for security purposes (e.g., don't index
* unpublished nodes or comments).
*
* @param array $items
* An array of items to be altered, keyed by item IDs.
*/
public function alterItems(array &$items) {
foreach ($items as $i => &$item) {
$handler = entity_translation_get_handler('node', $item);
$translations = array_keys($handler->getTranslations()->data);
if ($field = $this->options['lang_field']) {
$wrapper = $this->index->entityWrapper($item);
if (isset($wrapper->$field)) {
try {
$item->search_api_language = $wrapper->$field->value();
}
catch (EntityMetadataWrapperException $e) {
// Something went wrong while accessing the language field. Probably
// doesn't really matter.
}
}
}
if($item->$field != $this->options['language'] && !in_array($this->options['language'], $translations)){
unset($items[$i]);
}
else {
$item->search_api_language = $this->options['language'];
$item->$field = $this->options['language'];
}
}
}
}
@@ -0,0 +1,7 @@
name = "Search API Base Language"
description = "Helps to define the indexing language."
core = 7.x
package = Catch
files[] = SearchAPIBaseLanguage.inc
dependencies[] = search_api
dependencies[] = entity_translation
@@ -0,0 +1,14 @@
<?php
/**
* Implements hook_search_api_alter_callback_info
**/
function search_api_base_language_search_api_alter_callback_info() {
$callbacks['base_language'] = array(
'name' => t('Base language'),
'description' => t('The language to use when indexing content.'),
'class' => 'SearchAPIBaseLanguage',
'weight' => 100,
);
return $callbacks;
}