Passed
Push — main ( 99c066...305d80 )
by Dimitri
04:43
created

Redirection   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Test Coverage

Coverage 91.67%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 55
c 2
b 0
f 0
dl 0
loc 227
ccs 33
cts 36
cp 0.9167
rs 9.68
wmc 34

18 Methods

Rating   Name   Duplication   Size   Complexity  
A route() 0 3 1
A away() 0 3 1
A __construct() 0 5 1
A secure() 0 3 1
A to() 0 11 2
A home() 0 6 2
A withInput() 0 5 3
A createRedirect() 0 9 2
A with() 0 9 3
A removeFilesFromInput() 0 13 4
A withCookies() 0 3 1
A refresh() 0 3 1
A back() 0 3 1
A guest() 0 13 4
A setIntendedUrl() 0 3 1
A action() 0 3 1
A intended() 0 5 1
A withErrors() 0 13 4
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Http;
13
14
use BlitzPHP\Container\Services;
15
use BlitzPHP\Contracts\Http\StatusCode;
16
use BlitzPHP\Exceptions\HttpException;
17
use BlitzPHP\Session\Store;
18
use BlitzPHP\Validation\ErrorBag;
19
use GuzzleHttp\Psr7\UploadedFile;
20
21
/**
22
 * Gérer une réponse de redirection
23
 *
24
 * @credit CodeIgniter 4 <a href="https://codeigniter.com">CodeIgniter\HTTP\RedirectResponse</a>
25
 */
26
class Redirection extends Response
27
{
28
    /**
29
     * The session store instance.
30
     */
31
    protected Store $session;
32
33
    protected Request $request;
34
35
    /**
36
     * @param UrlGenerator $generator The URL generator instance.
37
     */
38
    public function __construct(protected UrlGenerator $generator, array $options = [])
39
    {
40 10
        parent::__construct($options);
41 10
        $this->request = $generator->getRequest();
42 10
        $this->session = $this->request->session();
43
    }
44
45
    /**
46
     * Creer une redirection vers la route nommee "home" ou vers la page d'accueil.
47
     */
48
    public function home(int $status = StatusCode::FOUND): static
49
    {
50
        try {
51 2
            return $this->to($this->generator->route('home'), $status);
52
        } catch (HttpException) {
53 2
            return $this->to('/', $status);
54
        }
55
    }
56
57
    /**
58
     * Définit l'URI vers lequel rediriger et, éventuellement, le code d'état HTTP à utiliser.
59
     * Si aucun code n'est fourni, il sera automatiquement déterminé.
60
     *
61
     * @param string   $uri  L'URI vers laquelle rediriger
62
     * @param int|null $code Code d'état HTTP
63
     */
64
    public function to(string $uri, ?int $code = null, array $headers = [], ?bool $secure = null, string $method = 'auto'): static
65
    {
66 6
        $uri = $this->generator->to($uri, [], $secure);
67
68
        // Si cela semble être une URL relative, alors convertissez-la en URL complète
69
        // pour une meilleure sécurité.
70
        if (! str_starts_with($uri, 'http')) {
71 6
            $uri = site_url($uri);
72
        }
73
74 6
        return $this->createRedirect($uri, $code, $headers, $method);
75
    }
76
77
    /**
78
     * Create a new redirect response to an external URL (no validation).
79
     */
80
    public function away(string $path, int $status = StatusCode::FOUND, array $headers = []): static
81
    {
82 2
        return $this->createRedirect($path, $status, $headers);
83
    }
84
85
    /**
86
     * Create a new redirect response to the given HTTPS path.
87
     */
88
    public function secure(string $path, int $status = StatusCode::FOUND, array $headers = []): static
89
    {
90 2
        return $this->to($path, $status, $headers, true);
91
    }
92
93
    /**
94
     * Sets the URI to redirect to but as a reverse-routed or named route
95
     * instead of a raw URI.
96
     */
97
    public function route(string $route, array $params = [], int $code = StatusCode::FOUND, array $headers = []): static
98
    {
99 2
        return $this->to($this->generator->route($route, $params, true), $code, $headers);
100
    }
101
102
    /**
103
     * Sets the URI to redirect to but as a controller action.
104
     */
105
    public function action(array|string $action, array $params = [], int $code = StatusCode::FOUND, array $headers = []): static
106
    {
107 2
        return $this->to($this->generator->action($action, $params, true), $code, $headers);
108
    }
109
110
    /**
111
     * Helper function to return to previous page.
112
     *
113
     * Example:
114
     *  return redirect()->back();
115
     *
116
     * @param mixed $status
117
     * @param mixed $fallback
118
     */
119
    public function back($status = StatusCode::FOUND, array $headers = [], $fallback = false): static
120
    {
121 2
        return $this->createRedirect($this->generator->previous($fallback), $status, $headers);
122
    }
123
124
    /**
125
     * Create a new redirect response to the current URI.
126
     */
127
    public function refresh(int $status = StatusCode::FOUND, array $headers = []): static
128
    {
129 2
        return $this->to($this->generator->getRequest()->path(), $status, $headers);
130
    }
131
132
    /**
133
     * Create a new redirect response, while putting the current URL in the session.
134
     */
135
    public function guest(string $path, int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): static
136
    {
137 2
        $request = $this->generator->getRequest();
138
139
        $intended = $request->method() === 'GET' && ! $request->expectsJson()
140
                        ? $this->generator->full()
141 2
                        : $this->generator->previous();
142
143
        if ($intended) {
144 2
            $this->setIntendedUrl($intended);
145
        }
146
147 2
        return $this->to($path, $status, $headers, $secure);
148
    }
149
150
    /**
151
     * Create a new redirect response.
152
     */
153
    protected function createRedirect(string $uri, ?int $code = null, array $headers = [], string $method = 'auto'): static
154
    {
155 8
        $instance = $this->redirect($uri, $method, $code);
156
157
        foreach ($headers as $key => $value) {
158 8
            $instance = $instance->withHeader($key, $value);
159
        }
160
161 8
        return $instance;
162
    }
163
164
    /**
165
     * Create a new redirect response to the previously intended location.
166
     */
167
    public function intended(string $default = '/', int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): static
168
    {
169 2
        $path = $this->session->pull('url.intended', $default);
170
171 2
        return $this->to($path, $status, $headers, $secure);
172
    }
173
174
    /**
175
     * Set the intended url.
176
     */
177
    public function setIntendedUrl(string $url): void
178
    {
179 2
        $this->session->put('url.intended', $url);
180
    }
181
182
    /**
183
     * Ajoute des erreurs à la session en tant que Flashdata.
184
     */
185
    public function withErrors(array|ErrorBag|string $errors, string $key = 'default'): static
186
    {
187
        if ($errors instanceof ErrorBag) {
0 ignored issues
show
introduced by
$errors is never a sub-type of BlitzPHP\Validation\ErrorBag.
Loading history...
188 2
            $errors = $errors->toArray();
189
        } elseif (is_string($errors)) {
0 ignored issues
show
introduced by
The condition is_string($errors) is always false.
Loading history...
190 2
            $errors = [$key => $errors];
191
        }
192
193
        if (! empty($errors)) {
194 2
            Services::viewer()->share('errors', new ErrorBag($this->session->flashErrors($errors, $key)));
195
        }
196
197 2
        return $this;
198
    }
199
200
    /**
201
     * Spécifie que les tableaux $_GET et $_POST actuels doivent être
202
     * emballé avec la réponse.
203
     *
204
     * Il sera alors disponible via la fonction d'assistance 'old()'.
205
     */
206
    public function withInput(): static
207
    {
208
        return $this->with('_blitz_old_input', [
209
            'get'  => $_GET ?: [],
210
            'post' => $_POST ?: [],
211 2
        ]);
212
    }
213
214
    /**
215
     * Ajoute une clé et un message à la session en tant que Flashdata.
216
     */
217
    public function with(array|string $key, mixed $value = null): static
218
    {
219 2
        $key = is_array($key) ? $key : [$key => $value];
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
220
221
        foreach ($key as $k => $v) {
222 2
            $this->session->flash($k, $v);
223
        }
224
225 2
        return $this;
226
    }
227
228
    /**
229
     * Copie tous les cookies de l’instance de réponse globale dans cette RedirectResponse.
230
     * Utile lorsque vous venez de définir un cookie mais que vous devez vous assurer qu'il est réellement envoyé avec la réponse au lieu d'être perdu.
231
     */
232
    public function withCookies(): static
233
    {
234 2
        return $this->withCookieCollection(Services::response()->getCookieCollection());
235
    }
236
237
    /**
238
     * Supprimez tous les fichiers téléchargés du tableau d’entrée donné.
239
     */
240
    protected function removeFilesFromInput(array $input): array
241
    {
242
        foreach ($input as $key => $value) {
243
            if (is_array($value)) {
244
                $input[$key] = $this->removeFilesFromInput($value);
245
            }
246
247
            if ($value instanceof UploadedFile) {
248
                unset($input[$key]);
249
            }
250
        }
251
252
        return $input;
253
    }
254
}
255