Completed
Push — master ( f65984...f14db4 )
by Sergey
06:25
created

Model::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
crap 2
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\Logable;
17
use Isswp101\Persimmon\Traits\Mergeable;
18
use Isswp101\Persimmon\Traits\Presentable;
19
use Isswp101\Persimmon\Traits\Timestampable;
20
use Isswp101\Persimmon\Traits\Userable;
21
use JsonSerializable;
22
23
abstract class Model implements Arrayable, Jsonable, Stringable, JsonSerializable
24
{
25
    use Idable, Userable, Timestampable;
26
    use Fillable, Cacheable, Logable;
27
    use Presentable, Eventable, Mergeable;
28
29
    /**
30
     * @var IDAL
31
     */
32
    public $_dal;
33
34
    /**
35
     * @var bool
36
     */
37
    public $_exist = false;
38
39
    /**
40
     * Create a new instance.
41
     *
42
     * @param array $attributes
43
     */
44 48
    public function __construct(array $attributes = [])
45
    {
46 48
        $this->injectDependencies();
47
48 48
        $this->fill($attributes);
49 48
    }
50
51
    /**
52
     * Inject data access layer.
53
     *
54
     * @param IDAL $dal
55
     */
56 48
    protected function injectDataAccessLayer(IDAL $dal)
57
    {
58 48
        $this->_dal = $dal;
59 48
    }
60
61
    abstract public function injectDependencies();
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function toArray()
67
    {
68 24
        return array_where(get_object_vars($this), function ($key) {
69 24
            return !starts_with($key, '_');
70 24
        });
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function jsonSerialize()
77
    {
78
        return $this->toArray();
79
    }
80
81
    /**
82
     * Save the model.
83
     *
84
     * @param array $columns
85
     * @return bool
86
     */
87 20
    public function save($columns = ['*'])
88
    {
89 20
        $columns = $columns ? (array)$columns : ['*'];
90
91 20
        if ($this->saving() === false) {
92
            return false;
93
        }
94
95 20
        $this->fillTimestamp();
96
97 20
        $this->_dal->put($columns);
98
99 20
        $this->_exist = true;
100
101
        // self::cache()->put($id, $this);
102
103 20
        if ($this->saved() === false) {
104
            return false;
105
        }
106
107 20
        return true;
108
    }
109
110
    /**
111
     * Delete the model.
112
     *
113
     * @return bool
114
     */
115 4
    public function delete()
116
    {
117 4
        if ($this->deleting() === false) {
118
            return false;
119
        }
120
121 4
        $this->_dal->delete();
122
123 4
        $this->_exist = false;
124
125 4
        $cache = self::cache();
126 4
        $cache->forget($this->getId());
127
128 4
        if ($this->deleted() === false) {
129
            return false;
130
        }
131
132 4
        return true;
133
    }
134
135
    /**
136
     * @return static
137
     */
138 38
    final public static function createInstance()
139
    {
140 38
        return new static();
141
    }
142
143
    /**
144
     * Find a model by its primary key.
145
     *
146
     * @param mixed $id
147
     * @param array $columns
148
     * @param array $options
149
     * @return static
150
     */
151 22
    public static function find($id, array $columns = ['*'], $options = [])
152
    {
153
        // Return a cached instance if one exists
154 22
        $cache = self::cache();
155 22
        if ($cache->containsAttributes($id, $columns)) {
156 10
            return $cache->get($id);
157
        }
158
159
        // Return attributes which are not cached
160 14
        $columns = $cache->getNotCachedAttributes($id, $columns);
161
162
        // Create a new model
163 14
        $model = static::createInstance();
164 14
        $model->setId($id);
165
166
        // Merge options
167 14
        $options = array_merge($options, ['columns' => $columns == ['*'] ? [] : $columns]);
168
169
        // Get by id
170
        try {
171 14
            $model->_dal->get($id, $options);
172 14
        } catch (Missing404Exception $e) {
173 4
            return null;
174
        }
175
176
        // Fill internal attributes
177 10
        $model->_exist = true;
178
179
        // Put model to cache
180 10
        $model = $cache->put($id, $model, $columns);
181
182 10
        return $model;
183
    }
184
185
    /**
186
     * Find a model by its primary key or return new model.
187
     *
188
     * @param mixed $id
189
     * @return static
190
     */
191 2
    public static function findOrNew($id)
192
    {
193 2
        $model = static::find($id);
194 2
        if (is_null($model)) {
195 2
            $model = static::createInstance();
196 2
            $model->setId($id);
197 2
        }
198 2
        return $model;
199
    }
200
201
    /**
202
     * Find a model by its primary key or throw an exception.
203
     *
204
     * @param mixed $id
205
     * @param array $columns
206
     * @param int $parent
207
     * @return static
208
     */
209 4
    public static function findOrFail($id, array $columns = ['*'], $parent = null)
210
    {
211 4
        $model = static::find($id, $columns, ['parent' => $parent]);
212 4
        if (is_null($model)) {
213 2
            throw new ModelNotFoundException(get_called_class(), $id);
214
        }
215 2
        return $model;
216
    }
217
218
    /**
219
     * Save a new model and return the instance.
220
     *
221
     * @param array $attributes
222
     * @throws Exception
223
     * @return static
224
     */
225 8
    public static function create(array $attributes = [])
226
    {
227 8
        $model = static::createInstance();
228
229 8
        if (array_key_exists('id', $attributes)) {
230 8
            $model->setId($attributes['id']);
231 8
        }
232
233 8
        $model->fill($attributes);
234
235 8
        $model->save();
236
237 8
        return $model;
238
    }
239
240
    /**
241
     * Destroy the models by the given id.
242
     *
243
     * @param mixed $id
244
     */
245 2
    public static function destroy($id)
246
    {
247 2
        $ids = is_array($id) ? $id : [$id];
248 2
        foreach ($ids as $id) {
249 2
            $model = static::find($id);
250 2
            if (!is_null($model)) {
251 2
                $model->delete();
252 2
            }
253 2
        }
254 2
    }
255
}
256