1 | <?php |
||
13 | class Query { |
||
14 | /** |
||
15 | * @var string |
||
16 | */ |
||
17 | private $from; |
||
18 | |||
19 | /** |
||
20 | * @var array The where clause. |
||
21 | */ |
||
22 | private $where; |
||
23 | |||
24 | /** |
||
25 | * @var array A pointer to the current where clause. |
||
26 | */ |
||
27 | private $currentWhere; |
||
28 | |||
29 | /** |
||
30 | * @var array Pointers to nested where brackets. |
||
31 | */ |
||
32 | private $whereStack; |
||
33 | |||
34 | /** |
||
35 | * @var int |
||
36 | */ |
||
37 | private $limit; |
||
38 | |||
39 | /** |
||
40 | * @var int |
||
41 | */ |
||
42 | private $offset; |
||
43 | |||
44 | /** |
||
45 | * @var string[] |
||
46 | */ |
||
47 | private $order; |
||
48 | |||
49 | /** |
||
50 | * Instantiate a new instance of the {@link Query} class. |
||
51 | * |
||
52 | * @param string $from The table to query. |
||
53 | */ |
||
54 | 11 | public function __construct($from = '') { |
|
60 | |||
61 | /** |
||
62 | * Begin an AND bracket group in the WHERE clause. |
||
63 | * |
||
64 | * @return $this |
||
65 | * @see Query::end() |
||
66 | */ |
||
67 | 5 | public function beginAnd() { |
|
71 | |||
72 | /** |
||
73 | * Begin an OR bracket group in the WHERE clause. |
||
74 | * |
||
75 | * @return $this |
||
76 | * @see Query::end() |
||
77 | */ |
||
78 | 4 | public function beginOr() { |
|
82 | |||
83 | /** |
||
84 | * Begin a bracket group in the WHERE clause. |
||
85 | * |
||
86 | * @param string $op One of the **DB::OP_*** constants. |
||
87 | * @return $this |
||
88 | */ |
||
89 | 8 | private function beginBracket($op) { |
|
97 | |||
98 | /** |
||
99 | * End a bracket group. |
||
100 | * |
||
101 | * @return $this |
||
102 | * @see Query::beginAnd(), Query::beginOr() |
||
103 | */ |
||
104 | 8 | public function end() { |
|
105 | // First unset the reference so it doesn't overwrite the original where clause. |
||
106 | 8 | unset($this->currentWhere); |
|
107 | |||
108 | // Move the pointer in the where stack back one level. |
||
109 | 8 | if (empty($this->whereStack)) { |
|
110 | trigger_error("Call to Query->end() without a corresponding call to Query->begin*().", E_USER_NOTICE); |
||
111 | $this->currentWhere = &$this->where; |
||
112 | } else { |
||
113 | 8 | $key = key(end($this->whereStack)); |
|
114 | 8 | $this->currentWhere = &$this->whereStack[$key]; |
|
115 | 8 | unset($this->whereStack[$key]); |
|
116 | |||
117 | } |
||
118 | 8 | return $this; |
|
119 | } |
||
120 | |||
121 | /** |
||
122 | * Add a WHERE condition to the query. |
||
123 | * |
||
124 | * A basic call to this method specifies a column name and a value. |
||
125 | * |
||
126 | * ```php |
||
127 | * $query->where('id', 123); |
||
128 | * ``` |
||
129 | * |
||
130 | * If you specify just a value then the query will perform an equality match. If you want to specify a different |
||
131 | * operator then you can pass in an array for {@link $value} with the key being the operator and the value being the |
||
132 | * value to filter on. |
||
133 | * |
||
134 | * ```php |
||
135 | * $query->where('count', [Db::GT => 100]); |
||
136 | * ``` |
||
137 | * |
||
138 | * @param string $column Either the name of the column or an array representing several query operators. |
||
139 | * @param mixed $value The value to match to the column. If using the array form of {@link $column} then this parameter |
||
140 | * can be omitted. |
||
141 | * @return $this |
||
142 | */ |
||
143 | 11 | public function addWhere($column, $value) { |
|
144 | 11 | if (array_key_exists($column, $this->currentWhere)) { |
|
145 | 2 | if (!is_array($this->currentWhere[$column])) { |
|
146 | // This is a basic equality statement. |
||
147 | 2 | $this->currentWhere[$column] = [Db::OP_EQ => $this->currentWhere[$column]]; |
|
148 | 2 | } elseif (array_key_exists(0, $this->currentWhere[$column])) { |
|
149 | // This is a basic IN clause. |
||
150 | 1 | $this->currentWhere[$column] = [Db::OP_IN => $this->currentWhere[$column]]; |
|
151 | 1 | } |
|
152 | |||
153 | // Massage the value for proper syntax. |
||
154 | 2 | if (!is_array($value)) { |
|
155 | 2 | $value = [Db::OP_EQ => $value]; |
|
156 | 2 | } elseif (array_key_exists(0, $value)) { |
|
157 | 1 | $value = [Db::OP_IN => $value]; |
|
158 | 1 | } |
|
159 | |||
160 | 2 | $this->currentWhere[$column] = array_merge($this->currentWhere[$column], $value); |
|
161 | 2 | } else { |
|
162 | 11 | $this->currentWhere[$column] = $value; |
|
163 | } |
||
164 | 11 | return $this; |
|
165 | } |
||
166 | |||
167 | /** |
||
168 | * Add a like statement to the current where clause. |
||
169 | * |
||
170 | * @param string $column The name of the column to compare. |
||
171 | * @param string $value The like query. |
||
172 | * @return $this |
||
173 | */ |
||
174 | public function addLike($column, $value) { |
||
178 | |||
179 | /** |
||
180 | * Add an in statement to the current where clause. |
||
181 | * |
||
182 | * @param string $column The name of the column to compare. |
||
183 | * @param array $values The in list to check against. |
||
184 | * @return $this |
||
185 | */ |
||
186 | public function addIn($column, array $values) { |
||
190 | |||
191 | /** |
||
192 | * Add an array of where statements. |
||
193 | * |
||
194 | * This method takes an array where the keys represent column names and the values represent filter values. |
||
195 | * |
||
196 | * ```php |
||
197 | * $query->where([ |
||
198 | * 'parentID' => 123, |
||
199 | * 'count' => [Db::GT => 0] |
||
200 | * ]); |
||
201 | * ``` |
||
202 | * |
||
203 | * @param array $where The array of where statements to add to the query. |
||
204 | * @return $this |
||
205 | * @see Query::addWhere() |
||
206 | */ |
||
207 | 1 | public function addWheres(array $where) { |
|
208 | 1 | foreach ($where as $column => $value) { |
|
209 | 1 | $this->addWhere($column, $value); |
|
210 | 1 | } |
|
211 | 1 | return $this; |
|
212 | } |
||
213 | |||
214 | /** |
||
215 | * Return an array representation of this query. |
||
216 | * |
||
217 | * @return array Returns an array with keys representing the query parts. |
||
218 | */ |
||
219 | 7 | public function toArray() { |
|
220 | $r = [ |
||
221 | 7 | 'from' => $this->from, |
|
222 | 7 | 'where' => $this->where, |
|
223 | 7 | 'order' => $this->order, |
|
224 | 7 | 'limit' => $this->limit, |
|
225 | 7 | 'offset' => $this->offset |
|
226 | 7 | ]; |
|
227 | |||
228 | 7 | return $r; |
|
229 | } |
||
230 | |||
231 | /** |
||
232 | * Execute this query against a database. |
||
233 | * |
||
234 | * @param Db $db The database to query. |
||
235 | * @return \PDOStatement Returns the query result. |
||
236 | */ |
||
237 | 4 | public function exec(Db $db) { |
|
238 | $options = [ |
||
239 | 4 | 'limit' => $this->limit, |
|
240 | 4 | 'offset' => $this->offset |
|
241 | 4 | ]; |
|
242 | |||
243 | 4 | $r = $db->get($this->from, $this->where, $options); |
|
244 | 4 | return $r; |
|
245 | } |
||
246 | |||
247 | /** |
||
248 | * Get the name of the table that is being queried. |
||
249 | * |
||
250 | * @return string Returns the from. |
||
251 | */ |
||
252 | public function getFrom() { |
||
255 | |||
256 | /** |
||
257 | * Set the name of the table that is being queried. |
||
258 | * |
||
259 | * @param string $from A table name. |
||
260 | * @return $this |
||
261 | */ |
||
262 | public function setFrom($from) { |
||
266 | |||
267 | /** |
||
268 | * Get the limit. |
||
269 | * |
||
270 | * @return int Returns the limit. |
||
271 | */ |
||
272 | public function getLimit() { |
||
275 | |||
276 | /** |
||
277 | * Set the limit. |
||
278 | * |
||
279 | * @param int $limit The new limit. |
||
280 | * @return $this |
||
281 | */ |
||
282 | public function setLimit($limit) { |
||
286 | |||
287 | /** |
||
288 | * Get the offset. |
||
289 | * |
||
290 | * @return int Returns the offset. |
||
291 | */ |
||
292 | public function getOffset() { |
||
295 | |||
296 | /** |
||
297 | * Set the offset. |
||
298 | * |
||
299 | * @param int $offset The new offset. |
||
300 | * @return $this |
||
301 | */ |
||
302 | public function setOffset($offset) { |
||
306 | |||
307 | /** |
||
308 | * Get the order. |
||
309 | * |
||
310 | * @return string[] Returns an array of column name, optionally starting with a "-". |
||
311 | */ |
||
312 | public function getOrder() { |
||
315 | |||
316 | /** |
||
317 | * Set the order. |
||
318 | * |
||
319 | * @param string[] $columns An array of column name, optionally starting with a "-". |
||
320 | * @return $this |
||
321 | */ |
||
322 | public function setOrder(...$columns) { |
||
326 | |||
327 | /** |
||
328 | * Add one or more columns to the the order array. |
||
329 | * |
||
330 | * @param string[] $columns Column names optionally starting with a "-". |
||
331 | * @return $this |
||
332 | */ |
||
333 | public function addOrder(...$columns) { |
||
337 | } |
||
338 |
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.
To visualize
will produce issues in the first and second line, while this second example
will produce no issues.