Passed
Push — main ( 02442c...4ee80d )
by Dimitri
13:27
created

Redirection::setIntendedUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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\Session\Store;
0 ignored issues
show
Bug introduced by
The type BlitzPHP\Session\Store was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Rakit\Validation\ErrorBag;
18
19
/**
20
 * Gérer une réponse de redirection
21
 *
22
 * @credit CodeIgniter 4 <a href="https://codeigniter.com">CodeIgniter\HTTP\RedirectResponse</a>
23
 */
24
class Redirection extends Response
25
{
26
    /**
27
     * The session store instance.
28
     */
29
    protected Store $session;
30
31
    /**
32
     * @param UrlGenerator $generator The URL generator instance.
33
     */
34
    public function __construct(protected UrlGenerator $generator, array $options = [])
35
    {
36
        parent::__construct($options);
37
        $this->session = $generator->getRequest()->session();
38
    }
39
40
    /**
41
     * Create a new redirect response to the "home" route.
42
     */
43
    public function home(int $status = StatusCode::FOUND): self
44
    {
45
        return $this->to($this->generator->route('home'), $status);
46
    }
47
48
    /**
49
     * Définit l'URI vers lequel rediriger et, éventuellement, le code d'état HTTP à utiliser.
50
     * Si aucun code n'est fourni, il sera automatiquement déterminé.
51
     *
52
     * @param string   $uri  L'URI vers laquelle rediriger
53
     * @param int|null $code Code d'état HTTP
54
     */
55
    public function to(string $uri, ?int $code = null, array $headers = [], ?bool $secure = null, string $method = 'auto'): self
56
    {
57
        $uri = $this->generator->to($uri, [], $secure);
58
        
59
        // Si cela semble être une URL relative, alors convertissez-la en URL complète
60
        // pour une meilleure sécurité.
61
        if (strpos($uri, 'http') !== 0) {
62
            $uri = site_url($uri);
63
        }
64
65
        return $this->createRedirect($uri, $code, $headers, $method);
66
    }
67
68
    /**
69
     * Create a new redirect response to an external URL (no validation).
70
     */
71
    public function away(string $path, int $status = StatusCode::FOUND, array $headers = []): self
72
    {
73
        return $this->createRedirect($path, $status, $headers);
74
    }
75
76
    /**
77
     * Create a new redirect response to the given HTTPS path.
78
     */
79
    public function secure(string $path, int $status = StatusCode::FOUND, array $headers = []): self
80
    {
81
        return $this->to($path, $status, $headers, true);
82
    }
83
84
    /**
85
     * Sets the URI to redirect to but as a reverse-routed or named route
86
     * instead of a raw URI.
87
     */
88
    public function route(string $route, array $params = [], int $code = StatusCode::FOUND, array $headers = []): self
89
    {
90
        return $this->to($this->generator->route($route, $params, true), $code, $headers);
91
    }
92
93
    /**
94
     * Helper function to return to previous page.
95
     *
96
     * Example:
97
     *  return redirect()->back();
98
     */
99
    public function back($status = StatusCode::FOUND, array $headers = [], $fallback = false): self
100
    {
101
        return $this->createRedirect($this->generator->previous($fallback), $status, $headers);
102
    }
103
104
    /**
105
     * Create a new redirect response to the current URI.
106
     */
107
    public function refresh(int $status = StatusCode::FOUND, array $headers = []): self
108
    {
109
        return $this->to($this->generator->getRequest()->path(), $status, $headers);
110
    }
111
112
    /**
113
     * Create a new redirect response, while putting the current URL in the session.
114
     */
115
    public function guest(string $path, int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): self
116
    {
117
        $request = $this->generator->getRequest();
118
119
        $intended = $request->method() === 'GET' && ! $request->expectsJson()
120
                        ? $this->generator->full()
121
                        : $this->generator->previous();
122
123
        if ($intended) {
124
            $this->setIntendedUrl($intended);
125
        }
126
127
        return $this->to($path, $status, $headers, $secure);
128
    }
129
130
    /**
131
     * Create a new redirect response.
132
     */
133
    protected function createRedirect(string $uri, ?int $code = null, array $headers = [], string $method = 'auto'): self
134
    {      
135
        $instance = $this->redirect($uri, $method, $code);
136
137
        foreach ($headers as $key => $value) {
138
            $instance = $instance->withHeader($key, $value);
139
        }
140
141
        return $instance;
142
    }
143
144
    /**
145
     * Create a new redirect response to the previously intended location.
146
     */
147
    public function intended(string $default = '/', int $status = StatusCode::FOUND, array $headers = [], ?bool $secure = null): self
148
    {
149
        $path = $this->session->pull('url.intended', $default);
150
151
        return $this->to($path, $status, $headers, $secure);
152
    }
153
154
    /**
155
     * Set the intended url.
156
     */
157
    public function setIntendedUrl(string $url): void
158
    {
159
        $this->session->put('url.intended', $url);
160
    }
161
162
    /**
163
     * Ajoute des erreurs à la session en tant que Flashdata.
164
     */
165
    public function withErrors(array|ErrorBag|string $errors, string $key = 'default'): self
166
    {
167
        if ($errors instanceof ErrorBag) {
0 ignored issues
show
introduced by
$errors is never a sub-type of Rakit\Validation\ErrorBag.
Loading history...
168
            $errors = $errors->all();
169
        } elseif (is_string($errors)) {
0 ignored issues
show
introduced by
The condition is_string($errors) is always false.
Loading history...
170
            $errors = [$errors];
171
        }
172
173
        if (! empty($errors)) {
174
            $_errors = $this->session->getFlashdata('errors') ?? [];
175
            $this->session->setFlashdata(
176
                'errors',
177
                array_merge($_errors, [$key => $errors])
178
            );
179
        }
180
181
        return $this;
182
    }
183
184
    /**
185
     * Spécifie que les tableaux $_GET et $_POST actuels doivent être
186
     * emballé avec la réponse.
187
     *
188
     * Il sera alors disponible via la fonction d'assistance 'old()'.
189
     */
190
    public function withInput(): self
191
    {
192
        return $this->with('_blitz_old_input', [
193
            'get'  => $_GET ?? [],
194
            'post' => $_POST ?? [],
195
        ]);
196
    }
197
198
    /**
199
     * Ajoute une clé et un message à la session en tant que Flashdata.
200
     *
201
     * @param array|string $message
202
     */
203
    public function with(string $key, $message): self
204
    {
205
        $this->session->setFlashdata($key, $message);
206
207
        return $this;
208
    }
209
210
    /**
211
     * Copie tous les en-têtes de l'instance de réponse globale
212
     * dans cette Redirection. Utile lorsque vous venez de
213
     * définir un en-tête pour s'assurer qu'il est bien envoyé
214
     * avec la réponse de redirection..
215
     */
216
    public function withHeaders(): self
217
    {
218
        $new = clone $this;
219
220
        foreach (Services::response()->getHeaders() as $name => $header) {
221
            $new = $new->withHeader($name, $header);
222
        }
223
224
        return $new;
225
    }
226
}
227