Completed
Pull Request — master (#1)
by Rougin
04:25
created

ObjectTrait::createObject()   F

Complexity

Conditions 18
Paths 1392

Size

Total Lines 75
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 51.5099

Importance

Changes 0
Metric Value
dl 0
loc 75
ccs 26
cts 49
cp 0.5306
rs 2.3285
c 0
b 0
f 0
cc 18
eloc 40
nc 1392
nop 3
crap 51.5099

How to fix   Long Method    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
namespace Rougin\Wildfire\Traits;
4
5
use Rougin\Describe\Column;
6
7
/**
8
 * Object Trait
9
 *
10
 * @package Wildfire
11
 * @author  Rougin Royce Gutib <[email protected]>
12
 *
13
 * @property \Rougin\Describe\Describe $describe
14
 */
15
trait ObjectTrait
16
{
17
    /**
18
     * @var array
19
     */
20
    protected $tables = [];
21
22
    /**
23
     * Creates an object from the specified table and row.
24
     *
25
     * @param  string  $table
26
     * @param  object  $row
27
     * @param  boolean $isForeignKey
28
     * @return array
29
     */
30 18
    protected function createObject($table, $row, $isForeignKey = false)
31
    {
32 18
        list($model, $newTable) = $this->getModel($table, $isForeignKey);
33
34 18
        if (! array_key_exists($newTable, $this->tables)) {
35 18
            $tableInfo = $this->describe->getTable($newTable);
36
37 18
            $this->tables[$newTable] = $tableInfo;
38 18
        } else {
39 15
            $tableInfo = $this->tables[$newTable];
40
        }
41
42 18
        $belongsTo     = [];
43 18
        $columns       = [];
44 18
        $hidden        = [];
45 18
        $relationships = [];
46
47
        // NOTE: To be removed in v1.0.0 (move to belongsTo)
48 18
        if (method_exists($model, 'getBelongsToRelationships')) {
49
            $belongsTo = $model->getBelongsToRelationships();
50
        }
51
52
        // NOTE: To be removed in v1.0.0 (move to columns)
53 18
        if (property_exists($model, 'columns')) {
54 3
            $columns = $model->columns;
55 18
        } elseif (property_exists($model, '_columns')) {
56
            $columns = $model->getColumns();
57
        }
58
59
        // NOTE: To be removed in v1.0.0 (move to hidden)
60 18
        if (method_exists($model, 'getHiddenColumns')) {
61
            $hidden = $model->getHiddenColumns();
62
        }
63
64
        // NOTE: To be removed in v1.0.0 (move to relationships)
65 18
        if (method_exists($model, 'getRelationships')) {
66
            $relationships = $model->getRelationships();
67
        }
68
69 18
        foreach ($tableInfo as $column) {
70 18
            $key = $column->getField();
71
72 18
            $hasInColumns       = ! empty($columns) && ! in_array($key, $columns);
73 18
            $hasInHidden        = ! empty($hidden) && ! in_array($key, $hidden);
74 18
            $isCodeigniterModel = $model instanceof \Rougin\Wildfire\CodeigniterModel;
75
76 18
            if ($hasInColumns || ! $hasInHidden) {
77 18
                continue;
78
            }
79
80
            $model->$key = $row->$key;
81
82
            // NOTE: To be removed in v1.0.0 (if condition only)
83
            if ($isCodeigniterModel) {
84
                foreach ($belongsTo as $key => $value) {
85
                    $option = $value;
86
87
                    if (is_string($value)) {
88
                        $option = [ 'primary_key' => $value . '_id', 'model' => $value ];
89
                    }
90
91
                    $tableName = (new $option['model'])->getTableName();
92
93
                    $isForeignPrimaryKey = $option['primary_key'] == $column->getField();
94
                    $isForeignTable      = $tableName == $column->getReferencedTable();
95
96
                    if (in_array($option['model'], $relationships) && $isForeignPrimaryKey && $isForeignTable) {
97
                        $this->setForeignField($model, $column);
98
                    }
99
                }
100
            }
101 18
        }
102
103 18
        return $model;
104
    }
105
106
    /**
107
     * Finds the row from the specified ID or with the list of delimiters from
108
     * the specified table.
109
     *
110
     * @param  string         $table
111
     * @param  array|integer  $delimiters
112
     * @param  boolean        $isForeignKey
113
     * @return object|boolean
114
     */
115
    abstract protected function find($table, $delimiters = [], $isForeignKey = false);
116
117
    /**
118
     * Gets the model class of the said table.
119
     *
120
     * @param  object|string|null $table
121
     * @param  boolean            $isForeignKey
122
     * @return array
123
     */
124 24
    protected function getModel($table = null, $isForeignKey = false)
125
    {
126 24
        if ($table == null && $this->table == null) {
0 ignored issues
show
Bug introduced by
The property table does not seem to exist. Did you mean tables?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
It seems like you are loosely comparing $table of type object|string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
127 6
            return [ null, '' ];
128
        }
129
130 24
        if ($table instanceof \Rougin\Wildfire\CodeigniterModel) {
131
            return [ $table, strtolower($table->getTableName()) ];
132
        }
133
134 24
        $newTable = $this->getTableName($table, $isForeignKey);
0 ignored issues
show
Bug introduced by
It seems like $table defined by parameter $table on line 124 can also be of type null or object; however, Rougin\Wildfire\Traits\ObjectTrait::getTableName() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
135 24
        $newModel = new $newTable;
136
137
        // NOTE: To be removed in v1.0.0
138 24
        if (property_exists($newModel, 'table')) {
139 3
            $newTable = $newModel->table;
140 24
        } elseif (property_exists($newModel, '_table')) {
141
            $newTable = $newModel->getTableName();
142
        }
143
144 24
        return [ $newModel, strtolower($newTable) ];
145
    }
146
147
    /**
148
     * Parses the table name from Describe class.
149
     *
150
     * @param  string  $table
151
     * @param  boolean $isForeignKey
152
     * @return string
153
     */
154
    abstract protected function getTableName($table, $isForeignKey = false);
155
156
    /**
157
     * Sets the foreign field of the column, if any.
158
     *
159
     * @param  \CI_Model               $model
160
     * @param  \Rougin\Describe\Column $column
161
     * @return void
162
     */
163
    protected function setForeignField(\CI_Model $model, Column $column)
164
    {
165
        if (! $column->isForeignKey()) {
166
            return;
167
        }
168
169
        $columnKey     = $column->getField();
170
        $foreignColumn = $column->getReferencedField();
171
        $foreignTable  = $column->getReferencedTable();
172
173
        $delimiters  = [ $foreignColumn => $model->$columnKey ];
174
        $foreignData = $this->find($foreignTable, $delimiters, true);
175
        $newColumn   = $this->getTableName($foreignTable, true);
176
177
        $model->$newColumn = $foreignData;
178
    }
179
}
180