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); |
|
|
|
|
96
|
|
|
|
97
|
|
|
// if ($model->shouldUseCache()) { |
|
|
|
|
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()) { |
|
|
|
|
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
|
|
|
} |
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.