UriFactory::detectPath()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 4
nc 5
nop 1
1
<?php
2
3
namespace OAuth\Common\Http\Uri;
4
5
use RuntimeException;
6
7
/**
8
 * Factory class for uniform resource indicators.
9
 */
10
class UriFactory implements UriFactoryInterface
11
{
12
    /**
13
     * Factory method to build a URI from a super-global $_SERVER array.
14
     *
15
     * @return UriInterface
16
     */
17
    public function createFromSuperGlobalArray(array $_server)
18
    {
19
        if ($uri = $this->attemptProxyStyleParse($_server)) {
20
            return $uri;
21
        }
22
23
        $scheme = $this->detectScheme($_server);
24
        $host = $this->detectHost($_server);
25
        $port = $this->detectPort($_server);
26
        $path = $this->detectPath($_server);
27
        $query = $this->detectQuery($_server);
28
29
        return $this->createFromParts($scheme, '', $host, $port, $path, $query);
30
    }
31
32
    /**
33
     * @param string $absoluteUri
34
     *
35
     * @return UriInterface
36
     */
37
    public function createFromAbsolute($absoluteUri)
38
    {
39
        return new Uri($absoluteUri);
40
    }
41
42
    /**
43
     * Factory method to build a URI from parts.
44
     *
45
     * @param string $scheme
46
     * @param string $userInfo
47
     * @param string $host
48
     * @param string $port
49
     * @param string $path
50
     * @param string $query
51
     * @param string $fragment
52
     *
53
     * @return UriInterface
54
     */
55
    public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '')
56
    {
57
        $uri = new Uri();
58
        $uri->setScheme($scheme);
59
        $uri->setUserInfo($userInfo);
60
        $uri->setHost($host);
61
        $uri->setPort($port);
62
        $uri->setPath($path);
63
        $uri->setQuery($query);
64
        $uri->setFragment($fragment);
65
66
        return $uri;
67
    }
68
69
    /**
70
     * @param array $_server
71
     *
72
     * @return null|UriInterface
73
     */
74
    private function attemptProxyStyleParse($_server)
75
    {
76
        // If the raw HTTP request message arrives with a proxy-style absolute URI in the
77
        // initial request line, the absolute URI is stored in $_SERVER['REQUEST_URI'] and
78
        // we only need to parse that.
79
        if (isset($_server['REQUEST_URI']) && parse_url($_server['REQUEST_URI'], PHP_URL_SCHEME)) {
80
            return new Uri($_server['REQUEST_URI']);
81
        }
82
83
        return null;
84
    }
85
86
    /**
87
     * @param array $_server
88
     *
89
     * @return string
90
     */
91
    private function detectPath($_server)
92
    {
93
        if (isset($_server['REQUEST_URI'])) {
94
            $uri = $_server['REQUEST_URI'];
95
        } elseif (isset($_server['REDIRECT_URL'])) {
96
            $uri = $_server['REDIRECT_URL'];
97
        } else {
98
            throw new RuntimeException('Could not detect URI path from superglobal');
99
        }
100
101
        $queryStr = strpos($uri, '?');
102
        if ($queryStr !== false) {
103
            $uri = substr($uri, 0, $queryStr);
104
        }
105
106
        return $uri;
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    private function detectHost(array $_server)
113
    {
114
        $host = $_server['HTTP_HOST'] ?? '';
115
116
        if (strstr($host, ':')) {
117
            $host = parse_url($host, PHP_URL_HOST);
118
        }
119
120
        return $host;
121
    }
122
123
    /**
124
     * @return string
125
     */
126
    private function detectPort(array $_server)
127
    {
128
        return $_server['SERVER_PORT'] ?? 80;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    private function detectQuery(array $_server)
135
    {
136
        return $_server['QUERY_STRING'] ?? '';
137
    }
138
139
    /**
140
     * Determine URI scheme component from superglobal array.
141
     *
142
     * When using ISAPI with IIS, the value will be "off" if the request was
143
     * not made through the HTTPS protocol. As a result, we filter the
144
     * value to a bool.
145
     *
146
     * @param array $_server A super-global $_SERVER array
147
     *
148
     * @return string Returns http or https depending on the URI scheme
149
     */
150
    private function detectScheme(array $_server)
151
    {
152
        if (isset($_server['HTTPS']) && filter_var($_server['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
153
            return 'https';
154
        }
155
156
        return 'http';
157
    }
158
}
159