UriFactory::factory()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace BenTools\UriFactory;
4
5
use BenTools\UriFactory\Adapter\AdapterInterface;
6
use BenTools\UriFactory\Adapter\GuzzleAdapter;
7
use BenTools\UriFactory\Adapter\LeagueUriAdapter;
8
use BenTools\UriFactory\Adapter\NyholmAdapter;
9
use BenTools\UriFactory\Adapter\ReactAdapter;
10
use BenTools\UriFactory\Adapter\RingCentralAdapter;
11
use Psr\Http\Message\UriInterface;
12
13
class UriFactory implements UriFactoryInterface
14
{
15
16
    /**
17
     * @var AdapterInterface[]
18
     */
19
    private $adapters = [];
20
21
    /**
22
     * UriFactory constructor.
23
     */
24
    protected function __construct()
25
    {
26
        $this->adapters = $this->getDefaultAdapters();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getDefaultAdapters() of type array<integer,string> is incompatible with the declared type BenTools\UriFactory\Adapter\AdapterInterface[] of property $adapters.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
27
    }
28
29
    /**
30
     * @return array
31
     */
32
    private function getDefaultAdapters(): array
33
    {
34
        return [
35
            NyholmAdapter::class,
36
            GuzzleAdapter::class,
37
            LeagueUriAdapter::class,
38
            RingCentralAdapter::class,
39
            ReactAdapter::class,
40
        ];
41
    }
42
43
    /**
44
     * @param string $uri
45
     * @param UriFactoryInterface|null $factory
46
     * @return UriInterface
47
     */
48
    public function createUri(string $uri = '', ?UriFactoryInterface $factory = null): UriInterface
49
    {
50
        if (null !== $factory) {
51
            return $factory->createUri($uri);
52
        }
53
54
        // Automatic discovery
55
        foreach ($this->adapters as $adapter) {
56
            if ($adapter::isInstalled()) {
57
                return $adapter::factory()->createUri($uri);
58
            }
59
        }
60
        throw new \RuntimeException(
61
            "No adapter is installed. Please install nyholm/psr7, ringcentral/psr7, guzzlehttp/psr7 or league/uri."
62
        );
63
    }
64
65
    /**
66
     * @param UriFactoryInterface|null $factory
67
     * @return UriInterface
68
     */
69
    public function createUriFromCurrentLocation(?UriFactoryInterface $factory = null): UriInterface
70
    {
71
        if (!isset($_SERVER['HTTP_HOST'])) {
72
            throw new \RuntimeException('$_SERVER[\'HTTP_HOST\'] has not been set.');
73
        }
74
        if (!isset($_SERVER['REQUEST_URI'])) {
75
            throw new \RuntimeException('$_SERVER[\'REQUEST_URI\'] has not been set.');
76
        }
77
        $currentLocation = sprintf(
78
            '%s://%s%s',
79
            $this->getSchemeFromServer($_SERVER),
80
            $_SERVER['HTTP_HOST'],
81
            $_SERVER['REQUEST_URI']
82
        );
83
        return $this->createUri($currentLocation, $factory);
84
    }
85
86
    /**
87
     * @param array $server
88
     * @return string
89
     */
90
    private function getSchemeFromServer(array $server): string
91
    {
92
        if (!empty($server['REQUEST_SCHEME'])) {
93
            return $server['REQUEST_SCHEME'];
94
        }
95
96
        switch ($server['HTTPS'] ?? null) {
97
            case 'on':
98
            case '1':
99
                return 'https';
100
        }
101
        return 'http';
102
    }
103
104
    /**
105
     * @return UriFactory
106
     */
107
    public static function factory(): UriFactoryInterface
108
    {
109
        return new self;
110
    }
111
}
112