GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Response::setHeader()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
eloc 2
nc 1
nop 2
1
<?php
2
/**
3
 * Kotori.php
4
 *
5
 * A Tiny Model-View-Controller PHP Framework
6
 *
7
 * This content is released under the Apache 2 License
8
 *
9
 * Copyright (c) 2015-2017 Kotori Technology. All rights reserved.
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 *     http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 */
23
24
/**
25
 * Response Class
26
 *
27
 * @package     Kotori
28
 * @subpackage  Http
29
 * @author      Kokororin
30
 * @link        https://kotori.love
31
 */
32
namespace Kotori\Http;
33
34
use Kotori\Debug\Hook;
35
use Kotori\Exception\ResponseException;
36
37
class Response
38
{
39
    /**
40
     * Status array
41
     *
42
     * @var array
43
     */
44
    protected $httpCode = [
45
        100 => 'Continue',
46
        101 => 'Switching Protocols',
47
        200 => 'OK',
48
        201 => 'Created',
49
        202 => 'Accepted',
50
        203 => 'Non-Authoritative Information',
51
        204 => 'No Content',
52
        205 => 'Reset Content',
53
        206 => 'Partial Content',
54
        300 => 'Multiple Choices',
55
        301 => 'Moved Permanently',
56
        302 => 'Found',
57
        303 => 'See Other',
58
        304 => 'Not Modified',
59
        305 => 'Use Proxy',
60
        307 => 'Temporary Redirect',
61
        400 => 'Bad Request',
62
        401 => 'Unauthorized',
63
        403 => 'Forbidden',
64
        404 => 'Not Found',
65
        405 => 'Method Not Allowed',
66
        406 => 'Not Acceptable',
67
        407 => 'Proxy Authentication Required',
68
        408 => 'Request Timeout',
69
        409 => 'Conflict',
70
        410 => 'Gone',
71
        411 => 'Length Required',
72
        412 => 'Precondition Failed',
73
        413 => 'Request Entity Too Large',
74
        414 => 'Request-URI Too Long',
75
        415 => 'Unsupported Media Type',
76
        416 => 'Requested Range Not Satisfiable',
77
        417 => 'Expectation Failed',
78
        422 => 'Unprocessable Entity',
79
        500 => 'Internal Server Error',
80
        501 => 'Not Implemented',
81
        502 => 'Bad Gateway',
82
        503 => 'Service Unavailable',
83
        504 => 'Gateway Timeout',
84
        505 => 'HTTP Version Not Supported',
85
    ];
86
87
    /**
88
     * Default Charset
89
     *
90
     * @var string
91
     */
92
    protected $charset = null;
93
94
    /**
95
     * Class constructor
96
     *
97
     * Initialize Response.
98
     */
99 1
    public function __construct()
100
    {
101 1
        Hook::listen(__CLASS__);
102 1
        $this->setCharset('UTF-8');
103 1
    }
104
105
    /**
106
     * Get current charset
107
     *
108
     * @return string
109
     */
110
    public function getCharset()
111
    {
112
        return $this->charset;
113
    }
114
115
    /**
116
     * Set current charset
117
     *
118
     * @param  string $charset
119
     * @return void
120
     */
121 1
    public function setCharset($charset = null)
122
    {
123 1
        $this->charset = empty($charset) ? 'UTF-8' : $charset;
124 1
    }
125
126
    /**
127
     * Set HTTP Status Header
128
     *
129
     * @param  int    $code
130
     * @param  string $text
131
     * @return void
132
     *
133
     * @throws \Kotori\Exception\ResponseException
134
     */
135
    public function setStatus($code = 200, $text = '')
0 ignored issues
show
Coding Style introduced by
setStatus uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
136
    {
137
        if (empty($code) or !is_numeric($code)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
138
            throw new ResponseException('Status codes must be numeric.');
139
        }
140
141
        if (empty($text)) {
142
            if (!is_int($code)) {
143
                $code = (int) $code;
144
            }
145
146
            if (isset($this->httpCode[$code])) {
147
                $text = $this->httpCode[$code];
148
            } else {
149
                throw new ResponseException('No status text available. Please check your status code number or supply your own message text.');
150
            }
151
        }
152
153
        if (strpos(PHP_SAPI, 'cgi') === 0) {
154
            header('Status: ' . $code . ' ' . $text, true);
155
        } else {
156
            $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
157
            header($protocol . ' ' . $code . ' ' . $text, true, $code);
158
        }
159
    }
160
161
    /**
162
     * Set Header
163
     *
164
     * Lets you set a server header which will be sent with the final output.
165
     *
166
     * @param  string $name
167
     * @param  string $value
168
     * @return void
169
     */
170
    public function setHeader($name, $value)
171
    {
172
        header($name . ': ' . $value, true);
173
    }
174
175
    /**
176
     * Set Content-Type
177
     *
178
     * Let you set a Content-Type header
179
     *
180
     * @param  string $contentType
181
     * @return void
182
     */
183
    public function setContentType($contentType = 'text/html')
184
    {
185
        header('Content-Type: ' . $contentType . '; charset=' . $this->getCharset(), true);
186
    }
187
188
    /**
189
     * Thown JSON to output
190
     *
191
     * @param  mixed $data
192
     * @return void
193
     */
194
    public function throwJSON($data)
195
    {
196
        $this->setContentType('application/json');
197
        exit(json_encode($data));
0 ignored issues
show
Coding Style Compatibility introduced by
The method throwJSON() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
198
    }
199
200
    /**
201
     * Header Redirect
202
     *
203
     * @param  string $location
204
     * @param  boolean $isPermanently
205
     * @return void
206
     */
207
    public function redirect($location, $isPermanently = false)
208
    {
209
        if ($isPermanently) {
210
            header('Location: ' . $location, false, 301);
211
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
212
        } else {
213
            header('Location: ' . $location, false, 302);
214
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
215
        }
216
    }
217
218
    /**
219
     * Output static file with 304 header
220
     *
221
     * @return void
222
     */
223
    public function setCacheHeader()
0 ignored issues
show
Coding Style introduced by
setCacheHeader uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
224
    {
225
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
226
            $this->setStatus(304);
227
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method setCacheHeader() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
228
        }
229
230
        $this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 365 * 24 * 60 * 60) . ' GMT');
231
        $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
232
        $this->setHeader('Cache-Control', 'immutable');
233
    }
234
}
235