Completed
Push — master ( 2e0ad9...b7a424 )
by Tobias
01:25
created

CommonClassesStrategy   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 2
dl 0
loc 113
ccs 0
cts 20
cp 0
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getCandidates() 0 21 5
A buzzInstantiate() 0 4 1
A symfonyPsr18Instantiate() 0 4 1
A isPsr17FactoryInstalled() 0 14 3
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
                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...
116
                    $candidates[] = $c;
117
                }
118
            }
119
120
            return $candidates;
121
        }
122
123
        if (isset(self::$classes[$type])) {
124
            return self::$classes[$type];
125
        }
126
127
        return [];
128
    }
129
130
    public static function buzzInstantiate()
131
    {
132
        return new \Buzz\Client\FileGetContents(MessageFactoryDiscovery::find());
133
    }
134
135
    public static function symfonyPsr18Instantiate()
136
    {
137
        return new SymfonyPsr18(null, Psr17FactoryDiscovery::findResponseFactory(), Psr17FactoryDiscovery::findStreamFactory());
138
    }
139
140
    /**
141
     * Can be used as a condition.
142
     *
143
     * @return bool
144
     */
145
    public static function isPsr17FactoryInstalled()
146
    {
147
        try {
148
            Psr17FactoryDiscovery::findResponseFactory();
149
        } catch (NotFoundException $e) {
150
            return false;
151
        } catch (\Throwable $e) {
152
            trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-17 ResponseFactory is available', get_class($e), $e->getMessage()), E_USER_WARNING);
153
154
            return false;
155
        }
156
157
        return true;
158
    }
159
}
160