1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @copyright Copyright (c) Flipbox Digital Limited |
5
|
|
|
* @license https://github.com/flipboxfactory/craft-ember/blob/master/LICENSE |
6
|
|
|
* @link https://github.com/flipboxfactory/craft-ember |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace flipbox\ember\services\traits; |
10
|
|
|
|
11
|
|
|
use flipbox\ember\exceptions\RecordNotFoundException; |
12
|
|
|
use flipbox\ember\helpers\QueryHelper; |
13
|
|
|
use flipbox\ember\helpers\RecordHelper; |
14
|
|
|
use yii\caching\Dependency; |
15
|
|
|
use yii\db\ActiveQuery; |
16
|
|
|
use yii\db\ActiveRecord as Record; |
17
|
|
|
use yii\db\Connection; |
18
|
|
|
use yii\db\TableSchema; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @author Flipbox Factory <[email protected]> |
22
|
|
|
* @since 1.0.0 |
23
|
|
|
* |
24
|
|
|
* @deprecated |
25
|
|
|
*/ |
26
|
|
|
trait ActiveRecord |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* @return string |
30
|
|
|
*/ |
31
|
|
|
public abstract static function recordClass(): string; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @return int|null |
35
|
|
|
*/ |
36
|
|
|
protected static function cacheDuration() |
37
|
|
|
{ |
38
|
|
|
return false; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @return null|Dependency |
43
|
|
|
*/ |
44
|
|
|
protected static function cacheDependency() |
45
|
|
|
{ |
46
|
|
|
return null; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @return Connection |
51
|
|
|
*/ |
52
|
|
|
public static function getDb(): Connection |
53
|
|
|
{ |
54
|
|
|
/** @var Record $recordClass */ |
55
|
|
|
$recordClass = static::recordClass(); |
56
|
|
|
|
57
|
|
|
return $recordClass::getDb(); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @return TableSchema |
62
|
|
|
* @throws \yii\base\InvalidConfigException |
63
|
|
|
*/ |
64
|
|
|
public static function getTableSchema(): TableSchema |
65
|
|
|
{ |
66
|
|
|
/** @var Record $recordClass */ |
67
|
|
|
$recordClass = static::recordClass(); |
68
|
|
|
|
69
|
|
|
return $recordClass::getTableSchema(); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/******************************************* |
73
|
|
|
* QUERY |
74
|
|
|
*******************************************/ |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* @param array $config |
78
|
|
|
* @return \yii\db\ActiveQuery |
79
|
|
|
*/ |
80
|
|
|
public function getQuery($config = []): ActiveQuery |
81
|
|
|
{ |
82
|
|
|
/** @var Record $recordClass */ |
83
|
|
|
$recordClass = static::recordClass(); |
84
|
|
|
|
85
|
|
|
$query = $recordClass::find(); |
86
|
|
|
|
87
|
|
|
if ($config) { |
|
|
|
|
88
|
|
|
QueryHelper::configure( |
89
|
|
|
$query, |
90
|
|
|
$config |
91
|
|
|
); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
return $query; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/******************************************* |
98
|
|
|
* CREATE |
99
|
|
|
*******************************************/ |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @param array $attributes |
103
|
|
|
* @param string $toScenario |
104
|
|
|
* @return Record |
105
|
|
|
*/ |
106
|
|
|
public function create(array $attributes = [], string $toScenario = null): Record |
107
|
|
|
{ |
108
|
|
|
/** @var string $recordClass */ |
109
|
|
|
$recordClass = static::recordClass(); |
110
|
|
|
|
111
|
|
|
/** @var Record $record */ |
112
|
|
|
$record = new $recordClass(); |
113
|
|
|
|
114
|
|
|
// Set scenario |
115
|
|
|
if ($toScenario) { |
|
|
|
|
116
|
|
|
$record->setScenario($toScenario); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
// Do we need to set properties too |
120
|
|
|
if (!empty($attributes)) { |
121
|
|
|
$record->setAttributes($attributes); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
return $record; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
|
128
|
|
|
/******************************************* |
129
|
|
|
* FIND / GET |
130
|
|
|
*******************************************/ |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* @param string $toScenario |
134
|
|
|
* @return Record[] |
135
|
|
|
*/ |
136
|
|
|
public function findAll(string $toScenario = null) |
137
|
|
|
{ |
138
|
|
|
return $this->findAllByCondition(null, $toScenario); |
|
|
|
|
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @param $identifier |
143
|
|
|
* @param string|null $toScenario |
144
|
|
|
* @return Record|null |
145
|
|
|
*/ |
146
|
|
|
public function find($identifier, string $toScenario = null) |
147
|
|
|
{ |
148
|
|
|
if ($identifier instanceof Record) { |
149
|
|
|
if (null !== $toScenario) { |
150
|
|
|
$identifier->setScenario($toScenario); |
151
|
|
|
} |
152
|
|
|
return $identifier; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
return $this->findByCondition($identifier, $toScenario); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @param $identifier |
160
|
|
|
* @param string $toScenario |
161
|
|
|
* @return Record |
162
|
|
|
* @throws RecordNotFoundException |
163
|
|
|
*/ |
164
|
|
|
public function get($identifier, string $toScenario = null): Record |
165
|
|
|
{ |
166
|
|
|
if (!$object = $this->find($identifier, $toScenario)) { |
167
|
|
|
$this->notFoundException(); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
return $object; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
|
174
|
|
|
/******************************************* |
175
|
|
|
* ONE CONDITION |
176
|
|
|
*******************************************/ |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* @param $condition |
180
|
|
|
* @param string $toScenario |
181
|
|
|
* @return Record|null |
182
|
|
|
*/ |
183
|
|
|
public function findByCondition($condition, string $toScenario = null) |
184
|
|
|
{ |
185
|
|
|
return $this->findByCriteria( |
186
|
|
|
RecordHelper::conditionToCriteria($condition), |
187
|
|
|
$toScenario |
188
|
|
|
); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* @param $condition |
193
|
|
|
* @param string $toScenario |
194
|
|
|
* @return Record |
195
|
|
|
* @throws RecordNotFoundException |
196
|
|
|
*/ |
197
|
|
|
public function getByCondition($condition, string $toScenario = null) |
198
|
|
|
{ |
199
|
|
|
if (!$record = $this->findByCondition($condition, $toScenario)) { |
200
|
|
|
$this->notFoundException(); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
return $record; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
|
207
|
|
|
/******************************************* |
208
|
|
|
* ONE CRITERIA |
209
|
|
|
*******************************************/ |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @param $criteria |
213
|
|
|
* @param string|null $toScenario |
214
|
|
|
* @return mixed |
215
|
|
|
*/ |
216
|
|
|
public function findByCriteria($criteria, string $toScenario = null) |
217
|
|
|
{ |
218
|
|
|
$record = $this->queryOne( |
219
|
|
|
$this->getQuery($criteria) |
220
|
|
|
); |
221
|
|
|
|
222
|
|
|
if ($record && $toScenario) { |
|
|
|
|
223
|
|
|
$record->setScenario($toScenario); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
return $record; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* @param $criteria |
231
|
|
|
* @param string $toScenario |
232
|
|
|
* @return Record |
233
|
|
|
* @throws RecordNotFoundException |
234
|
|
|
*/ |
235
|
|
|
public function getByCriteria($criteria, string $toScenario = null) |
236
|
|
|
{ |
237
|
|
|
if (!$record = $this->findByCriteria($criteria, $toScenario)) { |
238
|
|
|
$this->notFoundException(); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
return $record; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
|
245
|
|
|
/******************************************* |
246
|
|
|
* ALL CONDITION |
247
|
|
|
*******************************************/ |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @param array $condition |
251
|
|
|
* @param string $toScenario |
252
|
|
|
* @return Record[] |
253
|
|
|
*/ |
254
|
|
|
public function findAllByCondition($condition = [], string $toScenario = null) |
255
|
|
|
{ |
256
|
|
|
return $this->findAllByCriteria( |
257
|
|
|
RecordHelper::conditionToCriteria($condition), |
258
|
|
|
$toScenario |
259
|
|
|
); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param array $condition |
264
|
|
|
* @param string $toScenario |
265
|
|
|
* @return Record[] |
266
|
|
|
* @throws RecordNotFoundException |
267
|
|
|
*/ |
268
|
|
|
public function getAllByCondition($condition = [], string $toScenario = null) |
269
|
|
|
{ |
270
|
|
|
if (!$records = $this->findAllByCondition($condition, $toScenario)) { |
271
|
|
|
$this->notFoundException(); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
return $records; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/******************************************* |
278
|
|
|
* ALL CRITERIA |
279
|
|
|
*******************************************/ |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* @param array $criteria |
283
|
|
|
* @param string $toScenario |
284
|
|
|
* @return Record[] |
285
|
|
|
*/ |
286
|
|
|
public function findAllByCriteria($criteria = [], string $toScenario = null) |
287
|
|
|
{ |
288
|
|
|
$records = $this->queryAll( |
289
|
|
|
$this->getQuery($criteria) |
290
|
|
|
); |
291
|
|
|
|
292
|
|
|
if ($toScenario) { |
|
|
|
|
293
|
|
|
foreach ($records as $record) { |
294
|
|
|
$record->setScenario($toScenario); |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
return $records; |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/** |
302
|
|
|
* @param array $criteria |
303
|
|
|
* @param string $toScenario |
304
|
|
|
* @return Record[] |
305
|
|
|
* @throws RecordNotFoundException |
306
|
|
|
*/ |
307
|
|
|
public function getAllByCriteria($criteria = [], string $toScenario = null) |
308
|
|
|
{ |
309
|
|
|
if (!$records = $this->findAllByCriteria($criteria, $toScenario)) { |
310
|
|
|
$this->notFoundException(); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
return $records; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
|
317
|
|
|
/******************************************* |
318
|
|
|
* CACHE |
319
|
|
|
*******************************************/ |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* @param ActiveQuery $query |
323
|
|
|
* @return Record|null |
324
|
|
|
*/ |
325
|
|
|
protected function queryOne(ActiveQuery $query) |
326
|
|
|
{ |
327
|
|
|
$db = static::getDb(); |
328
|
|
|
|
329
|
|
|
try { |
330
|
|
|
if (false === ($cacheDuration = static::cacheDuration())) { |
331
|
|
|
return $query->one($db); |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
$record = $db->cache(function ($db) use ($query) { |
335
|
|
|
return $query->one($db); |
336
|
|
|
}, $cacheDuration, static::cacheDependency()); |
|
|
|
|
337
|
|
|
} catch (\Exception $e) { |
338
|
|
|
return null; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
return $record; |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* @param ActiveQuery $query |
346
|
|
|
* @return Record[] |
347
|
|
|
*/ |
348
|
|
|
protected function queryAll(ActiveQuery $query) |
349
|
|
|
{ |
350
|
|
|
$db = static::getDb(); |
351
|
|
|
|
352
|
|
|
try { |
353
|
|
|
if (false === ($cacheDuration = static::cacheDuration())) { |
354
|
|
|
return $query->all($db); |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
$record = $db->cache(function ($db) use ($query) { |
358
|
|
|
return $query->all($db); |
359
|
|
|
}, $cacheDuration, static::cacheDependency()); |
|
|
|
|
360
|
|
|
} catch (\Exception $e) { |
361
|
|
|
return []; |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
return $record; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/******************************************* |
368
|
|
|
* EXCEPTIONS |
369
|
|
|
*******************************************/ |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* @throws RecordNotFoundException |
373
|
|
|
*/ |
374
|
|
|
protected function notFoundException() |
375
|
|
|
{ |
376
|
|
|
throw new RecordNotFoundException( |
377
|
|
|
sprintf( |
378
|
|
|
"Record does not exist." |
379
|
|
|
) |
380
|
|
|
); |
381
|
|
|
} |
382
|
|
|
} |
383
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.