Passed
Push — master ( e046f3...04364f )
by Nate
02:43
created

ObjectRecordAccessor::getRecordById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/spark/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/spark
7
 */
8
9
namespace flipbox\spark\behaviors;
10
11
use Craft;
12
use flipbox\spark\exceptions\RecordNotFoundException;
13
use flipbox\spark\helpers\QueryHelper;
14
use flipbox\spark\helpers\RecordHelper;
15
use flipbox\spark\records\Record;
16
use yii\base\Behavior;
17
use yii\base\InvalidConfigException;
18
use yii\db\ActiveQuery;
19
20
/**
21
 * @package flipbox\spark\behaviors
22
 * @author Flipbox Factory <[email protected]>
23
 * @since 1.0.0
24
 */
25
class ObjectRecordAccessor extends Behavior
26
{
27
28
    /**
29
     * @var string
30
     */
31
    public $record;
32
33
    /**
34
     * @var string
35
     */
36
    public $instance = Record::class;
37
38
    /**
39
     * @inheritdoc
40
     *
41
     * @throws InvalidConfigException if the behavior was not configured properly
42
     */
43
    public function init()
44
    {
45
46
        parent::init();
47
48
        if ($this->record === null || ($this->instance && $this->record instanceof $this->instance)) {
49
            throw new InvalidConfigException('Invalid record class.');
50
        }
51
52
    }
53
54
    /**
55
     * @return string
56
     */
57
    protected function getRecordClass()
58
    {
59
        return $this->record;
60
    }
61
62
    /**
63
     * @param array $config
64
     * @return \yii\db\ActiveQuery
65
     */
66
    public function getRecordQuery($config = []): ActiveQuery
67
    {
68
69
        /** @var Record $recordClass */
70
        $recordClass = $this->getRecordClass();
71
72
        $query = $recordClass::find();
73
74
        if ($config) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $config of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
75
76
            QueryHelper::configure(
77
                $query,
78
                $config
79
            );
80
81
        }
82
83
        return $query;
84
85
    }
86
87
    /*******************************************
88
     * CREATE
89
     *******************************************/
90
91
    /**
92
     * @param array $attributes
93
     * @param string $toScenario
94
     * @return Record
95
     */
96
    public function createRecord(array $attributes = [], string $toScenario = null)
97
    {
98
99
        /** @var string $recordClass */
100
        $recordClass = $this->getRecordClass();
101
102
        /** @var Record $record */
103
        $record = new $recordClass();
104
105
        // Set scenario
106
        if ($toScenario) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $toScenario of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
107
            $record->setScenario($toScenario);
108
        }
109
110
        // Do we need to set properties too
111
        if (!empty($attributes)) {
112
            $record->setAttributes($attributes);
113
        }
114
115
        return $record;
116
117
    }
118
119
    /**
120
     * @param $condition
121
     * @param string $toScenario
122
     * @return Record|null
123
     */
124
    public function findRecordByCondition($condition, string $toScenario = null)
125
    {
126
127
        if (empty($condition)) {
128
            return null;
129
        }
130
131
        return $this->findRecordByCriteria(
132
            RecordHelper::conditionToCriteria($condition),
133
            $toScenario
134
        );
135
136
    }
137
138
    /**
139
     * @param $criteria
140
     * @param string $toScenario
141
     * @return Record
142
     */
143 View Code Duplication
    public function findRecordByCriteria($criteria, string $toScenario = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
144
    {
145
146
        $query = $this->getRecordQuery($criteria);
147
148
        /** @var Record $record */
149
        if ($record = $query->one()) {
0 ignored issues
show
Bug Compatibility introduced by
The expression $query->one(); of type yii\db\ActiveRecord|array|null adds the type array to the return on line 158 which is incompatible with the return type documented by flipbox\spark\behaviors\...r::findRecordByCriteria of type flipbox\spark\records\Record|null.
Loading history...
150
151
            // Set scenario
152
            if ($toScenario) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $toScenario of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
153
                $record->setScenario($toScenario);
154
            }
155
156
        }
157
158
        return $record;
159
160
    }
161
162
    /**
163
     * @param $condition
164
     * @param string $toScenario
165
     * @return Record
166
     * @throws RecordNotFoundException
167
     */
168
    public function getRecordByCondition($condition, string $toScenario = null)
169
    {
170
171
        if (!$record = $this->findRecordByCondition($condition, $toScenario)) {
172
173
            $this->notFoundRecordException();
174
175
        }
176
177
        return $record;
178
179
    }
180
181
    /**
182
     * @param $criteria
183
     * @param string $toScenario
184
     * @return Record
185
     * @throws RecordNotFoundException
186
     */
187
    public function getRecordByCriteria($criteria, string $toScenario = null)
188
    {
189
190
        if (!$record = $this->findRecordByCriteria($criteria, $toScenario)) {
191
192
            $this->notFoundRecordException();
193
194
        }
195
196
        return $record;
197
198
    }
199
200
201
    /**
202
     * @param string $toScenario
203
     * @return Record[]
204
     */
205
    public function findAllRecords(string $toScenario = null)
206
    {
207
        return $this->findAllRecordsByCondition(null, $toScenario);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
208
    }
209
210
    /**
211
     * @param array $condition
212
     * @param string $toScenario
213
     * @return Record[]
214
     */
215
    public function findAllRecordsByCondition($condition = [], string $toScenario = null)
216
    {
217
218
        return $this->findAllRecordsByCriteria(
219
            RecordHelper::conditionToCriteria($condition),
220
            $toScenario
221
        );
222
223
    }
224
225
    /**
226
     * @param array $criteria
227
     * @param string $toScenario
228
     * @return Record[]
229
     */
230 View Code Duplication
    public function findAllRecordsByCriteria($criteria = [], string $toScenario = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
231
    {
232
233
        $query = $this->getRecordQuery($criteria);
234
235
        /** @var Record[] $record s */
236
        $records = $query->all();
237
238
        // Set scenario
239
        if ($toScenario) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $toScenario of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
240
241
            /** @var Record $record */
242
            foreach ($records as $record) {
243
244
                // Set scenario
245
                $record->setScenario($toScenario);
246
247
            }
248
249
        }
250
251
        return $records;
252
253
    }
254
255
256
    /**
257
     * @deprecated
258
     * @param array $condition
259
     * @param string $toScenario
260
     * @return Record[]
261
     * @throws RecordNotFoundException
262
     */
263
    public function getAllRecords($condition = [], string $toScenario = null)
264
    {
265
266
        Craft::$app->getDeprecator()->log(
267
            __METHOD__,
268
            'Use the "getAllRecordsByCondition" method'
269
        );
270
271
        return $this->getAllRecordsByCondition($condition, $toScenario);
272
273
    }
274
275
    /**
276
     * @param array $condition
277
     * @param string $toScenario
278
     * @return Record[]
279
     * @throws RecordNotFoundException
280
     */
281
    public function getAllRecordsByCondition($condition = [], string $toScenario = null)
282
    {
283
284
        if (!$records = $this->findAllRecordsByCondition($condition, $toScenario)) {
285
286
            $this->notFoundRecordException();
287
288
        }
289
290
        return $records;
291
292
    }
293
294
    /**
295
     * @param array $criteria
296
     * @param string $toScenario
297
     * @return Record[]
298
     * @throws RecordNotFoundException
299
     */
300
    public function getAllRecordsByCriteria($criteria = [], string $toScenario = null)
301
    {
302
303
        if (!$records = $this->findAllRecordsByCriteria($criteria, $toScenario)) {
304
305
            $this->notFoundRecordException();
306
307
        }
308
309
        return $records;
310
311
    }
312
313
    /*******************************************
314
     * EXCEPTIONS
315
     *******************************************/
316
317
    /**
318
     * @throws RecordNotFoundException
319
     */
320
    protected function notFoundRecordException()
321
    {
322
323
        throw new RecordNotFoundException(
324
            sprintf(
325
                "Record does not exist."
326
            )
327
        );
328
329
    }
330
331
}
332