1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SleepingOwl\Admin\Repository; |
4
|
|
|
|
5
|
|
|
use Illuminate\Database\Eloquent\Model; |
6
|
|
|
use SleepingOwl\Admin\Contracts\RepositoryInterface; |
7
|
|
|
use SleepingOwl\Admin\Exceptions\RepositoryException; |
8
|
|
|
|
9
|
|
|
class BaseRepository implements RepositoryInterface |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* Repository related class name. |
13
|
|
|
* @var string |
14
|
|
|
*/ |
15
|
|
|
protected $class; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Repository related model instance. |
19
|
|
|
* @var Model |
20
|
|
|
*/ |
21
|
|
|
protected $model; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Eager loading relations. |
25
|
|
|
* @var string[] |
26
|
|
|
*/ |
27
|
|
|
protected $with = []; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @return string |
31
|
|
|
*/ |
32
|
15 |
|
public function getClass() |
33
|
|
|
{ |
34
|
15 |
|
return $this->class; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param string $class |
39
|
|
|
* |
40
|
|
|
* @return $this |
41
|
|
|
* @throws RepositoryException |
42
|
|
|
*/ |
43
|
59 |
|
public function setClass($class) |
44
|
|
|
{ |
45
|
59 |
|
if (! class_exists($class)) { |
46
|
1 |
|
throw new RepositoryException("Class {$class} not found."); |
47
|
|
|
} |
48
|
|
|
|
49
|
59 |
|
$this->setModel( |
50
|
59 |
|
new $class() |
51
|
59 |
|
); |
52
|
|
|
|
53
|
59 |
|
return $this; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @return Model |
58
|
|
|
*/ |
59
|
12 |
|
public function getModel() |
60
|
|
|
{ |
61
|
12 |
|
return $this->model; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param Model $model |
66
|
|
|
* |
67
|
|
|
* @return $this |
68
|
|
|
*/ |
69
|
69 |
|
public function setModel(Model $model) |
70
|
|
|
{ |
71
|
69 |
|
$this->model = $model; |
72
|
69 |
|
$this->class = get_class($model); |
73
|
|
|
|
74
|
69 |
|
return $this; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @return string[] |
79
|
|
|
*/ |
80
|
10 |
|
public function getWith() |
81
|
|
|
{ |
82
|
10 |
|
return $this->with; |
|
|
|
|
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @param string[] $with |
87
|
|
|
* |
88
|
|
|
* @return $this |
89
|
|
|
*/ |
90
|
2 |
|
public function with($with) |
91
|
|
|
{ |
92
|
2 |
|
if (! is_array($with)) { |
93
|
2 |
|
$with = func_get_args(); |
94
|
2 |
|
} |
95
|
|
|
|
96
|
2 |
|
$this->with = $with; |
97
|
|
|
|
98
|
2 |
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Get base query. |
103
|
|
|
* @return \Illuminate\Database\Eloquent\Builder |
104
|
|
|
*/ |
105
|
9 |
|
public function getQuery() |
106
|
|
|
{ |
107
|
9 |
|
return $this->getModel() |
108
|
9 |
|
->query() |
109
|
9 |
|
->with( |
110
|
9 |
|
$this->getWith() |
111
|
9 |
|
); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Find model instance by id. |
116
|
|
|
* |
117
|
|
|
* @param int $id |
118
|
|
|
* |
119
|
|
|
* @return mixed |
120
|
|
|
*/ |
121
|
3 |
|
public function find($id) |
122
|
|
|
{ |
123
|
3 |
|
$query = $this->getQuery(); |
124
|
3 |
|
if ($this->isRestorable()) { |
125
|
1 |
|
$query->withTrashed(); |
126
|
1 |
|
} |
127
|
|
|
|
128
|
3 |
|
return $query->find($id); |
|
|
|
|
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Find model instance by id. |
133
|
|
|
* |
134
|
|
|
* @param int $id |
135
|
|
|
* |
136
|
|
|
* @return mixed |
137
|
|
|
*/ |
138
|
3 |
|
public function findOnlyTrashed($id) |
139
|
|
|
{ |
140
|
3 |
|
return $this->getQuery()->onlyTrashed()->find($id); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Find model instances by ids. |
145
|
|
|
* |
146
|
|
|
* @param int[] $ids |
147
|
|
|
* |
148
|
|
|
* @return \Illuminate\Support\Collection |
149
|
|
|
*/ |
150
|
2 |
|
public function findMany(array $ids) |
151
|
|
|
{ |
152
|
2 |
|
$query = $this->getQuery(); |
153
|
2 |
|
if ($this->isRestorable()) { |
154
|
1 |
|
$query->withTrashed(); |
155
|
1 |
|
} |
156
|
|
|
|
157
|
2 |
|
return $query->whereIn($this->getModel()->getKeyName(), $ids)->get(); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Delete model instance by id. |
162
|
|
|
* |
163
|
|
|
* @param int $id |
164
|
|
|
*/ |
165
|
1 |
|
public function delete($id) |
166
|
|
|
{ |
167
|
1 |
|
$this->find($id)->delete(); |
|
|
|
|
168
|
1 |
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Permanently delete model instance by id. |
172
|
|
|
* |
173
|
|
|
* @param int $id |
174
|
|
|
*/ |
175
|
1 |
|
public function forceDelete($id) |
176
|
|
|
{ |
177
|
1 |
|
$this->findOnlyTrashed($id)->forceDelete(); |
178
|
1 |
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Restore model instance by id. |
182
|
|
|
* |
183
|
|
|
* @param int $id |
184
|
|
|
*/ |
185
|
1 |
|
public function restore($id) |
186
|
|
|
{ |
187
|
1 |
|
$this->findOnlyTrashed($id)->restore(); |
188
|
1 |
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @return bool |
192
|
|
|
*/ |
193
|
12 |
|
public function isRestorable() |
194
|
|
|
{ |
195
|
12 |
|
return in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, class_uses_recursive($this->getClass())); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.