vendor/meilisearch/meilisearch-php/src/Http/Client.php line 48

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Meilisearch\Http;
  4. use Http\Discovery\Psr17FactoryDiscovery;
  5. use Http\Discovery\Psr18ClientDiscovery;
  6. use Meilisearch\Contracts\Http;
  7. use Meilisearch\Exceptions\ApiException;
  8. use Meilisearch\Exceptions\CommunicationException;
  9. use Meilisearch\Exceptions\InvalidResponseBodyException;
  10. use Meilisearch\Exceptions\JsonDecodingException;
  11. use Meilisearch\Exceptions\JsonEncodingException;
  12. use Meilisearch\Http\Serialize\Json;
  13. use Meilisearch\Meilisearch;
  14. use Psr\Http\Client\ClientExceptionInterface;
  15. use Psr\Http\Client\ClientInterface;
  16. use Psr\Http\Client\NetworkExceptionInterface;
  17. use Psr\Http\Message\RequestFactoryInterface;
  18. use Psr\Http\Message\RequestInterface;
  19. use Psr\Http\Message\ResponseInterface;
  20. use Psr\Http\Message\StreamFactoryInterface;
  21. class Client implements Http
  22. {
  23.     private ClientInterface $http;
  24.     private RequestFactoryInterface $requestFactory;
  25.     private StreamFactoryInterface $streamFactory;
  26.     private array $headers;
  27.     private ?string $apiKey;
  28.     private string $baseUrl;
  29.     private Json $json;
  30.     /**
  31.      * Client constructor.
  32.      */
  33.     public function __construct(
  34.         string $url,
  35.         string $apiKey null,
  36.         ClientInterface $httpClient null,
  37.         RequestFactoryInterface $reqFactory null,
  38.         array $clientAgents = [],
  39.         StreamFactoryInterface $streamFactory null
  40.     ) {
  41.         $this->baseUrl $url;
  42.         $this->apiKey $apiKey;
  43.         $this->http $httpClient ?? Psr18ClientDiscovery::find();
  44.         $this->requestFactory $reqFactory ?? Psr17FactoryDiscovery::findRequestFactory();
  45.         $this->streamFactory $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory();
  46.         $this->headers array_filter([
  47.             'User-Agent' => implode(';'array_merge($clientAgents, [Meilisearch::qualifiedVersion()])),
  48.         ]);
  49.         if (null != $this->apiKey) {
  50.             $this->headers['Authorization'] = sprintf('Bearer %s'$this->apiKey);
  51.         }
  52.         $this->json = new Json();
  53.     }
  54.     /**
  55.      * @return mixed
  56.      *
  57.      * @throws ClientExceptionInterface
  58.      * @throws ApiException
  59.      * @throws CommunicationException
  60.      */
  61.     public function get(string $path, array $query = [])
  62.     {
  63.         $request $this->requestFactory->createRequest(
  64.             'GET',
  65.             $this->baseUrl.$path.$this->buildQueryString($query)
  66.         );
  67.         return $this->execute($request);
  68.     }
  69.     /**
  70.      * @param mixed|null $body
  71.      *
  72.      * @return mixed
  73.      *
  74.      * @throws ApiException
  75.      * @throws ClientExceptionInterface
  76.      * @throws CommunicationException
  77.      * @throws JsonEncodingException
  78.      */
  79.     public function post(string $path$body null, array $query = [], string $contentType null)
  80.     {
  81.         if (!\is_null($contentType)) {
  82.             $this->headers['Content-type'] = $contentType;
  83.         } else {
  84.             $this->headers['Content-type'] = 'application/json';
  85.             $body $this->json->serialize($body);
  86.         }
  87.         $request $this->requestFactory->createRequest(
  88.             'POST',
  89.             $this->baseUrl.$path.$this->buildQueryString($query)
  90.         )->withBody($this->streamFactory->createStream($body));
  91.         return $this->execute($request);
  92.     }
  93.     public function put(string $path$body null, array $query = [], string $contentType null)
  94.     {
  95.         if (!\is_null($contentType)) {
  96.             $this->headers['Content-type'] = $contentType;
  97.         } else {
  98.             $this->headers['Content-type'] = 'application/json';
  99.             $body $this->json->serialize($body);
  100.         }
  101.         $request $this->requestFactory->createRequest(
  102.             'PUT',
  103.             $this->baseUrl.$path.$this->buildQueryString($query)
  104.         )->withBody($this->streamFactory->createStream($body));
  105.         return $this->execute($request);
  106.     }
  107.     /**
  108.      * @param mixed|null $body
  109.      *
  110.      * @return mixed
  111.      *
  112.      * @throws ApiException
  113.      * @throws JsonEncodingException
  114.      */
  115.     public function patch(string $path$body null, array $query = [])
  116.     {
  117.         $this->headers['Content-type'] = 'application/json';
  118.         $request $this->requestFactory->createRequest(
  119.             'PATCH',
  120.             $this->baseUrl.$path.$this->buildQueryString($query)
  121.         )->withBody($this->streamFactory->createStream($this->json->serialize($body)));
  122.         return $this->execute($request);
  123.     }
  124.     /**
  125.      * @return mixed
  126.      *
  127.      * @throws ClientExceptionInterface
  128.      * @throws ApiException
  129.      */
  130.     public function delete(string $path, array $query = [])
  131.     {
  132.         $request $this->requestFactory->createRequest(
  133.             'DELETE',
  134.             $this->baseUrl.$path.$this->buildQueryString($query)
  135.         );
  136.         return $this->execute($request);
  137.     }
  138.     /**
  139.      * @return mixed
  140.      *
  141.      * @throws ApiException
  142.      * @throws ClientExceptionInterface
  143.      * @throws CommunicationException
  144.      */
  145.     private function execute(RequestInterface $request)
  146.     {
  147.         foreach ($this->headers as $header => $value) {
  148.             $request $request->withAddedHeader($header$value);
  149.         }
  150.         try {
  151.             return $this->parseResponse($this->http->sendRequest($request));
  152.         } catch (NetworkExceptionInterface $e) {
  153.             throw new CommunicationException($e->getMessage(), $e->getCode(), $e);
  154.         }
  155.     }
  156.     private function buildQueryString(array $queryParams = []): string
  157.     {
  158.         return \count($queryParams) > '?'.http_build_query($queryParams) : '';
  159.     }
  160.     /**
  161.      * @return mixed
  162.      *
  163.      * @throws ApiException
  164.      * @throws InvalidResponseBodyException
  165.      * @throws JsonDecodingException
  166.      */
  167.     private function parseResponse(ResponseInterface $response)
  168.     {
  169.         if (204 === $response->getStatusCode()) {
  170.             return null;
  171.         }
  172.         if (!\in_array('application/json'$response->getHeader('content-type'), true)) {
  173.             throw new InvalidResponseBodyException($response$response->getBody()->getContents());
  174.         }
  175.         if ($response->getStatusCode() >= 300) {
  176.             $body $this->json->unserialize($response->getBody()->getContents()) ?? $response->getReasonPhrase();
  177.             throw new ApiException($response$body);
  178.         }
  179.         return $this->json->unserialize($response->getBody()->getContents());
  180.     }
  181. }