set_http_status_header()   B
last analyzed

Complexity

Conditions 5
Paths 9

Size

Total Lines 61
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 55
c 0
b 0
f 0
nc 9
nop 2
dl 0
loc 61
rs 8.6707

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
31
    /**
32
     *  @file common.php
33
     *  
34
     *  Contains most of the commons functions used by the system
35
     *  
36
     *  @package	core
37
     *  @author	TNH Framework team
38
     *  @copyright	Copyright (c) 2017
39
     *  @license	http://opensource.org/licenses/MIT	MIT License
40
     *  @link	http://www.iacademy.cf
41
     *  @version 1.0.0
42
     *  @filesource
43
     */
44
	
45
46
    /**
47
     * This function is the class loader helper is used if the library "Loader" not yet loaded
48
     * he load the class once
49
     * @param  string $class  the class name to be loaded
50
     * @param  string $dir    the directory where to find the class
51
     * @param  mixed $params the parameter to pass as argument to the constructor of the class
52
     * @codeCoverageIgnore
53
     * 
54
     * @return object         the instance of the loaded class
55
     */
56
    function & class_loader($class, $dir = 'libraries', $params = null){
57
        //put the first letter of class to upper case 
58
        $class = ucfirst($class);
59
        /*
60
           TODO use the best method to get the Log instance
61
         */
62
        if ($class == 'Log') {
63
            require_once CORE_CLASSES_PATH . 'Log.php';
64
            //can't use the instruction like "return new Log()" 
65
            //because we need return the reference instance of the loaded class.
66
            $log = new Log();
67
            return $log;
68
        }
69
        static $classes = array();
70
        if (isset($classes[$class])) {
71
            return $classes[$class];
72
        }
73
        $found = false;
74
        foreach (array(APPS_PATH, CORE_PATH) as $path) {
75
            $file = $path . $dir . DS . $class . '.php';
76
            if (file_exists($file)) {
77
                require_once $file;
78
                //already found
79
                $found = true;
80
                break;
81
            }
82
        }
83
        if (!$found) {
84
            //can't use show_error() at this time because some dependencies not yet loaded
85
            set_http_status_header(503);
86
            echo 'Cannot find the class [' . $class . ']';
87
            die();
88
        }
89
        //track of loaded classes
90
        class_loaded($class);
91
		
92
        //record the class instance
93
        $classes[$class] = isset($params) ? new $class($params) : new $class();
94
		return $classes[$class];
95
    }
96
97
    /**
98
     * This function is the helper to record the loaded classes
99
     * @param  string $class the loaded class name
100
     * @codeCoverageIgnore
101
     * 
102
     * @return array        the list of the loaded classes
103
     */
104
    function & class_loaded($class = null){
105
        static $list = array();
106
        if ($class !== null) {
107
            $list[strtolower($class)] = $class;
108
        }
109
        return $list;
110
    }
111
112
    /**
113
     * This function is used to load the configurations in the 
114
     * case the "Config" library not yet loaded
115
     * @codeCoverageIgnore
116
     * 
117
     * @return array  the configurations values
118
     */
119
    function & load_configurations(){
120
        static $config;
121
        if (empty($config)) {
122
            $file = CONFIG_PATH . 'config.php';
123
            $found = false;
124
            if (file_exists($file)) {
125
                require_once $file;
126
                $found = true;
127
            }
128
            if (!$found) {
129
                set_http_status_header(503);
130
                echo 'Unable to find the configuration file [' . $file . ']';
131
                die();
132
            }
133
        }
134
        return $config;
135
    }
136
137
    /**
138
     * This function is the helper to get the config value in case the "Config" library not yet loaded
139
     * @param  string $key     the config item to get the vale
140
     * @param  mixed $default the default value to return if can't find the config item in the configuration
141
     * @test
142
     * 
143
     * @return mixed          the config value
144
     */
145
    function get_config($key, $default = null) {
146
        static $cfg;
147
        if (empty($cfg)) {
148
            $cfg[0] = & load_configurations();
149
            if(! is_array($cfg[0])){
150
                $cfg[0] = array();
151
            }
152
        }
153
        return array_key_exists($key, $cfg[0]) ? $cfg[0][$key] : $default;
154
    }
155
156
    /**
157
     *  This function displays an error message to the user and ends the 
158
     *  execution of the script.
159
     *  
160
     *  @param string $msg the message to display
161
     *  @param string $title the message title: "error", "info", "warning", etc.
162
     *  @param boolean $logging either to save error in log
163
     *  @param string $logLevel the log level to use
164
     *  
165
     *  @codeCoverageIgnore
166
     */
167
    function show_error($msg, $title = 'error', $logging = true, $logLevel = 'ERROR') {
168
        $title = strtoupper($title);
169
        $data = array();
170
        $data['error'] = $msg;
171
        $data['title'] = $title;
172
        if ($logging) {
173
            $log = & class_loader('Log', 'classes');
174
            $log->setLogger('APP::ERROR');
175
            $log->log($logLevel, strip_tags($msg));
176
        }
177
        $response = & class_loader('Response', 'classes');
178
        $response->sendError($data);
179
        die();
180
    }
181
182
     /**
183
     *  Function defined for PHP error message handling
184
     *              
185
     *  @param int $errno the type of error for example: E_USER_ERROR, E_USER_WARNING, etc.
186
     *  @param string $errstr the error message
187
     *  @param string $errfile the file where the error occurred
188
     *  @param int $errline the line number where the error occurred
189
     *  @codeCoverageIgnore
190
     *  
191
     *  @return boolean 
192
     */
193
    function fw_error_handler($errno, $errstr, $errfile, $errline) {
194
        $isError = (((E_ERROR | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $errno) === $errno);
195
        if ($isError) {
196
            set_http_status_header(500);
197
        }
198
        $errorType = 'Error';
199
        $errorsType = array (
200
                E_ERROR              => 'Error',
201
                E_WARNING            => 'Warning',
202
                E_PARSE              => 'Parsing Error',
203
                E_NOTICE             => 'Notice',
204
                E_CORE_ERROR         => 'Core Error',
205
                E_CORE_WARNING       => 'Core Warning',
206
                E_COMPILE_ERROR      => 'Compile Error',
207
                E_COMPILE_WARNING    => 'Compile Warning',
208
                E_USER_ERROR         => 'User Error',
209
                E_USER_WARNING       => 'User Warning',
210
                E_USER_NOTICE        => 'User Notice',
211
                E_STRICT             => 'Runtime Notice',
212
                E_RECOVERABLE_ERROR  => 'Catchable Fatal Error'
213
        );
214
        if (isset($errorsType[$errno])) {
215
           $errorType = $errorsType[$errno];
216
        }
217
        $errorText = 'An error is occurred in the file ' . substr($errfile, strlen(ROOT_PATH)) . ' at line ' . $errline . ' raison : ' . $errstr;
218
        if ((error_reporting() & $errno) !== $errno) {
219
            return;
220
        }
221
        if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) {
222
            show_error($errorText, 'PHP ' . $errorType);
223
        } else {
224
            $log = & class_loader('Log', 'classes');
225
            $log->setLogger('PHP ' . $errorType);
226
            $log->critical($errorText);
227
        }
228
        if ($isError) {
229
            die();
230
        }
231
        return true;
232
    }
233
234
    /**
235
     *  Function defined for handling PHP exception error message, 
236
     *  it displays an error message using the function "show_error"
237
     *  
238
     *  @param object $exception instance of the "Exception" class or a derived class
239
     *  @codeCoverageIgnore
240
     *  
241
     *  @return boolean
242
     */
243
    function fw_exception_handler($exception) {
244
        $errorText = 'An exception is occured in file ' . substr($exception->getFile(), strlen(ROOT_PATH)) . ' at line ' . $exception->getLine() . ' raison : ' . $exception->getMessage();
245
        if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors'))) {
246
            show_error($errorText, 'PHP Exception #' . $exception->getCode());
247
        } else {
248
            $log = & class_loader('Log', 'classes');
249
            $log->setLogger('PHP Exception #' . $exception->getCode());
250
            $log->critical($errorText);
251
        }
252
        return true;
253
    }
254
    
255
    /**
256
     * This function is used to run in shutdown situation of the script
257
     * @codeCoverageIgnore
258
     */
259
    function fw_shudown_handler() {
260
        $lastError = error_get_last();
261
        if (is_array($lastError) &&
262
            ($lastError['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))) {
263
            fw_error_handler($lastError['type'], $lastError['message'], $lastError['file'], $lastError['line']);
264
        }
265
    }
266
267
    /**
268
     * Set the HTTP status header
269
     * @param integer $code the HTTP status code
270
     * @param string  $text the HTTP status text
271
     * 
272
     * @codeCoverageIgnore
273
     */
274
    function set_http_status_header($code = 200, $text = null) {
275
        if (empty($text)) {
276
            $httpStatus = array(
277
                                100 => 'Continue',
278
                                101 => 'Switching Protocols',
279
                                200 => 'OK',
280
                                201 => 'Created',
281
                                202 => 'Accepted',
282
                                203 => 'Non-Authoritative Information',
283
                                204 => 'No Content',
284
                                205 => 'Reset Content',
285
                                206 => 'Partial Content',
286
                                300 => 'Multiple Choices',
287
                                301 => 'Moved Permanently',
288
                                302 => 'Found',
289
                                303 => 'See Other',
290
                                304 => 'Not Modified',
291
                                305 => 'Use Proxy',
292
                                307 => 'Temporary Redirect',
293
                                400 => 'Bad Request',
294
                                401 => 'Unauthorized',
295
                                402 => 'Payment Required',
296
                                403 => 'Forbidden',
297
                                404 => 'Not Found',
298
                                405 => 'Method Not Allowed',
299
                                406 => 'Not Acceptable',
300
                                407 => 'Proxy Authentication Required',
301
                                408 => 'Request Timeout',
302
                                409 => 'Conflict',
303
                                410 => 'Gone',
304
                                411 => 'Length Required',
305
                                412 => 'Precondition Failed',
306
                                413 => 'Request Entity Too Large',
307
                                414 => 'Request-URI Too Long',
308
                                415 => 'Unsupported Media Type',
309
                                416 => 'Requested Range Not Satisfiable',
310
                                417 => 'Expectation Failed',
311
                                418 => 'I\'m a teapot',
312
                                500 => 'Internal Server Error',
313
                                501 => 'Not Implemented',
314
                                502 => 'Bad Gateway',
315
                                503 => 'Service Unavailable',
316
                                504 => 'Gateway Timeout',
317
                                505 => 'HTTP Version Not Supported',
318
                            );
319
            if (isset($httpStatus[$code])) {
320
                $text = $httpStatus[$code];
321
            } else {
322
                show_error('No HTTP status text found for your code please check it.');
323
            }
324
        }
325
        
326
        if (strpos(php_sapi_name(), 'cgi') === 0) {
327
            header('Status: ' . $code . ' ' . $text, TRUE);
328
        } else {
329
            $globals = & class_loader('GlobalVar', 'classes');
330
            $proto = 'HTTP/1.1';
331
            if ($globals->server('SERVER_PROTOCOL')) {
332
                $proto = $globals->server('SERVER_PROTOCOL');
333
            }
334
            header($proto . ' ' . $code . ' ' . $text, TRUE, $code);
335
        }
336
    }
337
338
339
    /**
340
     *  Check whether the protocol used is "https" or not
341
     *  That is, the web server is configured to use a secure connection.
342
     *  @codeCoverageIgnore
343
     *  
344
     *  @return boolean true if the web server uses the https protocol, false if not.
345
     */
346
    function is_https() {
347
        /*
348
		* some servers pass the "HTTPS" parameter in the server variable,
349
		* if is the case, check if the value is "on", "true", "1".
350
		*/
351
        $globals = & class_loader('GlobalVar', 'classes');
352
        if ($globals->server('HTTPS') && strtolower($globals->server('HTTPS')) !== 'off') {
353
            return true;
354
        }
355
        if ($globals->server('HTTP_X_FORWARDED_PROTO') && $globals->server('HTTP_X_FORWARDED_PROTO') === 'https') {
356
            return true;
357
        }
358
        if ($globals->server('HTTP_FRONT_END_HTTPS') && strtolower($globals->server('HTTP_FRONT_END_HTTPS')) !== 'off') {
359
            return true;
360
        }
361
        return false;
362
    }
363
	
364
    /**
365
     *  This function is used to check the URL format of the given string argument. 
366
     *  The address is valid if the protocol is http, https, ftp, etc.
367
     *
368
     *  @param string $url the URL address to check
369
     *  @test
370
     *  
371
     *  @return boolean true if is a valid URL address or false.
372
     */
373
    function is_url($url) {
374
        return preg_match('/^(http|https|ftp):\/\/(.*)/', $url) == 1;
375
    }
376
	
377
    /**
378
     *  Function defined to load controller
379
     *  
380
     *  @param string $controllerClass the controller class name to be loaded
381
     *  @codeCoverageIgnore
382
     */
383
    function autoload_controller($controllerClass) {
384
        if (file_exists($path = APPS_CONTROLLER_PATH . $controllerClass . '.php')) {
385
            require_once $path;
386
        }
387
    }
388
389
    /**
390
     *  Convert array attributes to string
391
     *
392
     *  This function converts an associative array into HTML attributes.
393
     *  For example :
394
     *  $a = array('name' => 'Foo', 'type' => 'text'); => produces the following string:
395
     *  name = "Foo" type = "text"
396
     *
397
     *  @param array $attributes associative array to convert to a string attribute.
398
     *   
399
     *  @return string string of the HTML attribute.
400
     */
401
    function attributes_to_string(array $attributes) {
402
        $str = ' ';
403
        //we check that the array passed as an argument is not empty.
404
        if (!empty($attributes)) {
405
            foreach ($attributes as $key => $value) {
406
                $key = trim(htmlspecialchars($key));
407
                $value = trim(htmlspecialchars($value));
408
                /*
409
				* To predict the case where the string to convert contains the character "
410
				* we check if this is the case we add a slash to solve this problem.
411
				* For example:
412
				* 	$attr = array('placeholder' => 'I am a "puple"')
413
				* 	$str = attributes_to_string($attr); => placeholder = "I am a \"puple\""
414
				 */
415
                if ($value && strpos('"', $value) !== false) {
416
                    $value = addslashes($value);
417
                }
418
                $str .= $key . ' = "' . $value . '" ';
419
            }
420
        }
421
        //remove the space after using rtrim()
422
        return rtrim($str);
423
    }
424
425
426
    /**
427
     * Function to stringfy PHP variable, useful in debug situation
428
     *
429
     * @param mixed $var the variable to stringfy
430
     * @codeCoverageIgnore
431
     *
432
     * @return string the stringfy value
433
     */
434
    function stringify_vars($var) {
435
        return print_r($var, true);
436
    }
437
438
    /**
439
     * Clean the user input
440
     * @param  mixed $str the value to clean
441
     * @test
442
     * 
443
     * @return mixed   the sanitize value
444
     */
445
    function clean_input($str) {
446
        if (is_array($str)) {
447
            return array_map('clean_input', $str);
448
        } 
449
        if (is_object($str)) {
450
            $obj = $str;
451
            foreach ($str as $var => $value) {
452
                $obj->$var = clean_input($value);
453
            }
454
            return $obj;
455
        } 
456
        return htmlspecialchars(strip_tags($str), ENT_QUOTES, 'UTF-8');
457
    }
458
	
459
    /**
460
     * This function is used to hidden some part of the given string. Helpful if you need hide some confidential 
461
     * Information like credit card number, password, etc.
462
     *
463
     * @param  string $str the string you want to hide some part
464
     * @param  int $startCount the length of non hidden for the beginning char
465
     * @param  int $endCount the length of non hidden for the ending char
466
     * @param  string $hiddenChar the char used to hide the given string
467
     * @test
468
     * 
469
     * @return string the string with the hidden part.
470
     */
471
    function string_hidden($str, $startCount = 0, $endCount = 0, $hiddenChar = '*') {
472
        //get the string length
473
        $len = strlen($str);
474
        //if str is empty
475
        if ($len <= 0) {
476
            return str_repeat($hiddenChar, 6);
477
        }
478
        //if the length is less than startCount and endCount
479
        //or the startCount and endCount length is 0
480
        //or startCount is negative or endCount is negative
481
        //return the full string hidden
482
		
483
        if ((($startCount + $endCount) > $len) || ($startCount == 0 && $endCount == 0) || ($startCount < 0 || $endCount < 0)) {
484
            return str_repeat($hiddenChar, $len);
485
        }
486
        //the start non hidden string
487
        $startNonHiddenStr = substr($str, 0, $startCount);
488
        //the end non hidden string
489
        $endNonHiddenStr = null;
490
        if ($endCount > 0) {
491
            $endNonHiddenStr = substr($str, - $endCount);
492
        }
493
        //the hidden string
494
        $hiddenStr = str_repeat($hiddenChar, $len - ($startCount + $endCount));
495
		
496
        return $startNonHiddenStr . $hiddenStr . $endNonHiddenStr;
497
    }
498
	
499
    /**
500
     * This function is very useful, it allows to use the shared instance of 
501
     * the super controller in of all parts of your application.
502
     * 
503
     * NOTE: this function always returns the reference of the super instance.
504
     * For example :
505
     * $obj = & get_instance();
506
     * 
507
     * @codeCoverageIgnore
508
     *  
509
     * @return object the instance of the "Controller" class
510
     */
511
    function & get_instance(){
512
        return Controller::getInstance();
513
    }
514