Test Failed
Pull Request — master (#6)
by Arina
06:20
created

JsonResponse::setAttribute()   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 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace ArinaSystems\JsonResponse;
4
5
use Exception;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Facades\Response;
8
9
class JsonResponse
10
{
11
    /**
12
     * @var \ArinaSystems\JsonResponse\Status
13
     */
14
    protected $status;
15
16
    /**
17
     * @var \ArinaSystems\JsonResponse\Option
18
     */
19
    protected $options;
20
21
    /**
22
     * @var \ArinaSystems\JsonResponse\Attribute
23
     */
24
    protected $attributes;
25
26
    /**
27
     * Create a new instance.
28
     *
29
     * @param \ArinaSystems\JsonResponse\Option|array|string $options
30
     */
31
    public function __construct(Option $options, Attribute $attributes, Status $status)
32
    {
33
        $this->options = $options;
34
        $this->status = $status;
35
        $this->attributes = $attributes;
36
    }
37
38
    /**
39
     * Return json response.
40
     *
41
     * @param  string|array                    $status
42
     * @param  array                           $attributes
43
     * @param  array                           $options
44
     * @return \Illuminate\Http\JsonResponse
45
     */
46
    public function json($status = null, array $attributes = [], array $options = [])
47
    {
48
        if (is_array($status)) {
49
            extract($status);
50
        }
51
52
        if (! empty($options)) {
53
            $this->options($options);
54
        }
55
56
        if (! empty($attributes)) {
57
            $this->attributes($attributes);
58
        }
59
60
        if (! is_null($status) && is_string($status)) {
61
            $this->status($status);
62
        }
63
64
        $is_error = $this->attributes('exception') ? true : false;
65
66
        return Response::json(
67
            $this->build($is_error),
68
            $this->attributes('http_code', 200),
0 ignored issues
show
Bug introduced by
It seems like $this->attributes('http_code', 200) can also be of type ArinaSystems\JsonResponse\Attribute; however, parameter $status of Illuminate\Support\Facades\Response::json() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

68
            /** @scrutinizer ignore-type */ $this->attributes('http_code', 200),
Loading history...
69
            $this->attributes('headers', []),
0 ignored issues
show
Bug introduced by
It seems like $this->attributes('headers', array()) can also be of type ArinaSystems\JsonResponse\Attribute; however, parameter $headers of Illuminate\Support\Facades\Response::json() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

69
            /** @scrutinizer ignore-type */ $this->attributes('headers', []),
Loading history...
70
            $this->options('encoding_options')
0 ignored issues
show
Bug introduced by
It seems like $this->options('encoding_options') can also be of type ArinaSystems\JsonResponse\Option; however, parameter $options of Illuminate\Support\Facades\Response::json() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

70
            /** @scrutinizer ignore-type */ $this->options('encoding_options')
Loading history...
71
        );
72
    }
73
74
    /**
75
     * Return json response with error.
76
     *
77
     * @param  \Throwable                      $exception
78
     * @param  string|array                    $status
79
     * @param  array                           $attributes
80
     * @param  array                           $options
81
     * @return \Illuminate\Http\JsonResponse
82
     */
83
    public function error($exception, $status = null, array $attributes = [], array $options = [])
84
    {
85
        $this->setAttributes('exception', $exception);
86
87
        return $this->json($status, $attributes, $options);
88
    }
89
90
    /**
91
     * Retrieve/Set json response status.
92
     *
93
     * @param  string                                   $status
94
     * @return \ArinaSystems\JsonResponse\Status|self
95
     */
96
    public function status(string $status = null)
97
    {
98
        if (is_string($status)) {
99
            throw_if(! $this->status->has($status), new Exception("The \"{$status}\" response state does not exist"));
0 ignored issues
show
Bug introduced by
$status of type string is incompatible with the type array expected by parameter $key of ArinaSystems\JsonResponse\Status::has(). ( Ignorable by Annotation )

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

99
            throw_if(! $this->status->has(/** @scrutinizer ignore-type */ $status), new Exception("The \"{$status}\" response state does not exist"));
Loading history...
100
101
            return $this->status->call($status, $this);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->status->call($status, $this) returns the type array which is incompatible with the documented return type ArinaSystems\JsonRespons...ems\JsonResponse\Status.
Loading history...
102
        }
103
104
        return $this->status;
105
    }
106
107
    /**
108
     * Retrieve/Set json response options.
109
     *
110
     * @param  string|array|null                         $key
111
     * @param  mixed|null                                $default
112
     * @return \ArinaSystems\JsonResponse\Option|mixed
113
     */
114
    public function options($key = null, $default = null)
115
    {
116
        if (is_array($key)) {
117
            return $this->setOptions($key);
118
        }
119
120
        if (! is_null($key)) {
121
            return $this->options->get($key, $default);
122
        }
123
124
        return $this->options ?? $default;
125
    }
126
127
    /**
128
     * Retrieve/Set json response attributes.
129
     *
130
     * @param  string|array|null                            $key
131
     * @param  mixed|null                                   $default
132
     * @return \ArinaSystems\JsonResponse\Attribute|mixed
133
     */
134
    public function attributes($key = null, $default = null)
135
    {
136
        if (is_array($key)) {
137
            return $this->setAttributes($key);
138
        }
139
140
        if (is_string($key)) {
141
            return $this->attributes->get($key, $default);
142
        }
143
144
        return $this->attributes ?? $default;
145
    }
146
147
    /**
148
     * Set json response options.
149
     *
150
     * @param  \ArinaSystems\JsonResponse\Option|array|string $options
151
     * @param  null|mixed                                     $value
152
     * @return self
153
     */
154
    public function setOptions($options, $value = null)
155
    {
156
        if (is_a($options, Option::class)) {
157
            $this->options = $options;
158
        }
159
160
        $this->options->set($options, $value);
0 ignored issues
show
Bug introduced by
It seems like $options can also be of type ArinaSystems\JsonResponse\Option; however, parameter $keys of ArinaSystems\JsonResponse\Option::set() does only seem to accept array|string, maybe add an additional type check? ( Ignorable by Annotation )

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

160
        $this->options->set(/** @scrutinizer ignore-type */ $options, $value);
Loading history...
161
162
        return $this;
163
    }
164
165
    /**
166
     * Set json response option.
167
     *
168
     * @param  \ArinaSystems\JsonResponse\Option|array|string $options
169
     * @param  null|mixed                                     $value
170
     * @return self
171
     */
172
    public function setOption($options, $value = null)
173
    {
174
        return $this->setOptions($options, $value);
175
    }
176
177
    /**
178
     * Set json response attributes.
179
     *
180
     * @param  \ArinaSystems\JsonResponse\Attribute|array|string $attributes
181
     * @param  null|mixed                                        $value
182
     * @return self
183
     */
184
    public function setAttributes($attributes, $value = null)
185
    {
186
        if (is_a($attributes, Attribute::class)) {
187
            $this->attributes = $attributes;
188
        }
189
190
        $this->attributes->set($attributes, $value);
0 ignored issues
show
Bug introduced by
It seems like $attributes can also be of type ArinaSystems\JsonResponse\Attribute; however, parameter $keys of ArinaSystems\JsonResponse\Attribute::set() does only seem to accept array|string, maybe add an additional type check? ( Ignorable by Annotation )

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

190
        $this->attributes->set(/** @scrutinizer ignore-type */ $attributes, $value);
Loading history...
191
192
        return $this;
193
    }
194
195
    /**
196
     * Set json response attribute.
197
     *
198
     * @param  \ArinaSystems\JsonResponse\Attribute|array|string $attributes
199
     * @param  null|mixed                                        $value
200
     * @return self
201
     */
202
    public function setAttribute($attributes, $value = null)
203
    {
204
        return $this->setAttributes($attributes, $value);
205
    }
206
207
    /**
208
     * Get the json response data array.
209
     *
210
     * @param  bool    $error
211
     * @return array
212
     */
213
    protected function build(bool $error = false): array
214
    {
215
        $structure = $this->structure($error);
216
217
        if (! $this->options('debug')) {
218
            unset($structure['debug']);
219
        }
220
221
        $response = array_intersect_key($this->attributes->all('value'), $structure);
222
223
        return $response;
224
    }
225
226
    /**
227
     * Get response data structure.
228
     *
229
     * @param  bool    $error
230
     * @return array
231
     */
232
    public function structure(bool $error = false): array
233
    {
234
        $structure = Arr::where($this->attributes->all('on-'.($error ? 'error' : 'response')), function ($onStructure) {
235
            return boolval($onStructure);
236
        });
237
238
        $structure = array_keys($structure);
239
240
        return array_flip($structure);
241
    }
242
243
    /**
244
     * Get the current instance of json response builder.
245
     *
246
     * @return ArinaSystems\JsonResponse\JsonResponse
0 ignored issues
show
Bug introduced by
The type ArinaSystems\JsonRespons...onResponse\JsonResponse was not found. Did you mean ArinaSystems\JsonResponse\JsonResponse? If so, make sure to prefix the type with \.
Loading history...
247
     */
248
    public function instance(): self
249
    {
250
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type ArinaSystems\JsonResponse\JsonResponse which is incompatible with the documented return type ArinaSystems\JsonRespons...onResponse\JsonResponse.
Loading history...
251
    }
252
}
253