Completed
Push — master ( 9fd4f6...a07d82 )
by Sergey
04:32
created

Model::save()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.1158

Importance

Changes 7
Bugs 1 Features 0
Metric Value
c 7
b 1
f 0
dl 0
loc 24
ccs 10
cts 12
cp 0.8333
rs 8.5125
cc 5
eloc 11
nc 10
nop 1
crap 5.1158
1
<?php
2
3
namespace Isswp101\Persimmon;
4
5
use Elasticsearch\Common\Exceptions\Missing404Exception;
6
use Exception;
7
use Isswp101\Persimmon\Contracts\Arrayable;
8
use Isswp101\Persimmon\Contracts\Jsonable;
9
use Isswp101\Persimmon\Contracts\Stringable;
10
use Isswp101\Persimmon\DAL\IDAL;
11
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
12
use Isswp101\Persimmon\Traits\Cacheable;
13
use Isswp101\Persimmon\Traits\Eventable;
14
use Isswp101\Persimmon\Traits\Fillable;
15
use Isswp101\Persimmon\Traits\Idable;
16
use Isswp101\Persimmon\Traits\Mergeable;
17
use Isswp101\Persimmon\Traits\Presentable;
18
use JsonSerializable;
19
use LogicException;
20
21
abstract class Model implements Arrayable, Jsonable, Stringable, JsonSerializable
22
{
23
    use Presentable, Eventable, Mergeable;
24
    use Idable, Fillable, Cacheable;
25
26
    /**
27
     * @var IDAL
28
     */
29
    public $_dal;
30
31
    /**
32
     * @var bool
33
     */
34
    public $_exist = false;
35
36
    /**
37
     * Create a new instance.
38
     *
39
     * @param IDAL $dal
40
     * @param array $attributes
41
     */
42 52
    public function __construct(IDAL $dal, array $attributes = [])
43
    {
44 52
        $this->_dal = $dal;
45
46 52
        $this->fill($attributes);
47 52
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 28
    public function toArray()
53 2
    {
54 28
        return array_where(get_object_vars($this), function ($key) {
55 28
            return !starts_with($key, '_');
56 28
        });
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function jsonSerialize()
63
    {
64
        return $this->toArray();
65
    }
66
67
    /**
68
     * Save the model.
69
     *
70
     * @param array $columns
71
     * @return bool
72
     */
73 24
    public function save($columns = ['*'])
74
    {
75 24
        $columns = $columns ? (array)$columns : ['*'];
76
77 24
        if ($this->saving() === false) {
78
            return false;
79
        }
80
81 24
        if (method_exists($this, 'fillTimestamp')) {
82 24
            $this->fillTimestamp();
0 ignored issues
show
Bug introduced by
The method fillTimestamp() does not seem to exist on object<Isswp101\Persimmon\Model>.

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...
83 24
        }
84
85 24
        $this->_dal->put($columns);
86
87 24
        $this->_exist = true;
88
89
        // self::cache()->put($id, $this);
90
91 24
        if ($this->saved() === false) {
92
            return false;
93
        }
94
95 24
        return true;
96
    }
97
98
    /**
99
     * Delete the model.
100
     *
101
     * @return bool
102
     */
103 6
    public function delete()
104
    {
105 6
        if ($this->deleting() === false) {
106 2
            return false;
107
        }
108
109 6
        $this->_dal->delete();
110
111 6
        $this->_exist = false;
112
113 6
        $cache = self::cache();
114 6
        $cache->forget($this->getId());
115
116 6
        if ($this->deleted() === false) {
117
            return false;
118
        }
119
120 6
        return true;
121
    }
122
123
    /**
124
     * Create a new instance.
125
     *
126
     * @return static
127
     */
128
    public static function createInstance()
129
    {
130
        throw new LogicException('Static method `createInstance()` must be overridden and return `new static(args)`');
131
    }
132
133
    /**
134
     * Find a model by its primary key.
135
     *
136
     * @param mixed $id
137
     * @param array $columns
138
     * @param array $options
139
     * @return static
140
     */
141 22
    public static function find($id, array $columns = ['*'], $options = [])
142
    {
143
        // Return a cached instance if one exists
144 22
        $cache = self::cache();
145 22
        if ($cache->containsAttributes($id, $columns)) {
146 10
            return $cache->get($id);
147
        }
148
149
        // Return attributes which are not cached
150 14
        $columns = $cache->getNotCachedAttributes($id, $columns);
151
152
        // Create a new model
153 14
        $model = static::createInstance();
154 14
        $model->setId($id);
155
156
        // Merge options
157 14
        $options = array_merge($options, ['columns' => $columns == ['*'] ? [] : $columns]);
158
159
        // Get by id
160
        try {
161 14
            $model->_dal->get($id, $options);
162 14
        } catch (Missing404Exception $e) {
163 4
            return null;
164
        }
165
166
        // Fill internal attributes
167 10
        $model->_exist = true;
168
169
        // Put model to cache
170 10
        $model = $cache->put($id, $model, $columns);
171
172 10
        return $model;
173
    }
174
175
    /**
176
     * Find a model by its primary key or return new model.
177
     *
178
     * @param mixed $id
179
     * @return static
180
     */
181 2
    public static function findOrNew($id)
182
    {
183 2
        $model = static::find($id);
184 2
        if (is_null($model)) {
185 2
            $model = static::createInstance();
186 2
            $model->setId($id);
187 2
        }
188 2
        return $model;
189
    }
190
191
    /**
192
     * Find a model by its primary key or throw an exception.
193
     *
194
     * @param mixed $id
195
     * @param array $columns
196
     * @param int $parent
197
     * @return static
198
     */
199 4
    public static function findOrFail($id, array $columns = ['*'], $parent = null)
200
    {
201 4
        $model = static::find($id, $columns, ['parent' => $parent]);
202 4
        if (is_null($model)) {
203 2
            throw new ModelNotFoundException(get_called_class(), $id);
204
        }
205 2
        return $model;
206
    }
207
208
    /**
209
     * Save a new model and return the instance.
210
     *
211
     * @param array $attributes
212
     * @throws Exception
213
     * @return static
214
     */
215 8
    public static function create(array $attributes = [])
216
    {
217 8
        $model = static::createInstance();
218
219 8
        if (array_key_exists('id', $attributes)) {
220 8
            $model->setId($attributes['id']);
221 8
        }
222
223 8
        $model->fill($attributes);
224
225 8
        $model->save();
226
227 8
        return $model;
228
    }
229
230
    /**
231
     * Destroy the models by the given id.
232
     *
233
     * @param mixed $id
234
     */
235 2
    public static function destroy($id)
236
    {
237 2
        $ids = is_array($id) ? $id : [$id];
238 2
        foreach ($ids as $id) {
239 2
            $model = static::find($id);
240 2
            if (!is_null($model)) {
241 2
                $model->delete();
242 2
            }
243 2
        }
244 2
    }
245
}
246