Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
84.21% covered (success)
84.21%
32 / 38
CRAP
96.92% covered (success)
96.92%
220 / 227
Record
0.00% covered (danger)
0.00%
0 / 1
84.21% covered (success)
84.21%
32 / 38
112
96.92% covered (success)
96.92%
220 / 227
 __construct
0.00% covered (danger)
0.00%
0 / 1
12
96.30% covered (success)
96.30%
26 / 27
 hasDb
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setDb
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 setDefaultDb
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getDb
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 db
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getSql
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 sql
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 table
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 findById
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 findOne
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 findOneOrCreate
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
 findLatest
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
8 / 8
 findBy
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 findByOrCreate
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
 findAll
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 execute
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
19 / 19
 query
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
15 / 15
 getTotal
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
10 / 10
 getTableInfo
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 with
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
9 / 9
 getById
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
4 / 4
 getOne
0.00% covered (danger)
0.00%
0 / 1
7.07
88.89% covered (success)
88.89%
16 / 18
 getBy
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
16 / 16
 getAll
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 hasOne
0.00% covered (danger)
0.00%
0 / 1
3.14
75.00% covered (success)
75.00%
3 / 4
 hasOneOf
0.00% covered (danger)
0.00%
0 / 1
3.14
75.00% covered (success)
75.00%
3 / 4
 hasMany
0.00% covered (danger)
0.00%
0 / 1
3.14
75.00% covered (success)
75.00%
3 / 4
 belongsTo
0.00% covered (danger)
0.00%
0 / 1
3.14
75.00% covered (success)
75.00%
3 / 4
 increment
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 decrement
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 replicate
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
11 / 11
 isDirty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getDirty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 resetDirty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 save
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
12 / 12
 delete
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
13 / 13
 __callStatic
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
8 / 8
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2021 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Db;
15
16use Pop\Db\Record\Collection;
17
18/**
19 * Record class
20 *
21 * @category   Pop
22 * @package    Pop\Db
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2021 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    5.3.0
27 */
28class Record extends Record\AbstractRecord
29{
30
31    /**
32     * Constructor
33     *
34     * Instantiate the database record object
35     *
36     * Optional parameters are an array of column values, db adapter, or a table name
37     */
38    public function __construct()
39    {
40        $args    = func_get_args();
41        $columns = null;
42        $table   = null;
43        $db      = null;
44        $class   = get_class($this);
45
46        foreach ($args as $arg) {
47            if (is_array($arg) || ($arg instanceof \ArrayAccess) || ($arg instanceof \ArrayObject)) {
48                $columns = $arg;
49            } else if ($arg instanceof Adapter\AbstractAdapter) {
50                $db = $arg;
51            } else if (is_string($arg)) {
52                $table = $arg;
53            }
54        }
55
56        if (null !== $table) {
57            $this->setTable($table);
58        } else {
59            $this->setTableFromClassName($class);
60        }
61
62        if (null !== $db) {
63            Db::setDb($db, $class, null, ($class === __CLASS__));
64        }
65
66        if (!Db::hasDb($class)) {
67            throw new Exception('Error: A database connection has not been set.');
68        } else if (!Db::hasClassToTable($class)) {
69            Db::addClassToTable($class, $this->getFullTable());
70        }
71
72        $this->tableGateway = new Gateway\Table($this->getFullTable());
73        $this->rowGateway   = new Gateway\Row($this->getFullTable(), $this->primaryKeys);
74
75        if (null !== $columns) {
76            $this->isNew = true;
77            $this->setColumns($columns);
78        }
79    }
80
81/*
82 * Static methods
83 */
84
85    /**
86     * Check for a DB adapter
87     *
88     * @return boolean
89     */
90    public static function hasDb()
91    {
92        return Db::hasDb(get_called_class());
93    }
94
95    /**
96     * Set DB adapter
97     *
98     * @param  Adapter\AbstractAdapter $db
99     * @param  string                  $prefix
100     * @param  boolean                 $isDefault
101     * @return void
102     */
103    public static function setDb(Adapter\AbstractAdapter $db, $prefix = null, $isDefault = false)
104    {
105        $class = get_called_class();
106        if ($class == 'Pop\Db\Record') {
107            Db::setDefaultDb($db);
108        } else {
109            Db::setDb($db, $class, $prefix, $isDefault);
110        }
111    }
112
113    /**
114     * Set DB adapter
115     *
116     * @param  Adapter\AbstractAdapter $db
117     * @return void
118     */
119    public static function setDefaultDb(Adapter\AbstractAdapter $db)
120    {
121        Db::setDb($db, null, null, true);
122    }
123
124    /**
125     * Get DB adapter
126     *
127     * @return Adapter\AbstractAdapter
128     */
129    public static function getDb()
130    {
131        return Db::getDb(get_called_class());
132    }
133
134    /**
135     * Get DB adapter (alias)
136     *
137     * @return Adapter\AbstractAdapter
138     */
139    public static function db()
140    {
141        return Db::db(get_called_class());
142    }
143
144    /**
145     * Get SQL builder
146     *
147     * @return Sql
148     */
149    public static function getSql()
150    {
151        return Db::db(get_called_class())->createSql();
152    }
153
154    /**
155     * Get SQL builder (alias)
156     *
157     * @return Sql
158     */
159    public static function sql()
160    {
161        return Db::db(get_called_class())->createSql();
162    }
163
164    /**
165     * Get table name
166     *
167     * @return string
168     */
169    public static function table()
170    {
171        return (new static())->getFullTable();
172    }
173
174    /**
175     * Find by ID static method
176     *
177     * @param  mixed   $id
178     * @param  array   $options
179     * @param  boolean $asArray
180     * @return static|array
181     */
182    public static function findById($id, array $options = null, $asArray = false)
183    {
184        return (new static())->getById($id, $options, $asArray);
185    }
186
187    /**
188     * Find one static method
189     *
190     * @param  array   $columns
191     * @param  array   $options
192     * @param  boolean $asArray
193     * @return static|array
194     */
195    public static function findOne(array $columns = null, array $options = null, $asArray = false)
196    {
197        return (new static())->getOne($columns, $options, $asArray);
198    }
199
200    /**
201     * Find one or create static method
202     *
203     * @param  array   $columns
204     * @param  array   $options
205     * @param  boolean $asArray
206     * @return static|array
207     */
208    public static function findOneOrCreate(array $columns = null, array $options = null, $asArray = false)
209    {
210        $result = (new static())->getOne($columns, $options);
211
212        if (empty($result->toArray())) {
213            $newRecord = new static($columns);
214            $newRecord->save();
215            $result = $newRecord;
216        }
217
218        return ($asArray) ? $result->toArray() : $result;
219    }
220
221    /**
222     * Find latest static method
223     *
224     * @param  string  $by
225     * @param  array   $columns
226     * @param  array   $options
227     * @param  boolean $asArray
228     * @return static|array
229     */
230    public static function findLatest($by = null, array $columns = null, array $options = null, $asArray = false)
231    {
232        $record = new static();
233
234        if ((null === $by) && (count($record->getPrimaryKeys()) == 1)) {
235            $by = $record->getPrimaryKeys()[0];
236        }
237
238        if (null !== $by) {
239            if (null === $options) {
240                $options = ['order' => $by . ' DESC'];
241            } else {
242                $options['order'] = $by . ' DESC';
243            }
244        }
245
246        return $record->getOne($columns, $options, $asArray);
247    }
248
249    /**
250     * Find by static method
251     *
252     * @param  array   $columns
253     * @param  array   $options
254     * @param  boolean $asArray
255     * @return Collection|array
256     */
257    public static function findBy(array $columns = null, array $options = null, $asArray = false)
258    {
259        return (new static())->getBy($columns, $options, $asArray);
260    }
261
262    /**
263     * Find by or create static method
264     *
265     * @param  array   $columns
266     * @param  array   $options
267     * @param  boolean $asArray
268     * @return static|Collection|array
269     */
270    public static function findByOrCreate(array $columns = null, array $options = null, $asArray = false)
271    {
272        $result = (new static())->getBy($columns, $options);
273
274        if ($result->count() == 0) {
275            $newRecord = new static($columns);
276            $newRecord->save();
277            $result = $newRecord;
278        }
279
280        return ($asArray) ? $result->toArray() : $result;
281    }
282
283    /**
284     * Find all static method
285     *
286     * @param  array   $options
287     * @param  boolean $asArray
288     * @return static|Collection
289     */
290    public static function findAll(array $options = null, $asArray = false)
291    {
292        return static::findBy(null, $options, $asArray);
293    }
294
295    /**
296     * Static method to execute a custom prepared SQL statement.
297     *
298     * @param  mixed   $sql
299     * @param  array   $params
300     * @param  boolean $asArray
301     * @return mixed
302     */
303    public static function execute($sql, array $params = [], $asArray = false)
304    {
305        $record = new static();
306
307        if ($sql instanceof Sql) {
308            $sql = (string)$sql;
309        }
310
311        $db = Db::getDb($record->getFullTable());
312        $db->prepare($sql);
313        if (!empty($params)) {
314            $db->bindParams($params);
315        }
316        $db->execute();
317
318        $rows     = [];
319        $isSelect = false;
320
321        if (strtoupper(substr($sql, 0, 6)) == 'SELECT') {
322            $isSelect = true;
323            $rows     = $db->fetchAll();
324            foreach ($rows as $i => $row) {
325                $rows[$i] = $record->processRow($row, $asArray);
326            }
327        }
328
329        if ($isSelect) {
330            $collection = new Record\Collection($rows);
331            return ($asArray) ? $collection->toArray() : $collection;
332        } else {
333            return null;
334        }
335    }
336
337    /**
338     * Static method to execute a custom SQL query.
339     *
340     * @param  mixed   $sql
341     * @param  boolean $asArray
342     * @return mixed
343     */
344    public static function query($sql, $asArray = false)
345    {
346        $record = new static();
347
348        if ($sql instanceof Sql) {
349            $sql = (string)$sql;
350        }
351
352        $db = Db::getDb($record->getFullTable());
353        $db->query($sql);
354
355        $rows     = [];
356        $isSelect = false;
357
358        if (strtoupper(substr($sql, 0, 6)) == 'SELECT') {
359            $isSelect = true;
360            while (($row = $db->fetch())) {
361                $rows[] = $record->processRow($row, $asArray);
362            }
363        }
364
365        if ($isSelect) {
366            $collection = new Record\Collection($rows);
367            return ($asArray) ? $collection->toArray() : $collection;
368        } else {
369            return null;
370        }
371    }
372
373    /**
374     * Static method to get the total count of a set from the DB table
375     *
376     * @param  array $columns
377     * @param  array $options
378     * @return int
379     */
380    public static function getTotal(array $columns = null, array $options = null)
381    {
382        $record      = new static();
383        $expressions = null;
384        $params      = null;
385
386        if (null !== $columns) {
387            $db            = Db::getDb($record->getFullTable());
388            $sql           = $db->createSql();
389            ['expressions' => $expressions, 'params' => $params] =
390                Sql\Parser\Expression::parseShorthand($columns, $sql->getPlaceholder());
391        }
392
393        $rows = $record->getTableGateway()->select(['total_count' => 'COUNT(1)'], $expressions, $params, $options);
394
395        return (isset($rows[0]) && isset($rows[0]['total_count'])) ? (int)$rows[0]['total_count'] : 0;
396    }
397
398    /**
399     * Static method to get the total count of a set from the DB table
400     *
401     * @return array
402     */
403    public static function getTableInfo()
404    {
405        return (new static())->getTableGateway()->getTableInfo();
406    }
407
408    /**
409     * With a 1:many relationship (eager-loading)
410     *
411     * @param  mixed $name
412     * @param  array  $options
413     * @return static
414     */
415    public static function with($name, array $options = null)
416    {
417        $record = new static();
418
419        if (is_array($name)) {
420            foreach ($name as $key => $value) {
421                if (is_numeric($key) && is_string($value)) {
422                    $record->addWith($value);
423                } else if (!is_numeric($key) && is_array($value)) {
424                    $record->addWith($key, $value);
425                }
426            }
427        } else {
428            $record->addWith($name, $options);
429        }
430
431        return $record;
432    }
433
434/*
435 * Instance methods
436 */
437
438    /**
439     * Get by ID method
440     *
441     * @param  mixed   $id
442     * @param  array   $options
443     * @param  boolean $asArray
444     * @return static|array
445     */
446    public function getById($id, array $options = null, $asArray = false)
447    {
448        $this->setColumns($this->getRowGateway()->find($id, [], $options));
449        if ($this->hasWiths()) {
450            $this->getWithRelationships(false);
451        }
452        return ($asArray) ? $this->toArray() : $this;
453    }
454
455    /**
456     * Get one method
457     *
458     * @param  array  $columns
459     * @param  array  $options
460     * @param  boolean $asArray
461     * @return static|array
462     */
463    public function getOne(array $columns = null, array $options = null, $asArray = false)
464    {
465        if (null === $options) {
466            $options = ['limit' => 1];
467        } else {
468            $options['limit'] = 1;
469        }
470
471        $expressions = null;
472        $params      = null;
473        $select      = $options['select'] ?? null;
474
475        if (null !== $columns) {
476            $db            = Db::getDb($this->getFullTable());
477            $sql           = $db->createSql();
478            ['expressions' => $expressions, 'params' => $params] =
479                Sql\Parser\Expression::parseShorthand($columns, $sql->getPlaceholder());
480        }
481
482        $rows = $this->getTableGateway()->select($select, $expressions, $params, $options);
483
484        if ($this->hasWiths() && !empty($rows)) {
485            $this->getWithRelationships();
486            $this->processWithRelationships($rows);
487        }
488
489        if (isset($rows[0])) {
490            $this->setColumns($rows[0]);
491        }
492
493        return ($asArray) ? $this->toArray() : $this;
494    }
495
496    /**
497     * Get by method
498     *
499     * @param  array   $columns
500     * @param  array   $options
501     * @param  boolean $asArray
502     * @return Collection|array
503     */
504    public function getBy(array $columns = null, array $options = null, $asArray = false)
505    {
506        $expressions = null;
507        $params      = null;
508        $select      = $options['select'] ?? null;
509
510        if (null !== $columns) {
511            $db            = Db::getDb($this->getFullTable());
512            $sql           = $db->createSql();
513            ['expressions' => $expressions, 'params' => $params] =
514                Sql\Parser\Expression::parseShorthand($columns, $sql->getPlaceholder());
515        }
516
517        $rows = $this->getTableGateway()->select($select, $expressions, $params, $options);
518
519        foreach ($rows as $i => $row) {
520            $rows[$i] = $this->processRow($row);
521        }
522
523        if ($this->hasWiths() && !empty($rows)) {
524            $this->getWithRelationships();
525            $this->processWithRelationships($rows);
526        }
527
528        $collection = new Record\Collection($rows);
529        return ($asArray) ? $collection->toArray() : $collection;
530    }
531
532    /**
533     * Get all method
534     *
535     * @param  array   $options
536     * @param  boolean $asArray
537     * @return Collection
538     */
539    public function getAll(array $options = null, $asArray = false)
540    {
541        return $this->getBy(null, $options, $asArray);
542    }
543
544    /**
545     * Has one relationship
546     *
547     * @param  string  $foreignTable
548     * @param  string  $foreignKey
549     * @param  array   $options
550     * @param  boolean $eager
551     * @return Record|Record\Relationships\HasOne
552     */
553    public function hasOne($foreignTable, $foreignKey, array $options = null, $eager = false)
554    {
555        $relationship = new Record\Relationships\HasOne($this, $foreignTable, $foreignKey, $options);
556        if (!empty($this->withChildren)) {
557            $relationship->setChildRelationships($this->withChildren);
558        }
559        return ($eager) ? $relationship : $relationship->getChild($options);
560    }
561
562    /**
563     * Has one of relationship
564     *
565     * @param  string  $foreignTable
566     * @param  string  $foreignKey
567     * @param  array   $options
568     * @param  boolean $eager
569     * @return Record|Record\Relationships\HasOneOf
570     */
571    public function hasOneOf($foreignTable, $foreignKey, array $options = null, $eager = false)
572    {
573        $relationship = new Record\Relationships\HasOneOf($this, $foreignTable, $foreignKey, $options);
574        if (!empty($this->withChildren)) {
575            $relationship->setChildRelationships($this->withChildren);
576        }
577        return ($eager) ? $relationship : $relationship->getChild();
578    }
579
580    /**
581     * Has many relationship
582     *
583     * @param  string  $foreignTable
584     * @param  string  $foreignKey
585     * @param  array   $options
586     * @param  boolean $eager
587     * @return Collection|Record\Relationships\HasMany
588     */
589    public function hasMany($foreignTable, $foreignKey, array $options = null, $eager = false)
590    {
591        $relationship = new Record\Relationships\HasMany($this, $foreignTable, $foreignKey, $options);
592        if (!empty($this->withChildren)) {
593            $relationship->setChildRelationships($this->withChildren);
594        }
595        return ($eager) ? $relationship : $relationship->getChildren($options);
596    }
597
598    /**
599     * Belongs to relationship
600     *
601     * @param  string $foreignTable
602     * @param  string $foreignKey
603     * @param  array   $options
604     * @param  boolean $eager
605     * @return Record|Record\Relationships\BelongsTo
606     */
607    public function belongsTo($foreignTable, $foreignKey, array $options = null, $eager = false)
608    {
609        $relationship = new Record\Relationships\BelongsTo($this, $foreignTable, $foreignKey, $options);
610        if (!empty($this->withChildren)) {
611            $relationship->setChildRelationships($this->withChildren);
612        }
613        return ($eager) ? $relationship : $relationship->getParent($options);
614    }
615
616    /**
617     * Increment the record column and save
618     *
619     * @param  string $column
620     * @param  int    $amount
621     * @return void
622     */
623    public function increment($column, $amount = 1)
624    {
625        $this->{$column} += (int)$amount;
626        $this->save();
627    }
628
629    /**
630     * Decrement the record column and save
631     *
632     * @param  string $column
633     * @param  int    $amount
634     * @return void
635     */
636    public function decrement($column, $amount = 1)
637    {
638        $this->{$column} -= (int)$amount;
639        $this->save();
640    }
641
642    /**
643     * Replicate the record
644     *
645     * @param  array $replace
646     * @return static
647     */
648    public function replicate(array $replace = [])
649    {
650        $fields = $this->toArray();
651
652        foreach ($this->primaryKeys as $key) {
653            if (isset($fields[$key])) {
654                unset($fields[$key]);
655            }
656        }
657
658        if (!empty($replace)) {
659            foreach ($replace as $key => $value) {
660                if (isset($fields[$key])) {
661                    $fields[$key] = $value;
662                }
663            }
664        }
665
666        $newRecord = new static($fields);
667        $newRecord->save();
668
669        return $newRecord;
670    }
671
672    /**
673     * Check if row is dirty
674     *
675     * @return boolean
676     */
677    public function isDirty()
678    {
679        return $this->rowGateway->isDirty();
680    }
681
682    /**
683     * Get row's dirty columns
684     *
685     * @return array
686     */
687    public function getDirty()
688    {
689        return $this->rowGateway->getDirty();
690    }
691
692    /**
693     * Reset row's dirty columns
694     *
695     * @return void
696     */
697    public function resetDirty()
698    {
699        $this->rowGateway->resetDirty();
700    }
701
702    /**
703     * Save or update the record
704     *
705     * @param  array $columns
706     * @return void
707     */
708    public function save(array $columns = null)
709    {
710        // Save or update the record
711        if (null === $columns) {
712            if ($this->isNew) {
713                $this->rowGateway->save();
714                $this->isNew = false;
715            } else {
716                $this->rowGateway->update();
717                $record = $this->getById($this->rowGateway->getPrimaryValues());
718                if (isset($record[0])) {
719                    $this->setColumns($record[0]);
720                }
721            }
722        // Else, save multiple rows
723        } else {
724            if (isset($columns[0])) {
725                $this->tableGateway->insertRows($columns);
726            } else {
727                $this->tableGateway->insert($columns);
728            }
729        }
730    }
731
732    /**
733     * Delete the record
734     *
735     * @param  array $columns
736     * @return void
737     */
738    public function delete(array $columns = null)
739    {
740        // Delete the record
741        if (null === $columns) {
742            $this->rowGateway->delete();
743        // Delete multiple rows
744        } else {
745            $expressions = null;
746            $params      = [];
747
748            if (null !== $columns) {
749                $db            = Db::getDb($this->getFullTable());
750                $sql           = $db->createSql();
751                ['expressions' => $expressions, 'params' => $params] =
752                    Sql\Parser\Expression::parseShorthand($columns, $sql->getPlaceholder());
753            }
754
755            $this->tableGateway->delete($expressions, $params);
756        }
757
758        $this->setRows();
759        $this->setColumns();
760    }
761
762    /**
763     * Call static method for 'findWhere'
764     *
765     *      $users = Users::findWhereUsername('testuser');
766     *
767     * @param  string $name
768     * @param  array  $arguments
769     * @return mixed
770     */
771    public static function __callStatic($name, $arguments)
772    {
773        $record = null;
774
775        if (substr($name, 0, 9) == 'findWhere') {
776            $column = Sql\Parser\Table::parse(substr($name, 9));
777            $arg1   = $arguments[0] ?? null;
778            $arg2   = $arguments[1] ?? null;
779
780            if (null !== $arg1) {
781                $record = static::findBy([$column => $arg1], $arg2);
782            }
783        }
784
785        return $record;
786    }
787
788}