Passed
Push — 1.0.0-dev ( 459011...73c7ea )
by nguereza
03:08
created

DatabaseQueryBuilder::setSelectStr()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 4
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the GNU GPL License (GPL)
9
     *
10
     * Copyright (C) 2017 Tony NGUEREZA
11
     *
12
     * This program is free software; you can redistribute it and/or
13
     * modify it under the terms of the GNU General Public License
14
     * as published by the Free Software Foundation; either version 3
15
     * of the License, or (at your option) any later version.
16
     *
17
     * This program is distributed in the hope that it will be useful,
18
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     * GNU General Public License for more details.
21
     *
22
     * You should have received a copy of the GNU General Public License
23
     * along with this program; if not, write to the Free Software
24
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
     */
26
    class DatabaseQueryBuilder {
27
        /**
28
         * The SQL SELECT statment
29
         * @var string
30
         */
31
        private $select = '*';
32
  	
33
        /**
34
         * The SQL FROM statment
35
         * @var string
36
         */
37
        private $from = null;
38
  	
39
        /**
40
         * The SQL WHERE statment
41
         * @var string
42
         */
43
        private $where = null;
44
  	
45
        /**
46
         * The SQL LIMIT statment
47
         * @var string
48
         */
49
        private $limit = null;
50
  	
51
        /**
52
         * The SQL JOIN statment
53
         * @var string
54
         */
55
        private $join = null;
56
  	
57
        /**
58
         * The SQL ORDER BY statment
59
         * @var string
60
         */
61
        private $orderBy = null;
62
  	
63
        /**
64
         * The SQL GROUP BY statment
65
         * @var string
66
         */
67
        private $groupBy = null;
68
  	
69
        /**
70
         * The SQL HAVING statment
71
         * @var string
72
         */
73
        private $having = null;
74
  	
75
        /**
76
         * The full SQL query statment after build for each command
77
         * @var string
78
         */
79
        private $query = null;
80
  	
81
        /**
82
         * The list of SQL valid operators
83
         * @var array
84
         */
85
        private $operatorList = array('=', '!=', '<', '>', '<=', '>=', '<>');
86
  	
87
        /**
88
         * The prefix used in each database table
89
         * @var string
90
         */
91
        private $prefix = null;
92
        
93
94
        /**
95
         * The PDO instance
96
         * @var object
97
         */
98
        private $pdo = null;
99
	
100
        /**
101
         * The database driver name used
102
         * @var string
103
         */
104
        private $driver = null;
105
  	
106
	
107
        /**
108
         * Construct new DatabaseQueryBuilder
109
         * @param object $pdo the PDO object
110
         */
111
        public function __construct(PDO $pdo = null) {
112
            if (is_object($pdo)) {
113
                $this->setPdo($pdo);
114
            }
115
        }
116
117
        /**
118
         * Set the SQL FROM statment
119
         * @param  string|array $table the table name or array of table list
120
         * @return object        the current DatabaseQueryBuilder instance
121
         */
122
        public function from($table) {
123
            if (is_array($table)) {
124
                $froms = '';
125
                foreach ($table as $key) {
126
                    $froms .= $this->prefix . $key . ', ';
127
                }
128
                $this->from = rtrim($froms, ', ');
129
            } else {
130
                $this->from = $this->prefix . $table;
131
            }
132
            return $this;
133
        }
134
135
        /**
136
         * Set the SQL SELECT statment
137
         * @param  string|array $fields the field name or array of field list
138
         * @return object        the current DatabaseQueryBuilder instance
139
         */
140
        public function select($fields) {
141
            $select = $fields;
142
            if (is_array($fields)) {
143
                $select = implode(', ', $fields);
144
            }
145
            return $this->setSelectStr($select);
0 ignored issues
show
Bug introduced by
It seems like $select can also be of type array; however, parameter $newSelect of DatabaseQueryBuilder::setSelectStr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

145
            return $this->setSelectStr(/** @scrutinizer ignore-type */ $select);
Loading history...
146
        }
147
148
        /**
149
         * Set the SQL SELECT DISTINCT statment
150
         * @param  string $field the field name to distinct
151
         * @return object        the current DatabaseQueryBuilder instance
152
         */
153
        public function distinct($field) {
154
            return $this->setSelectStr(' DISTINCT ' . $field);
155
        }
156
157
        /**
158
         * Set the SQL function COUNT in SELECT statment
159
         * @param  string $field the field name
160
         * @param  string $name  if is not null represent the alias used for this field in the result
161
         * @return object        the current DatabaseQueryBuilder instance
162
         */
163
        public function count($field = '*', $name = null) {
164
            return $this->select_min_max_sum_count_avg('COUNT', $field, $name);
165
        }
166
    
167
        /**
168
         * Set the SQL function MIN in SELECT statment
169
         * @param  string $field the field name
170
         * @param  string $name  if is not null represent the alias used for this field in the result
171
         * @return object        the current DatabaseQueryBuilder instance
172
         */
173
        public function min($field, $name = null) {
174
            return $this->select_min_max_sum_count_avg('MIN', $field, $name);
175
        }
176
177
        /**
178
         * Set the SQL function MAX in SELECT statment
179
         * @param  string $field the field name
180
         * @param  string $name  if is not null represent the alias used for this field in the result
181
         * @return object        the current DatabaseQueryBuilder instance
182
         */
183
        public function max($field, $name = null) {
184
            return $this->select_min_max_sum_count_avg('MAX', $field, $name);
185
        }
186
187
        /**
188
         * Set the SQL function SUM in SELECT statment
189
         * @param  string $field the field name
190
         * @param  string $name  if is not null represent the alias used for this field in the result
191
         * @return object        the current DatabaseQueryBuilder instance
192
         */
193
        public function sum($field, $name = null) {
194
            return $this->select_min_max_sum_count_avg('SUM', $field, $name);
195
        }
196
197
        /**
198
         * Set the SQL function AVG in SELECT statment
199
         * @param  string $field the field name
200
         * @param  string $name  if is not null represent the alias used for this field in the result
201
         * @return object        the current DatabaseQueryBuilder instance
202
         */
203
        public function avg($field, $name = null) {
204
            return $this->select_min_max_sum_count_avg('AVG', $field, $name);
205
        }
206
207
        /**
208
         * Set the SQL JOIN statment
209
         * @param  string $table  the join table name
210
         * @param  string $field1 the first field for join conditions	
211
         * @param  string $op     the join condition operator. If is null the default will be "="
212
         * @param  string $field2 the second field for join conditions
213
         * @param  string $type   the type of join (INNER, LEFT, RIGHT)
214
         * @return object        the current DatabaseQueryBuilder instance
215
         */
216
        public function join($table, $field1 = null, $op = null, $field2 = null, $type = '') {
217
            $on = $field1;
218
            $table = $this->prefix . $table;
219
            if (!is_null($op)) {
220
                $on = (!in_array($op, $this->operatorList) 
221
                                                        ? ($this->prefix . $field1 . ' = ' . $this->prefix . $op) 
222
                                                        : ($this->prefix . $field1 . ' ' . $op . ' ' . $this->prefix . $field2));
223
            }
224
            if (empty($this->join)) {
225
                $this->join = ' ' . $type . ' JOIN' . ' ' . $table . ' ON ' . $on;
226
            } else {
227
                $this->join = $this->join . ' ' . $type . ' JOIN' . ' ' . $table . ' ON ' . $on;
228
            }
229
            return $this;
230
        }
231
232
        /**
233
         * Set the SQL INNER JOIN statment
234
         * @see  DatabaseQueryBuilder::join()
235
         * @return object        the current DatabaseQueryBuilder instance
236
         */
237
        public function innerJoin($table, $field1, $op = null, $field2 = '') {
238
            return $this->join($table, $field1, $op, $field2, 'INNER ');
239
        }
240
241
        /**
242
         * Set the SQL LEFT JOIN statment
243
         * @see  DatabaseQueryBuilder::join()
244
         * @return object        the current DatabaseQueryBuilder instance
245
         */
246
        public function leftJoin($table, $field1, $op = null, $field2 = '') {
247
            return $this->join($table, $field1, $op, $field2, 'LEFT ');
248
        }
249
250
        /**
251
         * Set the SQL RIGHT JOIN statment
252
         * @see  DatabaseQueryBuilder::join()
253
         * @return object        the current DatabaseQueryBuilder instance
254
         */
255
        public function rightJoin($table, $field1, $op = null, $field2 = '') {
256
            return $this->join($table, $field1, $op, $field2, 'RIGHT ');
257
        }
258
259
        /**
260
         * Set the SQL FULL OUTER JOIN statment
261
         * @see  DatabaseQueryBuilder::join()
262
         * @return object        the current DatabaseQueryBuilder instance
263
         */
264
        public function fullOuterJoin($table, $field1, $op = null, $field2 = '') {
265
            return $this->join($table, $field1, $op, $field2, 'FULL OUTER ');
266
        }
267
268
        /**
269
         * Set the SQL LEFT OUTER JOIN statment
270
         * @see  DatabaseQueryBuilder::join()
271
         * @return object        the current DatabaseQueryBuilder instance
272
         */
273
        public function leftOuterJoin($table, $field1, $op = null, $field2 = '') {
274
            return $this->join($table, $field1, $op, $field2, 'LEFT OUTER ');
275
        }
276
277
        /**
278
         * Set the SQL RIGHT OUTER JOIN statment
279
         * @see  DatabaseQueryBuilder::join()
280
         * @return object        the current DatabaseQueryBuilder instance
281
         */
282
        public function rightOuterJoin($table, $field1, $op = null, $field2 = '') {
283
            return $this->join($table, $field1, $op, $field2, 'RIGHT OUTER ');
284
        }
285
286
        /**
287
         * Set the SQL WHERE CLAUSE for IS NULL
288
         * @param  string|array $field  the field name or array of field list
289
         * @param  string $andOr the separator type used 'AND', 'OR', etc.
290
         * @return object        the current DatabaseQueryBuilder instance
291
         */
292
        public function whereIsNull($field, $andOr = 'AND') {
293
            if (is_array($field)) {
294
                foreach ($field as $f) {
295
                    $this->whereIsNull($f, $andOr);
296
                }
297
            } else {
298
                $this->setWhereStr($field . ' IS NULL ', $andOr);
299
            }
300
            return $this;
301
        }
302
303
        /**
304
         * Set the SQL WHERE CLAUSE for IS NOT NULL
305
         * @param  string|array $field  the field name or array of field list
306
         * @param  string $andOr the separator type used 'AND', 'OR', etc.
307
         * @return object        the current DatabaseQueryBuilder instance
308
         */
309
        public function whereIsNotNull($field, $andOr = 'AND') {
310
            if (is_array($field)) {
311
                foreach ($field as $f) {
312
                    $this->whereIsNotNull($f, $andOr);
313
                }
314
            } else {
315
                $this->setWhereStr($field . ' IS NOT NULL ', $andOr);
316
            }
317
            return $this;
318
        }
319
    
320
        /**
321
         * Set the SQL WHERE CLAUSE statment
322
         * @param  string|array  $where the where field or array of field list
323
         * @param  array|string  $op     the condition operator. If is null the default will be "="
324
         * @param  mixed  $val    the where value
325
         * @param  string  $type   the type used for this where clause (NOT, etc.)
326
         * @param  string  $andOr the separator type used 'AND', 'OR', etc.
327
         * @param  boolean $escape whether to escape or not the $val
328
         * @return object        the current DatabaseQueryBuilder instance
329
         */
330
        public function where($where, $op = null, $val = null, $type = '', $andOr = 'AND', $escape = true) {
331
            $whereStr = '';
332
            if (is_array($where)) {
333
                $whereStr = $this->getWhereStrIfIsArray($where, $type, $andOr, $escape);
334
            } else {
335
                if (is_array($op)) {
336
                    $whereStr = $this->getWhereStrIfOperatorIsArray($where, $op, $type, $escape);
337
                } else {
338
                    $whereStr = $this->getWhereStrForOperator($where, $op, $val, $type, $escape);
339
                }
340
            }
341
            $this->setWhereStr($whereStr, $andOr);
342
            return $this;
343
        }
344
345
        /**
346
         * Set the SQL WHERE CLAUSE statment using OR
347
         * @see  DatabaseQueryBuilder::where()
348
         * @return object        the current DatabaseQueryBuilder instance
349
         */
350
        public function orWhere($where, $op = null, $val = null, $escape = true) {
351
            return $this->where($where, $op, $val, '', 'OR', $escape);
352
        }
353
354
        /**
355
         * Set the SQL WHERE CLAUSE statment using AND and NOT
356
         * @see  DatabaseQueryBuilder::where()
357
         * @return object        the current DatabaseQueryBuilder instance
358
         */
359
        public function notWhere($where, $op = null, $val = null, $escape = true) {
360
            return $this->where($where, $op, $val, 'NOT ', 'AND', $escape);
361
        }
362
363
        /**
364
         * Set the SQL WHERE CLAUSE statment using OR and NOT
365
         * @see  DatabaseQueryBuilder::where()
366
         * @return object        the current DatabaseQueryBuilder instance
367
         */
368
        public function orNotWhere($where, $op = null, $val = null, $escape = true) {
369
            return $this->where($where, $op, $val, 'NOT ', 'OR', $escape);
370
        }
371
372
        /**
373
         * Set the opened parenthesis for the complex SQL query
374
         * @param  string $type   the type of this grouped (NOT, etc.)
375
         * @param  string $andOr the multiple conditions separator (AND, OR, etc.)
376
         * @return object        the current DatabaseQueryBuilder instance
377
         */
378
        public function groupStart($type = '', $andOr = ' AND') {
379
            if (empty($this->where)) {
380
                $this->where = $type . ' (';
381
            } else {
382
                if (substr(trim($this->where), -1) == '(') {
383
                    $this->where .= $type . ' (';
384
                } else {
385
                    $this->where .= $andOr . ' ' . $type . ' (';
386
                }
387
            }
388
            return $this;
389
        }
390
391
        /**
392
         * Set the opened parenthesis for the complex SQL query using NOT type
393
         * @see  DatabaseQueryBuilder::groupStart()
394
         * @return object        the current DatabaseQueryBuilder instance
395
         */
396
        public function notGroupStart() {
397
            return $this->groupStart('NOT');
398
        }
399
400
        /**
401
         * Set the opened parenthesis for the complex SQL query using OR for separator
402
         * @see  DatabaseQueryBuilder::groupStart()
403
         * @return object        the current DatabaseQueryBuilder instance
404
         */
405
        public function orGroupStart() {
406
            return $this->groupStart('', ' OR');
407
        }
408
409
        /**
410
         * Set the opened parenthesis for the complex SQL query using OR for separator and NOT for type
411
         * @see  DatabaseQueryBuilder::groupStart()
412
         * @return object        the current DatabaseQueryBuilder instance
413
         */
414
        public function orNotGroupStart() {
415
            return $this->groupStart('NOT', ' OR');
416
        }
417
418
        /**
419
         * Close the parenthesis for the grouped SQL
420
         * @return object        the current DatabaseQueryBuilder instance
421
         */
422
        public function groupEnd() {
423
            $this->where .= ')';
424
            return $this;
425
        }
426
427
        /**
428
         * Set the SQL WHERE CLAUSE statment for IN
429
         * @param  string  $field  the field name for IN statment
430
         * @param  array   $keys   the list of values used
431
         * @param  string  $type   the condition separator type (NOT)
432
         * @param  string  $andOr the multiple conditions separator (OR, AND)
433
         * @param  boolean $escape whether to escape or not the values
434
         * @return object        the current DatabaseQueryBuilder instance
435
         */
436
        public function in($field, array $keys, $type = '', $andOr = 'AND', $escape = true) {
437
            $_keys = array();
438
            foreach ($keys as $k => $v) {
439
                $v = $this->checkForNullValue($v);
440
                $_keys[] = (is_numeric($v) ? $v : $this->escape($v, $escape));
441
            }
442
            $keys = implode(', ', $_keys);
443
            $whereStr = $field . ' ' . $type . ' IN (' . $keys . ')';
444
            $this->setWhereStr($whereStr, $andOr);
445
            return $this;
446
        }
447
448
        /**
449
         * Set the SQL WHERE CLAUSE statment for NOT IN with AND separator
450
         * @see  DatabaseQueryBuilder::in()
451
         * @return object        the current DatabaseQueryBuilder instance
452
         */
453
        public function notIn($field, array $keys, $escape = true) {
454
            return $this->in($field, $keys, 'NOT ', 'AND', $escape);
455
        }
456
457
        /**
458
         * Set the SQL WHERE CLAUSE statment for IN with OR separator
459
         * @see  DatabaseQueryBuilder::in()
460
         * @return object        the current DatabaseQueryBuilder instance
461
         */
462
        public function orIn($field, array $keys, $escape = true) {
463
            return $this->in($field, $keys, '', 'OR', $escape);
464
        }
465
466
        /**
467
         * Set the SQL WHERE CLAUSE statment for NOT IN with OR separator
468
         * @see  DatabaseQueryBuilder::in()
469
         * @return object        the current DatabaseQueryBuilder instance
470
         */
471
        public function orNotIn($field, array $keys, $escape = true) {
472
            return $this->in($field, $keys, 'NOT ', 'OR', $escape);
473
        }
474
475
        /**
476
         * Set the SQL WHERE CLAUSE statment for BETWEEN
477
         * @param  string  $field  the field used for the BETWEEN statment
478
         * @param  mixed  $value1 the BETWEEN begin value
479
         * @param  mixed  $value2 the BETWEEN end value
480
         * @param  string  $type   the condition separator type (NOT)
481
         * @param  string  $andOr the multiple conditions separator (OR, AND)
482
         * @param  boolean $escape whether to escape or not the values
483
         * @return object        the current DatabaseQueryBuilder instance
484
         */
485
        public function between($field, $value1, $value2, $type = '', $andOr = 'AND', $escape = true) {
486
            $value1 = $this->checkForNullValue($value1);
487
            $value2 = $this->checkForNullValue($value2);
488
            $whereStr = $field . ' ' . $type . ' BETWEEN ' . $this->escape($value1, $escape) . ' AND ' . $this->escape($value2, $escape);
489
            $this->setWhereStr($whereStr, $andOr);
490
            return $this;
491
        }
492
493
        /**
494
         * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and AND separator
495
         * @see  DatabaseQueryBuilder::between()
496
         * @return object        the current DatabaseQueryBuilder instance
497
         */
498
        public function notBetween($field, $value1, $value2, $escape = true) {
499
            return $this->between($field, $value1, $value2, 'NOT ', 'AND', $escape);
500
        }
501
502
        /**
503
         * Set the SQL WHERE CLAUSE statment for BETWEEN with OR separator
504
         * @see  DatabaseQueryBuilder::between()
505
         * @return object        the current DatabaseQueryBuilder instance
506
         */
507
        public function orBetween($field, $value1, $value2, $escape = true) {
508
            return $this->between($field, $value1, $value2, '', 'OR', $escape);
509
        }
510
511
        /**
512
         * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and OR separator
513
         * @see  DatabaseQueryBuilder::between()
514
         * @return object        the current DatabaseQueryBuilder instance
515
         */
516
        public function orNotBetween($field, $value1, $value2, $escape = true) {
517
            return $this->between($field, $value1, $value2, 'NOT ', 'OR', $escape);
518
        }
519
520
        /**
521
         * Set the SQL WHERE CLAUSE statment for LIKE
522
         * @param  string  $field  the field name used in LIKE statment
523
         * @param  string  $data   the LIKE value for this field including the '%', and '_' part
524
         * @param  string  $type   the condition separator type (NOT)
525
         * @param  string  $andOr the multiple conditions separator (OR, AND)
526
         * @param  boolean $escape whether to escape or not the values
527
         * @return object        the current DatabaseQueryBuilder instance
528
         */
529
        public function like($field, $data, $type = '', $andOr = 'AND', $escape = true) {
530
            $data = $this->checkForNullValue($data);
531
            $this->setWhereStr($field . ' ' . $type . ' LIKE ' . ($this->escape($data, $escape)), $andOr);
532
            return $this;
533
        }
534
535
        /**
536
         * Set the SQL WHERE CLAUSE statment for LIKE with OR separator
537
         * @see  DatabaseQueryBuilder::like()
538
         * @return object        the current DatabaseQueryBuilder instance
539
         */
540
        public function orLike($field, $data, $escape = true) {
541
            return $this->like($field, $data, '', 'OR', $escape);
542
        }
543
544
        /**
545
         * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and AND separator
546
         * @see  DatabaseQueryBuilder::like()
547
         * @return object        the current DatabaseQueryBuilder instance
548
         */
549
        public function notLike($field, $data, $escape = true) {
550
            return $this->like($field, $data, 'NOT ', 'AND', $escape);
551
        }
552
553
        /**
554
         * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and OR separator
555
         * @see  DatabaseQueryBuilder::like()
556
         * @return object        the current DatabaseQueryBuilder instance
557
         */
558
        public function orNotLike($field, $data, $escape = true) {
559
            return $this->like($field, $data, 'NOT ', 'OR', $escape);
560
        }
561
562
        /**
563
         * Set the SQL LIMIT statment
564
         * @param  int $limit    the limit offset. If $limitEnd is null this will be the limit count
565
         * like LIMIT n;
566
         * @param  int $limitEnd the limit count
567
         * @return object        the current DatabaseQueryBuilder instance
568
         */
569
        public function limit($limit, $limitEnd = null) {
570
            if (empty($limit)) {
571
                $limit = 0;
572
            }
573
            if (!is_null($limitEnd)) {
574
                $this->limit = $limit . ', ' . $limitEnd;
575
            } else {
576
                $this->limit = $limit;
577
            }
578
            return $this;
579
        }
580
581
        /**
582
         * Set the SQL ORDER BY CLAUSE statment
583
         * @param  string $orderBy   the field name used for order
584
         * @param  string $orderDir the order direction (ASC or DESC)
585
         * @return object        the current DatabaseQueryBuilder instance
586
         */
587
        public function orderBy($orderBy, $orderDir = ' ASC') {
588
            if (stristr($orderBy, ' ') || $orderBy == 'rand()') {
589
                $this->orderBy = empty($this->orderBy) ? $orderBy : $this->orderBy . ', ' . $orderBy;
590
            } else {
591
                $this->orderBy = empty($this->orderBy) 
592
                            ? ($orderBy . ' ' . strtoupper($orderDir)) 
593
                            : $this->orderBy . ', ' . $orderBy . ' ' . strtoupper($orderDir);
594
            }
595
            return $this;
596
        }
597
598
        /**
599
         * Set the SQL GROUP BY CLAUSE statment
600
         * @param  string|array $field the field name used or array of field list
601
         * @return object        the current DatabaseQueryBuilder instance
602
         */
603
        public function groupBy($field) {
604
            $groupBy = $field;
605
            if (is_array($field)) {
606
                $groupBy = implode(', ', $field);
607
            } 
608
            $this->groupBy = $groupBy;
0 ignored issues
show
Documentation Bug introduced by
It seems like $groupBy can also be of type array. However, the property $groupBy is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
609
            return $this;
610
        }
611
612
        /**
613
         * Set the SQL HAVING CLAUSE statment
614
         * @param  string  $field  the field name used for HAVING statment
615
         * @param  string|array  $op     the operator used or array
616
         * @param  mixed  $val    the value for HAVING comparaison
617
         * @param  boolean $escape whether to escape or not the values
618
         * @return object        the current DatabaseQueryBuilder instance
619
         */
620
        public function having($field, $op = null, $val = null, $escape = true) {
621
            if (is_array($op)) {
622
                $this->having = $this->getHavingStrIfOperatorIsArray($field, $op, $escape);
623
            } else if (!in_array($op, $this->operatorList)) {
624
                $op = $this->checkForNullValue($op);
625
                $this->having = $field . ' > ' . ($this->escape($op, $escape));
626
            } else {
627
                $val = $this->checkForNullValue($val);
628
                $this->having = $field . ' ' . $op . ' ' . ($this->escape($val, $escape));
629
            }
630
            return $this;
631
        }
632
633
        /**
634
         * Insert new record in the database
635
         * @param  array   $data   the record data
636
         * @param  boolean $escape  whether to escape or not the values
637
         * @return object  the current DatabaseQueryBuilder instance        
638
         */
639
        public function insert($data = array(), $escape = true) {
640
            $columns = array_keys($data);
641
            $column = implode(', ', $columns);
642
            $values = implode(', ', ($escape ? array_map(array($this, 'escape'), $data) : $data));
643
644
            $this->query = 'INSERT INTO ' . $this->from . ' (' . $column . ') VALUES (' . $values . ')';
645
            return $this;
646
        }
647
648
        /**
649
         * Update record in the database
650
         * @param  array   $data   the record data if is empty will use the $this->data array.
651
         * @param  boolean $escape  whether to escape or not the values
652
         * @return object  the current DatabaseQueryBuilder instance 
653
         */
654
        public function update($data = array(), $escape = true) {
655
            $query = 'UPDATE ' . $this->from . ' SET ';
656
            $values = array();
657
            foreach ($data as $column => $val) {
658
                $values[] = $column . ' = ' . ($this->escape($val, $escape));
659
            }
660
            $query .= implode(', ', $values);
661
            $query .= $this->buildQueryPart('where', ' WHERE ');
662
            $query .= $this->buildQueryPart('orderBy', ' ORDER BY ');
663
            $query .= $this->buildQueryPart('limit', ' LIMIT ');
664
665
            $this->query = $query;
666
            return $this;
667
        }
668
669
        /**
670
         * Delete the record in database
671
         * @return object  the current DatabaseQueryBuilder instance 
672
         */
673
        public function delete() {
674
            $query = 'DELETE FROM ' . $this->from;
675
            $isTruncate = $query;
676
            $query .= $this->buildQueryPart('where', ' WHERE ');
677
            $query .= $this->buildQueryPart('orderBy', ' ORDER BY ');
678
            $query .= $this->buildQueryPart('limit', ' LIMIT ');
679
680
            if ($isTruncate == $query && $this->driver != 'sqlite') {  
681
                $query = 'TRUNCATE TABLE ' . $this->from;
682
            }
683
            $this->query = $query;
684
            return $this;
685
        }
686
687
        /**
688
         * Escape the data before execute query useful for security.
689
         * @param  mixed $data the data to be escaped
690
         * @param boolean $escaped whether we can do escape of not 
691
         * @return mixed       the data after escaped or the same data if not
692
         */
693
        public function escape($data, $escaped = true) {
694
            $data = trim($data);
695
            if ($escaped) {
696
                return $this->pdo->quote($data);
697
            }
698
            return $data;  
699
        }
700
701
        /**
702
         * Return the current SQL query string
703
         * @return string
704
         */
705
        public function getQuery() {
706
            //INSERT, UPDATE, DELETE already set it, if is SELECT we need set it now
707
            if (empty($this->query)) {
708
                $query = 'SELECT ' . $this->select . ' FROM ' . $this->from;
709
                $query .= $this->buildQueryPart('join', '');
710
                $query .= $this->buildQueryPart('where', ' WHERE ');
711
                $query .= $this->buildQueryPart('groupBy', ' GROUP BY ');
712
                $query .= $this->buildQueryPart('having', ' HAVING ');
713
                $query .= $this->buildQueryPart('orderBy', ' ORDER BY ');
714
                $query .= $this->buildQueryPart('limit', ' LIMIT ');
715
                $this->query = $query;
716
            }
717
            return $this->query;
718
        }
719
720
        /**
721
         * Build the part of SQL query
722
         * @param  string $property the name of this class attribute, use after $this->
723
         * @param  string $command  the SQL command like WHERE, HAVING, etc.
724
         * 
725
         * @return string|null
726
         */
727
         protected function buildQueryPart($property, $command = ''){
728
            if (!empty($this->{$property})) {
729
                return $command . ' ' . $this->{$property};
730
            }
731
            return null;
732
         }
733
734
	
735
        /**
736
         * Return the PDO instance
737
         * @return object
738
         */
739
        public function getPdo() {
740
            return $this->pdo;
741
        }
742
743
        /**
744
         * Set the PDO instance
745
         * @param PDO $pdo the pdo object
746
         * @return object DatabaseQueryBuilder
747
         */
748
        public function setPdo(PDO $pdo = null) {
749
            $this->pdo = $pdo;
750
            return $this;
751
        }
752
    	
753
        /**
754
         * Return the database table prefix
755
         * @return string
756
         */
757
        public function getPrefix() {
758
            return $this->prefix;
759
        }
760
761
        /**
762
         * Set the database table prefix
763
         * @param string $prefix the new prefix
764
         * @return object DatabaseQueryBuilder
765
         */
766
        public function setPrefix($prefix) {
767
            $this->prefix = $prefix;
768
            return $this;
769
        }
770
    	
771
        /**
772
         * Return the database driver
773
         * @return string
774
         */
775
        public function getDriver() {
776
            return $this->driver;
777
        }
778
779
        /**
780
         * Set the database driver
781
         * @param string $driver the new driver
782
         * @return object DatabaseQueryBuilder
783
         */
784
        public function setDriver($driver) {
785
            $this->driver = $driver;
786
            return $this;
787
        }
788
	
789
        /**
790
         * Reset the DatabaseQueryBuilder class attributs to the initial values before each query.
791
         * @return object  the current DatabaseQueryBuilder instance 
792
         */
793
        public function reset() {
794
            $this->select   = '*';
795
            $this->from     = null;
796
            $this->where    = null;
797
            $this->limit    = null;
798
            $this->orderBy  = null;
799
            $this->groupBy  = null;
800
            $this->having   = null;
801
            $this->join     = null;
802
            $this->query    = null;
803
            return $this;
804
        }
805
806
        /**
807
         * Set the value for SELECT command and update it if already exists
808
         * @param string $newSelect the new value to set
809
         *
810
         * @return object the current instance
811
         */
812
        protected function setSelectStr($newSelect){
813
            $this->select = (($this->select == '*' || empty($this->select)) 
814
                                    ? $newSelect 
815
                                    : $this->select . ', ' . $newSelect);
816
            return $this;
817
        }
818
819
        /**
820
         * Check if the value is null will return an empty string
821
         * to prevent have error like field1 =  ANd field2 = 'foo'
822
         * @param  string|null $value the value to check
823
         * @return string        the empty string if the value is null
824
         * otherwise the same value will be returned
825
         */
826
        protected function checkForNullValue($value){
827
            if(is_null($value)){
828
                return '';
829
            }
830
            return $value;
831
        }
832
833
        /**
834
         * Get the SQL HAVING clause when operator argument is an array
835
         * @see DatabaseQueryBuilder::having
836
         *
837
         * @return string
838
         */
839
        protected function getHavingStrIfOperatorIsArray($field, $op = null, $escape = true) {
840
            $x = explode('?', $field);
841
            $w = '';
842
            foreach ($x as $k => $v) {
843
                if (!empty($v)) {
844
                    if (!isset($op[$k])) {
845
                        $op[$k] = '';
846
                    }
847
                    $value = '';
848
                    if (isset($op[$k])) {
849
                        $value = $this->escape($op[$k], $escape);
850
                    }
851
                    $w .= $v . $value;
852
                }
853
            }
854
            return $w;
855
        }
856
857
        /**
858
         * Get the SQL WHERE clause using array column => value
859
         * @see DatabaseQueryBuilder::where
860
         *
861
         * @return string
862
         */
863
        protected function getWhereStrIfIsArray(array $where, $type = '', $andOr = 'AND', $escape = true) {
864
            $_where = array();
865
            foreach ($where as $column => $data) {
866
                $data = $this->checkForNullValue($data);
867
                $_where[] = $type . $column . ' = ' . ($this->escape($data, $escape));
868
            }
869
            $where = implode(' ' . $andOr . ' ', $_where);
870
            return $where;
871
        }
872
873
        /**
874
         * Get the SQL WHERE clause when operator argument is an array
875
         * @see DatabaseQueryBuilder::where
876
         *
877
         * @return string
878
         */
879
        protected function getWhereStrIfOperatorIsArray($where, array $op, $type = '', $escape = true) {
880
            $x = explode('?', $where);
881
            $w = '';
882
            foreach ($x as $k => $v) {
883
                if (!empty($v)) {
884
                    $value = '';
885
                    if (isset($op[$k])) {
886
                        $value = $this->escape($op[$k], $escape);
887
                    }
888
                    $w .= $type . $v . $value;
889
                }
890
            }
891
            return $w;
892
        }
893
894
        /**
895
         * Get the default SQL WHERE clause using operator = or the operator argument
896
         * @see DatabaseQueryBuilder::where
897
         *
898
         * @return string
899
         */
900
        protected function getWhereStrForOperator($where, $op = null, $val = null, $type = '', $escape = true) {
901
            $w = '';
902
            if (!in_array((string) $op, $this->operatorList)) {
903
                $op = $this->checkForNullValue($op);
904
                $w = $type . $where . ' = ' . ($this->escape($op, $escape));
905
            } else {
906
                $val = $this->checkForNullValue($val);
907
                $w = $type . $where . ' ' . $op . ' ' . ($this->escape($val, $escape));
908
            }
909
            return $w;
910
        }
911
912
        /**
913
         * Set the $this->where property 
914
         * @param string $whereStr the WHERE clause string
915
         * @param  string  $andOr the separator type used 'AND', 'OR', etc.
916
         */
917
        protected function setWhereStr($whereStr, $andOr = 'AND') {
918
            if (empty($this->where)) {
919
                $this->where = $whereStr;
920
            } else {
921
                if (substr(trim($this->where), -1) == '(') {
922
                    $this->where = $this->where . ' ' . $whereStr;
923
                } else {
924
                    $this->where = $this->where . ' ' . $andOr . ' ' . $whereStr;
925
                }
926
            }
927
        }
928
929
        /**
930
         * Set the SQL SELECT for function MIN, MAX, SUM, AVG, COUNT, AVG
931
         * @param  string $clause the clause type like MIN, MAX, etc.
932
         * @see  DatabaseQueryBuilder::min
933
         * @see  DatabaseQueryBuilder::max
934
         * @see  DatabaseQueryBuilder::sum
935
         * @see  DatabaseQueryBuilder::count
936
         * @see  DatabaseQueryBuilder::avg
937
         * @return object
938
         */
939
        protected function select_min_max_sum_count_avg($clause, $field, $name = null) {
940
            $clause = strtoupper($clause);
941
            $func = $clause . '(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
942
            return $this->setSelectStr($func);
943
        }
944
}
945