vendor/friendsofsymfony/elastica-bundle/src/Elastica/Client.php line 56

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSElasticaBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <https://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\ElasticaBundle\Elastica;
  11. use Elastica\Client as BaseClient;
  12. use Elastica\Exception\ClientException;
  13. use Elastica\Exception\ExceptionInterface;
  14. use Elastica\Index as BaseIndex;
  15. use Elastica\Request;
  16. use Elastica\Response;
  17. use FOS\ElasticaBundle\Logger\ElasticaLogger;
  18. use Symfony\Component\Stopwatch\Stopwatch;
  19. /**
  20.  * Extends the default Elastica client to provide logging for errors that occur
  21.  * during communication with ElasticSearch.
  22.  *
  23.  * @author Gordon Franke <info@nevalon.de>
  24.  */
  25. class Client extends BaseClient
  26. {
  27.     /**
  28.      * Stores created indexes to avoid recreation.
  29.      *
  30.      * @var array<string, BaseIndex>
  31.      */
  32.     private $indexCache = [];
  33.     /**
  34.      * Stores created index template to avoid recreation.
  35.      *
  36.      * @var array<string, IndexTemplate>
  37.      */
  38.     private $indexTemplateCache = [];
  39.     /**
  40.      * Symfony's debugging Stopwatch.
  41.      *
  42.      * @var Stopwatch|null
  43.      */
  44.     private $stopwatch;
  45.     /**
  46.      * @param array<mixed> $data
  47.      * @param array<mixed> $query
  48.      */
  49.     public function request(string $pathstring $method Request::GET$data = [], array $query = [], string $contentType Request::DEFAULT_CONTENT_TYPE): Response
  50.     {
  51.         if ($this->stopwatch) {
  52.             $this->stopwatch->start('es_request''fos_elastica');
  53.         }
  54.         try {
  55.             $response parent::request($path$method$data$query$contentType);
  56.         } catch (ExceptionInterface $e) {
  57.             $this->logQuery($path$method$data$query000);
  58.             throw $e;
  59.         }
  60.         $responseData $response->getData();
  61.         $transportInfo $response->getTransferInfo();
  62.         $connection $this->getLastRequest()->getConnection();
  63.         $forbiddenHttpCodes $connection->hasConfig('http_error_codes') ? $connection->getConfig('http_error_codes') : [];
  64.         if (isset($transportInfo['http_code']) && \in_array($transportInfo['http_code'], $forbiddenHttpCodestrue)) {
  65.             $body \json_encode($responseData);
  66.             $message \sprintf('Error in transportInfo: response code is %s, response body is %s'$transportInfo['http_code'], $body);
  67.             throw new ClientException($message);
  68.         }
  69.         if (isset($responseData['took'], $responseData['hits'])) {
  70.             $this->logQuery($path$method$data$query$response->getQueryTime(), $response->getEngineTime(), $responseData['hits']['total']['value'] ?? 0);
  71.         } else {
  72.             $this->logQuery($path$method$data$query$response->getQueryTime(), 00);
  73.         }
  74.         if ($this->stopwatch) {
  75.             $this->stopwatch->stop('es_request');
  76.         }
  77.         return $response;
  78.     }
  79.     public function getIndex(string $name): BaseIndex
  80.     {
  81.         // TODO PHP >= 7.4 ??=
  82.         return $this->indexCache[$name] ?? ($this->indexCache[$name] = new Index($this$name));
  83.     }
  84.     /**
  85.      * @param string $name
  86.      */
  87.     public function getIndexTemplate($name): IndexTemplate
  88.     {
  89.         // TODO PHP >= 7.4 ??=
  90.         return $this->indexTemplateCache[$name] ?? ($this->indexTemplateCache[$name] = new IndexTemplate($this$name));
  91.     }
  92.     /**
  93.      * Sets a stopwatch instance for debugging purposes.
  94.      */
  95.     public function setStopwatch(?Stopwatch $stopwatch null): void
  96.     {
  97.         $this->stopwatch $stopwatch;
  98.     }
  99.     /**
  100.      * Log the query if we have an instance of ElasticaLogger.
  101.      *
  102.      * @param array<mixed>|string $data
  103.      * @param array<mixed>        $query
  104.      * @param float               $queryTime
  105.      * @param int                 $engineMS
  106.      */
  107.     private function logQuery(string $pathstring $method$data, array $query$queryTime$engineMS 0int $itemCount 0): void
  108.     {
  109.         if (!$this->_logger instanceof ElasticaLogger) {
  110.             return;
  111.         }
  112.         $connection $this->getLastRequest()->getConnection();
  113.         $connectionArray = [
  114.             'host' => $connection->getHost(),
  115.             'port' => $connection->getPort(),
  116.             'transport' => $connection->getTransport(),
  117.             'headers' => $connection->hasConfig('headers') ? $connection->getConfig('headers') : [],
  118.         ];
  119.         $this->_logger->logQuery($path$method$data$queryTime$connectionArray$query$engineMS$itemCount);
  120.     }
  121. }