Completed
Push — master ( 27903a...838e7a )
by David
04:38 queued 03:33
created

CommonClassesStrategy::getCandidates()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 0
cts 10
cp 0
rs 8.8977
c 0
b 0
f 0
cc 6
nc 7
nop 1
crap 42
1
<?php
2
3
namespace Http\Discovery\Strategy;
4
5
use GuzzleHttp\Promise\Promise;
6
use GuzzleHttp\Psr7\Request as GuzzleRequest;
7
use Http\Client\HttpAsyncClient;
8
use Http\Client\HttpClient;
9
use Http\Discovery\Exception\NotFoundException;
10
use Http\Discovery\MessageFactoryDiscovery;
11
use Http\Discovery\Psr17FactoryDiscovery;
12
use Http\Message\RequestFactory;
13
use Psr\Http\Message\RequestFactoryInterface as Psr17RequestFactory;
14
use Http\Message\MessageFactory;
15
use Http\Message\MessageFactory\GuzzleMessageFactory;
16
use Http\Message\StreamFactory;
17
use Http\Message\StreamFactory\GuzzleStreamFactory;
18
use Http\Message\UriFactory;
19
use Http\Message\UriFactory\GuzzleUriFactory;
20
use Http\Message\MessageFactory\DiactorosMessageFactory;
21
use Http\Message\StreamFactory\DiactorosStreamFactory;
22
use Http\Message\UriFactory\DiactorosUriFactory;
23
use Psr\Http\Client\ClientInterface as Psr18Client;
24
use Zend\Diactoros\Request as DiactorosRequest;
25
use Http\Message\MessageFactory\SlimMessageFactory;
26
use Http\Message\StreamFactory\SlimStreamFactory;
27
use Http\Message\UriFactory\SlimUriFactory;
28
use Slim\Http\Request as SlimRequest;
29
use Http\Adapter\Guzzle6\Client as Guzzle6;
30
use Http\Adapter\Guzzle5\Client as Guzzle5;
31
use Http\Client\Curl\Client as Curl;
32
use Http\Client\Socket\Client as Socket;
33
use Http\Adapter\React\Client as React;
34
use Http\Adapter\Buzz\Client as Buzz;
35
use Http\Adapter\Cake\Client as Cake;
36
use Http\Adapter\Zend\Client as Zend;
37
use Http\Adapter\Artax\Client as Artax;
38
use Symfony\Component\HttpClient\HttplugClient as SymfonyHttplug;
39
use Symfony\Component\HttpClient\Psr18Client as SymfonyPsr18;
40
use Nyholm\Psr7\Factory\HttplugFactory as NyholmHttplugFactory;
41
42
/**
43
 * @internal
44
 *
45
 * @author Tobias Nyholm <[email protected]>
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, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
73
            ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
74
            ['class' => Curl::class, 'condition' => Curl::class],
75
            ['class' => React::class, 'condition' => React::class],
76
        ],
77
        HttpClient::class => [
78
            ['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
79
            ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
80
            ['class' => Guzzle5::class, 'condition' => Guzzle5::class],
81
            ['class' => Curl::class, 'condition' => Curl::class],
82
            ['class' => Socket::class, 'condition' => Socket::class],
83
            ['class' => Buzz::class, 'condition' => Buzz::class],
84
            ['class' => React::class, 'condition' => React::class],
85
            ['class' => Cake::class, 'condition' => Cake::class],
86
            ['class' => Zend::class, 'condition' => Zend::class],
87
            ['class' => Artax::class, 'condition' => Artax::class],
88
            [
89
                'class' => [self::class, 'buzzInstantiate'],
90
                'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
91
            ],
92
        ],
93
        Psr18Client::class => [
94
            [
95
                'class' => [self::class, 'symfonyPsr18Instantiate'],
96
                'condition' => [SymfonyPsr18::class, Psr17RequestFactory::class],
97
            ],
98
            [
99
                'class' => [self::class, 'buzzInstantiate'],
100
                'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
101
            ],
102
        ],
103
    ];
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public static function getCandidates($type)
109
    {
110
        if (Psr18Client::class === $type) {
111
            $candidates = self::$classes[PSR18Client::class];
112
113
            // HTTPlug 2.0 clients implements PSR18Client too.
114
            foreach (self::$classes[HttpClient::class] as $c) {
115
                try {
116
                    if (is_subclass_of($c['class'], Psr18Client::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Psr\Http\Client\ClientInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
117
                        $candidates[] = $c;
118
                    }
119
                } catch (\Throwable $e) {
120
                    trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-18 Client is available', get_class($e), $e->getMessage()), E_USER_WARNING);
121
                }
122
            }
123
124
            return $candidates;
125
        }
126
127
        if (isset(self::$classes[$type])) {
128
            return self::$classes[$type];
129
        }
130
131
        return [];
132
    }
133
134
    public static function buzzInstantiate()
135
    {
136
        return new \Buzz\Client\FileGetContents(MessageFactoryDiscovery::find());
137
    }
138
139
    public static function symfonyPsr18Instantiate()
140
    {
141
        return new SymfonyPsr18(null, Psr17FactoryDiscovery::findResponseFactory(), Psr17FactoryDiscovery::findStreamFactory());
142
    }
143
144
    /**
145
     * Can be used as a condition.
146
     *
147
     * @return bool
148
     */
149
    public static function isPsr17FactoryInstalled()
150
    {
151
        try {
152
            Psr17FactoryDiscovery::findResponseFactory();
153
        } catch (NotFoundException $e) {
154
            return false;
155
        } catch (\Throwable $e) {
156
            trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-17 ResponseFactory is available', get_class($e), $e->getMessage()), E_USER_WARNING);
157
158
            return false;
159
        }
160
161
        return true;
162
    }
163
}
164