Commit 413a91d8 authored by Matt Glaman's avatar Matt Glaman Committed by Matt Glaman
Browse files

Issue #3316883 by nkoporec: Remove usage of PSR-18 adapter to support Guzzle 6 and 7



DIT-952

Co-authored-by: default avatarnkoporec <me@nkoporec.com>
parent fefe74e8
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -6,8 +6,7 @@
    "require": {
        "drupal/search_api_solr": "^4.1.12",
        "http-interop/http-factory-guzzle": "^1.0",
        "guzzlehttp/guzzle": "^6.5 || ^7.2",
        "php-http/guzzle6-adapter": "^2.0 || ^3.0"
        "guzzlehttp/guzzle": "^6 || ^7"
    },
    "conflict": {
        "drupal/acquia_connector": "<3",
@@ -25,8 +24,5 @@
                "drush.services.yml": "^10 || ^11"
            }
        }
    },
    "suggest": {
        "php-http/guzzle6-adapter":"Required to use Acquia Connector with Guzzle 6 / Drupal 9.3 and lower"
    }
}
+0 −87
Original line number Diff line number Diff line
<?php

namespace Drupal\acquia_search\Client\Adapter;

use Http\Factory\Guzzle\RequestFactory;
use Http\Factory\Guzzle\StreamFactory;
use Psr\Http\Client\ClientInterface;
use Solarium\Core\Client\Adapter\AdapterInterface;
use Solarium\Core\Client\Adapter\Psr18Adapter;
use Solarium\Core\Client\Adapter\TimeoutAwareInterface;
use Solarium\Core\Client\Endpoint;
use Solarium\Core\Client\Request;
use Solarium\Core\Client\Response;

/**
 * Psr18 Adapter that implements TimeoutAwareInterface.
 */
class TimeoutAwarePsr18Adapter implements AdapterInterface, TimeoutAwareInterface {

  /**
   * Timeout in seconds.
   *
   * @var int
   */
  protected $timeout;

  /**
   * Solarium Psr18 Adapter.
   *
   * @var \Solarium\Core\Client\Adapter\Psr18Adapter
   */
  protected $psr18Adapter;

  /**
   * Constructor of TimeoutAwarePsr18Adapter.
   *
   * @param \Psr\Http\Client\ClientInterface $httpClient
   *   Guzzle HTTP Client.
   */
  public function __construct(ClientInterface $httpClient) {
    $this->psr18Adapter = new Psr18Adapter(
      $httpClient,
      new RequestFactory(),
      new StreamFactory()
    );
  }

  /**
   * Retrieves adapter timeout.
   *
   * @return int
   *   Timeout in seconds.
   */
  public function getTimeout(): int {
    return $this->timeout;
  }

  /**
   * Sets adapter timeout.
   *
   * @param int $timeoutInSeconds
   *   Timeout in seconds.
   */
  public function setTimeout(int $timeoutInSeconds): void {
    $this->timeout = $timeoutInSeconds;
  }

  /**
   * Executes request.
   *
   * @param \Solarium\Core\Client\Request $request
   *   Solarium Request.
   * @param \Solarium\Core\Client\Endpoint $endpoint
   *   Solarium Endpoint.
   *
   * @return \Solarium\Core\Client\Response
   *   Solarium response object.
   */
  public function execute(Request $request, Endpoint $endpoint): Response {
    $request->setOptions([
      'timeout' => $this->timeout,
    ]);

    return $this->psr18Adapter->execute($request, $endpoint);
  }

}
+1 −29
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@

namespace Drupal\acquia_search\Plugin\SolrConnector;

use Drupal\acquia_search\Client\Adapter\TimeoutAwarePsr18Adapter;
use Drupal\acquia_search\Helper\Messages;
use Drupal\acquia_search\Helper\Runtime;
use Drupal\acquia_search\Helper\Storage;
@@ -11,10 +10,6 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\search_api_solr\SolrConnector\SolrConnectorPluginBase;
use GuzzleHttp\Client as GuzzleClient;
use Http\Adapter\Guzzle6\Client as Guzzle6Client;
use Psr\Http\Client\ClientInterface;
use Solarium\Core\Client\Client;
use Solarium\Core\Client\Endpoint;
use Solarium\Exception\UnexpectedValueException;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -318,38 +313,16 @@ class SearchApiSolrAcquiaConnector extends SolrConnectorPluginBase {
   * {@inheritdoc}
   */
  protected function connect() {

    if ($this->solr) {
      return;
    }

    // Create a PSR-18 adapter instance, since Solarium's HTTP adapter is
    // incompatible with remote_stream_wrapper.
    // See https://www.drupal.org/project/acquia_search/issues/3209704
    // And https://www.drupal.org/project/acquia_search_solr/issues/3171407
    $httpClient = new GuzzleClient();
    if (!($httpClient instanceof ClientInterface)) {
      // BC for Drupal 9 and 8 using Guzzle 6.
      if (class_exists(Guzzle6Client::class)) {
        $httpClient = new Guzzle6Client();
      }
      else {
        \Drupal::logger('acquia_search')->error("Guzzle7 or php-http/guzzle6-adapter is required to use Acquia Search");
        return FALSE;
      }
    }

    $adapter = new TimeoutAwarePsr18Adapter($httpClient);

    $this->solr = new Client($adapter, $this->eventDispatcher);

    // Scheme should always be https and port 443.
    $this->configuration['scheme'] = 'https';
    $this->configuration['port'] = 443;
    $this->configuration['key'] = self::ENDPOINT_KEY;
    $this->configuration['path'] = '/';
    $this->configuration[self::QUERY_TIMEOUT] = $this->configuration['timeout'];

    $this->solr = $this->createClient($this->configuration);
    $this->solr->createEndpoint($this->configuration, TRUE);
    $this->solr->registerPlugin('acquia_solr_search_subscriber', $this->searchSubscriber);
  }
@@ -361,7 +334,6 @@ class SearchApiSolrAcquiaConnector extends SolrConnectorPluginBase {
   *   Renderable array.
   */
  protected function getAcquiaSearchCores(): array {

    if (!$this->storage->getApiKey() || !$this->storage->getIdentifier() || !$this->storage->getUuid() || !$this->storage->getApiHost()) {
      return [
        '#markup' => $this->t('Please provide API credentials for Acquia Search.'),