Completed
Push — master ( d508c6...ead087 )
by smiley
02:37
created

WhereTrait::_closeBracket()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
 * Trait WhereTrait
4
 *
5
 * @filesource   WhereTrait.php
6
 * @created      12.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
trait WhereTrait{
18
19
	/**
20
	 * @var array
21
	 */
22
	protected $where = [];
23
24
	protected function _addWhere($val1, $val2 = null, $operator = null, $bind = true, $join = 'AND'){
25
		$operator = strtoupper(trim($operator));
26
		$join = strtoupper(trim($join));
27
28
		$operators = [
29
			'=', '>=', '>', '<=', '<', '<>', '!=',
30
			'|', '&', '<<', '>>', '+', '-', '*', '/', '%', '^', '<=>', '~', '!', 'DIV', 'MOD',
31
			'IS', 'IS NOT', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'REGEXP', 'NOT REGEXP', 'BETWEEN', 'NOT BETWEEN', 'EXISTS'
32
		];
33
34
		if(in_array($operator, $operators, true)){
35
			$where = [$this->quote($val1)];
0 ignored issues
show
Bug introduced by
It seems like quote() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
36
			$values = [];
37
38
			if(in_array($operator, ['IN', 'NOT IN'], true)){
39
40
				if(is_array($val2)){
41
					if($bind){
42
						$where[] = 'IN('.implode(',', array_fill(0, count($val2), '?')).')';
43
						$values = array_merge($values, $val2);
44
					}
45
					else{
46
						$where[] = 'IN('.implode(',', $val2).')'; // @todo: quote
47
					}
48
				}
49
				else if($val2 instanceof StatementInterface){
50
					$where[] = 'IN('.$val2->sql().')';
51
					$values = array_merge($values, $val2->bindValues());
52
				}
53
54
			}
55
			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...
56
				// @todo
57
			}
58
			else{
59
				$where[] = $operator;
60
61
				if(is_null($val2)){
62
					$where[] = 'NULL';
63
				}
64
				else if(is_bool($val2)){
65
					$where[] = $val2 ? 'TRUE' : 'FALSE';
66
				}
67
				else if(in_array(strtolower($val2), ['null', 'false', 'true', 'unknown'])){
68
					$where[] = strtoupper($val2);
69
				}
70
				else if($val2 instanceof StatementInterface){
71
					$where[] = '('.$val2->sql().')';
72
					$values = array_merge($values, $val2->bindValues());
73
				}
74
				else{
75
					if($bind){
76
						$where[] = '?';
77
						$values[] = $val2;
78
					}
79
					else{
80
						if(!empty($val2)){
81
							$where[] = $this->quote($val2);
0 ignored issues
show
Bug introduced by
It seems like quote() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
82
						}
83
					}
84
				}
85
86
			}
87
88
			$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...
89
			$this->where[] = [
90
				'join' => in_array($join, ['AND', 'OR', 'XOR']) ? $join : 'AND',
91
				'stmt' => implode(' ', $where),
92
			];
93
94
		}
95
96
		return $this;
97
	}
98
99
	/**
100
	 * @param string|null $join
101
	 *
102
	 * @return $this
103
	 */
104
	protected function _openBracket($join = null){
105
		$join = strtoupper(trim($join));
106
107
		if(in_array($join, ['AND', 'OR', 'XOR'])){
108
			$this->where[] = $join;
109
		}
110
111
		$this->where[] = '(';
112
113
		return $this;
114
	}
115
116
	/**
117
	 * @return $this
118
	 */
119
	protected function _closeBracket(){
120
		$this->where[] = ')';
121
122
		return $this;
123
	}
124
125
	/**
126
	 * @return string
127
	 */
128
	protected function _getWhere():string {
129
		$where = [];
130
131
		foreach($this->where as $k => $v){
132
			$last = $this->where[$k-1] ?? false;
133
134
			if(in_array($v, ['AND', 'OR', 'XOR', '(', ')'], true)){
135
				$where[] = $v;
136
137
				continue;
138
			}
139
140
			if(!is_array($v)){
141
				continue;
142
			}
143
144
			if(!$last || $last === '('){
145
				$where[] = $v['stmt'];
146
			}
147
			else{
148
				$where[] = $v['join'].' '.$v['stmt'];
149
			}
150
151
		}
152
153
		return !empty($where) ? PHP_EOL.'WHERE '.implode(' '.PHP_EOL."\t", $where) : '';
154
	}
155
156
}
157