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

ObjectTrait   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 49.32%

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 2
dl 0
loc 165
ccs 36
cts 73
cp 0.4932
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
F createObject() 0 75 18
find() 0 1 ?
B getModel() 0 22 6
getTableName() 0 1 ?
A setForeignField() 0 16 2
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