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

ResponseTrait::cookie()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 2
cts 2
cp 1
crap 3
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\Concerns;
13
14
use BlitzPHP\Container\Services;
15
use BlitzPHP\Contracts\Http\StatusCode;
16
use BlitzPHP\Contracts\Session\CookieInterface;
17
use BlitzPHP\Exceptions\LoadException;
18
use BlitzPHP\Formatter\Formatter;
19
use DateTime;
20
use DateTimeZone;
21
use GuzzleHttp\Psr7\Utils;
22
use InvalidArgumentException;
23
use Psr\Http\Message\StreamInterface;
24
use SplFileInfo;
25
26
trait ResponseTrait
27
{
28
    /**
29
     * Obtient le code d'état de la réponse.
30
     */
31
    public function status(): int
32
    {
33
        return $this->getStatusCode();
0 ignored issues
show
Bug introduced by
It seems like getStatusCode() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

33
        return $this->/** @scrutinizer ignore-call */ getStatusCode();
Loading history...
34
    }
35
36
    /**
37
     * Obtient la phrase de motif de réponse associée au code d'état.
38
     */
39
    public function statusText(): string
40
    {
41
        return $this->getReasonPhrase();
0 ignored issues
show
Bug introduced by
It seems like getReasonPhrase() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

41
        return $this->/** @scrutinizer ignore-call */ getReasonPhrase();
Loading history...
42
    }
43
44
    /**
45
     * Obtient le contenu de la réponse
46
     */
47
    public function content(): string
48
    {
49 2
        return $this->getBody()->getContents();
0 ignored issues
show
Bug introduced by
It seems like getBody() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
        return $this->/** @scrutinizer ignore-call */ getBody()->getContents();
Loading history...
50
    }
51
52
    /**
53
     * Définissez un en-tête sur la réponse.
54
     *
55
     * @param string|string[] $values
56
     */
57
    public function header(string $key, array|string $values, bool $replace = true): static
58
    {
59
        if ($replace) {
60 2
            return $this->withHeader($key, $values);
0 ignored issues
show
Bug introduced by
The method withHeader() does not exist on BlitzPHP\Http\Concerns\ResponseTrait. Did you maybe mean withHeaders()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
            return $this->/** @scrutinizer ignore-call */ withHeader($key, $values);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
61
        }
62
63
        return $this->withAddedHeader($key, $values);
0 ignored issues
show
Bug introduced by
It seems like withAddedHeader() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

63
        return $this->/** @scrutinizer ignore-call */ withAddedHeader($key, $values);
Loading history...
64
    }
65
66
    /**
67
     * Ajoutez un cookie à la réponse.
68
     *
69
     * @param CookieInterface|string $cookie
70
     */
71
    public function cookie($cookie): static
72
    {
73
        if (is_string($cookie) && function_exists('cookie')) {
74 4
            $cookie = cookie(...func_get_args());
0 ignored issues
show
Bug introduced by
func_get_args() is expanded, but the parameter $name of cookie() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
            $cookie = cookie(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
75
        }
76
77 4
        return $this->withCookie($cookie);
0 ignored issues
show
Bug introduced by
It seems like withCookie() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
        return $this->/** @scrutinizer ignore-call */ withCookie($cookie);
Loading history...
78
    }
79
80
    /**
81
     * Définit l'en-tête de date
82
     */
83
    public function withDate(DateTime $date): self
84
    {
85 2
        $date->setTimezone(new DateTimeZone('UTC'));
86
87 2
        return $this->withHeader('Date', $date->format('D, d M Y H:i:s') . ' GMT');
88
    }
89
90
    /**
91
     * Copie tous les en-têtes de l'instance de réponse globale dans cette Redirection.
92
     * Utile lorsque vous venez de définir un en-tête pour s'assurer qu'il est bien envoyé avec la réponse de redirection..
93
     */
94
    public function withHeaders(array $headers = []): static
95
    {
96 4
        $new     = clone $this;
97 4
        $headers = $headers === [] ? Services::response()->getHeaders() : $headers;
98
99
        foreach ($headers as $name => $header) {
100 2
            $new = $new->withHeader($name, $header);
101
        }
102
103 4
        return $new;
104
    }
105
106
    /**
107
     * Convertit le $body en JSON et définit l'en-tête Content Type.
108
     */
109
    public function json(array|string $body, int $status = StatusCode::OK): self
110
    {
111
        return $this->withType('application/json')
0 ignored issues
show
Bug introduced by
It seems like withType() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        return $this->/** @scrutinizer ignore-call */ withType('application/json')
Loading history...
112
            ->withStringBody(Formatter::type('json')->format($body))
113 2
            ->withStatus($status);
114
    }
115
116
    /**
117
     * Renvoie le corps actuel, converti en JSON s'il ne l'est pas déjà.
118
     *
119
     * @throws InvalidArgumentException Si la propriété body n'est pas un json valide.
120
     */
121
    public function toJson(): array
122
    {
123
        $body = $this->getBody()->getContents();
124
125
        return Formatter::type('json')->parse($body);
126
    }
127
128
    /**
129
     * Convertit $body en XML et définit le Content-Type correct.
130
     */
131
    public function xml(array|string $body, int $status = StatusCode::OK): self
132
    {
133
        return $this->withType('application/xml')
134
            ->withStringBody(Formatter::type('xml')->format($body))
135 2
            ->withStatus($status);
136
    }
137
138
    /**
139
     * Récupère le corps actuel dans XML et le renvoie.
140
     */
141
    public function toXml()
142
    {
143
        $body = $this->getBody()->getContents();
144
145
        return Formatter::type('xml')->parse($body);
146
    }
147
148
    /**
149
     * Définit les en-têtes appropriés pour garantir que cette réponse n'est pas mise en cache par les navigateurs.
150
     *
151
     * @todo Recommander la recherche de ces directives, pourrait avoir besoin: 'private', 'no-transform', 'no-store', 'must-revalidate'
152
     */
153
    public function noCache(): self
154
    {
155
        return $this->withoutHeader('Cache-Control')
0 ignored issues
show
Bug introduced by
The method withoutHeader() does not exist on BlitzPHP\Http\Concerns\ResponseTrait. Did you maybe mean withHeaders()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

155
        return $this->/** @scrutinizer ignore-call */ withoutHeader('Cache-Control')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
156
            ->withHeader('Cache-Control', ['no-store', 'max-age=0', 'no-cache']);
157
    }
158
159
    /**
160
     * Génère les en-têtes qui forcent un téléchargement à se produire.
161
     * Et envoie le fichier au navigateur.
162
     *
163
     * @param SplFileInfo|string $file    Le chemin absolue du fichier à télécharger ou une instance SplFileInfo
164
     * @param ?string            $name    Le nom que vous souhaitez donner au fichier téléchargé
165
     * @param array              $headers Les entêtes supplémentaires à definir dans la réponse
166
     */
167
    public function download(SplFileInfo|string $file, ?string $name = null, array $headers = []): static
168
    {
169
        if (is_string($file) && ! is_file($file)) {
170 2
            throw new LoadException('The requested file was not found');
171
        }
172
173 2
        return $this->withHeaders($headers)->withFile($file, ['download' => true, 'name' => $name]);
0 ignored issues
show
Bug introduced by
It seems like withFile() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

173
        return $this->withHeaders($headers)->/** @scrutinizer ignore-call */ withFile($file, ['download' => true, 'name' => $name]);
Loading history...
174
    }
175
176
    /**
177
     * Créez une nouvelle instance de réponse diffusée en continu sous forme de téléchargement de fichier.
178
     */
179
    public function streamDownload(callable|StreamInterface|string $stream, string $name, array $headers = []): static
180
    {
181
        if (! ($stream instanceof StreamInterface)) {
182 2
            $stream = to_stream($stream);
183
        }
184
185 2
        return $this->withHeaders($headers)->withBody($stream)->withType(pathinfo($name, PATHINFO_EXTENSION))->withDownload($name);
0 ignored issues
show
Bug introduced by
It seems like withBody() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
        return $this->withHeaders($headers)->/** @scrutinizer ignore-call */ withBody($stream)->withType(pathinfo($name, PATHINFO_EXTENSION))->withDownload($name);
Loading history...
186
    }
187
188
    /**
189
     * Renvoie le contenu brut d'un fichier binaire.
190
     */
191
    public function file(SplFileInfo|string $file, array $headers = []): static
192
    {
193
        return $this->withHeaders($headers)->withFile($file);
194
    }
195
196
    /**
197
     * Renvoi une vue comme reponse
198
     */
199
    public function view(string $view, array $data = [], array|int $optionsOrStatus = StatusCode::OK): static
200
    {
201
        if (is_int($optionsOrStatus)) {
202
            $status  = $optionsOrStatus;
203
            $options = [];
204
        } else {
205
            $status  = $optionsOrStatus['status'] ?? StatusCode::OK;
206
            $options = array_filter($optionsOrStatus, static fn ($k) => $k !== 'status', ARRAY_FILTER_USE_KEY);
207
        }
208
209
        $viewContent = view($view, $data, $options)->get();
210
211
        return $this->withStatus($status)->withBody(Utils::streamFor($viewContent));
0 ignored issues
show
Bug introduced by
It seems like withStatus() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

211
        return $this->/** @scrutinizer ignore-call */ withStatus($status)->withBody(Utils::streamFor($viewContent));
Loading history...
212
    }
213
}
214