Passed
Push — main ( cd5116...99c066 )
by Dimitri
12:52
created

Redirection::withCookies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
     * Helper function to return to previous page.
104
     *
105
     * Example:
106
     *  return redirect()->back();
107
     *
108
     * @param mixed $status
109
     * @param mixed $fallback
110
     */
111
    public function back($status = StatusCode::FOUND, array $headers = [], $fallback = false): static
112
    {
113 2
        return $this->createRedirect($this->generator->previous($fallback), $status, $headers);
114
    }
115
116
    /**
117
     * Create a new redirect response to the current URI.
118
     */
119
    public function refresh(int $status = StatusCode::FOUND, array $headers = []): static
120
    {
121 2
        return $this->to($this->generator->getRequest()->path(), $status, $headers);
122
    }
123
124
    /**
125
     * Create a new redirect response, while putting the current URL in the session.
126
     */
127
    public function guest(string $path, int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): static
128
    {
129 2
        $request = $this->generator->getRequest();
130
131
        $intended = $request->method() === 'GET' && ! $request->expectsJson()
132
                        ? $this->generator->full()
133 2
                        : $this->generator->previous();
134
135
        if ($intended) {
136 2
            $this->setIntendedUrl($intended);
137
        }
138
139 2
        return $this->to($path, $status, $headers, $secure);
140
    }
141
142
    /**
143
     * Create a new redirect response.
144
     */
145
    protected function createRedirect(string $uri, ?int $code = null, array $headers = [], string $method = 'auto'): static
146
    {
147 8
        $instance = $this->redirect($uri, $method, $code);
148
149
        foreach ($headers as $key => $value) {
150 8
            $instance = $instance->withHeader($key, $value);
151
        }
152
153 8
        return $instance;
154
    }
155
156
    /**
157
     * Create a new redirect response to the previously intended location.
158
     */
159
    public function intended(string $default = '/', int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): static
160
    {
161 2
        $path = $this->session->pull('url.intended', $default);
162
163 2
        return $this->to($path, $status, $headers, $secure);
164
    }
165
166
    /**
167
     * Set the intended url.
168
     */
169
    public function setIntendedUrl(string $url): void
170
    {
171 2
        $this->session->put('url.intended', $url);
172
    }
173
174
    /**
175
     * Ajoute des erreurs à la session en tant que Flashdata.
176
     */
177
    public function withErrors(array|ErrorBag|string $errors, string $key = 'default'): static
178
    {
179
        if ($errors instanceof ErrorBag) {
0 ignored issues
show
introduced by
$errors is never a sub-type of BlitzPHP\Validation\ErrorBag.
Loading history...
180 2
            $errors = $errors->toArray();
181
        } elseif (is_string($errors)) {
0 ignored issues
show
introduced by
The condition is_string($errors) is always false.
Loading history...
182 2
            $errors = [$key => $errors];
183
        }
184
185
        if (! empty($errors)) {
186 2
            Services::viewer()->share('errors', new ErrorBag($this->session->flashErrors($errors, $key)));
187
        }
188
189 2
        return $this;
190
    }
191
192
    /**
193
     * Spécifie que les tableaux $_GET et $_POST actuels doivent être
194
     * emballé avec la réponse.
195
     *
196
     * Il sera alors disponible via la fonction d'assistance 'old()'.
197
     */
198
    public function withInput(): static
199
    {
200
        return $this->with('_blitz_old_input', [
201
            'get'  => $_GET ?: [],
202
            'post' => $_POST ?: [],
203 2
        ]);
204
    }
205
206
    /**
207
     * Ajoute une clé et un message à la session en tant que Flashdata.
208
     */
209
    public function with(array|string $key, mixed $value = null): static
210
    {
211 2
        $key = is_array($key) ? $key : [$key => $value];
0 ignored issues
show
introduced by
The condition is_array($key) is always true.
Loading history...
212
213
        foreach ($key as $k => $v) {
214 2
            $this->session->flash($k, $v);
215
        }
216
217 2
        return $this;
218
    }
219
220
    /**
221
     * Copie tous les cookies de l’instance de réponse globale dans cette RedirectResponse.
222
     * 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.
223
     */
224
    public function withCookies(): static
225
    {
226 2
        return $this->withCookieCollection(Services::response()->getCookieCollection());
227
    }
228
229
    /**
230
     * Copie tous les en-têtes de l'instance de réponse globale
231
     * dans cette Redirection. Utile lorsque vous venez de
232
     * définir un en-tête pour s'assurer qu'il est bien envoyé
233
     * avec la réponse de redirection..
234
     */
235
    public function withHeaders(): static
236
    {
237 2
        $new = clone $this;
238
239
        foreach (Services::response()->getHeaders() as $name => $header) {
240 2
            $new = $new->withHeader($name, $header);
241
        }
242
243 2
        return $new;
244
    }
245
246
    /**
247
     * Supprimez tous les fichiers téléchargés du tableau d’entrée donné.
248
     */
249
    protected function removeFilesFromInput(array $input): array
250
    {
251
        foreach ($input as $key => $value) {
252
            if (is_array($value)) {
253
                $input[$key] = $this->removeFilesFromInput($value);
254
            }
255
256
            if ($value instanceof UploadedFile) {
257
                unset($input[$key]);
258
            }
259
        }
260
261
        return $input;
262
    }
263
}
264