1
|
|
|
<?php |
2
|
|
|
namespace ANavallaSuiza\Laravel\Database\Repository\Eloquent; |
3
|
|
|
|
4
|
|
|
use ANavallaSuiza\Laravel\Database\Contracts\Repository\Repository as RepositoryContract; |
5
|
|
|
use ANavallaSuiza\Laravel\Database\Contracts\Repository\CriteriaPerformer; |
6
|
|
|
use ANavallaSuiza\Laravel\Database\Contracts\Repository\Criteria; |
7
|
|
|
use ANavallaSuiza\Laravel\Database\Repository\Eloquent\Criteria\WithCriteria; |
8
|
|
|
use ANavallaSuiza\Laravel\Database\Repository\Exceptions\RepositoryException; |
9
|
|
|
use Illuminate\Database\Eloquent\Model as EloquentModel; |
10
|
|
|
use Illuminate\Support\Collection; |
11
|
|
|
|
12
|
|
|
class Repository implements RepositoryContract, CriteriaPerformer |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* @var EloquentModel |
16
|
|
|
*/ |
17
|
|
|
protected $model; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var Collection |
21
|
|
|
*/ |
22
|
|
|
protected $criteria; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var bool |
26
|
|
|
*/ |
27
|
|
|
protected $skipCriteria = false; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
*/ |
31
|
11 |
|
public function __construct(EloquentModel $model) |
32
|
|
|
{ |
33
|
11 |
|
$this->model = $model; |
34
|
11 |
|
$this->criteria = new Collection; |
35
|
11 |
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @return EloquentModel |
39
|
|
|
*/ |
40
|
1 |
|
public function getModel() |
41
|
|
|
{ |
42
|
1 |
|
return $this->model; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param array $with |
47
|
|
|
* @return Collection |
48
|
|
|
*/ |
49
|
1 |
|
public function all(array $with = array()) |
50
|
|
|
{ |
51
|
1 |
|
$this->addWithCriteria($with); |
52
|
1 |
|
$this->applyCriteria(); |
53
|
|
|
|
54
|
1 |
|
$result = $this->model->get(); |
55
|
|
|
|
56
|
1 |
|
$this->refresh(); |
57
|
|
|
|
58
|
1 |
|
return $result; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param int $perPage |
63
|
|
|
* @return mixed |
64
|
|
|
*/ |
65
|
1 |
|
public function paginate($perPage = 15, array $with = array()) |
66
|
|
|
{ |
67
|
1 |
|
$this->addWithCriteria($with); |
68
|
1 |
|
$this->applyCriteria(); |
69
|
|
|
|
70
|
1 |
|
$result = $this->model->paginate($perPage); |
71
|
|
|
|
72
|
1 |
|
$this->refresh(); |
73
|
|
|
|
74
|
1 |
|
return $result; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @param array $data |
79
|
|
|
* @return EloquentModel |
80
|
|
|
*/ |
81
|
2 |
|
public function create(array $data) |
82
|
|
|
{ |
83
|
2 |
|
$result = $this->model->create($data); |
84
|
|
|
|
85
|
2 |
|
$this->refresh(); |
86
|
|
|
|
87
|
2 |
|
return $result; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @param array $data |
92
|
|
|
* @param $id |
93
|
|
|
* @param string $field |
94
|
|
|
* @return EloquentModel |
95
|
|
|
*/ |
96
|
2 |
|
public function update(array $data, $id, $field = "id") |
97
|
|
|
{ |
98
|
2 |
|
$result = $this->model->where($field, '=', $id)->update($data); |
99
|
|
|
|
100
|
2 |
|
$this->refresh(); |
101
|
|
|
|
102
|
2 |
|
if (! $result) { |
103
|
1 |
|
throw new RepositoryException("There was an error updating the model"); |
104
|
|
|
} |
105
|
|
|
|
106
|
1 |
|
$model = $this->find($id); |
107
|
|
|
|
108
|
1 |
|
return $model; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param $id |
113
|
|
|
* @return integer |
114
|
|
|
*/ |
115
|
|
|
public function delete($id) |
116
|
|
|
{ |
117
|
|
|
$result = $this->model->destroy($id); |
118
|
|
|
|
119
|
|
|
$this->refresh(); |
120
|
|
|
|
121
|
|
|
return $result; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* @param $id |
126
|
|
|
* @return mixed |
127
|
|
|
*/ |
128
|
1 |
|
public function find($id, array $with = array()) |
|
|
|
|
129
|
|
|
{ |
130
|
1 |
|
$this->addWithCriteria($with); |
131
|
1 |
|
$this->applyCriteria(); |
132
|
|
|
|
133
|
1 |
|
$result = $this->model->find($id); |
134
|
|
|
|
135
|
1 |
|
$this->refresh(); |
136
|
|
|
|
137
|
1 |
|
return $result; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param $id |
142
|
|
|
* @return mixed|Exception |
143
|
|
|
*/ |
144
|
|
|
public function findOrFail($id, array $with = array()) |
145
|
|
|
{ |
146
|
|
|
$this->addWithCriteria($with); |
147
|
|
|
$this->applyCriteria(); |
148
|
|
|
|
149
|
|
|
$result = $this->model->findOrFail($id); |
150
|
|
|
|
151
|
|
|
$this->refresh(); |
152
|
|
|
|
153
|
|
|
return $result; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @param $field |
158
|
|
|
* @param $value |
159
|
|
|
* @return mixed |
160
|
|
|
*/ |
161
|
|
|
public function findBy($field, $value, array $with = array()) |
162
|
|
|
{ |
163
|
|
|
$this->addWithCriteria($with); |
164
|
|
|
$this->applyCriteria(); |
165
|
|
|
|
166
|
|
|
$result = $this->model->where($field, '=', $value)->first(); |
167
|
|
|
|
168
|
|
|
$this->refresh(); |
169
|
|
|
|
170
|
|
|
return $result; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param $field |
175
|
|
|
* @param $value |
176
|
|
|
* @return mixed |
177
|
|
|
*/ |
178
|
|
|
public function findByOrFail($field, $value, array $with = array()) |
179
|
|
|
{ |
180
|
|
|
$this->addWithCriteria($with); |
181
|
|
|
$this->applyCriteria(); |
182
|
|
|
|
183
|
|
|
$result = $this->model->where($field, '=', $value)->firstOrFail(); |
184
|
|
|
|
185
|
|
|
$this->refresh(); |
186
|
|
|
|
187
|
|
|
return $result; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @param $field |
192
|
|
|
* @param $value |
193
|
|
|
* @return mixed |
194
|
|
|
*/ |
195
|
|
|
public function findAllBy($field, $value, array $with = array()) |
|
|
|
|
196
|
|
|
{ |
197
|
|
|
$this->addWithCriteria($with); |
198
|
|
|
$this->applyCriteria(); |
199
|
|
|
|
200
|
|
|
$result = $this->model->where($field, '=', $value)->get(); |
201
|
|
|
|
202
|
|
|
$this->refresh(); |
203
|
|
|
|
204
|
|
|
return $result; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* @param array $with |
209
|
|
|
* @return void |
210
|
|
|
*/ |
211
|
3 |
|
protected function addWithCriteria(array $with = array()) |
212
|
|
|
{ |
213
|
3 |
|
if (count($with) > 0) { |
214
|
|
|
$this->pushCriteria(new WithCriteria($with)); |
215
|
|
|
} |
216
|
3 |
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* |
220
|
|
|
*/ |
221
|
5 |
|
protected function refresh() |
222
|
|
|
{ |
223
|
5 |
|
if (! $this->model instanceof EloquentModel) { |
224
|
|
|
$this->model = $this->model->getModel(); |
225
|
|
|
} |
226
|
|
|
|
227
|
5 |
|
$this->model = $this->model->newInstance(); |
228
|
5 |
|
$this->criteria = new Collection; |
229
|
5 |
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* @param bool $status |
233
|
|
|
* @return $this |
234
|
|
|
*/ |
235
|
|
|
public function skipCriteria($status = true) |
236
|
|
|
{ |
237
|
|
|
$this->skipCriteria = $status; |
238
|
|
|
|
239
|
|
|
return $this; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @return Collection |
244
|
|
|
*/ |
245
|
3 |
|
public function getCriteria() |
246
|
|
|
{ |
247
|
3 |
|
return $this->criteria; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @param Criteria $criteria |
252
|
|
|
* @return $this |
253
|
|
|
*/ |
254
|
|
|
public function getByCriteria(Criteria $criteria) |
255
|
|
|
{ |
256
|
|
|
$this->model = $criteria->apply($this->model, $this); |
257
|
|
|
|
258
|
|
|
return $this; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* @param Criteria $criteria |
263
|
|
|
* @return $this |
264
|
|
|
*/ |
265
|
|
|
public function pushCriteria(Criteria $criteria) |
266
|
|
|
{ |
267
|
|
|
$this->criteria->push($criteria); |
268
|
|
|
|
269
|
|
|
return $this; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* @return $this |
274
|
|
|
*/ |
275
|
3 |
|
public function applyCriteria() |
276
|
|
|
{ |
277
|
3 |
|
if ($this->skipCriteria === true) { |
278
|
|
|
return $this; |
279
|
|
|
} |
280
|
|
|
|
281
|
3 |
|
foreach ($this->getCriteria() as $criteria) { |
282
|
|
|
$this->model = $criteria->apply($this->model, $this); |
283
|
3 |
|
} |
284
|
|
|
|
285
|
3 |
|
return $this; |
286
|
|
|
} |
287
|
|
|
} |
288
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.