search_api_solr.install in Search API Solr 8.3
Same filename and directory in other branches
Install, update and uninstall functions for the Search API Solr module.
File
search_api_solr.installView source
<?php
/**
* @file
* Install, update and uninstall functions for the Search API Solr module.
*/
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\Entity\ConfigEntityType;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\search_api_solr\SearchApiSolrConflictingEntitiesException;
use Drupal\search_api_solr\SearchApiSolrException;
use Solarium\Client;
use Drupal\search_api_solr\Controller\SolrConfigSetController;
use Drupal\search_api_solr\Utility\Utility as SearchApiSolrUtility;
/**
* Implements hook_requirements().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\search_api\SearchApiException
*/
function search_api_solr_requirements($phase) {
$requirements = [];
if ($phase === 'install') {
if (!class_exists('\\Solarium\\Core\\Client\\Request')) {
$requirements['search_api_solr_library'] = [
'description' => t('Solr search requires the solarium/solarium library.'),
'severity' => REQUIREMENT_ERROR,
];
}
}
elseif ($phase === 'runtime') {
$servers = search_api_solr_get_servers();
$count = 0;
$unavailable = 0;
$multiple_indexes = 0;
$last = NULL;
foreach ($servers as $server_id => $server) {
if (!$server
->getBackend()
->isAvailable()) {
++$unavailable;
$last = $server;
}
$indexes = $server
->getIndexes();
if (count($indexes) > 1) {
$active = 0;
foreach ($indexes as $index) {
if ($index
->status()) {
++$active;
}
}
if ($active > 1) {
++$multiple_indexes;
}
}
++$count;
}
if (!$count) {
return [];
}
$requirements['search_api_solr'] = [
'title' => \Drupal::translation()
->translate('Solr servers'),
'value' => \Drupal::translation()
->formatPlural($count, '1 server', '@count servers'),
];
if ($unavailable) {
if ($unavailable == 1) {
$requirements['search_api_solr']['description'] = \Drupal::translation()
->translate('The Solr server of <a href=":url">%name</a> could not be reached.', [
':url' => Url::fromRoute('entity.search_api_server.canonical', [
'search_api_server' => $last
->id(),
])
->toString(),
'%name' => $last
->label(),
]);
}
else {
$requirements['search_api_solr']['description'] = \Drupal::translation()
->translate('@count Solr servers could not be reached.', [
'@count' => $unavailable,
]);
}
$requirements['search_api_solr']['severity'] = REQUIREMENT_ERROR;
}
else {
$requirements['search_api_solr']['description'] = \Drupal::translation()
->formatPlural($count, 'The Solr server could be reached.', 'All @count Solr servers could be reached.');
$requirements['search_api_solr']['severity'] = REQUIREMENT_OK;
}
$requirements['search_api_solr_multiple_indexes'] = [
'title' => \Drupal::translation()
->translate('Solr servers with multiple indexes'),
'value' => \Drupal::translation()
->formatPlural($count, '1 server', '@count servers'),
];
if ($multiple_indexes) {
// @todo Warn if autocomplete uses an implementation that is not suitable
// for multiple indexes per core. But we need the possibility to turn that
// off if the user acknowledged it because he might really want to have
// it like this as a feature.
}
foreach ($servers as $server) {
/** @var \Drupal\search_api_solr\SolrBackendInterface $backend */
$backend = $server
->getBackend();
$requirements['search_api_solr_' . $server
->id() . '_languages'] = [
'title' => t('Solr Server %server_id', [
'%server_id' => $server
->id(),
]),
'value' => t('Schema covers all languages'),
'severity' => REQUIREMENT_OK,
'description' => t('Schema on server <a href=":url">@server</a> contains all required language-specific fields.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
]),
];
$connector = $backend
->getSolrConnector();
if ($backend
->isAvailable() && $connector
->pingCore()) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications'] = [
'title' => t('Solr Server %server_id', [
'%server_id' => $server
->id(),
]),
'value' => t('Schema up to date'),
'severity' => REQUIREMENT_OK,
'description' => t('Schema on server <a href=":url">@server</a> is up to date.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
]),
];
if (!$backend
->isNonDrupalOrOutdatedConfigSetAllowed()) {
$stats = $backend
->getSchemaLanguageStatistics();
if ($missing_languages = array_filter($stats, function ($state) {
return !$state;
})) {
$requirements['search_api_solr_' . $server
->id() . '_languages']['value'] = t('Schema incomplete');
$requirements['search_api_solr_' . $server
->id() . '_languages']['severity'] = REQUIREMENT_WARNING;
$requirements['search_api_solr_' . $server
->id() . '_languages']['description'] = t('There are some language-specific field types missing in schema of Solr server <a href=":url">@server</a>: @languages.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
'@languages' => implode(', ', array_keys($missing_languages)),
]);
}
$config_set_controller = new SolrConfigSetController();
$config_set_controller
->setServer($server);
$new_config_set = [];
try {
// The freshly generated files.
$new_config_set = $config_set_controller
->getConfigFiles();
} catch (\Exception $e) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['value'] = t('Schema not generated');
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['severity'] = REQUIREMENT_ERROR;
if ($e instanceof SearchApiSolrConflictingEntitiesException) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['description'] = t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup(str_replace('core_issue_2919648_workaround', $server
->id(), $e), []),
]);
}
else {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['description'] = t('The config-set for the Solr server <a href=":url">@server</a> could not be generated.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
]);
}
}
if (!empty($new_config_set)) {
$server_files_list = SearchApiSolrUtility::getServerFiles($server);
// The files that are already on the server.
$server_file_names = array_keys($server_files_list);
$new_config_file_names = array_keys($new_config_set);
$extra_release_files = array_diff($new_config_file_names, $server_file_names);
if (!empty($extra_release_files)) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['value'] = t('Schema incomplete');
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['severity'] = REQUIREMENT_WARNING;
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['description'] = t('There are some files missing in the Solr server schema <a href=":url">@server</a>: @files. An updated config.zip should be downloaded and deployed to your Solr server.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
'@files' => implode(', ', array_keys($extra_release_files)),
]);
}
foreach ($new_config_set as $new_file_name => $new_file_body) {
if (stripos(strrev($new_file_name), 'lmx.') === 0) {
try {
$server_file_data = $connector
->getFile($new_file_name);
$server_file_body = $server_file_data
->getBody();
} catch (SearchApiSolrException $e) {
$server_file_body = '';
}
[
$version_number_server,
$xml_server,
] = SearchApiSolrUtility::normalizeXml($server_file_body);
[
$version_number_new,
$xml_new,
] = SearchApiSolrUtility::normalizeXml($new_file_body);
if (strcmp($xml_server, $xml_new) !== 0) {
if ($version_number_server !== $version_number_new) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['value'] = t('Schema not up to date');
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['severity'] = REQUIREMENT_ERROR;
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['description'] = t('There are some configuration elements missing in the Solr server schema <a href=":url">@server</a>. This is likely due to using an outdated version of either Drupal or Solr. The recommended version is: @version. An updated config.zip should be downloaded and deployed to your Solr server.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
'@version' => $version_number_new,
]);
break;
}
elseif ($version_number_server === $version_number_new) {
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['value'] = t('Schema modified');
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['severity'] = REQUIREMENT_WARNING;
$requirements['search_api_solr_schema_' . $server
->id() . '_modifications']['description'] = t('Your config-set contains manually added customizations. Be aware that these will be lost when the config-set needs to be regenerated.', []);
}
}
}
}
}
}
}
else {
$requirements['search_api_solr_' . $server
->id() . '_languages']['value'] = t('Not reachable');
$requirements['search_api_solr_' . $server
->id() . '_languages']['severity'] = REQUIREMENT_ERROR;
$requirements['search_api_solr_' . $server
->id() . '_languages']['description'] = t('Solr server <a href=":url">@server</a> is not reachable.', [
':url' => $server
->toUrl('canonical')
->toString(),
'@server' => $server
->label(),
]);
}
}
if (Client::checkMinimal('5.1.4')) {
$requirements['search_api_solr_solarium'] = [
'title' => t('solarium library'),
'value' => t('Up to date'),
'description' => t('Solarium @version is installed.', [
'@version' => Client::VERSION,
]),
'severity' => REQUIREMENT_OK,
];
}
else {
$requirements['search_api_solr_solarium'] = [
'title' => t('solarium library'),
'value' => t('Outdated'),
'description' => t('Solarium @version is too old and has known issues. In order to get composer to upgrade solarium to a recent version a core patch or a workaround is required. Have a look at this <a href=":core">Core issue</a> and this <a href=":search_api_solr">Search API Solr issue</a>.', [
'@version' => Client::VERSION,
':core' => 'https://www.drupal.org/project/drupal/issues/2876675',
':search_api_solr' => 'https://www.drupal.org/project/search_api_solr/issues/3085196',
]),
'severity' => REQUIREMENT_ERROR,
];
}
}
return $requirements;
}
/**
* Implements hook_uninstall().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\search_api\SearchApiException
*/
function search_api_solr_uninstall() {
\Drupal::state()
->delete('search_api_solr.last_optimize');
\Drupal::state()
->delete('search_api_solr.endpoint.data');
\Drupal::state()
->delete('search_api_solr.site_hash');
\Drupal::state()
->delete('search_api_solr.search_all_rows');
foreach (search_api_solr_get_servers() as $server) {
foreach ($server
->getIndexes() as $index) {
\Drupal::state()
->delete('search_api_solr.' . $index
->id() . '.last_update');
}
\Drupal::state()
->delete('search_api_solr.' . $server
->id() . '.schema_parts');
}
}
/**
* Gets all backend configs for active Solr servers.
*
* @param string $pattern
*
* @return array
* All backend configs for active Solr servers keyed by server name.
*/
function search_api_solr_update_helper_get_backend_configs($pattern = 'solr') {
$config_factory = \Drupal::configFactory();
$backend_configs = [];
foreach ($config_factory
->listAll('search_api.server.') as $server_name) {
$server = $config_factory
->get($server_name);
// Covers search_api_solr_multilingual, too.
if (strpos($server
->get('backend'), $pattern) !== FALSE) {
$backend_configs[$server_name] = $server
->get('backend_config');
}
}
return $backend_configs;
}
/**
* Saves a modified backend config for a given Solr server.
*
* @param string $server_name
* Name of the solr server.
* @param array $backend_config
* Solr backend configuration.
* @param bool $trusted_data
*/
function search_api_solr_update_helper_save_backend_config($server_name, array $backend_config, $trusted_data = TRUE) {
\Drupal::configFactory()
->getEditable($server_name)
->set('backend_config', $backend_config)
->save($trusted_data);
}
/**
* Gets all index third party settings for Solr servers.
*
* @param string $pattern
*
* @return array
* All backend configs for active Solr servers keyed by server name.
*/
function search_api_solr_update_helper_get_index_third_party_settings($pattern = 'solr') {
$backend_configs = search_api_solr_update_helper_get_backend_configs($pattern);
$indexes = search_api_solr_update_helper_get_indexes($pattern);
$index_third_party_settings = [];
foreach ($indexes as $index_id => $index) {
$config_id = 'search_api.server.' . $index
->get('server');
if (isset($backend_configs[$config_id])) {
// This index belongs to a Solr server.
$index_third_party_settings[$index_id] = $index
->get('third_party_settings.search_api_solr');
}
}
return $index_third_party_settings;
}
/**
* Saves a modified backend config for a given Solr server.
*
* @param string $index_id
* Id of the solr index.
* @param array $third_party_settings
* @param bool $trusted_data
*/
function search_api_solr_update_helper_save_index_third_party_settings($index_id, array $third_party_settings, $trusted_data = TRUE) {
\Drupal::configFactory()
->getEditable($index_id)
->set('third_party_settings.search_api_solr', $third_party_settings)
->save($trusted_data);
}
/**
* Gets all index settings for Solr servers.
*
* @param string $pattern
*
* @return array
* All index configs for Solr servers keyed by index name.
*/
function search_api_solr_update_helper_get_indexes($pattern = 'solr') {
$backend_configs = search_api_solr_update_helper_get_backend_configs($pattern);
$config_factory = \Drupal::configFactory();
$indexes = [];
foreach ($config_factory
->listAll('search_api.index.') as $index_id) {
$index = $config_factory
->get($index_id);
$config_id = 'search_api.server.' . $index
->get('server');
if (isset($backend_configs[$config_id])) {
// This index belongs to a Solr server.
$indexes[$index_id] = $index;
}
}
return $indexes;
}
/**
* Saves a modified index config.
*
* @param string $index_id
* Id of the Solr Index.
* @param array $settings
* @param bool $trusted_data
*/
function search_api_solr_update_helper_save_indexes($index_id, array $settings, $trusted_data = TRUE) {
\Drupal::configFactory()
->getEditable($index_id)
->setData($settings)
->save($trusted_data);
}
/**
* Gets all solr field type configs.
*
* @return array
* All solr field type configs.
*/
function search_api_solr_update_helper_get_field_type_configs() {
$config_factory = \Drupal::configFactory();
$field_type_configs = [];
foreach ($config_factory
->listAll('search_api_solr.solr_field_type.') as $field_type_name) {
$field_type_configs[$field_type_name] = $config_factory
->get($field_type_name)
->getRawData();
}
return $field_type_configs;
}
/**
* Saves a modified solr field type config.
*
* @param string $field_type_name
* @param array $field_type_config
* @param bool $trusted_data
*/
function search_api_solr_update_helper_save_field_type_config($field_type_name, array $field_type_config, $trusted_data = TRUE) {
\Drupal::configFactory()
->getEditable($field_type_name)
->setData($field_type_config)
->save($trusted_data);
}
/**
* Helper function to install all new configs.
*
* @param string $directory
*/
function search_api_solr_update_helper_install_configs($directory = InstallStorage::CONFIG_OPTIONAL_DIRECTORY) {
/** @var \Drupal\Core\Config\ConfigInstallerInterface $config_installer */
$config_installer = \Drupal::service('config.installer');
$config_installer
->installDefaultConfig('module', 'search_api_solr');
$optional_install_path = \Drupal::moduleHandler()
->getModule('search_api_solr')
->getPath() . '/' . $directory;
if (is_dir($optional_install_path)) {
// Install any optional config the module provides.
$storage = new FileStorage($optional_install_path, StorageInterface::DEFAULT_COLLECTION);
$config_installer
->installOptionalConfig($storage);
}
$restrict_by_dependency = [
'module' => 'search_api_solr',
];
$config_installer
->installOptionalConfig(NULL, $restrict_by_dependency);
}
/**
* Split Solr paths stored in configurations into server and core parts.
*/
function search_api_solr_update_8001() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$parts = explode('/', $backend_config['path']);
if (count($parts) > 2) {
$backend_config['core'] = array_pop($parts);
$backend_config['path'] = implode('/', $parts);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
}
/**
* Convert http_user and http_pass to username and password config for Solarium.
*/
function search_api_solr_update_8002() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['username'] = $backend_config['http_user'];
$backend_config['password'] = $backend_config['http_pass'];
unset($backend_config['http_user'], $backend_config['http_pass']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Add default timeout settings to existing configs.
*/
function search_api_solr_update_8003() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['timeout'] = 5;
$backend_config['index_timeout'] = 5;
$backend_config['optimize_timeout'] = 10;
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Migrate existing backend configurations to the basic auth connector plugin.
*/
function search_api_solr_update_8004() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['connector'] = 'basic_auth';
$backend_config['connector_config'] = [];
foreach ([
'scheme',
'host',
'port',
'path',
'core',
'timeout',
'index_timeout',
'optimize_timeout',
'solr_version',
'http_method',
'username',
'password',
] as $key) {
$backend_config['connector_config'][$key] = $backend_config[$key];
unset($backend_config[$key]);
}
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Add commit_within settings to existing connector configs.
*/
function search_api_solr_update_8005() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['connector_config']['commit_within'] = 1000;
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Add autocomplete settings to existing configs.
*/
function search_api_solr_update_8006() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['suggest_suffix'] = TRUE;
$backend_config['suggest_corrections'] = TRUE;
$backend_config['suggest_words'] = FALSE;
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Remove old autocomplete settings in existing configs.
*/
function search_api_solr_update_8007() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
unset($backend_config['autocorrect_spell']);
unset($backend_config['autocorrect_suggest_words']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Remove obsolete settings in existing configs.
*/
function search_api_solr_update_8008() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory
->listAll('search_api_solr.settings.') as $setting) {
$config = $config_factory
->getEditable($setting);
$data = $config
->getRawData();
unset($data['autocomplete_max_occurrences']);
unset($data['http_get_max_length']);
$config
->setData($data);
$config
->save(TRUE);
}
}
/**
* Install Solr Field Types.
*/
function search_api_solr_update_8200() {
// 8.x-1.x to 8.x-2.x migration path is obsolete and therefore removed. Just
// install the latest field types.
\Drupal::entityDefinitionUpdateManager()
->installEntityType(new ConfigEntityType([
'id' => 'solr_field_type',
'label' => new TranslatableMarkup('Solr Field Type'),
'handlers' => [
'list_builder' => 'Drupal\\search_api_solr\\Controller\\SolrFieldTypeListBuilder',
'form' => [
'add' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeForm',
'edit' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeForm',
'delete' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeDeleteForm',
],
],
'config_prefix' => 'solr_field_type',
'admin_permission' => 'administer search_api',
'entity_keys' => [
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
],
'links' => [
'edit-form' => '/admin/config/search/search-api/solr_field_type/{solr_field_type}',
'delete-form' => '/admin/config/search/search-api/solr_field_type/{solr_field_type}/delete',
'disable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/disable',
'enable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/enable',
'collection' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type',
],
]));
search_api_solr_update_helper_install_configs();
}
/**
* Fix suggester field type.
*/
function search_api_solr_update_8201() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['solr_configs']) && !empty($field_type_config['solr_configs']['searchComponents'])) {
foreach ($field_type_config['solr_configs']['searchComponents'] as &$component) {
if ($component['name'] === 'suggest') {
foreach ($component['lst'] as &$lst) {
foreach ($lst['str'] as &$entry) {
if ($entry['name'] === 'field') {
$entry['VALUE'] = 'twm_suggest';
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
break;
}
}
}
}
}
}
}
}
/**
* Enable support for targeted domains for all backends and add custom codes.
*/
function search_api_solr_update_8202() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (!isset($backend_config['domain'])) {
if (isset($backend_config['sasm_domain'])) {
$backend_config['domain'] = $backend_config['sasm_domain'];
unset($backend_config['sasm_domain']);
}
else {
$backend_config['domain'] = 'generic';
}
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!isset($field_type_config['custom_code'])) {
$field_type_config['custom_code'] = '';
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
// Removed search_api_solr_update_8203().
/**
* Enable phrase suggestions support.
*/
function search_api_solr_update_8204() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (!isset($backend_config['suggest_phrases'])) {
$backend_config['suggest_phrases'] = FALSE;
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
}
/**
* Drop never implemented word suggestions support.
*/
function search_api_solr_update_8205() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (isset($backend_config['suggest_words'])) {
unset($backend_config['suggest_words']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
}
/**
* Remove obsolete autocomplete settings.
*/
function search_api_solr_update_8206() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
unset($backend_config['suggest_suffix']);
unset($backend_config['suggest_corrections']);
unset($backend_config['suggest_phrases']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
/**
* Fix language undefined field types.
*/
function search_api_solr_update_8207() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (strpos($field_type_name, 'text_und') === 0) {
$save = FALSE;
if (!empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
foreach ($field_type_config['field_type']['analyzers'] as &$component) {
foreach ($component['filters'] as &$filter) {
foreach ($filter as &$entry) {
if ($entry['class'] === 'solr.SnowballPorterFilterFactory') {
unset($entry);
$save = TRUE;
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Enable new highlighter.
*/
function search_api_solr_update_8208() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (isset($backend_config['excerpt'])) {
unset($backend_config['excerpt']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
$config_factory = \Drupal::configFactory();
$config = $config_factory
->getEditable('search_api_solr.standard_highlighter');
$data = $config
->getRawData();
unset($data['excerpt']);
$data['highlight']['snippets'] = 3;
$data['highlight']['fragsize'] = 0;
$config
->setData($data);
$config
->save(TRUE);
}
// Removed search_api_solr_update_8209().
// Removed search_api_solr_update_8210().
/**
* Add default finalize timeout settings to existing configs.
*/
function search_api_solr_update_8211() {
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (!isset($backend_config['finalize_timeout'])) {
$backend_config['finalize_timeout'] = 30;
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
}
/**
* Configure highlighter individually per index and remove global config.
*/
function search_api_solr_update_8212() {
$config_factory = \Drupal::configFactory();
$config = $config_factory
->getEditable('search_api_solr.standard_highlighter');
$data = $config
->getRawData();
foreach (search_api_solr_update_helper_get_index_third_party_settings() as $index_id => $third_party_settings) {
if (!isset($third_party_settings['highlighter'])) {
$third_party_settings['highlighter'] = $data;
search_api_solr_update_helper_save_index_third_party_settings($index_id, $third_party_settings);
}
}
$config
->delete();
}
/**
* Configure index prefixes individually per server and index.
*/
function search_api_solr_update_8213() {
$config_factory = \Drupal::configFactory();
$config = $config_factory
->getEditable('search_api_solr.settings');
$data = $config
->getRawData();
foreach (search_api_solr_update_helper_get_index_third_party_settings() as $index_id => $third_party_settings) {
if (!isset($third_party_settings['advanced']) || !isset($third_party_settings['advanced']['index_prefix'])) {
$prefix = 'index_prefix_' . $index_id;
$third_party_settings['advanced']['index_prefix'] = $data[$prefix] ?? '';
unset($data[$prefix]);
search_api_solr_update_helper_save_index_third_party_settings($index_id, $third_party_settings);
}
}
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (!isset($backend_config['server_prefix'])) {
$backend_config['server_prefix'] = isset($data['index_prefix']) ? $data['index_prefix'] : '';
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
unset($data['index_prefix']);
$config
->setData($data);
$config
->save(TRUE);
}
/**
* Migrate Solr backends to the new unified Solr backend.
*/
function search_api_solr_update_8300() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory
->listAll('search_api_solr.solr_field_type.m_') as $field_type_name) {
$config_factory
->getEditable($field_type_name)
->delete();
}
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
unset($field_type_config['managed_schema']);
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
foreach ($config_factory
->listAll('search_api.server.') as $server_name) {
$server = $config_factory
->getEditable($server_name);
$backend_config = $server
->get('backend_config');
switch ($server
->get('backend')) {
case 'search_api_solr':
$backend_config['sasm_limit_search_page_to_content_language'] = FALSE;
$backend_config['sasm_search_page_include_language_independent'] = TRUE;
break;
case 'search_api_solr_multilingual':
case 'search_api_solr_multilingual_managed_schema':
unset($backend_config['sasm_language_unspecific_fallback_on_schema_issues']);
$server
->set('backend', 'search_api_solr');
break;
case 'search_api_solr_any_schema':
$backend_config['sasm_limit_search_page_to_content_language'] = FALSE;
$backend_config['sasm_search_page_include_language_independent'] = TRUE;
$server
->set('backend', 'search_api_solr');
break;
default:
continue 2;
}
$dependencies = $server
->get('dependencies');
$dependencies['module'] = [
'search_api_solr',
];
$server
->set('backend_config', $backend_config)
->set('dependencies', $dependencies)
->save(TRUE);
}
foreach ($config_factory
->listAll('search_api.index.') as $index_name) {
$index = $config_factory
->getEditable($index_name);
$field_settings = $index
->get('field_settings');
foreach ($field_settings as &$field_setting) {
if ('solr_string_doc_values' === $field_setting['type']) {
$field_setting['type'] = 'string';
}
}
$index
->set('field_settings', $field_settings)
->save(TRUE);
}
}
/**
* Field types clean-up.
*/
function search_api_solr_update_8301() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory
->listAll('search_api.index.') as $index_name) {
$index = $config_factory
->getEditable($index_name);
$field_settings = $index
->get('field_settings');
foreach ($field_settings as &$field_setting) {
if ('solr_text_ngram' === $field_setting['type']) {
$field_setting['type'] = 'solr_text_custom:edge';
}
if ('solr_string_ngram' === $field_setting['type']) {
$field_setting['type'] = 'solr_text_custom:edgestring';
}
if ('solr_text_phonetic' === $field_setting['type']) {
$field_setting['type'] = 'solr_text_custom:phonetic';
}
}
$index
->set('field_settings', $field_settings)
->save(TRUE);
}
}
/**
* Re-install language-specific field types to enable the new spellcheckers.
*/
function search_api_solr_update_8302() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory
->listAll('search_api_solr.solr_field_type.text_') as $field_type_name) {
if (preg_match('/^search_api_solr\\.solr_field_type\\.text_[a-z]{2}[_-]{1}/', $field_type_name)) {
$config_factory
->getEditable($field_type_name)
->delete();
}
}
}
/**
* Remove obsolete setting in config.
*/
function search_api_solr_update_8303() {
// Obsolete because of search_api_solr_update_8304().
}
/**
* Convert site_hash from setting to state.
*/
function search_api_solr_update_8304() {
$config_factory = \Drupal::configFactory();
$settings = $config_factory
->getEditable('search_api_solr.settings');
\Drupal::state()
->set('search_api_solr.site_hash', $settings
->get('site_hash') ?? '');
$settings
->delete();
foreach ($config_factory
->listAll('search_api.server.') as $server_name) {
$server = $config_factory
->getEditable($server_name);
$backend_config = $server
->get('backend_config');
$backend_config['optimize'] = FALSE;
$server
->set('backend_config', $backend_config)
->save(TRUE);
}
}
/**
* Add Dutch nouns and improve stemming for Dutch language.
*/
function search_api_solr_update_8305() {
$nouns = '';
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (strpos($field_type_name, 'text_nl') !== FALSE) {
$save = FALSE;
if (!empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
foreach ($field_type_config['field_type']['analyzers'] as &$component) {
foreach ($component['filters'] as &$filter) {
if ($filter['class'] === 'solr.SnowballPorterFilterFactory') {
if ($filter['language'] === 'Dutch') {
$filter['language'] = 'Kp';
$save = TRUE;
}
}
}
}
}
if (!empty($field_type_config['text_files'])) {
if (empty($field_type_config['text_files']['nouns']) || $field_type_config['text_files']['nouns'] == PHP_EOL) {
if (!$nouns) {
// We always use this hardcoded source file to have valid one for
// different domains created by users, example:
// text_nl_scientific_6_0_0.
$filename = __DIR__ . '/config/optional/search_api_solr.solr_field_type.text_nl_7_0_0.yml';
$nouns = Yaml::decode(file_get_contents($filename));
}
$field_type_config['text_files']['nouns'] = $nouns['text_files']['nouns'];
$save = TRUE;
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Replace deprecated Solr filters by their successors for Solr 7.
*/
function search_api_solr_update_8306() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (version_compare($field_type_config['minimum_solr_version'], '7.0.0', '>=') && !empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
foreach ($field_type_config['field_type']['analyzers'] as &$component) {
foreach ($component['filters'] as &$filter) {
switch ($filter['class']) {
case 'solr.WordDelimiterFilterFactory':
$filter['class'] = 'solr.WordDelimiterGraphFilterFactory';
break;
case 'solr.SynonymFilterFactory':
$filter['class'] = 'solr.SynonymGraphFilterFactory';
break;
case 'solr.StopFilterFactory':
unset($filter['enablePositionIncrements']);
break;
}
}
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Avoid redundant text files in generated Solr config files.
*/
function search_api_solr_update_8307() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (strpos($field_type_name, 'text_phonetic') !== FALSE || strpos($field_type_name, 'text_edge_und') !== FALSE || strpos($field_type_name, 'text_ngram_und') !== FALSE) {
$dependency = str_replace([
'text_phonetic',
'text_edge_und',
'text_ngram_und',
], [
'text',
'text_und',
'text_und',
], $field_type_name);
if (!isset($field_type_config['dependencies']['config']) || !in_array($dependency, $field_type_config['dependencies']['config'])) {
$field_type_config['dependencies']['config'][] = $dependency;
}
if (!empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
foreach ($field_type_config['field_type']['analyzers'] as &$component) {
if (!empty($component['charFilters'])) {
foreach ($component['charFilters'] as &$charFilter) {
if ($charFilter['class'] === 'solr.MappingCharFilterFactory') {
$charFilter['mapping'] = 'accents_' . $field_type_config['field_type_language_code'] . '.txt';
}
}
}
foreach ($component['filters'] as &$filter) {
if ($filter['class'] === 'solr.WordDelimiterFilterFactory' || $filter['class'] === 'solr.WordDelimiterGraphFilterFactory') {
$filter['protected'] = 'protwords_' . $field_type_config['field_type_language_code'] . '.txt';
}
elseif ($filter['class'] === 'solr.DictionaryCompoundWordTokenFilterFactory') {
$filter['dictionary'] = 'nouns_' . $field_type_config['field_type_language_code'] . '.txt';
}
elseif ($filter['class'] === 'solr.StopFilterFactory') {
$filter['words'] = 'stopwords_' . $field_type_config['field_type_language_code'] . '.txt';
}
elseif ($filter['class'] === 'solr.SynonymFilterFactory' || $filter['class'] === 'solr.SynonymGraphFilterFactory') {
$filter['synonyms'] = 'synonyms_' . $field_type_config['field_type_language_code'] . '.txt';
}
}
}
}
if (!empty($field_type_config['text_files'])) {
$field_type_config['text_files'] = [];
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Configure multilingual features individually per index.
*/
function search_api_solr_update_8308() {
$settings = [];
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
\Drupal::state()
->delete('sasm.' . $server_name . '.schema_parts');
$settings[$server_name] = [
'limit_to_content_language' => FALSE,
'include_language_independent' => TRUE,
];
if (isset($backend_config['sasm_limit_search_page_to_content_language'])) {
$settings[$server_name]['limit_to_content_language'] = $backend_config['sasm_limit_search_page_to_content_language'];
unset($backend_config['sasm_limit_search_page_to_content_language']);
}
if (isset($backend_config['sasm_search_page_include_language_independent'])) {
$settings[$server_name]['include_language_independent'] = $backend_config['sasm_search_page_include_language_independent'];
unset($backend_config['sasm_search_page_include_language_independent']);
}
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
$indexes = search_api_solr_update_helper_get_indexes();
foreach (search_api_solr_update_helper_get_index_third_party_settings() as $index_id => $third_party_settings) {
if (!isset($third_party_settings['multilingual']) || !isset($third_party_settings['multilingual']['limit_to_content_language'])) {
$third_party_settings['multilingual']['limit_to_content_language'] = $settings['search_api.server.' . $indexes[$index_id]
->get('server')]['limit_to_content_language'];
}
if (!isset($third_party_settings['multilingual']) || !isset($third_party_settings['multilingual']['include_language_independent'])) {
$third_party_settings['multilingual']['include_language_independent'] = $settings['search_api.server.' . $indexes[$index_id]
->get('server')]['include_language_independent'];
}
search_api_solr_update_helper_save_index_third_party_settings($index_id, $third_party_settings);
}
}
/**
* Solarium 5 adjustments. Warning! If you have overwritten the connection
* settings, don't forget to adjust the 'path'. See the release notes for
* details.
*/
function search_api_solr_update_8309() {
// Remove the V1 API endpoint from the path.
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
$backend_config['connector_config']['path'] = preg_replace('@/solr$@', '/', $backend_config['connector_config']['path']);
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
// Reset the states.
\Drupal::state()
->delete('search_api_solr.endpoint.data');
}
/**
* Enable language-specific collations.
*/
function search_api_solr_update_8310() {
$valid_icu_locales = [
'ar',
'cs',
'da',
'de',
'el',
'en',
'es',
'fi',
'fr',
'it',
'ja',
'nl',
'pl',
'ru',
'sk',
'uk',
'br',
'be',
'zh',
'tr',
'th',
'sl',
'ro',
'pt',
'mk',
'is',
'hr',
'bg',
'af',
'yi',
'vi',
'sv',
'sr',
'sq',
'si',
'pa',
'or',
'nn',
'ne',
'my',
'mt',
'lt',
'ln',
'ko',
'id',
'hu',
'hi',
'he',
'fa',
'et',
'am',
];
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (empty($field_type_config['collated_field_type'])) {
if (!in_array($field_type_config['field_type_language_code'], $valid_icu_locales) || empty($field_type_config['spellcheck_field_type'])) {
continue;
}
$field_type_config['collated_field_type'] = [
'name' => 'collated_' . $field_type_config['field_type_language_code'],
'class' => 'solr.ICUCollationField',
'locale' => $field_type_config['field_type_language_code'],
'strength' => 'primary',
'caseLevel' => FALSE,
];
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
/**
* Add the Polish diacritics to the language configs. Unset the obsolete min and
* max parameters from the CJKWidthFilter of the spellchecker (mainly for
* Japanese).
*/
function search_api_solr_update_8311() {
$accents = <<<ACCENTS
# Ą => A
"\\u0104" => "A"
# Ć => C
"\\u0106" => "C"
# Ę => E
"\\u0118" => "E"
# Ł => L
"\\u0141" => "L"
# Ń => N
"\\u0143" => "N"
# Ś => S
"\\u015a" => "S"
# Ź => Z
"\\u0179" => "Z"
# Ż => Z
"\\u017b" => "Z"
ACCENTS;
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['text_files']['accents'])) {
if ('pl' === $field_type_config['field_type_language_code']) {
continue;
}
if (strpos($field_type_config['text_files']['accents'], '\\u0104') !== FALSE) {
continue;
}
$field_type_config['text_files']['accents'] = $field_type_config['text_files']['accents'] . $accents;
}
if (!empty($field_type_config['spellcheck_field_type']) && !empty($field_type_config['spellcheck_field_type']['analyzers'])) {
foreach ($field_type_config['spellcheck_field_type']['analyzers'] as &$component) {
if (!empty($component['filters'])) {
foreach ($component['filters'] as &$filter) {
if ('solr.CJKWidthFilterFactory' === $filter['class']) {
unset($filter['min']);
unset($filter['max']);
}
}
}
}
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
/**
* Add language-specific unstemmed field types.
*/
function search_api_solr_update_8312() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['custom_code'])) {
continue;
}
if (!isset($field_type_config['unstemmed_field_type'])) {
$temp_field_type = $field_type_config['field_type'];
$stemmer_removed = FALSE;
if (!empty($temp_field_type['analyzers'])) {
foreach ($temp_field_type['analyzers'] as &$component) {
if (!empty($component['filters'])) {
foreach ($component['filters'] as $key => &$filter) {
if ('solr.SnowballPorterFilterFactory' === $filter['class'] || strpos($filter['class'], 'Stem')) {
unset($component['filters'][$key]);
$stemmer_removed = TRUE;
}
}
}
}
}
if ($stemmer_removed) {
$temp_field_type['name'] = 'text_unstemmed_' . $field_type_config['field_type_language_code'];
$field_type_config['unstemmed_field_type'] = $temp_field_type;
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Distinguish between simplified and traditional Chinese.
*/
function search_api_solr_update_8313() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if ('zh-hans' === $field_type_config['field_type_language_code']) {
if (!empty($field_type_config['field_type'])) {
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if ('org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' !== $analyzers['tokenizer']['class']) {
$analyzers['tokenizer']['class'] = 'org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer';
}
foreach ($analyzers['filters'] as $key => $filter) {
if ('solr.CJKBigramFilterFactory' === $filter['class']) {
unset($analyzers['filters'][$key]);
}
}
}
}
}
}
if (!empty($field_type_config['spellcheck_field_type'])) {
foreach ($field_type_config['spellcheck_field_type'] as &$components) {
if (is_array($components) && 'org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' !== $components['tokenizer']['class']) {
$components['tokenizer']['class'] = 'org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer';
}
}
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Enable language-unspecific collation.
*/
function search_api_solr_update_8314() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (empty($field_type_config['collated_field_type']) && !empty($field_type_config['spellcheck_field_type']) && LanguageInterface::LANGCODE_NOT_SPECIFIED == $field_type_config['field_type_language_code']) {
$field_type_config['collated_field_type'] = [
'name' => 'collated_' . $field_type_config['field_type_language_code'],
'class' => 'solr.ICUCollationField',
'locale' => 'en',
'strength' => 'primary',
'caseLevel' => FALSE,
];
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Avoid Solr exceptions.
*
* Avoid Solr exceptions when multilingual spell checking by using unified
* analyzer.
*/
function search_api_solr_update_8315() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['spellcheck_field_type'])) {
if (!in_array($field_type_config['field_type_language_code'], [
'und',
'ja',
'th',
'zh-hans',
'zh-hant',
])) {
unset($field_type_config['spellcheck_field_type']);
}
if (!empty($field_type_config['solr_configs']) && !empty($field_type_config['solr_configs']['searchComponents'])) {
foreach ($field_type_config['solr_configs']['searchComponents'] as &$component) {
if ('spellcheck' === $component['name']) {
if (isset($component['lst']) && is_array($component['lst'])) {
foreach ($component['lst'] as &$lst) {
if ('spellchecker' === $lst['name']) {
$lst['str'][] = [
'name' => 'onlyMorePopular',
'VALUE' => 'true',
];
}
}
}
}
}
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Use Ukrainian lemmatization instead of Russian SnowballPorterFilterFactory.
*/
function search_api_solr_update_8316() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if ('uk' === $field_type_config['field_type_language_code'] && !empty($field_type_config['field_type'])) {
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as $key => &$filter) {
if ('solr.SnowballPorterFilterFactory' === $filter['class']) {
$filter['class'] = 'solr.MorfologikFilterFactory';
unset($filter['language']);
unset($filter['protected']);
$filter['dictionary'] = 'org/apache/lucene/analysis/uk/ukrainian.dict';
}
}
}
}
}
}
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Replace erroneous Swedish default field type.
*/
function search_api_solr_update_8317() {
$filename = __DIR__ . '/config/optional/search_api_solr.solr_field_type.text_sv_7_0_0.yml';
$sv = Yaml::decode(file_get_contents($filename));
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if ('search_api_solr.solr_field_type.text_sv_7_0_0' === $field_type_name) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $sv);
break;
}
}
}
/**
* Replace solr.MorphologikFilterFactory by solr.MorfologikFilterFactory.
*/
function search_api_solr_update_8318() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
$save = FALSE;
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as $key => &$filter) {
if ('solr.MorphologikFilterFactory' === $filter['class']) {
$filter['class'] = 'solr.MorfologikFilterFactory';
$filter['dictionary'] = 'org/apache/lucene/analysis/uk/ukrainian.dict';
$save = TRUE;
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Fix Solr 6 Czech Field Type and improve spellcheckers.
*/
function search_api_solr_update_8319() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
$save = FALSE;
if (!empty($field_type_config['field_type'])) {
$save = FALSE;
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as $key => &$filter) {
if ('solr.RemoveDuplicatesTokenFilterFactor' === $filter['class']) {
$filter['class'] = 'solr.RemoveDuplicatesTokenFilterFactory';
$save = TRUE;
}
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Fix 2.x to 3.0 upgrade path of spellcheck components.
*/
function search_api_solr_update_8320() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
$save = FALSE;
if (isset($field_type_config['spellcheck_field_type']) && empty($field_type_config['spellcheck_field_type'])) {
unset($field_type_config['spellcheck_field_type']);
$save = TRUE;
}
if (!empty($field_type_config['solr_configs']) && !empty($field_type_config['solr_configs']['searchComponents'])) {
foreach ($field_type_config['solr_configs']['searchComponents'] as &$component) {
if ('spellcheck' === $component['name']) {
if (isset($component['lst']) && is_array($component['lst'])) {
foreach ($component['lst'] as $key => &$lst) {
if ('spellchecker' === $lst['name']) {
if (isset($lst['str']) && is_array($lst['str'])) {
foreach ($lst['str'] as $str) {
if ('onlyMorePopular' === $str['name']) {
continue 2;
}
}
$lst['str'][] = [
'name' => 'onlyMorePopular',
'VALUE' => 'true',
];
$save = TRUE;
}
}
}
if ('str' === $key) {
// An previously erroneous implementation of
// search_api_solr_update_8315() added that entry which needs to
// be removed now.
unset($component['lst']['str']);
$save = TRUE;
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
/**
* Fix Chinese Field Types.
*/
function search_api_solr_update_8321() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
$save = FALSE;
if ('zh-hans' === $field_type_config['field_type_language_code']) {
$field_type_config['label'] = 'Simplified Chinese Text Field';
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if ('org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' === $analyzers['tokenizer']['class']) {
$analyzers['tokenizer']['class'] = 'solr.HMMChineseTokenizerFactory';
$analyzers['filters'] = [
[
'class' => 'solr.CJKWidthFilterFactory',
],
[
'class' => 'solr.StopFilterFactory',
'words' => 'org/apache/lucene/analysis/cn/smart/stopwords.txt',
],
[
'class' => 'solr.PorterStemFilterFactory',
],
[
'class' => 'solr.LowerCaseFilterFactory',
],
];
$save = TRUE;
}
}
}
}
if (!empty($field_type_config['spellcheck_field_type'])) {
foreach ($field_type_config['spellcheck_field_type'] as &$analyzer) {
if (is_array($analyzer)) {
if ('org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' === $analyzer['tokenizer']['class']) {
$analyzer['tokenizer']['class'] = 'solr.HMMChineseTokenizerFactory';
$analyzer['filters'] = [
[
'class' => 'solr.CJKWidthFilterFactory',
],
[
'class' => 'solr.LowerCaseFilterFactory',
],
];
$save = TRUE;
}
}
}
}
if (!isset($field_type_config['unstemmed_field_type'])) {
$field_type_config['unstemmed_field_type'] = [
'name' => 'text_unstemmed_zh_hans',
'class' => 'solr.TextField',
'positionIncrementGap' => 100,
'analyzers' => [
[
'type' => 'index',
'tokenizer' => [
'class' => 'solr.HMMChineseTokenizerFactory',
],
'filters' => [
[
'class' => 'solr.CJKWidthFilterFactory',
],
[
'class' => 'solr.StopFilterFactory',
'words' => 'org/apache/lucene/analysis/cn/smart/stopwords.txt',
],
[
'class' => 'solr.LowerCaseFilterFactory',
],
],
],
],
];
$save = TRUE;
}
}
elseif ('zh-hant' === $field_type_config['field_type_language_code']) {
$field_type_config['label'] = 'Traditional Chinese Text Field';
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if ('org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' === $analyzers['tokenizer']['class']) {
$analyzers['tokenizer']['class'] = 'solr.ICUTokenizerFactory';
$analyzers['filters'] = [
[
'class' => 'solr.CJKBigramFilterFactory',
'han' => TRUE,
'hiragana' => FALSE,
'katakana' => FALSE,
'hangul' => FALSE,
'outputUnigrams' => FALSE,
],
[
'class' => 'solr.CJKWidthFilterFactory',
],
[
'class' => 'solr.LowerCaseFilterFactory',
],
];
$save = TRUE;
}
}
}
}
if (!empty($field_type_config['spellcheck_field_type'])) {
foreach ($field_type_config['spellcheck_field_type'] as &$analyzer) {
if (is_array($analyzer)) {
if ('org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer' === $analyzer['tokenizer']['class']) {
$analyzer['tokenizer']['class'] = 'solr.ICUTokenizerFactory';
$analyzer['filters'] = [
[
'class' => 'solr.CJKBigramFilterFactory',
'han' => TRUE,
'hiragana' => FALSE,
'katakana' => FALSE,
'hangul' => FALSE,
'outputUnigrams' => FALSE,
],
[
'class' => 'solr.CJKWidthFilterFactory',
],
[
'class' => 'solr.LowerCaseFilterFactory',
],
];
$save = TRUE;
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Fix Thai and Turkish Field Types.
*/
function search_api_solr_update_8322() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
$save = FALSE;
if ('th' === $field_type_config['field_type_language_code']) {
if (!empty($field_type_config['spellcheck_field_type']['analyzer']['filters'])) {
foreach ($field_type_config['spellcheck_field_type']['analyzer']['filters'] as &$filter) {
if ('stopwords_th.txty' === $filter['words']) {
$filter['words'] = 'stopwords_th.txt';
$save = TRUE;
}
}
}
}
if ('tr' === $field_type_config['field_type_language_code']) {
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as $key => &$filter) {
if ('stopwords_tr.tx' === $filter['words']) {
$filter['words'] = 'stopwords_tr.txt';
$save = TRUE;
}
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
/**
* Fix path to ukrainian.dict for Solr 8.2.0.
*/
function search_api_solr_update_8323() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
if ('uk' === $field_type_config['field_type_language_code']) {
$save = FALSE;
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as &$filter) {
if ('solr.MorfologikFilterFactory' === $filter['class']) {
$filter['dictionary'] = 'ua/net/nlp/ukrainian.dict';
$save = TRUE;
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
}
/**
* Install new Norwegian configs if required.
*/
function search_api_solr_update_8324() {
// search_api_solr_update_helper_install_configs();
}
/**
* Fix the Polish phonetic field type.
*/
function search_api_solr_update_8325() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
$save = FALSE;
if ('text_phonetic_pl_7_0_0' === $field_type_config['id']) {
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers) && 'query' === $analyzers['type']) {
foreach ($analyzers['filters'] as $key => &$filter) {
if ('solr.WordDelimiterGraphFilterFactory' === $filter['class'] && 'protwords_de.txt' === $filter['protected']) {
$filter['protected'] = 'protwords_pl.txt';
$save = TRUE;
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
}
/**
* Replace the StempelPolishStemFilterFactory by the MorfologikFilterFactory.
*/
function search_api_solr_update_8326() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
if ('pl' === $field_type_config['field_type_language_code']) {
$save = FALSE;
foreach ($field_type_config['field_type'] as &$components) {
if (is_array($components)) {
foreach ($components as &$analyzers) {
if (is_array($analyzers)) {
foreach ($analyzers['filters'] as &$filter) {
if ('solr.StempelPolishStemFilterFactory' === $filter['class']) {
$filter['class'] = 'solr.MorfologikFilterFactory';
$save = TRUE;
}
}
}
}
}
}
if ($save) {
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
}
/**
* Update the Portuguese, Portugal config locale from 'pt' to 'pt-pt'.
*/
function search_api_solr_update_8327() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (!empty($field_type_config['field_type'])) {
if ('pt' === $field_type_config['field_type_language_code']) {
$config_factory = \Drupal::configFactory();
$config = $config_factory
->getEditable('search_api_solr.solr_field_type.text_pt_7_0_0.yml');
$config
->delete();
}
}
}
// search_api_solr_update_helper_install_configs();
}
/**
* Install Solr Cache Configs.
*/
function search_api_solr_update_8328() {
// search_api_solr_update_helper_install_configs();
foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
if (!isset($backend_config['environment'])) {
$backend_config['environment'] = 'default';
search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
}
}
}
/**
* Install Solr Request Handler Configs.
*/
function search_api_solr_update_8329() {
// search_api_solr_update_helper_install_configs();
}
/**
* Install Solr Request Dispatcher Configs.
*/
function search_api_solr_update_8330() {
// search_api_solr_update_helper_install_configs();
}
/**
* Install Solr Cache, Request Handler, Request Dispatcher config entity types.
*/
function search_api_solr_update_8331() {
$manager = \Drupal::entityDefinitionUpdateManager();
if ($manager
->getEntityType('solr_cache') === NULL) {
$manager
->installEntityType(new ConfigEntityType([
'id' => 'solr_cache',
'label' => new TranslatableMarkup('Solr Cache'),
'handlers' => [
'list_builder' => 'Drupal\\search_api_solr\\Controller\\SolrCacheListBuilder',
'form' => [],
],
'config_prefix' => 'solr_cache',
'admin_permission' => 'administer search_api',
'entity_keys' => [
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
'disabled' => 'disabled_caches',
],
'links' => [
'disable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_cache/{solr_cache}/disable',
'enable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_cache/{solr_cache}/enable',
'collection' => '/admin/config/search/search-api/server/{search_api_server}/solr_cache',
],
]));
}
if ($manager
->getEntityType('solr_request_dispatcher') === NULL) {
$manager
->installEntityType(new ConfigEntityType([
'id' => 'solr_request_dispatcher',
'label' => new TranslatableMarkup('Solr Request Dispatcher'),
'handlers' => [
'list_builder' => 'Drupal\\search_api_solr\\Controller\\SolrRequestDispatcherListBuilder',
'form' => [],
],
'config_prefix' => 'solr_request_dispatcher',
'admin_permission' => 'administer search_api',
'entity_keys' => [
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
'disabled' => 'disabled_request_dispatchers',
],
'links' => [
'disable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_dispatcher/{solr_request_dispatcher}/disable',
'enable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_dispatcher/{solr_request_dispatcher}/enable',
'collection' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_dispatcher',
],
]));
}
if ($manager
->getEntityType('solr_request_handler') === NULL) {
$manager
->installEntityType(new ConfigEntityType([
'id' => 'solr_request_handler',
'label' => new TranslatableMarkup('Solr Request Handler'),
'handlers' => [
'list_builder' => 'Drupal\\search_api_solr\\Controller\\SolrRequestHandlerListBuilder',
'form' => [],
],
'config_prefix' => 'solr_request_handler',
'admin_permission' => 'administer search_api',
'entity_keys' => [
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
'disabled' => 'disabled_request_handlers',
],
'links' => [
'disable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_handler/{solr_request_handler}/disable',
'enable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_handler/{solr_request_handler}/enable',
'collection' => '/admin/config/search/search-api/server/{search_api_server}/solr_request_handler',
],
]));
}
// For people who upgrade from 8.x-1.x using core >= 8.7.
if ($manager
->getEntityType('solr_field_type') === NULL) {
$manager
->installEntityType(new ConfigEntityType([
'id' => 'solr_field_type',
'label' => new TranslatableMarkup('Solr Field Type'),
'handlers' => [
'list_builder' => 'Drupal\\search_api_solr\\Controller\\SolrFieldTypeListBuilder',
'form' => [
'add' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeForm',
'edit' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeForm',
'delete' => 'Drupal\\search_api_solr\\Form\\SolrFieldTypeDeleteForm',
],
],
'config_prefix' => 'solr_field_type',
'admin_permission' => 'administer search_api',
'entity_keys' => [
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
'disabled' => 'disabled_field_types',
],
'links' => [
'edit-form' => '/admin/config/search/search-api/solr_field_type/{solr_field_type}',
'delete-form' => '/admin/config/search/search-api/solr_field_type/{solr_field_type}/delete',
'disable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/disable',
'enable-for-server' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/enable',
'collection' => '/admin/config/search/search-api/server/{search_api_server}/solr_field_type',
],
]));
}
else {
$entity_type = $manager
->getEntityType('solr_field_type');
$entity_keys = $entity_type
->get('entity_keys');
$entity_keys['disabled'] = 'disabled_field_types';
$entity_type
->set('entity_keys', $entity_keys);
$links = $entity_type
->get('links');
$links['disable-for-server'] = '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/disable';
$links['enable-for-server'] = '/admin/config/search/search-api/server/{search_api_server}/solr_field_type/{solr_field_type}/enable';
$entity_type
->set('links', $links);
$manager
->updateEntityType($entity_type);
}
search_api_solr_update_helper_install_configs();
}
/**
* Adds missing solr.ElisionFilterFactory to text_fr field query analyzer.
*/
function search_api_solr_update_8332() {
foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
if (strpos($field_type_name, 'search_api_solr.solr_field_type.text_fr') === 0) {
foreach ($field_type_config['field_type']['analyzers'] as $key => $analyzer) {
if ($analyzer['type'] === 'index') {
$index_analyzer = $analyzer;
}
if ($analyzer['type'] === 'query') {
$query_analyzer = $analyzer;
$query_analyzer_key = $key;
}
}
// Retrieve the filter position in the index analyzer:
foreach ($index_analyzer['filters'] as $filter_position => $filter) {
if ($filter['class'] === 'solr.ElisionFilterFactory') {
$elision_filter_position = $filter_position;
}
}
$proceed_update = TRUE;
foreach ($query_analyzer['filters'] as $filter_position => $filter) {
if ($filter['class'] === 'solr.ElisionFilterFactory') {
$proceed_update = FALSE;
}
}
// Adds the filter to the query if it isn't already in it:
if ($proceed_update) {
array_splice($query_analyzer['filters'], $elision_filter_position, 0, [
[
'class' => 'solr.ElisionFilterFactory',
],
]);
$field_type_config['field_type']['analyzers'][$query_analyzer_key] = $query_analyzer;
search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
}
}
}
}
Functions
Name | Description |
---|---|
search_api_solr_requirements | Implements hook_requirements(). |
search_api_solr_uninstall | Implements hook_uninstall(). |
search_api_solr_update_8001 | Split Solr paths stored in configurations into server and core parts. |
search_api_solr_update_8002 | Convert http_user and http_pass to username and password config for Solarium. |
search_api_solr_update_8003 | Add default timeout settings to existing configs. |
search_api_solr_update_8004 | Migrate existing backend configurations to the basic auth connector plugin. |
search_api_solr_update_8005 | Add commit_within settings to existing connector configs. |
search_api_solr_update_8006 | Add autocomplete settings to existing configs. |
search_api_solr_update_8007 | Remove old autocomplete settings in existing configs. |
search_api_solr_update_8008 | Remove obsolete settings in existing configs. |
search_api_solr_update_8200 | Install Solr Field Types. |
search_api_solr_update_8201 | Fix suggester field type. |
search_api_solr_update_8202 | Enable support for targeted domains for all backends and add custom codes. |
search_api_solr_update_8204 | Enable phrase suggestions support. |
search_api_solr_update_8205 | Drop never implemented word suggestions support. |
search_api_solr_update_8206 | Remove obsolete autocomplete settings. |
search_api_solr_update_8207 | Fix language undefined field types. |
search_api_solr_update_8208 | Enable new highlighter. |
search_api_solr_update_8211 | Add default finalize timeout settings to existing configs. |
search_api_solr_update_8212 | Configure highlighter individually per index and remove global config. |
search_api_solr_update_8213 | Configure index prefixes individually per server and index. |
search_api_solr_update_8300 | Migrate Solr backends to the new unified Solr backend. |
search_api_solr_update_8301 | Field types clean-up. |
search_api_solr_update_8302 | Re-install language-specific field types to enable the new spellcheckers. |
search_api_solr_update_8303 | Remove obsolete setting in config. |
search_api_solr_update_8304 | Convert site_hash from setting to state. |
search_api_solr_update_8305 | Add Dutch nouns and improve stemming for Dutch language. |
search_api_solr_update_8306 | Replace deprecated Solr filters by their successors for Solr 7. |
search_api_solr_update_8307 | Avoid redundant text files in generated Solr config files. |
search_api_solr_update_8308 | Configure multilingual features individually per index. |
search_api_solr_update_8309 | Solarium 5 adjustments. Warning! If you have overwritten the connection settings, don't forget to adjust the 'path'. See the release notes for details. |
search_api_solr_update_8310 | Enable language-specific collations. |
search_api_solr_update_8311 | Add the Polish diacritics to the language configs. Unset the obsolete min and max parameters from the CJKWidthFilter of the spellchecker (mainly for Japanese). |
search_api_solr_update_8312 | Add language-specific unstemmed field types. |
search_api_solr_update_8313 | Distinguish between simplified and traditional Chinese. |
search_api_solr_update_8314 | Enable language-unspecific collation. |
search_api_solr_update_8315 | Avoid Solr exceptions. |
search_api_solr_update_8316 | Use Ukrainian lemmatization instead of Russian SnowballPorterFilterFactory. |
search_api_solr_update_8317 | Replace erroneous Swedish default field type. |
search_api_solr_update_8318 | Replace solr.MorphologikFilterFactory by solr.MorfologikFilterFactory. |
search_api_solr_update_8319 | Fix Solr 6 Czech Field Type and improve spellcheckers. |
search_api_solr_update_8320 | Fix 2.x to 3.0 upgrade path of spellcheck components. |
search_api_solr_update_8321 | Fix Chinese Field Types. |
search_api_solr_update_8322 | Fix Thai and Turkish Field Types. |
search_api_solr_update_8323 | Fix path to ukrainian.dict for Solr 8.2.0. |
search_api_solr_update_8324 | Install new Norwegian configs if required. |
search_api_solr_update_8325 | Fix the Polish phonetic field type. |
search_api_solr_update_8326 | Replace the StempelPolishStemFilterFactory by the MorfologikFilterFactory. |
search_api_solr_update_8327 | Update the Portuguese, Portugal config locale from 'pt' to 'pt-pt'. |
search_api_solr_update_8328 | Install Solr Cache Configs. |
search_api_solr_update_8329 | Install Solr Request Handler Configs. |
search_api_solr_update_8330 | Install Solr Request Dispatcher Configs. |
search_api_solr_update_8331 | Install Solr Cache, Request Handler, Request Dispatcher config entity types. |
search_api_solr_update_8332 | Adds missing solr.ElisionFilterFactory to text_fr field query analyzer. |
search_api_solr_update_helper_get_backend_configs | Gets all backend configs for active Solr servers. |
search_api_solr_update_helper_get_field_type_configs | Gets all solr field type configs. |
search_api_solr_update_helper_get_indexes | Gets all index settings for Solr servers. |
search_api_solr_update_helper_get_index_third_party_settings | Gets all index third party settings for Solr servers. |
search_api_solr_update_helper_install_configs | Helper function to install all new configs. |
search_api_solr_update_helper_save_backend_config | Saves a modified backend config for a given Solr server. |
search_api_solr_update_helper_save_field_type_config | Saves a modified solr field type config. |
search_api_solr_update_helper_save_indexes | Saves a modified index config. |
search_api_solr_update_helper_save_index_third_party_settings | Saves a modified backend config for a given Solr server. |