Failed Conditions
Push — master ( a26426...65249a )
by Arnold
14:53 queued 04:44
created

src/Traits/Header.php (4 issues)

Severity
1
<?php
2
declare(strict_types=1);
3
4
namespace Jasny\Controller\Traits;
5
6
use Psr\Http\Message\ResponseInterface;
7
8
/**
9
 * Set HTTP response header.
10
 */
11
trait Header
12
{
13
    abstract protected function getResponse(): ResponseInterface;
14
15
    abstract protected function setResponse(ResponseInterface $response): void;
16
17
    abstract protected function getLocalReferer(): ?string;
18
19
    abstract protected function output(string $content, ?string $format = null): static;
20
21
22
    /**
23
     * Set a response header.
24
     *
25
     * @return $this
26
     */
27
    protected function header(string $header, string|int|\Stringable $value, bool $add = false): static
28
    {
29
        $response = $add
30
            ? $this->getResponse()->withAddedHeader($header, (string)$value)
31
            : $this->getResponse()->withHeader($header, (string)$value);
32
        $this->setResponse($response);
33
34
        return $this;
35
    }
36
37
    /**
38
     * Set the HTTP status code.
39
     * @link http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
40
     *
41
     * Examples:
42
     * <code>
43
     *   $this->status(200);
44
     *   $this->status("200 Ok");
45
     * </code>
46
     *
47
     * @param int|string $status
48
     * @return $this
49
     */
50
    protected function status(int|string $status): static
51
    {
52
        if (is_string($status)) {
53
            [$status, $phrase] = explode(' ', $status, 2) + [1 => ''];
54
        } else {
55
            $phrase = '';
56
        }
57
58
        $response = $this->getResponse()->withStatus((int)$status, $phrase);
59
        $this->setResponse($response);
60
61
        return $this;
62
    }
63
64
65
    /**
66
     * Response with 200 Ok
67
     *
68
     * @return $this
69
     */
70
    protected function ok(): static
71
    {
72
        return $this->status(200);
73
    }
74
75
    /**
76
     * Response with created 201 code, and optionally the created location
77
     *
78
     * @param string|null $location  Url of created resource
79
     * @return $this
80
     */
81
    protected function created(?string $location = null): static
82
    {
83
        $this->status(201);
84
85
        if (!empty($location)) {
0 ignored issues
show
Construct empty() is not allowed. Use more strict comparison.
Loading history...
86
            $this->header('Location', $location);
87
        }
88
89
        return $this;
90
    }
91
92
    /**
93
     * Response with 202 Accepted
94
     */
95
    protected function accepted(): static
96
    {
97
        return $this->status(202);
98
    }
99
100
    /**
101
     * Response with 204 No Content
102
     *
103
     * @param int $status  204 (No Content) or 205 (Reset Content)
104
     */
105
    protected function noContent(int $status = 204): static
106
    {
107
        if ($status !== 204 && $status !== 205) {
108
            throw new \DomainException("Invalid status code $status for no content response");
109
        }
110
111
        return $this->status($status);
112
    }
113
114
    /**
115
     * Respond with a 206 Partial content with `Content-Range` header
116
     *
117
     * @param int $rangeFrom  Beginning of the range in bytes
118
     * @param int $rangeTo    End of the range in bytes
119
     * @param int $totalSize  Total size in bytes
120
     * @return $this
121
     */
122
    protected function partialContent(int $rangeFrom, int $rangeTo, int $totalSize): static
123
    {
124
        return $this
125
            ->status(206)
126
            ->header('Content-Range', "bytes {$rangeFrom}-{$rangeTo}/{$totalSize}")
127
            ->header('Content-Length', $rangeTo - $rangeFrom);
128
    }
129
130
131
    /**
132
     * Redirect to url and output a short message with the link
133
     *
134
     * @param string     $url
135
     * @param int|string $status  301 (Moved Permanently), 302 (Found), 303 (See Other) or 307 (Temporary Redirect)
136
     */
137
    protected function redirect(string $url, int|string $status = 303): static
138
    {
139
        if ($status < 300 || $status >= 400) {
140
            throw new \DomainException("Invalid status code $status for redirect");
141
        }
142
143
        $urlHtml = htmlentities($url);
144
145
        return $this
146
            ->status($status)
147
            ->header('Location', $url)
148
            ->output('You are being redirected to <a href="' . $urlHtml . '">' . $urlHtml . '</a>', 'text/html');
149
    }
150
151
    /**
152
     * Redirect to previous page or to home page.
153
     *
154
     * @return $this
155
     */
156
    protected function back(): static
157
    {
158
        return $this->redirect($this->getLocalReferer() ?: '/');
0 ignored issues
show
Method Jasny\Controller\Controller::back() should return $this(Jasny\Controller\Controller) but returns static(Jasny\Controller\Controller).
Loading history...
Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.
Loading history...
Method Jasny\Controller\Guard::back() should return $this(Jasny\Controller\Guard) but returns static(Jasny\Controller\Guard).
Loading history...
159
    }
160
161
    /**
162
     * Respond with 304 Not Modified.
163
     *
164
     * @return $this
165
     */
166
    protected function notModified(): static
167
    {
168
        return $this->status(304);
169
    }
170
171
172
    /**
173
     * Respond with 400 Bad Request
174
     *
175
     * @param int $status  HTTP status code
176
     * @return $this
177
     */
178
    protected function badRequest(int $status = 400): static
179
    {
180
        if ($status < 400 || $status >= 500) {
181
            throw new \DomainException("Invalid status code $status for bad request response");
182
        }
183
184
        return $this->status($status);
185
    }
186
187
    /**
188
     * Respond with a 401 Unauthorized
189
     *
190
     * @return $this
191
     */
192
    protected function unauthorized(): static
193
    {
194
        return $this->status(401);
195
    }
196
197
    /**
198
     * Respond with 402 Payment Required
199
     *
200
     * @return $this
201
     */
202
    protected function paymentRequired(): static
203
    {
204
        return $this->status(402);
205
    }
206
207
    /**
208
     * Respond with 403 Forbidden
209
     *
210
     * @return $this
211
     */
212
    protected function forbidden(): static
213
    {
214
        return $this->status(403);
215
    }
216
217
    /**
218
     * Respond with 404 Not Found, 405 Method not allowed or 410 Gone
219
     *
220
     * @param int $status  404 (Not Found), 405 (Method not allowed) or 410 (Gone)
221
     * @return $this
222
     */
223
    protected function notFound(int $status = 404): static
224
    {
225
        if ($status !== 404 && $status !== 405 && $status !== 410) {
226
            throw new \DomainException("Invalid status code $status for no content response");
227
        }
228
229
        return $this->status($status);
230
    }
231
232
    /**
233
     * Respond with 406 Not Acceptable
234
     *
235
     * @return $this
236
     */
237
    protected function notAcceptable(): static
238
    {
239
        return $this->status(406);
240
    }
241
242
    /**
243
     * Respond with 409 Conflict
244
     *
245
     * @return $this
246
     */
247
    protected function conflict(): static
248
    {
249
        return $this->status(409);
250
    }
251
252
    /**
253
     * Respond with 429 Too Many Requests
254
     *
255
     * @return $this
256
     */
257
    protected function tooManyRequests(): static
258
    {
259
        return $this->status(429);
260
    }
261
262
263
    /**
264
     * Respond with a server error
265
     *
266
     * @param int $status  HTTP status code
267
     * @return $this
268
     */
269
    protected function error(int $status = 500): static
270
    {
271
        if ($status < 500 || $status >= 600) {
272
            throw new \DomainException("Invalid status code $status for server error response");
273
        }
274
275
        return $this->status($status);
276
    }
277
278
}
279