toolshed-8.x-1.x-dev/modules/toolshed_search/src/Utility/SearchServerHelper.php
modules/toolshed_search/src/Utility/SearchServerHelper.php
<?php
namespace Drupal\toolshed_search\Utility;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Site\Settings;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\ServerInterface;
/**
* Helper function to make toolshed adjustments to Search API server settings.
*
* Toolshed search allows Solr server configurations to be controlled in the
* settings.php files. This includes switching the Solr connector plugin and
* setting "read only" flag at the server level (instead of just per index).
*
* This helper assists with finding those settings and applying them to the
* Search API server.
*/
class SearchServerHelper {
/**
* The settings service instance.
*
* @var \Drupal\Core\Site\Settings
*/
protected Settings $settings;
/**
* Entity storage handler for search_api server entities.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected EntityStorageInterface $serverStorage;
/**
* Creates a new instance of the SearchServerHelper class.
*
* @param \Drupal\Core\Site\Settings $settings
* The settings service instance.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(Settings $settings, EntityTypeManagerInterface $entity_type_manager) {
$this->settings = $settings;
$this->serverStorage = $entity_type_manager->getStorage('search_api_server');
}
/**
* Gets a Search API server in matching the server entity ID.
*
* @param string $server_id
* The server ID to fetch the server instance for.
*
* @return \Drupal\search_api\ServerInterface|null
* The server instance matching the requested ID if one was found, otherwise
* NULL is returned.
*/
protected function getServer($server_id): ?ServerInterface {
/** @var \Drupal\search_api\ServerInterface|null $server */
$server = $this->serverStorage->load($server_id);
return $server;
}
/**
* Get the toolshed search connector settings values for a Search API server.
*
* @param \Drupal\search_api\ServerInterface $server
* The Search API server entity to get the setting for.
*
* @return array|null
* The search connector settings values if the server has them. Otherwise
* return NULL.
*/
protected function getConnectorSettings(ServerInterface $server): ?array {
$config = $server->getBackendConfig();
if (!empty($config['connector']) && 'toolshed_settings' === $config['connector']) {
$hosts = $this->settings->get('solr_core_connector.hosts') ?? [];
$instance = $config['connector_config']['solr_instance'] ?? FALSE;
if ($instance && !empty($hosts[$instance])) {
return $hosts[$instance];
}
}
return NULL;
}
/**
* Check the Search API server connector settings for a plugin override.
*
* The Toolshed connector settings can specify that a different connector
* plugin should be used. If the connector instance settings, has a
* "plugin_id" value specified, switch the configured connector ID.
*
* @param \Drupal\search_api\ServerInterface $server
* The Search API entity instance to check the connector settings for.
*/
public function alterBackendConnector(ServerInterface $server): void {
$settings = $this->getConnectorSettings($server);
// If the settings are overriding the connector plugin settings, override
// the plugin and connector configurations. This is usually an override
// for a specific environment.
if ($settings && !empty($settings['plugin_id'])) {
$backendConfig = $server->getBackendConfig();
$backendConfig['connector'] = $settings['plugin_id'];
$overrides = $settings['plugin_overrides'] ?? [];
unset($backendConfig['connector_config']['solr_instance']);
$backendConfig['connector_config'] = $overrides + $backendConfig['connector_config'];
$server->setBackendConfig($backendConfig);
}
}
/**
* Apply the read-only status of Search API servers to their indexes.
*
* @param \Drupal\search_api\IndexInterface $index
* The index to check the server read-only status for. If server is set
* as read-only then this will alter the index to also be read-only.
*/
public function applyServerReadOnly(IndexInterface $index): void {
$serverId = $index->getServerId();
if (empty($serverId)) {
return;
}
// Get the server settings, and check if this server is set as read-only.
if ($server = $this->getServer($serverId)) {
$settings = $this->getConnectorSettings($server);
if (empty($settings['plugin_id']) && !empty($settings['read_only'])) {
$index->set('read_only', TRUE);
}
}
}
}
