Passed
Push — master ( ce58fd...b8d195 )
by Matthias
02:26
created

RequestManager::getHeaders()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 7
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
crap 12
1
<?php
2
/*
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2015 zepi
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 *
25
 */
26
27
/**
28
 * The RequestManager parses the request params and creates
29
 * the Request object for the input data.
30
 * 
31
 * @package Zepi\Turbo\Manager
32
 * @author Matthias Zobrist <[email protected]>
33
 * @copyright Copyright (c) 2015 zepi
34
 */
35
36
namespace Zepi\Turbo\Manager;
37
38
use \Zepi\Turbo\Framework;
39
use \Zepi\Turbo\Request\CliRequest;
40
use \Zepi\Turbo\Request\WebRequest;
41
use Zepi\Turbo\Request\RequestAbstract;
42
43
/**
44
 * The RequestManager parses the request params and creates
45
 * the Request object for the input data.
46
 * 
47
 * @author Matthias Zobrist <[email protected]>
48
 * @copyright Copyright (c) 2015 zepi
49
 */
50
class RequestManager
51
{
52
    /**
53
     * @access protected
54
     * @var Framework
55
     */
56
    protected $framework;
57
    
58
    /**
59
     * Constructs the object
60
     * 
61
     * @access public
62
     * @param \Zepi\Turbo\Framework $framework
63
     */
64 17
    public function __construct(Framework $framework)
65
    {
66 17
        $this->framework = $framework;
67 17
    }
68
    
69
    /**
70
     * Builds the RequestAbstract object for the given input
71
     * data.
72
     * 
73
     * @access public
74
     */
75 17
    public function buildRequest()
76
    {
77 17
        if (php_sapi_name() === 'cli') {
78 17
            return $this->buildCliRequest();
79
        } else {
80
            return $this->buildWebRequest();
81
        }
82
    }
83
    
84
    /**
85
     * Builds the cli request object
86
     * 
87
     * @access protected
88
     * @return \Zepi\Turbo\Request\CliRequest
89
     */
90 17
    protected function buildCliRequest()
91
    {
92 17
        global $argv;
93
        
94 17
        $args = $argv;
95 17
        $params = array();
96 17
        $route = '';
97
        
98 17
        foreach ($args as $arg) {
99 17
            if ($arg === $_SERVER['PHP_SELF']) {
100 17
                continue;
101
            }
102
            
103 17
            if (strpos($arg, '-') === 0) {
104 17
                $arg = ltrim($arg, '-');
105
                
106 17
                $key = $arg;
107 17
                $value = true;
108
                
109 17
                if (strpos($arg, '=') !== false) {
110 17
                    $key = substr($arg, 0, strpos($arg, '='));
111 17
                    $value = substr($arg, strpos($arg, '=') + 1);
112
                    
113 17
                    if (is_numeric($value)) {
114
                        // Transform the value into the correct data type
115
                        $value = $value * 1;
116
                    }
117
                }
118
                
119 17
                $params[$key] = $value;
120
            } else {
121
                if ($route !== '') {
122
                    $route .= ' ';
123
                }
124
                
125 17
                $route .= $arg;
126
            }
127
        }
128
        
129 17
        $base = $argv[0];
130
        
131 17
        $operatingSystem = $this->getOperatingSystem();
132
        
133 17
        return new CliRequest($route, $params, $base, 'en_US', $operatingSystem);
134
    }
135
136
    /**
137
     * Builds the html request object
138
     * 
139
     * @access protected
140
     * @return \Zepi\Turbo\Request\WebRequest
141
     */
142
    protected function buildWebRequest()
143
    {
144
        $args = $_REQUEST;
145
        $params = array();
146
147
        $route = $_SERVER['REQUEST_URI'];
148
        $posQuestionMark = strpos($route, '?');
149
        if ($posQuestionMark !== false) {
150
            $route = substr($route, 0, $posQuestionMark);
151
        }
152
        
153
        $posIndex = strpos($route, 'index.php');
154
        if ($posIndex !== false) {
155
            $route = substr($route, $posIndex + strlen('index.php'));
156
        }
157
        
158
        // Transform the arguments
159
        foreach ($args as $key => $value) {
160
            if (is_numeric($value)) {
161
                // Transform the value into the correct data type
162
                $value = $value * 1;
163
            }
164
            
165
            $params[$key] = $value;
166
        }
167
168
        // Generate the full url and extract the base
169
        $scheme = $this->getScheme();
170
        $fullUrl = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
171
172
        $isSsl = false;
173
        if ($scheme == 'https') {
174
            $isSsl = true;
175
        }
176
        
177
        $routePosition = strlen($fullUrl);
178
        if ($route !== '' && $route !== '/') {
179
            $routePosition = strpos($fullUrl, $route);
180
        }
181
        
182
        $method = $_SERVER['REQUEST_METHOD'];
183
        $requestedUrl = $this->getRequestedUrl();
184
        $base = substr($fullUrl, 0, $routePosition);
185
        $headers = $this->getHeaders($_SERVER);
186
        $protocol = $_SERVER['SERVER_PROTOCOL'];
187
        
188
        $locale = 'en_US';
189
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
190
            $locale = $this->getLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']);
191
        }
192
        
193
        $operatingSystem = $this->getOperatingSystem();
194
195
        return new WebRequest($method, $requestedUrl, $route, $params, $base, $locale, $operatingSystem, $isSsl, $headers, $protocol);
196
    }
197
    
198
    /**
199
     * Returns the name of the operating system
200
     * 
201
     * @access protected
202
     * @return string
203
     */
204 17
    protected function getOperatingSystem()
205
    {
206 17
        $osRaw = strtolower(PHP_OS);
207
        
208 17
        if (strpos($osRaw, 'linux') !== false) {
209 17
            return RequestAbstract::OS_LINUX;
210
        } else if (strpos($osRaw, 'windows') !== false) {
211
            return RequestAbstract::OS_WINDOWS;
212
        } else {
213
            return RequestAbstract::OS_UNKNOWN;
214
        }
215
    }
216
    
217
    /**
218
     * Returns the scheme of the request
219
     * 
220
     * @return string
221
     */
222
    protected function getScheme()
223
    {
224
        if (isset($_SERVER['REQUEST_SCHEME'])) {
225
            $scheme = $_SERVER['REQUEST_SCHEME'];
226
        } else if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
227
            $scheme = 'https';
228
        } else {
229
            if ($_SERVER['SERVER_PORT'] == 443) {
230
                $scheme = 'https';
231
            } else {
232
                $scheme = 'http';
233
            }
234
        }
235
        
236
        return $scheme;
237
    }
238
    
239
    /**
240
     * Returns the requested url
241
     * 
242
     * @access protected
243
     * @return string
244
     */
245
    protected function getRequestedUrl()
246
    {
247
        $scheme = $this->getScheme();
248
249
        return $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
250
    }
251
252
    /**
253
     * Returns an array with all headers of this request
254
     * 
255
     * @access protected
256
     * @param array $params
257
     * @return array
258
     */
259
    protected function getHeaders($params)
260
    {
261
        $headers = array();
262
        
263
        foreach ($params as $name => $value) {
264
            if (substr($name, 0, 5) === 'HTTP_') {
265
                $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
266
                $headers[$key] = $value;
267
            }
268
        }
269
        
270
        return $headers;
271
    }
272
    
273
    /**
274
     * Returns the best acceptable locale from the language header.
275
     * 
276
     * @access protected
277
     * @param string $acceptLanguageHeader
278
     * @return string
279
     */
280
    protected function getLocale($acceptLanguageHeader)
281
    {
282
        $acceptLanguageHeader = str_replace('-', '_', $acceptLanguageHeader);
283
        $locales = explode(',', $acceptLanguageHeader);
284
        
285
        $acceptableLocales = array();
286
        foreach ($locales as $locale) {
287
            $priority = 1;
288
            if (strpos($locale, ';') !== false) {
289
                $priority = floatval(substr($locale, strpos($locale, ';')));
290
                $locale = substr($locale, 0, strpos($locale, ';'));
291
            }
292
            
293
            $acceptableLocales[$priority] = $locale;
294
        }
295
        
296
        krsort($acceptableLocales);
297
        
298
        // Get the first locale - it will have the highest priority
299
        $locale = array_shift($acceptableLocales);
300
        
301
        if ($locale == '') {
302
            $locale = 'en_US';
303
        } else if (strpos($locale, '_') === false) {
304
            $locale = $locale . '_' . strtoupper($locale);
305
        }
306
        
307
        return $locale;
308
    }
309
}
310