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.
Completed
Push — master ( 4f628a...3fa33b )
by やかみ
02:35
created

Response   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 15.22%

Importance

Changes 0
Metric Value
dl 0
loc 200
ccs 7
cts 46
cp 0.1522
rs 10
c 0
b 0
f 0
wmc 19
lcom 2
cbo 2

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getCharset() 0 4 1
C setStatus() 0 25 8
A setHeader() 0 4 1
A setContentType() 0 4 1
A throwJSON() 0 5 1
A redirect() 0 10 2
A setCacheHeader() 0 11 2
A __construct() 0 5 1
A setCharset() 0 4 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
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
100
     */
101 1
    public function __construct()
102
    {
103 1
        Hook::listen(__CLASS__);
104 1
        $this->setCharset('UTF-8');
105 1
    }
106
107
    /**
108
     * Get current charset
109
     *
110
     * @return string
111
     */
112
    public function getCharset()
113
    {
114
        return $this->charset;
115
    }
116
117
    /**
118
     * Set current charset
119
     *
120
     * @return void
121
     */
122 1
    public function setCharset($charset = null)
123
    {
124 1
        $this->charset = empty($charset) ? 'UTF-8' : $charset;
125 1
    }
126
127
    /**
128
     * Set HTTP Status Header
129
     *
130
     * @param  int    $code
131
     * @param  string $text
132
     * @return void
133
     *
134
     * @throws \Kotori\Exception\ResponseException
135
     */
136
    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...
137
    {
138
        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...
139
            throw new ResponseException('Status codes must be numeric.');
140
        }
141
142
        if (empty($text)) {
143
            if (!is_int($code)) {
144
                $code = (int) $code;
145
            }
146
147
            if (isset($this->httpCode[$code])) {
148
                $text = $this->httpCode[$code];
149
            } else {
150
                throw new ResponseException('No status text available. Please check your status code number or supply your own message text.');
151
            }
152
        }
153
154
        if (strpos(PHP_SAPI, 'cgi') === 0) {
155
            header('Status: ' . $code . ' ' . $text, true);
156
        } else {
157
            $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
158
            header($server_protocol . ' ' . $code . ' ' . $text, true, $code);
159
        }
160
    }
161
162
    /**
163
     * Set Header
164
     *
165
     * Lets you set a server header which will be sent with the final output.
166
     *
167
     * @param  string $name
168
     * @param  string $value
169
     * @return void
170
     */
171
    public function setHeader($name, $value)
172
    {
173
        header($name . ': ' . $value, true);
174
    }
175
176
    /**
177
     * Set Content-Type
178
     *
179
     * Let you set a Content-Type header
180
     *
181
     * @param  string $contentType
182
     * @return void
183
     */
184
    public function setContentType($contentType = 'text/html')
185
    {
186
        header('Content-Type: ' . $contentType . '; charset=' . $this->getCharset(), true);
187
    }
188
189
    /**
190
     * Thown JSON to output
191
     *
192
     * @param  mixed $data
193
     * @return void
194
     */
195
    public function throwJSON($data)
196
    {
197
        $this->setContentType('application/json');
198
        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...
199
    }
200
201
    /**
202
     * Header Redirect
203
     *
204
     * @param  string $location
205
     * @param  boolean $isPermanently
206
     * @return void
207
     */
208
    public function redirect($location, $isPermanently = false)
209
    {
210
        if ($isPermanently) {
211
            header('Location: ' . $location, false, 301);
212
            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...
213
        } else {
214
            header('Location: ' . $location, false, 302);
215
            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...
216
        }
217
    }
218
219
    /**
220
     * Output static file with 304 header
221
     *
222
     * @return void
223
     */
224
    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...
225
    {
226
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
227
            $this->setStatus(304);
228
            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...
229
        }
230
231
        $this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 365 * 24 * 60 * 60) . ' GMT');
232
        $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
233
        $this->setHeader('Cache-Control', 'immutable');
234
    }
235
236
}
237