Request::detectSsl()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 10
nc 4
nop 0
dl 0
loc 14
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace BFW;
4
5
/**
6
 * Class to get informations about http request.
7
 * Singleton pattern.
8
 */
9
class Request
10
{
11
    /**
12
     * @const ERR_KEY_NOT_EXIST Exception code if a key not exist into the
13
     * $_SERVER array.
14
     */
15
    const ERR_KEY_NOT_EXIST = 1107001;
16
    
17
    /**
18
     * @var \BFW\Request $instance Instance for this class (singleton pattern)
19
     */
20
    protected static $instance = null;
21
22
    /**
23
     * @var string $ip The client IP
24
     */
25
    protected $ip = '';
26
27
    /**
28
     * @var string $lang The client primary language
29
     */
30
    protected $lang = '';
31
32
    /**
33
     * @var string $referer The referer url
34
     */
35
    protected $referer = '';
36
37
    /**
38
     * @var string $method The HTTP method (GET/POST/PUT/DELETE/...)
39
     */
40
    protected $method = '';
41
42
    /**
43
     * @var boolean|null $ssl If the request is with ssl (https) or not
44
     */
45
    protected $ssl;
46
47
    /**
48
     * @var \stdClass|null The current request
49
     */
50
    protected $request;
51
52
    /**
53
     * Create singleton instance for this class
54
     * 
55
     * @return \BFW\Request
56
     */
57
    public static function getInstance(): Request
58
    {
59
        if (self::$instance === null) {
60
            $calledClass    = get_called_class(); //Autorize extends this class
61
            self::$instance = new $calledClass;
62
        }
63
64
        return self::$instance;
65
    }
66
67
    /**
68
     * Get the client IP
69
     * 
70
     * @return string
71
     */
72
    public function getIp(): string
73
    {
74
        return $this->ip;
75
    }
76
77
    /**
78
     * Get the client primary language
79
     * 
80
     * @return string
81
     */
82
    public function getLang(): string
83
    {
84
        return $this->lang;
85
    }
86
87
    /**
88
     * Get the referer url
89
     * 
90
     * @return string
91
     */
92
    public function getReferer(): string
93
    {
94
        return $this->referer;
95
    }
96
97
    /**
98
     * Get the http method
99
     * 
100
     * @return string
101
     */
102
    public function getMethod(): string
103
    {
104
        return $this->method;
105
    }
106
107
    /**
108
     * Get information about if the request is ssl
109
     * 
110
     * @return boolean|null
111
     */
112
    public function getSsl()
113
    {
114
        return $this->ssl;
115
    }
116
117
    /**
118
     * Get the current request
119
     * 
120
     * @return \stdClass|null
121
     */
122
    public function getRequest()
123
    {
124
        return $this->request;
125
    }
126
127
    /**
128
     * Get the information from the $_SERVER array if the key exist.
129
     * If not exist, return an exception.
130
     * 
131
     * @param string $keyName The key's value in $_SERVER array
132
     * 
133
     * @return string
134
     * 
135
     * @throws \Exception If the key not exist into $_SERVER
136
     */
137
    public static function getServerValue(string $keyName): string
138
    {
139
        if (!isset($_SERVER[$keyName])) {
140
            throw new \Exception(
141
                'The key '.$keyName.' not exist into $_SERVER array',
142
                self::ERR_KEY_NOT_EXIST
143
            );
144
        }
145
146
        return $_SERVER[$keyName];
147
    }
148
    
149
    /**
150
     * Get the information from the $_SERVER array if the key exist.
151
     * If not exist, return a empty string.
152
     * 
153
     * @param string $keyName The key's value in $_SERVER array
154
     * 
155
     * @return string
156
     */
157
    protected function serverValue(string $keyName): string
158
    {
159
        $calledClass = get_called_class(); //Autorize extends this class
160
        
161
        try {
162
            return $calledClass::getServerValue($keyName);
163
        } catch (\Exception $e) {
164
            return '';
165
        }
166
    }
167
    
168
    /**
169
     * Run all detect method
170
     * 
171
     * @return void
172
     */
173
    public function runDetect()
174
    {
175
        $this->detectIp();
176
        $this->detectLang();
177
        $this->detectReferer();
178
        $this->detectMethod();
179
        $this->detectSsl();
180
        $this->detectRequest();
181
    }
182
183
    /**
184
     * Detect the client IP
185
     * 
186
     * @return void
187
     */
188
    protected function detectIp()
189
    {
190
        $this->ip = $this->serverValue('REMOTE_ADDR');
191
    }
192
193
    /**
194
     * Detect the primary client's language
195
     * 
196
     * @return void
197
     */
198
    protected function detectLang()
199
    {
200
        /*
201
         * HTTP_ACCEPT_LANGUAGE -> fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
202
         * First "fr-FR" (preference 1/1)
203
         * After in the order, "fr" (preference 0.8 / 1)
204
         * Next "en-US" (preference 0.6/1)
205
         * End "en" (preference 0.4/1)
206
         **/
207
        
208
        $acceptLanguage = $this->serverValue('HTTP_ACCEPT_LANGUAGE');
209
        if (empty($acceptLanguage)) {
210
            $this->lang = '';
211
            return;
212
        }
213
        
214
        $acceptedLangs = explode(',', $acceptLanguage);
215
        $firstLang     = explode(';', $acceptedLangs[0]);
216
        $lang          = strtolower($firstLang[0]);
217
218
        if (strpos($lang, '-') !== false) {
219
            $minLang = explode('-', $lang);
220
            $lang    = $minLang[0];
221
        }
222
223
        $this->lang = $lang;
224
    }
225
226
    /**
227
     * Detect the referer page
228
     * 
229
     * @return void
230
     */
231
    protected function detectReferer()
232
    {
233
        $this->referer = $this->serverValue('HTTP_REFERER');
234
    }
235
236
    /**
237
     * Detect the http method
238
     * 
239
     * @return void
240
     */
241
    protected function detectMethod()
242
    {
243
        $this->method = $this->serverValue('REQUEST_METHOD');
244
    }
245
246
    /**
247
     * Detect if the request is with ssl (https)
248
     * 
249
     * @return void
250
     */
251
    protected function detectSsl()
252
    {
253
        $serverHttps = $this->serverValue('HTTPS');
254
        $fwdProto    = $this->serverValue('HTTP_X_FORWARDED_PROTO');
255
        $fwdSsl      = $this->serverValue('HTTP_X_FORWARDED_SSL');
256
257
        $this->ssl = false;
258
259
        if (!empty($serverHttps) && $serverHttps !== 'off') {
260
            $this->ssl = true;
261
        } elseif (!empty($fwdProto) && $fwdProto === 'https') {
262
            $this->ssl = true;
263
        } elseif (!empty($fwdSsl) && $fwdSsl === 'on') {
264
            $this->ssl = true;
265
        }
266
    }
267
268
    /**
269
     * Detect the current request informations
270
     * 
271
     * @return void
272
     */
273
    protected function detectRequest()
274
    {
275
        $parseUrl = parse_url($this->serverValue('REQUEST_URI'));
276
        $scheme   = ($this->ssl === true) ? 'https' : 'http';
277
278
        $request = [
279
            'scheme'   => $scheme,
280
            'host'     => $this->serverValue('HTTP_HOST'),
281
            'port'     => $this->serverValue('SERVER_PORT'),
282
            'user'     => $this->serverValue('PHP_AUTH_USER'),
283
            'pass'     => $this->serverValue('PHP_AUTH_PW'),
284
            'path'     => '',
285
            'query'    => '',
286
            'fragment' => '',
287
        ];
288
289
        //Keep auto-convert to object. Less complexity for merge with array.
290
        $this->request = (object) array_merge($request, $parseUrl);
291
    }
292
}
293