vendor/php-http/discovery/src/Strategy/CommonClassesStrategy.php line 129

Open in your IDE?
  1. <?php
  2. namespace Http\Discovery\Strategy;
  3. use GuzzleHttp\Client as GuzzleHttp;
  4. use GuzzleHttp\Promise\Promise;
  5. use GuzzleHttp\Psr7\Request as GuzzleRequest;
  6. use Http\Adapter\Artax\Client as Artax;
  7. use Http\Adapter\Buzz\Client as Buzz;
  8. use Http\Adapter\Cake\Client as Cake;
  9. use Http\Adapter\Guzzle5\Client as Guzzle5;
  10. use Http\Adapter\Guzzle6\Client as Guzzle6;
  11. use Http\Adapter\Guzzle7\Client as Guzzle7;
  12. use Http\Adapter\React\Client as React;
  13. use Http\Client\Curl\Client as Curl;
  14. use Http\Client\HttpAsyncClient;
  15. use Http\Client\HttpClient;
  16. use Http\Client\Socket\Client as Socket;
  17. use Http\Discovery\ClassDiscovery;
  18. use Http\Discovery\Exception\NotFoundException;
  19. use Http\Discovery\MessageFactoryDiscovery;
  20. use Http\Discovery\Psr17FactoryDiscovery;
  21. use Http\Message\MessageFactory;
  22. use Http\Message\MessageFactory\DiactorosMessageFactory;
  23. use Http\Message\MessageFactory\GuzzleMessageFactory;
  24. use Http\Message\MessageFactory\SlimMessageFactory;
  25. use Http\Message\StreamFactory;
  26. use Http\Message\StreamFactory\DiactorosStreamFactory;
  27. use Http\Message\StreamFactory\GuzzleStreamFactory;
  28. use Http\Message\StreamFactory\SlimStreamFactory;
  29. use Http\Message\UriFactory;
  30. use Http\Message\UriFactory\DiactorosUriFactory;
  31. use Http\Message\UriFactory\GuzzleUriFactory;
  32. use Http\Message\UriFactory\SlimUriFactory;
  33. use Laminas\Diactoros\Request as DiactorosRequest;
  34. use Nyholm\Psr7\Factory\HttplugFactory as NyholmHttplugFactory;
  35. use Psr\Http\Client\ClientInterface as Psr18Client;
  36. use Psr\Http\Message\RequestFactoryInterface as Psr17RequestFactory;
  37. use Slim\Http\Request as SlimRequest;
  38. use Symfony\Component\HttpClient\HttplugClient as SymfonyHttplug;
  39. use Symfony\Component\HttpClient\Psr18Client as SymfonyPsr18;
  40. /**
  41.  * @internal
  42.  *
  43.  * @author Tobias Nyholm <tobias.nyholm@gmail.com>
  44.  *
  45.  * Don't miss updating src/Composer/Plugin.php when adding a new supported class.
  46.  */
  47. final class CommonClassesStrategy implements DiscoveryStrategy
  48. {
  49.     /**
  50.      * @var array
  51.      */
  52.     private static $classes = [
  53.         MessageFactory::class => [
  54.             ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
  55.             ['class' => GuzzleMessageFactory::class, 'condition' => [GuzzleRequest::class, GuzzleMessageFactory::class]],
  56.             ['class' => DiactorosMessageFactory::class, 'condition' => [DiactorosRequest::class, DiactorosMessageFactory::class]],
  57.             ['class' => SlimMessageFactory::class, 'condition' => [SlimRequest::class, SlimMessageFactory::class]],
  58.         ],
  59.         StreamFactory::class => [
  60.             ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
  61.             ['class' => GuzzleStreamFactory::class, 'condition' => [GuzzleRequest::class, GuzzleStreamFactory::class]],
  62.             ['class' => DiactorosStreamFactory::class, 'condition' => [DiactorosRequest::class, DiactorosStreamFactory::class]],
  63.             ['class' => SlimStreamFactory::class, 'condition' => [SlimRequest::class, SlimStreamFactory::class]],
  64.         ],
  65.         UriFactory::class => [
  66.             ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
  67.             ['class' => GuzzleUriFactory::class, 'condition' => [GuzzleRequest::class, GuzzleUriFactory::class]],
  68.             ['class' => DiactorosUriFactory::class, 'condition' => [DiactorosRequest::class, DiactorosUriFactory::class]],
  69.             ['class' => SlimUriFactory::class, 'condition' => [SlimRequest::class, SlimUriFactory::class]],
  70.         ],
  71.         HttpAsyncClient::class => [
  72.             ['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, Promise::class, [self::class, 'isPsr17FactoryInstalled']]],
  73.             ['class' => Guzzle7::class, 'condition' => Guzzle7::class],
  74.             ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
  75.             ['class' => Curl::class, 'condition' => Curl::class],
  76.             ['class' => React::class, 'condition' => React::class],
  77.         ],
  78.         HttpClient::class => [
  79.             ['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, [self::class, 'isPsr17FactoryInstalled']]],
  80.             ['class' => Guzzle7::class, 'condition' => Guzzle7::class],
  81.             ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
  82.             ['class' => Guzzle5::class, 'condition' => Guzzle5::class],
  83.             ['class' => Curl::class, 'condition' => Curl::class],
  84.             ['class' => Socket::class, 'condition' => Socket::class],
  85.             ['class' => Buzz::class, 'condition' => Buzz::class],
  86.             ['class' => React::class, 'condition' => React::class],
  87.             ['class' => Cake::class, 'condition' => Cake::class],
  88.             ['class' => Artax::class, 'condition' => Artax::class],
  89.             [
  90.                 'class' => [self::class, 'buzzInstantiate'],
  91.                 'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
  92.             ],
  93.         ],
  94.         Psr18Client::class => [
  95.             [
  96.                 'class' => [self::class, 'symfonyPsr18Instantiate'],
  97.                 'condition' => [SymfonyPsr18::class, Psr17RequestFactory::class],
  98.             ],
  99.             [
  100.                 'class' => GuzzleHttp::class,
  101.                 'condition' => [self::class, 'isGuzzleImplementingPsr18'],
  102.             ],
  103.             [
  104.                 'class' => [self::class, 'buzzInstantiate'],
  105.                 'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
  106.             ],
  107.         ],
  108.     ];
  109.     /**
  110.      * {@inheritdoc}
  111.      */
  112.     public static function getCandidates($type)
  113.     {
  114.         if (Psr18Client::class === $type) {
  115.             return self::getPsr18Candidates();
  116.         }
  117.         return self::$classes[$type] ?? [];
  118.     }
  119.     /**
  120.      * @return array The return value is always an array with zero or more elements. Each
  121.      *               element is an array with two keys ['class' => string, 'condition' => mixed].
  122.      */
  123.     private static function getPsr18Candidates()
  124.     {
  125.         $candidates self::$classes[Psr18Client::class];
  126.         // HTTPlug 2.0 clients implements PSR18Client too.
  127.         foreach (self::$classes[HttpClient::class] as $c) {
  128.             if (!is_string($c['class'])) {
  129.                 continue;
  130.             }
  131.             try {
  132.                 if (ClassDiscovery::safeClassExists($c['class']) && is_subclass_of($c['class'], Psr18Client::class)) {
  133.                     $candidates[] = $c;
  134.                 }
  135.             } catch (\Throwable $e) {
  136.                 trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-18 Client is available'get_class($e), $e->getMessage()), E_USER_WARNING);
  137.             }
  138.         }
  139.         return $candidates;
  140.     }
  141.     public static function buzzInstantiate()
  142.     {
  143.         return new \Buzz\Client\FileGetContents(MessageFactoryDiscovery::find());
  144.     }
  145.     public static function symfonyPsr18Instantiate()
  146.     {
  147.         return new SymfonyPsr18(nullPsr17FactoryDiscovery::findResponseFactory(), Psr17FactoryDiscovery::findStreamFactory());
  148.     }
  149.     public static function isGuzzleImplementingPsr18()
  150.     {
  151.         return defined('GuzzleHttp\ClientInterface::MAJOR_VERSION');
  152.     }
  153.     /**
  154.      * Can be used as a condition.
  155.      *
  156.      * @return bool
  157.      */
  158.     public static function isPsr17FactoryInstalled()
  159.     {
  160.         try {
  161.             Psr17FactoryDiscovery::findResponseFactory();
  162.         } catch (NotFoundException $e) {
  163.             return false;
  164.         } catch (\Throwable $e) {
  165.             trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-17 ResponseFactory is available'get_class($e), $e->getMessage()), E_USER_WARNING);
  166.             return false;
  167.         }
  168.         return true;
  169.     }
  170. }