1
|
|
|
<?php |
2
|
|
|
namespace Wandu\Bridges\Eloquent; |
3
|
|
|
|
4
|
|
|
use Illuminate\Database\Eloquent\Builder; |
5
|
|
|
use Illuminate\Database\Eloquent\Collection; |
6
|
|
|
use Illuminate\Database\Eloquent\Model; |
7
|
|
|
use InvalidArgumentException; |
8
|
|
|
|
9
|
|
|
class EloquentRepository |
10
|
|
|
{ |
11
|
|
|
/** @var string */ |
12
|
|
|
protected $model; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @todo get default orders from model's primaryKey. |
16
|
|
|
* @var array |
17
|
|
|
*/ |
18
|
|
|
protected $orders = [ |
19
|
|
|
'id' => false, |
20
|
|
|
]; |
21
|
|
|
|
22
|
|
|
/** @var array */ |
23
|
|
|
protected $cached = []; |
24
|
|
|
|
25
|
|
|
/** @var bool */ |
26
|
|
|
protected $cacheEnabled = true; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* {@inheritdoc} |
30
|
|
|
*/ |
31
|
|
|
public function countAll() |
32
|
|
|
{ |
33
|
|
|
return $this->createQuery()->count(); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @todo data filter |
38
|
|
|
* {@inheritdoc} |
39
|
|
|
*/ |
40
|
|
|
public function insertItems(array $items) |
41
|
|
|
{ |
42
|
|
|
if ($items !== array_values($items)) { |
43
|
|
|
throw new InvalidArgumentException('first parameter must be array of array.'); |
44
|
|
|
} |
45
|
|
|
if (count($items) === 0) { |
46
|
|
|
return; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
if (count($items) <= 10) { |
50
|
|
|
$this->createQuery()->insert($items); |
51
|
|
|
return; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
// more than 10, chunk insert items. |
55
|
|
|
foreach (array_chunk($items, 10) as $chunkedItems) { |
56
|
|
|
$this->createQuery()->insert($chunkedItems); |
57
|
|
|
} |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* {@inheritdoc} |
62
|
|
|
*/ |
63
|
|
|
public function findItems(array $where) |
64
|
|
|
{ |
65
|
|
|
$query = $this->createQuery(); |
66
|
|
|
foreach ($this->filterWhere($where) as $key => $value) { |
67
|
|
|
$query = $query->where($key, $value); |
68
|
|
|
} |
69
|
|
|
return $this->cacheItems($query->get()); |
|
|
|
|
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* {@inheritdoc} |
74
|
|
|
*/ |
75
|
|
|
public function getAllItems() |
76
|
|
|
{ |
77
|
|
|
return $this->cacheItems($this->applyScopeOrders($this->createQuery())->get()); |
|
|
|
|
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* {@inheritdoc} |
82
|
|
|
*/ |
83
|
|
|
public function getItem($id) |
84
|
|
|
{ |
85
|
|
|
if (!isset($this->cached[$id])) { |
86
|
|
|
$item = $this->createQuery()->find($id); |
87
|
|
|
if (isset($item)) { |
88
|
|
|
$this->cacheItem($item); |
|
|
|
|
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
return isset($this->cached[$id]) ? $this->cached[$id] : null; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* {@inheritdoc} |
96
|
|
|
*/ |
97
|
|
|
public function getItemsById(array $arrayOfId) |
98
|
|
|
{ |
99
|
|
|
$keyName = $this->getKeyName(); |
100
|
|
|
$items = $this->createQuery()->whereIn($keyName, $arrayOfId)->get(); |
101
|
|
|
return $this->cacheItems($items); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* {@inheritdoc} |
106
|
|
|
*/ |
107
|
|
|
public function updateItem($id, array $dataSet) |
108
|
|
|
{ |
109
|
|
|
$item = $this->getItem($id)->fill($this->filterDataSet($dataSet)); |
110
|
|
|
$item->save(); |
111
|
|
|
return $item; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* {@inheritdoc} |
116
|
|
|
*/ |
117
|
|
|
public function createItem(array $dataSet) |
118
|
|
|
{ |
119
|
|
|
return $this->cacheItem( |
120
|
|
|
forward_static_call(([$this->getAttributeModel(), 'create']), $this->filterDataSet($dataSet)) |
121
|
|
|
); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* {@inheritdoc} |
126
|
|
|
*/ |
127
|
|
|
public function deleteItem($id) |
128
|
|
|
{ |
129
|
|
|
$this->createQuery()->where($this->createModel()->getKeyName(), $id)->delete(); |
130
|
|
|
$this->flushItem($id); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* {@inheritdoc} |
135
|
|
|
*/ |
136
|
|
|
public function cacheItem(Model $item) |
137
|
|
|
{ |
138
|
|
|
if ($this->cacheEnabled) { |
139
|
|
|
$this->cached[$item->getKey()] = $item; |
140
|
|
|
} |
141
|
|
|
return $item; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* {@inheritdoc} |
146
|
|
|
*/ |
147
|
|
|
public function cacheItems(Collection $items) |
148
|
|
|
{ |
149
|
|
|
if ($this->cacheEnabled) { |
150
|
|
|
foreach ($items as $item) { |
151
|
|
|
$this->cacheItem($item); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
return $items; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* {@inheritdoc} |
159
|
|
|
*/ |
160
|
|
|
public function flushItem($id) |
161
|
|
|
{ |
162
|
|
|
unset($this->cached[$id]); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* {@inheritdoc} |
167
|
|
|
*/ |
168
|
|
|
public function flushAllItems() |
169
|
|
|
{ |
170
|
|
|
$this->cached = []; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* {@inheritdoc} |
175
|
|
|
*/ |
176
|
|
|
public function cacheEnable($cacheEnabled = true) |
177
|
|
|
{ |
178
|
|
|
$lastCacheEnabled = $this->cacheEnabled; |
179
|
|
|
$this->cacheEnabled = $cacheEnabled; |
180
|
|
|
return $lastCacheEnabled; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* @param array $dataSet |
185
|
|
|
* @return array |
186
|
|
|
*/ |
187
|
|
|
public function filterDataSet(array $dataSet) |
188
|
|
|
{ |
189
|
|
|
return $dataSet; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @param array $where |
194
|
|
|
* @return array |
195
|
|
|
*/ |
196
|
|
|
public function filterWhere(array $where) |
197
|
|
|
{ |
198
|
|
|
return $where; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* @param \Illuminate\Database\Eloquent\Builder $query |
203
|
|
|
* @param bool $reversed |
204
|
|
|
* @return \Illuminate\Database\Eloquent\Builder |
205
|
|
|
*/ |
206
|
|
|
protected function applyScopeOrders(Builder $query, $reversed = false) |
207
|
|
|
{ |
208
|
|
|
foreach ($this->orders as $key => $asc) { |
209
|
|
|
$query = $query->orderBy($key, $asc ^ $reversed ? 'ASC' : 'DESC'); |
210
|
|
|
} |
211
|
|
|
return $query; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* @return string |
216
|
|
|
*/ |
217
|
|
|
protected function getKeyName() |
218
|
|
|
{ |
219
|
|
|
static $keyName; |
220
|
|
|
if (!isset($keyName)) { |
221
|
|
|
$keyName = $this->createModel()->getKeyName(); |
222
|
|
|
} |
223
|
|
|
return $keyName; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* @return \Illuminate\Database\Eloquent\Builder |
228
|
|
|
*/ |
229
|
|
|
protected function createQuery() |
230
|
|
|
{ |
231
|
|
|
return $this->createModel()->newQuery(); |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* @return \Illuminate\Database\Eloquent\Model |
236
|
|
|
*/ |
237
|
|
|
protected function createModel() |
238
|
|
|
{ |
239
|
|
|
$model = $this->getAttributeModel(); |
240
|
|
|
return new $model; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @return string |
245
|
|
|
*/ |
246
|
|
|
protected function getAttributeModel() |
247
|
|
|
{ |
248
|
|
|
if (isset($this->model) && class_exists($this->model)) { |
249
|
|
|
return $this->model; |
250
|
|
|
} |
251
|
|
|
throw new NotDefinedModelException; |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.