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

ResponseTrait::header()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2.5

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 3
dl 0
loc 7
ccs 1
cts 2
cp 0.5
crap 2.5
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\Contracts\Http\StatusCode;
15
use BlitzPHP\Contracts\Session\CookieInterface;
16
use BlitzPHP\Formatter\Formatter;
17
use DateTime;
18
use DateTimeZone;
19
use GuzzleHttp\Psr7\Utils;
20
use InvalidArgumentException;
21
22
trait ResponseTrait
23
{
24
    /**
25
     * Obtient le code d'état de la réponse.
26
     */
27
    public function status(): int
28
    {
29
        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

29
        return $this->/** @scrutinizer ignore-call */ getStatusCode();
Loading history...
30
    }
31
32
    /**
33
     * Obtient la phrase de motif de réponse associée au code d'état.
34
     */
35
    public function statusText(): string
36
    {
37
        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

37
        return $this->/** @scrutinizer ignore-call */ getReasonPhrase();
Loading history...
38
    }
39
40
    /**
41
     * Obtient le contenu de la réponse
42
     */
43
    public function content(): string
44
    {
45
        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

45
        return $this->/** @scrutinizer ignore-call */ getBody()->getContents();
Loading history...
46
    }
47
48
    /**
49
     * Définissez un en-tête sur la réponse.
50
     *
51
     * @param string|string[] $values
52
     */
53
    public function header(string $key, array|string $values, bool $replace = true): static
54
    {
55
        if ($replace) {
56 2
            return $this->withHeader($key, $values);
0 ignored issues
show
Bug introduced by
It seems like withHeader() 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

56
            return $this->/** @scrutinizer ignore-call */ withHeader($key, $values);
Loading history...
57
        }
58
59
        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

59
        return $this->/** @scrutinizer ignore-call */ withAddedHeader($key, $values);
Loading history...
60
    }
61
62
    /**
63
     * Ajoutez un cookie à la réponse.
64
     *
65
     * @param CookieInterface|string $cookie
66
     */
67
    public function cookie($cookie): static
68
    {
69
        if (is_string($cookie) && function_exists('cookie')) {
70 2
            $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

70
            $cookie = cookie(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
71
        }
72
73 2
        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

73
        return $this->/** @scrutinizer ignore-call */ withCookie($cookie);
Loading history...
74
    }
75
76
    /**
77
     * Définit l'en-tête de date
78
     */
79
    public function withDate(DateTime $date): self
80
    {
81
        $date->setTimezone(new DateTimeZone('UTC'));
82
83
        return $this->withHeader('Date', $date->format('D, d M Y H:i:s') . ' GMT');
84
    }
85
86
    /**
87
     * Convertit le $body en JSON et définit l'en-tête Content Type.
88
     */
89
    public function json(array|string $body, int $status = StatusCode::OK): self
90
    {
91
        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

91
        return $this->/** @scrutinizer ignore-call */ withType('application/json')
Loading history...
92
            ->withStringBody(Formatter::type('json')->format($body))
93
            ->withStatus($status);
94
    }
95
96
    /**
97
     * Renvoie le corps actuel, converti en JSON s'il ne l'est pas déjà.
98
     *
99
     * @throws InvalidArgumentException Si la propriété body n'est pas un json valide.
100
     */
101
    public function toJson(): array
102
    {
103
        $body = $this->getBody()->getContents();
104
105
        return Formatter::type('json')->parse($body);
106
    }
107
108
    /**
109
     * Convertit $body en XML et définit le Content-Type correct.
110
     */
111
    public function xml(array|string $body, int $status = StatusCode::OK): self
112
    {
113
        return $this->withType('application/xml')
114
            ->withStringBody(Formatter::type('xml')->format($body))
115
            ->withStatus($status);
116
    }
117
118
    /**
119
     * Récupère le corps actuel dans XML et le renvoie.
120
     */
121
    public function toXml()
122
    {
123
        $body = $this->getBody()->getContents();
124
125
        return Formatter::type('xml')->parse($body);
126
    }
127
128
    /**
129
     * Définit les en-têtes appropriés pour garantir que cette réponse n'est pas mise en cache par les navigateurs.
130
     *
131
     * @todo Recommander la recherche de ces directives, pourrait avoir besoin: 'private', 'no-transform', 'no-store', 'must-revalidate'
132
     */
133
    public function noCache(): self
134
    {
135
        return $this->withoutHeader('Cache-Control')
0 ignored issues
show
Bug introduced by
It seems like withoutHeader() 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

135
        return $this->/** @scrutinizer ignore-call */ withoutHeader('Cache-Control')
Loading history...
136
            ->withHeader('Cache-Control', ['no-store', 'max-age=0', 'no-cache']);
137
    }
138
139
    /**
140
     * Génère les en-têtes qui forcent un téléchargement à se produire.
141
     * Et envoie le fichier au navigateur.
142
     *
143
     * @param string      $filename Le nom que vous souhaitez donner au fichier téléchargé ou le chemin d'accès au fichier à envoyer
144
     * @param string|null $data     Les données à télécharger. Définissez null si le $filename est le chemin du fichier
145
     */
146
    public function download(string $filename, ?string $data = ''): static
147
    {
148
        if (is_file($filename)) {
149
            $filepath = realpath($filename);
150
            $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
151
            $filename = end($filename);
152
153
            return $this->withFile($filepath, ['download' => true, 'name' => $filename]);
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

153
            return $this->/** @scrutinizer ignore-call */ withFile($filepath, ['download' => true, 'name' => $filename]);
Loading history...
154
        }
155
156
        if (! empty($data)) {
157
            return $this->withStringBody($data)
0 ignored issues
show
Bug introduced by
It seems like withStringBody() 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

157
            return $this->/** @scrutinizer ignore-call */ withStringBody($data)
Loading history...
158
                ->withType(pathinfo($filename, PATHINFO_EXTENSION))
159
                ->withDownload($filename);
160
        }
161
162
        return $this;
163
    }
164
165
    /**
166
     * Renvoi une vue comme reponse
167
     */
168
    public function view(string $view, array $data = [], array|int $optionsOrStatus = StatusCode::OK): static
169
    {
170
        if (is_int($optionsOrStatus)) {
171
            $status  = $optionsOrStatus;
172
            $options = [];
173
        } else {
174
            $status  = $optionsOrStatus['status'] ?? StatusCode::OK;
175
            $options = array_filter($optionsOrStatus, static fn ($k) => $k !== 'status', ARRAY_FILTER_USE_KEY);
176
        }
177
178
        $viewContent = view($view, $data, $options)->get();
179
180
        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

180
        return $this->/** @scrutinizer ignore-call */ withStatus($status)->withBody(Utils::streamFor($viewContent));
Loading history...
181
    }
182
}
183