Completed
Pull Request — master (#22)
by Sergey
16:14
created

Eloquent::save()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
nc 9
cc 5
eloc 13
nop 1
1
<?php
2
3
namespace Isswp101\Persimmon\Model;
4
5
use Isswp101\Persimmon\Collection\ICollection;
6
use Isswp101\Persimmon\DI\Container;
7
use Isswp101\Persimmon\Exceptions\IllegalCollectionException;
8
use Isswp101\Persimmon\Exceptions\IllegalModelHashException;
9
use Isswp101\Persimmon\Exceptions\ModelNotFoundException;
10
use Isswp101\Persimmon\QueryBuilder\IQueryBuilder;
11
use Isswp101\Persimmon\Traits\Containerable;
12
use Isswp101\Persimmon\Traits\Eventable;
13
use Isswp101\Persimmon\Traits\Timestampable;
14
15
/**
16
 * @TODO
17
 * 1. Cache
18
 * 2. Consider columns when searching
19
 * 3. Check __clone()
20
 */
21
abstract class Eloquent implements IEloquent
22
{
23
    use Containerable, Timestampable, Eventable;
24
25
    protected $primaryKey;
26
    protected $exists = false;
27
    protected $timestamps = false;
28
    protected $cache = false;
29
30
    /** @MustBeOverridden */
31
    const COLLECTION = null;
32
33
    const PRIMARY_KEY = 'id';
34
    const CREATED_AT = 'created_at';
35
    const UPDATED_AT = 'updated_at';
36
37
    abstract protected static function di(): Container;
38
39
    protected static function instantiate(string $primaryKey): IEloquent
40
    {
41
        $model = new static();
42
        $model->setPrimaryKey($primaryKey);
43
        return $model;
44
    }
45
46
    public function __construct(array $attributes = [])
47
    {
48
        $this->fill($attributes);
49
    }
50
51
    public function setPrimaryKey(string $key)
52
    {
53
        $this->primaryKey = $key;
54
    }
55
56
    public function getPrimaryKey(): string
57
    {
58
        if ($this->primaryKey == null) {
59
            $this->setPrimaryKey($this->{static::PRIMARY_KEY});
60
        }
61
        return $this->primaryKey;
62
    }
63
64
    final public static function getCollection(): string
65
    {
66
        if (static::COLLECTION == null) {
67
            throw new IllegalCollectionException();
68
        }
69
        return static::COLLECTION;
70
    }
71
72
    public function exists(bool $value = null): bool
73
    {
74
        if ($value != null) {
75
            $this->exists = $value;
76
        }
77
        return $this->exists;
78
    }
79
80
    public static function all(IQueryBuilder $query, callable $callback = null): ICollection
81
    {
82
        $collection = static::di()->getRepository()->all($query, static::class,
83
            function (IEloquent $model) use ($callback) {
84
                $model->exists(true);
85
                if ($callback != null) {
86
                    $callback($model);
87
                }
88
            });
89
        return $collection;
90
    }
91
92
    public static function find(string $id, array $columns = []): ?IEloquent
93
    {
94
        $di = static::di();
95
//        $model = static::instantiate($id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96
97
//        if ($model->shouldUseCache()) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
98
//            $cache = $di->getCache()->get($model->getHash());
99
//            $columns = array_diff($columns, $cache->getCachedAttributes());
100
//            if (!$columns && $cache->get() != null) {
101
//                return $cache->get();
102
//            }
103
//        }
104
//
105
//        $cache = $di->getCacheRepository()->find($id, static::class, $columns);
106
//        if ($cache->isReturnable()) {
107
//
108
//        }
109
110
111
        $model = $di->getRepository()->find($id, static::class, $columns);
112
        if ($model != null) {
113
            $model->exists = true;
114
//            if ($model->shouldUseCache()) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
115
//                $cache->put($model, $columns);
116
//            }
117
        }
118
        return $model;
119
    }
120
121
    public static function findOrFail(string $id, array $columns = []): IEloquent
122
    {
123
        $model = static::find($id, $columns);
124
        if ($model == null) {
125
            throw new ModelNotFoundException(get_called_class(), $id);
126
        }
127
        return $model;
128
    }
129
130
    public static function create(array $attributes): IEloquent
131
    {
132
        $model = new static($attributes);
133
        $model->save();
134
        return $model;
135
    }
136
137
    public static function destroy(string $id): void
138
    {
139
        static::findOrFail($id)->delete();
140
    }
141
142
    public function save(array $columns = []): void
143
    {
144
        if ($this->saving() === false) {
145
            return;
146
        }
147
        $repository = $this->di()->getRepository();
148
        if ($this->timestamps) {
149
            $this->updateTimestamps();
150
        }
151
        if (!$this->exists) {
152
            $repository->insert($this);
153
        } else {
154
            $repository->update($this);
155
        }
156
        $this->exists = true;
157
        if ($this->saved() === false) {
158
            return;
159
        }
160
    }
161
162
    public function delete(): void
163
    {
164
        if ($this->deleting() === false) {
165
            return;
166
        }
167
        $this->di()->getRepository()->delete($this);
168
        $this->exists = false;
169
        if ($this->deleted() === false) {
170
            return;
171
        }
172
    }
173
174
    public function getHash(): string
175
    {
176
        if ($this->getPrimaryKey() == null) {
177
            throw new IllegalModelHashException($this);
178
        }
179
        return get_class($this) . '@' . $this->getPrimaryKey();
180
    }
181
182
    public function shouldUseCache(): bool
183
    {
184
        return $this->cache;
185
    }
186
}