Model::offsetUnset()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2
c 0
b 0
f 0
rs 10
cc 1
eloc 0
nc 1
nop 1
1
<?php
2
3
namespace Amelia\Monzo\Models;
4
5
use ArrayAccess;
6
use Carbon\Carbon;
7
use JsonSerializable;
8
use Amelia\Monzo\Monzo;
9
use Illuminate\Support\Str;
10
use Illuminate\Contracts\Support\Jsonable;
11
use Illuminate\Contracts\Support\Arrayable;
12
13
class Model implements Jsonable, Arrayable, JsonSerializable, ArrayAccess
14
{
15
    /**
16
     * The original values given to this model.
17
     *
18
     * @var array
19
     */
20
    protected $original = [];
21
22
    /**
23
     * An array of attributes on this model.
24
     *
25
     * @var array
26
     */
27
    protected $attributes = [];
28
29
    /**
30
     * Attributes to append to this model's json output.
31
     *
32
     * @var array
33
     */
34
    protected $appends = [];
35
36
    /**
37
     * An array of cast types for this model.
38
     *
39
     * As an improvement over laravel, you can cast to models, too.
40
     *
41
     * @var array
42
     */
43
    protected $casts = [];
44
45
    /**
46
     * A static monzo instance.
47
     *
48
     * @var \Amelia\Monzo\Monzo
49
     */
50
    protected $monzo;
51
52
    /**
53
     * Base Monzo model constructor.
54
     *
55
     * @param array $attributes
56
     * @param \Amelia\Monzo\Monzo|null $monzo
57
     */
58
    public function __construct(array $attributes = [], Monzo $monzo = null)
59
    {
60
        $this->setAttributes($attributes);
61
62
        // dev UX test: make models API-aware?
63
        // bonus: it's already authed from the previous call.
64
        if ($monzo !== null) {
65
            $this->monzo = $monzo;
66
        }
67
    }
68
69
    /**
70
     * Get the instance as an array.
71
     *
72
     * @return array
73
     */
74
    public function toArray()
75
    {
76
        $attributes = $this->attributes;
77
78
        foreach ($this->appends as $append) {
79
            $method = 'get' . Str::studly($append) . 'Attribute';
80
81
            if (method_exists($this, $method)) {
82
                $attributes[$append] = $this->$method();
83
            }
84
        }
85
86
        return $attributes;
87
    }
88
89
    /**
90
     * Get an array suitable for JSON encoding.
91
     *
92
     * @return array
93
     */
94
    public function toJsonArray()
95
    {
96
        return collect($this->toArray())->map(function ($value) {
97
            return $value instanceof Carbon
98
                ? $value->format('Y-m-d\TH:i:s.uP')
99
                : $value;
100
        })->all();
101
    }
102
103
    /**
104
     * Convert the object to its JSON representation.
105
     *
106
     * @param  int $options
107
     * @return string
108
     */
109
    public function toJson($options = 0)
110
    {
111
        return json_encode($this->toJsonArray(), $options);
112
    }
113
114
    /**
115
     * Specify data which should be serialized to JSON.
116
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
117
     * @return mixed data which can be serialized by <b>json_encode</b>,
118
     * which is a value of any type other than a resource.
119
     * @since 5.4.0
120
     */
121
    public function jsonSerialize()
122
    {
123
        return $this->toJsonArray();
124
    }
125
126
    /**
127
     * Set attributes on this model.
128
     *
129
     * @param array $attributes
130
     * @return void
131
     */
132
    public function setAttributes(array $attributes)
133
    {
134
        $this->original = $attributes;
135
136
        foreach ($attributes as $key => $value) {
137
            $this->attributes[$key] = $this->cast($key, $value);
138
        }
139
    }
140
141
    /**
142
     * Cast a value explicitly to a type defined in {@see static::$casts}.
143
     *
144
     * @param string $key
145
     * @param mixed $value
146
     * @return mixed
147
     */
148
    public function cast(string $key, $value)
149
    {
150
        if (! array_key_exists($key, $this->casts) || $value === null) {
151
            return $value;
152
        }
153
154
        $cast = $this->casts[$key];
155
        $collection = false;
156
157
        if (starts_with($cast, 'collection:') && is_array($value)) {
158
            $collection = true;
159
            $cast = substr($cast, 10);
160
        }
161
162
        if (class_exists($cast) && is_array($value)) {
163
            return $this->castClass($cast, $value, $collection);
164
        }
165
166
        switch ($cast) {
167
            case 'date':
168
                return Carbon::parse($value);
169
170
            default:
171
                return $value;
172
        }
173
    }
174
175
    /**
176
     * Cast to a class (aka a relation).
177
     *
178
     * @param string $cast
179
     * @param array|mixed $value
180
     * @param bool $collection
181
     * @return \Amelia\Monzo\Models\Model|\Illuminate\Support\Collection
182
     */
183
    protected function castClass(string $cast, $value, bool $collection = false)
184
    {
185
        if ($collection) {
186
            return collect($value)->map(function (array $item) use ($cast) {
187
                return new $cast($item);
188
            });
189
        }
190
191
        return new $cast($value);
192
    }
193
194
    /**
195
     * Get an attribute on this model.
196
     *
197
     * @param string $key
198
     * @return mixed|null
199
     */
200
    public function getAttribute(string $key)
201
    {
202
        $method = 'get' . Str::studly($key) . 'Attribute';
203
204
        if (method_exists($this, $method)) {
205
            return $this->$method();
206
        }
207
208
        return $this->attributes[$key] ?? null;
209
    }
210
211
    /**
212
     * Dynamically get an attribute on this model.
213
     *
214
     * @param string $key
215
     * @return mixed|null
216
     */
217
    public function __get(string $key)
218
    {
219
        return $this->getAttribute($key);
220
    }
221
222
    /**
223
     * Debug information for var_dump/dd.
224
     *
225
     * @return array
226
     */
227
    public function __debugInfo()
228
    {
229
        return $this->toJsonArray();
230
    }
231
232
    /**
233
     * Whether a offset exists.
234
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
235
     * @param mixed $offset <p>
236
     * An offset to check for.
237
     * </p>
238
     * @return bool true on success or false on failure.
239
     * </p>
240
     * <p>
241
     * The return value will be casted to boolean if non-boolean was returned.
242
     * @since 5.0.0
243
     */
244
    public function offsetExists($offset)
245
    {
246
        return array_key_exists($offset, $this->attributes);
247
    }
248
249
    /**
250
     * Offset to retrieve.
251
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
252
     * @param mixed $offset <p>
253
     * The offset to retrieve.
254
     * </p>
255
     * @return mixed Can return all value types.
256
     * @since 5.0.0
257
     */
258
    public function offsetGet($offset)
259
    {
260
        return $this->getAttribute($offset);
261
    }
262
263
    /**
264
     * Offset to set.
265
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
266
     * @param mixed $offset <p>
267
     * The offset to assign the value to.
268
     * </p>
269
     * @param mixed $value <p>
270
     * The value to set.
271
     * </p>
272
     * @return void
273
     * @since 5.0.0
274
     */
275
    public function offsetSet($offset, $value)
276
    {
277
        //
278
    }
279
280
    /**
281
     * Offset to unset.
282
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
283
     * @param mixed $offset <p>
284
     * The offset to unset.
285
     * </p>
286
     * @return void
287
     * @since 5.0.0
288
     */
289
    public function offsetUnset($offset)
290
    {
291
        //
292
    }
293
}
294