Completed
Push — master ( b41b74...318069 )
by Oscar
01:33
created

SimpleCrud::getQuery()   C

Complexity

Conditions 10
Paths 144

Size

Total Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 61
rs 6.6909
c 0
b 0
f 0
cc 10
nc 144
nop 1

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 Folk\Entities;
4
5
use Folk\SearchQuery;
6
use SimpleCrud\Table;
7
use SimpleCrud\Row;
8
use SimpleCrud\Scheme\Scheme;
9
use SimpleCrud\Queries\Query;
10
11
abstract class SimpleCrud extends AbstractEntity
12
{
13
    protected $searchFields;
14
    protected $firstField;
15
16
    /**
17
     * Returns the simple-crud table.
18
     */
19
    abstract protected function getTable(): Table;
20
21
    /**
22
     * Generates the query to search rows.
23
     */
24
    protected function getQuery(SearchQuery $search): Query
25
    {
26
        $table = $this->getTable();
27
28
        $query = $table->select();
29
30
        //Filter by id
31
        if (count($search->getIds())) {
32
            $query->where('id IN', $search->getIds());
33
        }
34
35
        if ($search->getPage() !== null) {
36
            $limit = $search->getLimit();
37
38
            $query->offset(($search->getPage() * $limit) - $limit)->limit($limit);
39
        }
40
41
        if ($this->searchFields === null) {
42
            $this->searchFields = [$this->getFirstField()];
43
        }
44
45
        $orderBy = $search->getSort();
46
47
        if (empty($orderBy)) {
48
            $query->orderBy("{$table->id} DESC");
49
        } else {
50
            foreach ($orderBy as $field => $direction) {
51
                $query->orderBy("{$table->$field} {$direction}");
52
            }
53
        }
54
55
        //Filter by words
56
        foreach ($search->getWords() as $word) {
57
            $query->where('(');
58
            $like = "%{$word}%";
59
60
            foreach ($this->searchFields as $k => $field) {
61
                if ($k !== 0) {
62
                    $query->catWhere(' OR ');
63
                }
64
65
                $query->catWhere("{$table->$field} LIKE ", $like);
66
            }
67
68
            $query->catWhere(')');
69
        }
70
71
        //Filter by relations
72
        $db = $table->getDatabase();
73
74
        foreach ($search->getConditions() as $name => $value) {
75
            $related = $db->$name
76
                ->select()
77
                ->whereEquals(['id' => $value])
78
                ->run();
79
80
            $query->relatedWith($related);
81
        }
82
83
        return $query;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function search(SearchQuery $search): array
90
    {
91
        $result = [];
92
93
        foreach ($this->getQuery($search)->run() as $row) {
0 ignored issues
show
Bug introduced by
The expression $this->getQuery($search)->run() of type null is not traversable.
Loading history...
94
            $result[$row->id] = $row->toArray(true);
95
        }
96
97
        return $result;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function create(array $data)
104
    {
105
        $row = $this->getTable()->create();
106
        
107
        $this->save($row, $data);
108
109
        return $row->id;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function read($id): array
116
    {
117
        $table = $this->getTable();
118
        $db = $table->getDatabase();
119
120
        $row = $table[$id];
121
122
        if (empty($row)) {
123
            return [];
124
        }
125
126
        $array = $row->toArray(true);
127
        $foreignKey = $table->getForeignKey();
0 ignored issues
show
Unused Code introduced by
$foreignKey is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
128
129
        foreach ($db->getScheme()->getTables() as $tableName) {
130
            $table2 = $db->{$tableName};
131
132
            //Has many OR has many to many
133
            if ($table2->getJoinField($table) || $table->getJoinTable($table2)) {
134
                $array[$tableName] = array_values($row->$tableName->id);
135
                continue;
136
            }
137
        }
138
139
        return $array;
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function update($id, array $data)
146
    {
147
        $row = $this->getTable()[$id];
148
149
        $this->save($row, $data);
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function delete($id)
156
    {
157
        $table = $this->getTable();
158
159
        unset($table[$id]);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function getLabel($id, array $data): string
166
    {
167
        return "{$id} - ".$data[$this->getFirstField()];
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173
    protected function getFirstField(): string
174
    {
175
        if ($this->firstField === null) {
176
            foreach ($this->getTable()->getFields() as $field) {
177
                if ($field->getName() !== 'id') {
178
                    return $this->firstField = $field->getName();
179
                }
180
            }
181
        }
182
183
        return $this->firstField;
184
    }
185
186
    /**
187
     * Save the data in the database.
188
     * 
189
     * @param Row   $row
190
     * @param array $data
191
     */
192
    protected function save(Row $row, array $data)
193
    {
194
        $table = $this->getTable();
195
        $db = $table->getDatabase();
196
        $tables = $db->getScheme()->getTables();
197
        $relations = [];
198
199
        foreach ($data as $name => $value) {
200
            if (isset($table->$name)) {
201
                $row->$name = $value;
202
                continue;
203
            }
204
205
            if (in_array($name, $tables)) {
206
                $relations[$name] = (array) $value;
207
            }
208
        }
209
210
        foreach ($relations as $name => $ids) {
211
            $table2 = $db->$name;
212
            $related = $row->$name;
213
214
            foreach ($related as $id => $r) {
215
                if (!in_array($id, $ids)) {
216
                    $row->unrelate($r);
217
                }
218
            }
219
220
            foreach ($ids as $id) {
221
                if ($id && !isset($related[$id])) {
222
                    if ($r = $table2[$id]) {
223
                        $row->relate($r);
224
                    }
225
                }
226
            }
227
        }
228
229
        $row->save();
230
    }
231
}
232