JsonResponse::structure()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 9
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 (! is_null($status) && is_string($status)) {
57
            $this->status($status);
58
        }
59
60
        if (! empty($attributes)) {
61
            $this->attributes($attributes);
62
        }
63
64
        $is_error = $this->attributes('exception') ? true : false;
65
66
        return Response::json(
67
            $this->build($is_error),
68
            /* @scrutinizer ignore-type */
69
            $this->attributes('http_code', 200),
70
            /* @scrutinizer ignore-type */
71
            $this->attributes('headers', []),
72
            /* @scrutinizer ignore-type */
73
            $this->options('encoding_options')
74
        );
75
    }
76
77
    /**
78
     * Return json response with error.
79
     *
80
     * @param  \Throwable  $exception
81
     * @param  string|array  $status
82
     * @param  array  $attributes
83
     * @param  array  $options
84
     * @return \Illuminate\Http\JsonResponse
85
     */
86
    public function error($exception, $status = null, array $attributes = [], array $options = [])
87
    {
88
        $this->setAttributes('exception', $exception);
89
90
        return $this->json($status, $attributes, $options);
91
    }
92
93
    /**
94
     * Retrieve/Set json response status.
95
     *
96
     * @param  string  $status
97
     * @return \ArinaSystems\JsonResponse\Status|self
98
     */
99
    public function status(string $status = null)
100
    {
101
        if (is_string($status)) {
102
            throw_if(! $this->status->has($status), new Exception("The \"{$status}\" response state does not exist"));
103
104
            return $this->status->call($status, $this);
105
        }
106
107
        return $this->status;
108
    }
109
110
    /**
111
     * Retrieve/Set json response options.
112
     *
113
     * @param  string|array|null  $key
114
     * @param  mixed|null  $default
115
     * @return \ArinaSystems\JsonResponse\Option|mixed
116
     */
117
    public function options($key = null, $default = null)
118
    {
119
        if (is_array($key)) {
120
            return $this->setOptions($key);
121
        }
122
123
        if (! is_null($key)) {
124
            return $this->options->get($key, $default);
125
        }
126
127
        return $this->options ?? $default;
128
    }
129
130
    /**
131
     * Retrieve/Set json response attributes.
132
     *
133
     * @param  string|array|null  $key
134
     * @param  mixed|null  $default
135
     * @return \ArinaSystems\JsonResponse\Attribute|mixed
136
     */
137
    public function attributes($key = null, $default = null)
138
    {
139
        if (is_array($key)) {
140
            return $this->setAttributes($key);
141
        }
142
143
        if (is_string($key)) {
144
            return $this->attributes->get($key, $default);
145
        }
146
147
        return $this->attributes ?? $default;
148
    }
149
150
    /**
151
     * Set json response options.
152
     *
153
     * @param  \ArinaSystems\JsonResponse\Option|array|string  $options
154
     * @param  null|mixed  $value
155
     * @return self
156
     */
157
    public function setOptions($options, $value = null)
158
    {
159
        if (is_a($options, Option::class)) {
160
            $this->options = $options;
161
        }
162
163
        $this->options->set(/* @scrutinizer ignore-type */ $options, $value);
164
165
        return $this;
166
    }
167
168
    /**
169
     * Set json response option.
170
     *
171
     * @param  \ArinaSystems\JsonResponse\Option|array|string  $options
172
     * @param  null|mixed  $value
173
     * @return self
174
     */
175
    public function setOption($options, $value = null)
176
    {
177
        return $this->setOptions($options, $value);
178
    }
179
180
    /**
181
     * Set json response attributes.
182
     *
183
     * @param  \ArinaSystems\JsonResponse\Attribute|array|string  $attributes
184
     * @param  null|mixed  $value
185
     * @return self
186
     */
187
    public function setAttributes($attributes, $value = null)
188
    {
189
        if (is_a($attributes, Attribute::class)) {
190
            $this->attributes = $attributes;
191
        }
192
193
        $this->attributes->set(/* @scrutinizer ignore-type */ $attributes, $value);
194
195
        return $this;
196
    }
197
198
    /**
199
     * Set json response attribute.
200
     *
201
     * @param  \ArinaSystems\JsonResponse\Attribute|array|string  $attributes
202
     * @param  null|mixed  $value
203
     * @return self
204
     */
205
    public function setAttribute($attributes, $value = null)
206
    {
207
        return $this->setAttributes($attributes, $value);
208
    }
209
210
    /**
211
     * Get the json response data array.
212
     *
213
     * @param  bool  $error
214
     * @return array
215
     */
216
    protected function build(bool $error = false): array
217
    {
218
        $structure = $this->structure($error);
219
220
        if (! $this->options('debug')) {
221
            unset($structure['debug']);
222
        }
223
224
        $response = array_intersect_key($this->attributes->all('value'), $structure);
225
226
        return $response;
227
    }
228
229
    /**
230
     * Get response data structure.
231
     *
232
     * @param  bool  $error
233
     * @return array
234
     */
235
    public function structure(bool $error = false): array
236
    {
237
        $structure = Arr::where($this->attributes->all('on-'.($error ? 'error' : 'response')), function ($onStructure) {
238
            return boolval($onStructure);
239
        });
240
241
        $structure = array_keys($structure);
242
243
        return array_flip($structure);
244
    }
245
246
    /**
247
     * Get the current instance of json response builder.
248
     *
249
     * @return \ArinaSystems\JsonResponse\JsonResponse
250
     */
251
    public function instance(): self
252
    {
253
        return $this;
254
    }
255
}
256