Passed
Branch main (5746ae)
by Sammy
02:23
created

Select   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 82
dl 0
loc 189
rs 9.2
c 1
b 0
f 0
wmc 40

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 4
A columns() 0 11 3
A limit() 0 6 1
A retObj() 0 3 2
B generate() 0 32 7
A addPart() 0 5 1
A tableAlias() 0 7 2
A retNum() 0 3 1
A groupBy() 0 13 4
A tableLabel() 0 3 1
A selectAlso() 0 4 2
A retKey() 0 3 1
A retCol() 0 3 1
A retAss() 0 3 1
A retPar() 0 3 1
A orderBy() 0 19 6
A joinRaw() 0 3 1
A having() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Select often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Select, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace HexMakina\Crudites\Queries;
4
5
use HexMakina\BlackBox\Database\TableManipulationInterface;
6
use HexMakina\BlackBox\Database\SelectInterface;
7
use HexMakina\Crudites\CruditesException;
8
9
class Select extends BaseQuery implements SelectInterface
10
{
11
    use ClauseJoin;
0 ignored issues
show
Bug introduced by
The type HexMakina\Crudites\Queries\ClauseJoin 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...
12
    use ClauseWhere;
13
14
    protected $selection = [];
15
    protected $table_alias = null;
16
    protected $join = [];
17
18
    protected $group = [];
19
    protected $having = [];
20
    protected $order = [];
21
22
    protected $limit = null;
23
    protected $limit_number = null;
24
    protected $limit_offset = 0;
25
26
27
    public function __construct($select_fields = null, TableManipulationInterface $table = null, $table_alias = null)
28
    {
29
        $this->table = $table;
30
        $this->table_alias = $table_alias;
31
32
        if (is_null($select_fields)) {
33
            $this->selection = ['*'];
34
        } elseif (is_string($select_fields)) {
35
            $this->selection = explode(',', $select_fields);
36
        } elseif (is_array($select_fields)) {
37
            $this->selection = $select_fields;
38
        }
39
    }
40
41
    public function tableLabel($forced_value = null)
42
    {
43
        return $forced_value ?? $this->table_alias ?? $this->tableName();
44
    }
45
46
    public function columns($setter = null)
47
    {
48
        if (is_null($setter)) {
49
            return $this->selection;
50
        }
51
52
        if (is_array($setter)) {
53
            $this->selection = $setter;
54
        }
55
56
        return $this;
57
    }
58
59
    public function selectAlso($setter)
60
    {
61
        $this->selection = array_merge($this->selection, is_array($setter) ? $setter : [$setter]);
62
        return $this;
63
    }
64
65
    private function addPart($group, $part)
66
    {
67
        $this->$group = $this->$group ?? [];
68
        array_push($this->$group, $part);
69
        return $this;
70
    }
71
72
    public function joinRaw($sql)
73
    {
74
        return $this->addPart('join', $sql);
75
    }
76
77
    public function tableAlias($setter = null)
78
    {
79
        if (!is_null($setter)) {
80
            $this->table_alias = $setter;
81
        }
82
83
        return $this->table_alias ?? $this->tableName();
84
    }
85
86
    public function groupBy($clause)
87
    {
88
        if (is_string($clause)) {
89
            $this->addPart('group', $this->backTick($clause, $this->tableLabel()));
90
        } elseif (is_array($clause)) {
91
            if (isset($clause[1])) { // 0: table, 1: field
92
                $this->addPart('group', $this->backTick($clause[1], $clause[0]));
93
            } else { // 0: field
94
                $this->addPart('group', $this->backTick($clause[0], null));
95
            }
96
        }
97
98
        return $this;
99
    }
100
101
    public function having($condition)
102
    {
103
        return $this->addPart('having', $condition);
104
    }
105
106
    public function orderBy($clause)
107
    {
108
        if (is_string($clause)) {
109
            $this->addPart('order', $clause);
110
        } elseif (is_array($clause) && count($clause) > 1) {
111
            if (isset($clause[2])) { // 0:table, 1:field, 2:direction
112
                $this->addPart(
113
                    'order',
114
                    sprintf('%s %s', $this->backTick($clause[1], $clause[0]), $clause[2])
115
                );
116
            } elseif (isset($clause[1])) { // 0: field, 1: direction
117
                $this->addPart(
118
                    'order',
119
                    sprintf('%s %s', $this->backTick($clause[0], $this->tableLabel()), $clause[1])
120
                );
121
            }
122
        }
123
124
        return $this;
125
    }
126
127
    public function limit($number, $offset = null)
128
    {
129
        $this->limit_number = $number;
130
        $this->limit_offset = $offset;
131
132
        return $this;
133
    }
134
135
    public function generate(): string
136
    {
137
        if (is_null($this->table)) {
138
            throw new CruditesException('NO_TABLE');
139
        }
140
141
        $this->table_alias = $this->table_alias ?? '';
142
143
        $query_fields = empty($this->selection) ? ['*'] : $this->selection;
144
145
        $ret = PHP_EOL . 'SELECT ' . implode(', ' . PHP_EOL, $query_fields);
146
        $ret .= PHP_EOL . sprintf(' FROM `%s` %s ', $this->tableName(), $this->table_alias);
147
148
        if (!empty($this->join)) {
149
            $ret .= PHP_EOL . ' ' . implode(PHP_EOL . ' ', $this->join);
150
        }
151
152
        $ret .= $this->generateWhere();
153
154
        foreach (['group' => 'GROUP BY', 'having' => 'HAVING', 'order' => 'ORDER BY'] as $part => $prefix) {
155
            if (!empty($this->$part)) {
156
                $ret .= PHP_EOL . " $prefix " . implode(', ', $this->$part);
157
            }
158
        }
159
160
        if (!empty($this->limit_number)) {
161
            $offset = $this->limit_offset ?? 0;
162
            $number = $this->limit_number;
163
            $ret .= PHP_EOL . " LIMIT $offset, $number";
164
        }
165
166
        return $ret;
167
    }
168
169
    //------------------------------------------------------------ SELECT:FETCHING RESULT
170
171
    public function retObj($c = null)
172
    {
173
        return is_null($c) ? $this->ret(\PDO::FETCH_OBJ) : $this->ret(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, $c);
174
    }
175
176
    public function retNum()
177
    {
178
        return $this->ret(\PDO::FETCH_NUM);
179
    }
180
    //ret:
181
    public function retAss()
182
    {
183
        return $this->ret(\PDO::FETCH_ASSOC);
184
    }
185
    //ret: array indexed by column name
186
    public function retCol()
187
    {
188
        return $this->ret(\PDO::FETCH_COLUMN);
189
    }
190
    //ret: all values of a single column from the result set
191
    public function retPar()
192
    {
193
        return $this->ret(\PDO::FETCH_KEY_PAIR);
194
    }
195
    public function retKey()
196
    {
197
        return $this->ret(\PDO::FETCH_UNIQUE);
198
    }
199
}
200