GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Row::fetchFieldsInto()   B
last analyzed

Complexity

Conditions 11
Paths 49

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 39
rs 7.3166
c 0
b 0
f 0
cc 11
nc 49
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Database\DataObjects\Result;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Database\DataObjects\Result\Row\Record;
19
use O2System\Spl\DataStructures\Traits\ArrayConversionTrait;
20
use O2System\Spl\Exceptions\Logic\InvalidArgumentException;
21
use O2System\Spl\Iterators\ArrayIterator;
22
use Traversable;
23
24
/**
25
 * Class Row
26
 *
27
 * @package O2System\Database\DataObjects\Result
28
 */
29
class Row implements
30
    \IteratorAggregate,
31
    \ArrayAccess,
32
    \Countable,
33
    \Serializable,
34
    \JsonSerializable
35
{
36
    use ArrayConversionTrait;
37
38
    /**
39
     * Row::$columns
40
     *
41
     * List of result row fields
42
     *
43
     * @access  protected
44
     * @type    array
45
     */
46
    protected $columns = [];
47
48
    /**
49
     * Row::$record
50
     *
51
     * @var Record
52
     */
53
    protected $record;
54
55
    // ------------------------------------------------------------------------
56
57
    /**
58
     * Row::__construct
59
     *
60
     * @param array $columns
61
     */
62
    public function __construct(array $columns = [])
63
    {
64
        $this->record = new Record();
65
66
        foreach ($columns as $name => $value) {
67
            if (strpos($name, 'record_create') !== false) {
68
                $this->record->create->offsetSet(
0 ignored issues
show
Bug Best Practice introduced by
The property create does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
69
                    str_replace('record_create_', '', $name),
70
                    $value
71
                );
72
                unset($columns[ $name ]);
73
            } elseif (strpos($name, 'record_update') !== false) {
74
                $this->record->create->offsetSet(
75
                    str_replace('record_update_', '', $name),
76
                    $value
77
                );
78
                unset($columns[ $name ]);
79
            } elseif (strpos($name, 'record') !== false) {
80
                $this->record->offsetSet(
81
                    str_replace('record_', '', $name),
82
                    $value
83
                );
84
                unset($columns[ $name ]);
85
            }
86
        }
87
88
        $this->columns = $columns;
89
    }
90
91
    // ------------------------------------------------------------------------
92
93
    /**
94
     * Row::count
95
     *
96
     * Num of row fields
97
     *
98
     * @return int
99
     */
100
    public function count()
101
    {
102
        return count($this->columns);
103
    }
104
105
    // ------------------------------------------------------------------------
106
107
    /**
108
     * Row::getFields
109
     *
110
     * Return row fields
111
     *
112
     * @return array
113
     */
114
    public function getColumns()
115
    {
116
        return array_keys($this->columns);
117
    }
118
119
    // ------------------------------------------------------------------------
120
121
    /**
122
     * Row::fetchFieldsInto
123
     *
124
     * @param string $className Name of the created class..
125
     * @param array  $classArgs Arguments to be passed into created class constructor.
126
     *
127
     * @return object
128
     * @throws \O2System\Spl\Exceptions\Logic\InvalidArgumentException
129
     * @throws \ReflectionException
130
     */
131
    public function fetchFieldsInto($className, array $classArgs = [])
132
    {
133
        if (is_string($className)) {
0 ignored issues
show
introduced by
The condition is_string($className) is always true.
Loading history...
134
            if ( ! class_exists($className)) {
135
                throw new InvalidArgumentException('E_DB_FETCH_FIELDS_INTO_CLASS_NOT_FOUND', 0, [$className]);
136
            }
137
        }
138
139
        $classObject = $className;
140
        $reflection = new \ReflectionClass($className);
141
142
        if (count($classArgs)) {
143
            $constructor = $reflection->getConstructor();
144
            $classObject = is_null($constructor)
145
                ? $reflection->newInstance()
146
                : $reflection->newInstanceArgs(
147
                    $classArgs
148
                );
149
        } elseif (is_string($className)) {
0 ignored issues
show
introduced by
The condition is_string($className) is always true.
Loading history...
150
            $classObject = new $className;
151
        }
152
153
        foreach ($this->columns as $fieldName => $fieldValue) {
154
            if (method_exists($classObject, $setFieldMethod = 'set' . studlycase($fieldName))) {
155
                call_user_func_array([&$classObject, $setFieldMethod], [$fieldValue]);
156
            } elseif (method_exists($classObject, '__set')) {
157
                $classObject->__set($fieldName, $fieldValue);
158
            } else {
159
                if ($this->isJSON($fieldValue)) {
160
                    $classObject->{camelcase($fieldName)} = new Columns\DataJSON(json_decode($fieldValue, true));
0 ignored issues
show
Bug introduced by
The type O2System\Database\DataOb...Result\Columns\DataJSON was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
161
                } elseif ($this->isSerialized($fieldValue)) {
162
                    $classObject->{camelcase($fieldName)} = new Columns\DataSerialize(unserialize($fieldValue));
0 ignored issues
show
Bug introduced by
The type O2System\Database\DataOb...t\Columns\DataSerialize was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
163
                } else {
164
                    $classObject->{camelcase($fieldName)} = $fieldValue;
165
                }
166
            }
167
        }
168
169
        return $classObject;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $classObject also could return the type object which is incompatible with the documented return type object.
Loading history...
170
    }
171
172
    // ------------------------------------------------------------------------
173
174
    /**
175
     * Row::isJSON
176
     *
177
     * Checks if field value is JSON format.
178
     *
179
     * @param string $string
180
     *
181
     * @return bool
182
     */
183
    protected function isJSON($string)
184
    {
185
        // make sure provided input is of type string
186
        if ( ! is_string($string)) {
0 ignored issues
show
introduced by
The condition is_string($string) is always true.
Loading history...
187
            return false;
188
        }
189
190
        // trim white spaces
191
        $string = trim($string);
192
193
        // get first character
194
        $first_char = substr($string, 0, 1);
195
196
        // get last character
197
        $last_char = substr($string, -1);
198
199
        // check if there is a first and last character
200
        if ( ! $first_char || ! $last_char) {
201
            return false;
202
        }
203
204
        // make sure first character is either { or [
205
        if ($first_char !== '{' && $first_char !== '[') {
206
            return false;
207
        }
208
209
        // make sure last character is either } or ]
210
        if ($last_char !== '}' && $last_char !== ']') {
211
            return false;
212
        }
213
214
        // let's leave the rest to PHP.
215
        // try to decode string
216
        json_decode($string);
217
218
        // check if error occurred
219
        if (json_last_error() === JSON_ERROR_NONE) {
220
            return true;
221
        }
222
223
        return false;
224
    }
225
226
    // ------------------------------------------------------------------------
227
228
    /**
229
     * Row::isSerialized
230
     *
231
     * Checks if field value is PHP serialize format.
232
     *
233
     * @param $string
234
     *
235
     * @return bool
236
     */
237
    protected function isSerialized($string)
238
    {
239
        // if it isn't a string, it isn't serialized
240
        if ( ! is_string($string)) {
241
            return false;
242
        }
243
        $string = trim($string);
244
        if ('N;' == $string) {
245
            return true;
246
        }
247
        if ( ! preg_match('/^([adObis]):/', $string, $matches)) {
248
            return false;
249
        }
250
        switch ($matches[ 1 ]) {
251
            case 'a' :
252
            case 'O' :
253
            case 's' :
254
                if (preg_match("/^{$matches[1]}:[0-9]+:.*[;}]\$/s", $string)) {
255
                    return true;
256
                }
257
                break;
258
            case 'b' :
259
            case 'i' :
260
            case 'd' :
261
                if (preg_match("/^{$matches[1]}:[0-9.E-]+;\$/", $string)) {
262
                    return true;
263
                }
264
                break;
265
        }
266
267
        return false;
268
    }
269
270
    // ------------------------------------------------------------------------
271
272
    /**
273
     * Row::getArrayCopy
274
     *
275
     * Gets array fields copy.
276
     *
277
     * @return array
278
     */
279
    public function getArrayCopy()
280
    {
281
        $fields = $this->columns;
282
283
        foreach ($fields as $fieldName => $fieldValue) {
284
            if ($this->isJSON($fieldValue)) {
285
                $fields[ $fieldName ] = new Row\Columns\DataJSON(json_decode($fieldValue, true));
286
            } elseif ($this->isSerialized($fieldValue)) {
287
                $fields[ $fieldName ] = new Row\Columns\DataSerialize(unserialize($fieldValue));
288
            } else {
289
                $fields[ $fieldName ] = $fieldValue;
290
            }
291
        }
292
293
        return $fields;
294
    }
295
296
    // ------------------------------------------------------------------------
297
298
    /**
299
     * Row::getValues
300
     *
301
     * Return row fields values.
302
     *
303
     * @return array
304
     */
305
    public function getValues()
306
    {
307
        return array_values($this->columns);
308
    }
309
310
    // ------------------------------------------------------------------------
311
312
    /**
313
     * Row::__get
314
     *
315
     * Route magic method __get into offsetGet method.
316
     *
317
     * @param string $field Field name.
318
     *
319
     * @return mixed|null
320
     */
321
    public function __get($field)
322
    {
323
        return $this->offsetGet($field);
324
    }
325
326
    // ------------------------------------------------------------------------
327
328
    /**
329
     * Row::__set
330
     *
331
     * Route magic method __set into offsetSet method.
332
     *
333
     * @param string $field Input name
334
     * @param mixed  $value Input value
335
     */
336
    public function __set($field, $value)
337
    {
338
        $this->offsetSet($field, $value);
339
    }
340
341
    // ------------------------------------------------------------------------
342
343
    /**
344
     * Row::offsetGet
345
     *
346
     * Offset to retrieve
347
     *
348
     * @link  http://php.net/manual/en/arrayaccess.offsetget.php
349
     *
350
     * @param mixed $offset <p>
351
     *                      The offset to retrieve.
352
     *                      </p>
353
     *
354
     * @return mixed Can return all value types.
355
     * @since 5.0.0
356
     */
357
    public function offsetGet($offset)
358
    {
359
        if (isset($this->columns[ $offset ])) {
360
361
            $data = $this->columns[ $offset ];
362
363
            if ($this->isJSON($data)) {
364
                return new Row\Columns\DataJSON(json_decode($data, true));
365
            } elseif ($this->isSerialized($data)) {
366
                return new Row\Columns\DataSerialize(unserialize($data));
367
            } else {
368
                return $data;
369
            }
370
        } elseif(strpos($offset, 'record') !== false) {
371
            switch ($offset) {
372
                case 'record':
373
                    return $this->record;
374
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
375
                case 'record_status':
376
                    return $this->record->status;
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
377
                    break;
378
                case 'record_left':
379
                    return $this->record->left;
0 ignored issues
show
Bug Best Practice introduced by
The property left does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
380
                    break;
381
                case 'record_right':
382
                    return $this->record->right;
0 ignored issues
show
Bug Best Practice introduced by
The property right does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
383
                    break;
384
                case 'record_depth':
385
                    return $this->record->depth;
0 ignored issues
show
Bug Best Practice introduced by
The property depth does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
386
                    break;
387
                case 'record_ordering':
388
                    return $this->record->ordering;
0 ignored issues
show
Bug Best Practice introduced by
The property ordering does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
389
                    break;
390
                case 'record_create_user':
391
                    return $this->record->create->user;
0 ignored issues
show
Bug Best Practice introduced by
The property create does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
392
                    break;
393
                case 'record_create_timestamp':
394
                    return $this->record->create->timestamp;
395
                    break;
396
                case 'record_update_user':
397
                    return $this->record->update->user;
0 ignored issues
show
Bug Best Practice introduced by
The property update does not exist on O2System\Database\DataObjects\Result\Row\Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
398
                    break;
399
                case 'record_update_timestamp':
400
                    return $this->record->update->timestamp;
401
                    break;
402
            }
403
        }
404
405
        return null;
406
    }
407
408
    // ------------------------------------------------------------------------
409
410
    /**
411
     * Row::getRecord
412
     *
413
     * @return \O2System\Database\DataObjects\Result\Row\Record
414
     */
415
    public function getRecord()
416
    {
417
        return $this->record;
418
    }
419
420
    // ------------------------------------------------------------------------
421
422
    /**
423
     * Row::offsetSet
424
     *
425
     * Offset to set
426
     *
427
     * @link  http://php.net/manual/en/arrayaccess.offsetset.php
428
     *
429
     * @param mixed $offset <p>
430
     *                      The offset to assign the value to.
431
     *                      </p>
432
     * @param mixed $value  <p>
433
     *                      The value to set.
434
     *                      </p>
435
     *
436
     * @return void
437
     * @since 5.0.0
438
     */
439
    public function offsetSet($offset, $value)
440
    {
441
        $this->columns[ $offset ] = $value;
442
    }
443
444
    // ------------------------------------------------------------------------
445
446
    /**
447
     * Row::getIterator
448
     *
449
     * Retrieve an external iterator
450
     *
451
     * @link  http://php.net/manual/en/iteratoraggregate.getiterator.php
452
     * @return Traversable An instance of an object implementing <b>Iterator</b> or
453
     *        <b>Traversable</b>
454
     * @since 5.0.0
455
     */
456
    public function getIterator()
457
    {
458
        return new ArrayIterator($this->columns);
459
    }
460
461
    // ------------------------------------------------------------------------
462
463
    /**
464
     * Row::offsetExists
465
     *
466
     * Whether a offset exists
467
     *
468
     * @link  http://php.net/manual/en/arrayaccess.offsetexists.php
469
     *
470
     * @param mixed $offset <p>
471
     *                      An offset to check for.
472
     *                      </p>
473
     *
474
     * @return boolean true on success or false on failure.
475
     * </p>
476
     * <p>
477
     * The return value will be casted to boolean if non-boolean was returned.
478
     * @since 5.0.0
479
     */
480
    public function offsetExists($offset)
481
    {
482
        return isset($this->columns[ $offset ]);
483
    }
484
485
    // ------------------------------------------------------------------------
486
487
    /**
488
     * Row::offsetUnset
489
     *
490
     * Offset to unset
491
     *
492
     * @link  http://php.net/manual/en/arrayaccess.offsetunset.php
493
     *
494
     * @param mixed $offset <p>
495
     *                      The offset to unset.
496
     *                      </p>
497
     *
498
     * @return void
499
     * @since 5.0.0
500
     */
501
    public function offsetUnset($field)
502
    {
503
        unset($this->columns[ $field ]);
504
    }
505
506
    // ------------------------------------------------------------------------
507
508
    /**
509
     * String representation of object
510
     *
511
     * @link  http://php.net/manual/en/serializable.serialize.php
512
     * @return string the string representation of the object or null
513
     * @since 5.1.0
514
     */
515
    public function serialize()
516
    {
517
        return serialize($this->rows);
518
    }
519
520
    // ------------------------------------------------------------------------
521
522
    /**
523
     * Constructs the object
524
     *
525
     * @link  http://php.net/manual/en/serializable.unserialize.php
526
     *
527
     * @param string $serialized <p>
528
     *                           The string representation of the object.
529
     *                           </p>
530
     *
531
     * @return void
532
     * @since 5.1.0
533
     */
534
    public function unserialize($serialized)
535
    {
536
        $this->rows = unserialize($serialized);
0 ignored issues
show
Bug Best Practice introduced by
The property rows does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
537
    }
538
539
    // ------------------------------------------------------------------------
540
541
    /**
542
     * Specify data which should be serialized to JSON
543
     *
544
     * @link  http://php.net/manual/en/jsonserializable.jsonserialize.php
545
     * @return mixed data which can be serialized by <b>json_encode</b>,
546
     *        which is a value of any type other than a resource.
547
     * @since 5.4.0
548
     */
549
    public function jsonSerialize()
550
    {
551
        return $this->columns;
552
    }
553
}