Completed
Push — master ( f08c1d...ffbb02 )
by smiley
02:22
created

WhereTrait::_getWhere()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 14
nc 10
nop 0
1
<?php
2
/**
3
 * Trait WhereTrait
4
 *
5
 * @filesource   WhereTrait.php
6
 * @created      07.06.2017
7
 * @package      chillerlan\Database\Query\Traits
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Query\Traits;
14
15
use chillerlan\Database\Query\StatementInterface;
16
17
/**
18
 * @method quote(string $str):string
19
 */
20
trait WhereTrait{
21
22
	/**
23
	 * @var array
24
	 */
25
	protected $where = [];
26
27
	/**
28
	 * @param null $join
29
	 *
30
	 * @return $this
31
	 */
32
	protected function _openBracket($join = null){
33
		$join = strtoupper(trim($join));
34
35
		if(in_array($join, ['AND', 'OR', 'XOR'])){
36
			$this->where[] = $join;
37
		}
38
39
		$this->where[] = '(';
40
41
		return $this;
42
	}
43
44
	/**
45
	 * @return $this
46
	 */
47
	protected function _closeBracket(){
48
		$this->where[] = ')';
49
50
		return $this;
51
	}
52
53
	/**
54
	 * @param        $val1
55
	 * @param null   $val2
56
	 * @param null   $operator
57
	 * @param bool   $bind
58
	 * @param string $join
59
	 *
60
	 * @return $this
61
	 */
62
	protected function _addWhere($val1, $val2 = null, $operator = null, $bind = true, $join = 'AND'){
63
		$operator = strtoupper(trim($operator));
64
		$join = strtoupper(trim($join));
65
66
		$operators = [
67
			'=', '>=', '>', '<=', '<', '<>', '!=',
68
			'|', '&', '<<', '>>', '+', '-', '*', '/', '%', '^', '<=>', '~', '!', 'DIV', 'MOD',
69
			'IS', 'IS NOT', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'REGEXP', 'NOT REGEXP', 'BETWEEN', 'NOT BETWEEN', 'EXISTS'
70
		];
71
72
		if(in_array($operator, $operators, true)){
73
			$where = [$this->quote($val1)];
74
			$values = [];
75
76
			if(in_array($operator, ['IN', 'NOT IN'], true)){
77
78
				if(is_array($val2)){
79
					if($bind){
80
						$where[] = 'IN('.implode(',', array_fill(0, count($val2), '?')).')';
81
						$values = array_merge($values, $val2);
82
					}
83
					else{
84
						$where[] = 'IN('.implode(',', $val2).')'; // @todo: quote
85
					}
86
				}
87
				else if($val2 instanceof StatementInterface){
88
					$where[] = 'IN('.$val2->sql().')';
89
					$values = array_merge($values, $val2->bindValues());
90
				}
91
92
			}
93
			else if(in_array($operator, ['BETWEEN', 'NOT BETWEEN'], true)){
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
94
95
			}
96
			else{
97
				$where[] = $operator;
98
99
				if(is_null($val2)){
100
					$where[] = 'NULL';
101
				}
102
				else if(is_bool($val2)){
103
					$where[] = $val2 ? 'TRUE' : 'FALSE';
104
				}
105
				else if(in_array(strtolower($val2), ['null', 'false', 'true', 'unknown'])){
106
					$where[] = strtoupper($val2);
107
				}
108
				else if($val2 instanceof StatementInterface){
109
					$where[] = '('.$val2->sql().')';
110
					$values = array_merge($values, $val2->bindValues());
111
				}
112
				else{
113
					if($bind){
114
						$where[] = '?';
115
						$values[] = $val2;
116
					}
117
					else{
118
						if(!empty($val2)){
119
							$where[] = $this->quote($val2);
120
						}
121
					}
122
				}
123
124
			}
125
126
			$this->bindValues = array_merge($this->bindValues, $values);
0 ignored issues
show
Bug introduced by
The property bindValues does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
127
			$this->where[] = [
128
				'join' => in_array($join, ['AND', 'OR', 'XOR']) ? $join : 'AND',
129
				'stmt' => implode(' ', $where),
130
			];
131
132
		}
133
134
		return $this;
135
	}
136
137
	/**
138
	 * @return string
139
	 */
140
	protected function _getWhere():string {
141
		$where = [];
142
143
		foreach($this->where as $k => $v){
144
			$last = $this->where[$k-1] ?? false;
145
#			print_r([$last, $v]);
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
146
147
			if(in_array($v, ['AND', 'OR', 'XOR', '(', ')'], true)){
148
				$where[] = $v;
149
150
				continue;
151
			}
152
153
			if(!is_array($v)){
154
				continue;
155
			}
156
157
			if(!$last || $last === '('){
158
				$where[] = $v['stmt'];
159
			}
160
			else{
161
				$where[] = $v['join'].' '.$v['stmt'];
162
			}
163
164
		}
165
166
		return !empty($where) ? PHP_EOL.'WHERE '.implode(' '.PHP_EOL."\t", $where) : '';
167
	}
168
}
169