toolshed-8.x-1.x-dev/modules/toolshed_search/src/Plugin/SolrConnector/SettingsSolrConnector.php

modules/toolshed_search/src/Plugin/SolrConnector/SettingsSolrConnector.php
<?php

namespace Drupal\toolshed_search\Plugin\SolrConnector;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Site\Settings;
use Drupal\search_api_solr\Plugin\SolrConnector\StandardSolrConnector;
use Drupal\search_api_solr\SearchApiSolrException;
use Solarium\QueryType\Update\Query\Query;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Solr connector where the connection settings are from the settings file.
 *
 * @SolrConnector(
 *   id = "toolshed_settings",
 *   label = @Translation("Settings file values"),
 *   description = @Translation("A connector that uses host settings from the site's settings.php file.")
 * )
 */
class SettingsSolrConnector extends StandardSolrConnector implements ContainerFactoryPluginInterface {

  /**
   * The site settings for the currently active site.
   *
   * @var \Drupal\Core\Site\Settings
   */
  protected Settings $settings;

  /**
   * Create a new instance of the SettingsSolrConnector connector plugin.
   *
   * @param array $configuration
   *   Plugin configuration array.
   * @param string $plugin_id
   *   The plugin unique identifier.
   * @param mixed $plugin_definition
   *   Plugin definition from the plugin manager.
   * @param \Drupal\Core\Site\Settings $settings
   *   Setting from the site settings file.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, Settings $settings) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->settings = $settings;

    try {
      $this->configuration = $this->generateConfiguration($this->configuration);
    }
    catch (SearchApiSolrException $e) {
      // If there was a settings error, log it and prevent use of these options.
      $this
        ->getLogger()
        ->error($e->getMessage());
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    $plugin = new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('settings')
    );

    $plugin->eventDispatcher = $container->get('event_dispatcher');
    return $plugin;
  }

  /**
   * Resolves the 'solr_instance' configuration value into Solr host settings.
   *
   * @param array $configuration
   *   Configuration to use in as defaults and to determine which set of
   *   settings to use from the Drupal settings.
   *
   * @return array
   *   The a configuration with the settings applied if the appropriate settings
   *   could be found with defaults applied. If no settings were found, it
   *   will just return the original settings back.
   */
  protected function generateConfiguration(array $configuration): array {
    $instances = $this->settings->get('solr_core_connector.hosts');
    $instance = $configuration['solr_instance'] ?? '';

    $settings = [];
    if (!empty($instances[$instance])) {
      $solrConfig = $instances[$instance] + parent::defaultConfiguration();
      $violations = [];

      // Validate the protocol scheme type.
      if (!preg_match('#https?#', $solrConfig['scheme'])) {
        $violations[] = $this->t('Only "http" and "https" are supported as scheme types.');
      }
      else {
        $settings['scheme'] = $solrConfig['scheme'];
      }

      // Validate the host name.
      if (preg_match('#[^\w\-_.]#', $solrConfig['host'])) {
        $violations[] = $this->t('Provider host should only contain letters, numbers, periods, hyphens or underscores.');
      }
      else {
        $settings['host'] = $solrConfig['host'];
      }

      // Validate the Solr path setting.
      if (strpos($solrConfig['path'], '/') !== 0) {
        $violations[] = $this->t('Provider path should start with a "%i"', ['%i' => '/']);
      }
      else {
        $settings['path'] = $solrConfig['path'];
      }

      // Validate a Solr core name.
      if (preg_match('#^/|[^\w\-_]#', $solrConfig['core'], $matches)) {
        $violations[] = (strpos($matches[0], '/') === 0)
          ? $this->t('Provider core should not start with "%i".', ['%i' => '/'])
          : $this->t('Provider core should only contain letters, numbers, hyphens or underscores.');
      }
      else {
        $settings['core'] = $solrConfig['core'];
      }

      $port = intval($solrConfig['port'] ?? 8983);
      if ($port > 0 && $port < 65535) {
        $settings['port'] = $port;
      }
      else {
        $violations[] = $this->t('Invalid port specified.');
      }

      // Apply basic auth if the credentials are provided, through settings.
      if (!empty($solrConfig['user']) && !empty($solrConfig['pass'])) {
        $settings['username'] = $solrConfig['user'];
        $settings['password'] = $solrConfig['pass'];
      }

      if (!empty($violations)) {
        throw new SearchApiSolrException(sprintf(
          "Format validation for the following Solr hosting settings: %s",
          '<ul><li>' . implode("</li><li> - ", $violations) . '</li></ul>'
        ));
      }
    }

    return $settings + $configuration;
  }

  /**
   * {@inheritdoc}
   *
   * @throws \Exception
   *   If this index in read-only mode.
   */
  public function getUpdateQuery(): Query {
    if (!empty($this->configuration['read_only'])) {
      $message = 'The Search API Server serving this index is currently in read-only mode.';
      $this->getLogger()->error($message);
      throw new \Exception($message);
    }

    return parent::getUpdateQuery();
  }

  /**
   * Get a list of keys to exclude from the Solr configurations.
   *
   * @return string[]
   *   List of keys which to exclude from the connector configuration.
   */
  protected function getExcludeConfigKeys(): array {
    return [
      'scheme' => 'scheme',
      'host' => 'host',
      'path' => 'path',
      'core' => 'core',
      'port' => 'port',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    // Allow all the defaults except for the ones provided by the settings.php
    // configuration arrays (@see generateConfiguration()).
    $defaults = array_diff_key(parent::defaultConfiguration(), $this->getExcludeConfigKeys());

    return $defaults + [
      'solr_instance' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function setConfiguration(array $configuration): void {
    // Set this to silence some notice warnings in the parent class.
    $configuration['port'] = 8983;

    parent::setConfiguration($configuration);

    // Ensure configurations set by the settings file should be filtered out
    // of the plugin configurations, and not saved.
    $this->configuration = array_diff_key($this->configuration, $this->getExcludeConfigKeys());
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form = parent::buildConfigurationForm($form, $form_state);
    $instances = $this->settings->get('solr_core_connector.hosts', []);

    $solrOpts = [];
    foreach ($instances as $key => $solrInstance) {
      $solrOpts[$key] = $solrInstance['label'] ?? $key;
    }

    if ($solrOpts) {
      $form['solr_instance'] = [
        '#type' => 'select',
        '#title' => $this->t('Solr instance settings'),
        '#required' => TRUE,
        '#weight' => -5,
        '#options' => $solrOpts,
        '#default_value' => $this->configuration['solr_instance'],
      ];
    }
    else {
      $form['solr_instance'] = [
        '#theme' => 'status_messages',
        '#status_headings' => [
          'error' => $this->t('No Solr servers available'),
        ],
        '#message_list' => [
          'error' => [
            $this->t('Unable to find any Solr configurations in the settings.php file. Add your Solr server settings to $settings["solr_core_connector.hosts"], see README.md for a full description of usage.'),
          ],
        ],
        '#weight' => -5,
      ];
    }

    // These are replaces by their respective @settings values.
    foreach ($this->getExcludeConfigKeys() as $configKey) {
      unset($form[$configKey]);
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state): void {
    if (!$form_state->hasAnyErrors()) {
      try {
        $values = $form_state->getValues();

        if (empty($values['solr_instance'])) {
          throw new \InvalidArgumentException();
        }

        $values = $this->generateConfiguration($values);

        // Try to orchestrate a server link from form values.
        $solr = $this->createClient($values);
        $solr->createEndpoint($values + ['key' => 'search_api_solr'], TRUE);
        $this->getServerLink();
      }
      catch (SearchApiSolrException $e) {
        $form_state->setError($form['solr_instance'], Markup::create($e->getMessage()));
      }
      catch (\InvalidArgumentException $e) {
        $form_state->setError($form['solr_instance'], $this->t('The server link generated from the form values is illegal.'));
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc