PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / libraries / http / discovery / Strategy / CommonClassesStrategy.php

CommonClassesStrategy.php in DecaLog 4.4.0, at includes/libraries/http/discovery/Strategy/CommonClassesStrategy.php

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