Passed
Push — master ( 36ec95...f2dea1 )
by Nate
07:31
created

ObjectTrait   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 286
Duplicated Lines 14.69 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 6
dl 42
loc 286
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
recordClass() 0 1 ?
A recordClassInstance() 0 4 1
A getRecordQuery() 0 20 2
A createRecord() 0 22 3
A findRecordByCondition() 0 13 2
A findRecordByCriteria() 18 18 3
A getRecordByCondition() 0 12 2
A getRecordByCriteria() 0 12 2
A findAllRecords() 0 4 1
A findAllRecordsByCondition() 0 9 1
B findAllRecordsByCriteria() 24 24 3
A getAllRecords() 0 11 1
A getAllRecordsByCondition() 0 12 2
A getAllRecordsByCriteria() 0 12 2
A notFoundRecordException() 0 10 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\services\traits;
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\models\Model;
16
use flipbox\spark\records\Record;
17
use yii\db\ActiveQuery;
18
19
/**
20
 * @package flipbox\spark\services\traits
21
 * @author Flipbox Factory <[email protected]>
22
 * @since 1.1.0
23
 */
24
trait ObjectTrait
25
{
26
27
    /**
28
     * @return string
29
     */
30
    public abstract static function recordClass(): string;
31
32
    /**
33
     * @return string
34
     */
35
    public static function recordClassInstance(): string
36
    {
37
        return Record::class;
38
    }
39
40
    /**
41
     * @param array $config
42
     * @return \yii\db\ActiveQuery
43
     */
44
    public function getRecordQuery($config = []): ActiveQuery
45
    {
46
47
        /** @var Record $recordClass */
48
        $recordClass = $this->recordClass();
49
50
        $query = $recordClass::find();
51
52
        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...
53
54
            QueryHelper::configure(
55
                $query,
56
                $config
57
            );
58
59
        }
60
61
        return $query;
62
63
    }
64
65
    /*******************************************
66
     * CREATE
67
     *******************************************/
68
69
    /**
70
     * @param array $attributes
71
     * @param string $toScenario
72
     * @return Record
73
     */
74
    public function createRecord(array $attributes = [], string $toScenario = null)
75
    {
76
77
        /** @var string $recordClass */
78
        $recordClass = static::recordClass();
79
80
        /** @var Record $record */
81
        $record = new $recordClass();
82
83
        // Set scenario
84
        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...
85
            $record->setScenario($toScenario);
86
        }
87
88
        // Do we need to set properties too
89
        if (!empty($attributes)) {
90
            $record->setAttributes($attributes);
91
        }
92
93
        return $record;
94
95
    }
96
97
    /**
98
     * @param $condition
99
     * @param string $toScenario
100
     * @return Record|null
101
     */
102
    public function findRecordByCondition($condition, string $toScenario = null)
103
    {
104
105
        if (empty($condition)) {
106
            return null;
107
        }
108
109
        return $this->findRecordByCriteria(
110
            RecordHelper::conditionToCriteria($condition),
111
            $toScenario
112
        );
113
114
    }
115
116
    /**
117
     * @param $criteria
118
     * @param string $toScenario
119
     * @return Record
120
     */
121 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...
122
    {
123
124
        $query = $this->getRecordQuery($criteria);
125
126
        /** @var Record $record */
127
        if ($record = $query->one()) {
128
129
            // Set scenario
130
            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...
131
                $record->setScenario($toScenario);
132
            }
133
134
        }
135
136
        return $record;
137
138
    }
139
140
    /**
141
     * @param $condition
142
     * @param string $toScenario
143
     * @return Record
144
     * @throws RecordNotFoundException
145
     */
146
    public function getRecordByCondition($condition, string $toScenario = null)
147
    {
148
149
        if (!$record = $this->findRecordByCondition($condition, $toScenario)) {
150
151
            $this->notFoundRecordException();
152
153
        }
154
155
        return $record;
156
157
    }
158
159
    /**
160
     * @param $criteria
161
     * @param string $toScenario
162
     * @return Record
163
     * @throws RecordNotFoundException
164
     */
165
    public function getRecordByCriteria($criteria, string $toScenario = null)
166
    {
167
168
        if (!$record = $this->findRecordByCriteria($criteria, $toScenario)) {
169
170
            $this->notFoundRecordException();
171
172
        }
173
174
        return $record;
175
176
    }
177
178
179
    /**
180
     * @param string $toScenario
181
     * @return Record[]
182
     */
183
    public function findAllRecords(string $toScenario = null)
184
    {
185
        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...
186
    }
187
188
    /**
189
     * @param array $condition
190
     * @param string $toScenario
191
     * @return Record[]
192
     */
193
    public function findAllRecordsByCondition($condition = [], string $toScenario = null)
194
    {
195
196
        return $this->findAllRecordsByCriteria(
197
            RecordHelper::conditionToCriteria($condition),
198
            $toScenario
199
        );
200
201
    }
202
203
    /**
204
     * @param array $criteria
205
     * @param string $toScenario
206
     * @return Record[]
207
     */
208 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...
209
    {
210
211
        $query = $this->getRecordQuery($criteria);
212
213
        /** @var Record[] $record s */
214
        $records = $query->all();
215
216
        // Set scenario
217
        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...
218
219
            /** @var Record $record */
220
            foreach ($records as $record) {
221
222
                // Set scenario
223
                $record->setScenario($toScenario);
224
225
            }
226
227
        }
228
229
        return $records;
230
231
    }
232
233
234
    /**
235
     * @deprecated
236
     * @param array $condition
237
     * @param string $toScenario
238
     * @return Record[]
239
     * @throws RecordNotFoundException
240
     */
241
    public function getAllRecords($condition = [], string $toScenario = null)
242
    {
243
244
        Craft::$app->getDeprecator()->log(
245
            __METHOD__,
246
            'Use the "getAllRecordsByCondition" method'
247
        );
248
249
        return $this->getAllRecordsByCondition($condition, $toScenario);
250
251
    }
252
253
    /**
254
     * @param array $condition
255
     * @param string $toScenario
256
     * @return Record[]
257
     * @throws RecordNotFoundException
258
     */
259
    public function getAllRecordsByCondition($condition = [], string $toScenario = null)
260
    {
261
262
        if (!$records = $this->findAllRecordsByCondition($condition, $toScenario)) {
263
264
            $this->notFoundRecordException();
265
266
        }
267
268
        return $records;
269
270
    }
271
272
    /**
273
     * @param array $criteria
274
     * @param string $toScenario
275
     * @return Record[]
276
     * @throws RecordNotFoundException
277
     */
278
    public function getAllRecordsByCriteria($criteria = [], string $toScenario = null)
279
    {
280
281
        if (!$records = $this->findAllRecordsByCriteria($criteria, $toScenario)) {
282
283
            $this->notFoundRecordException();
284
285
        }
286
287
        return $records;
288
289
    }
290
291
    /*******************************************
292
     * EXCEPTIONS
293
     *******************************************/
294
295
    /**
296
     * @throws RecordNotFoundException
297
     */
298
    protected function notFoundRecordException()
299
    {
300
301
        throw new RecordNotFoundException(
302
            sprintf(
303
                "Record does not exist."
304
            )
305
        );
306
307
    }
308
309
}
310