|
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_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.