WhereTrait::where()   C
last analyzed

Complexity

Conditions 16
Paths 100

Size

Total Lines 76
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 16
eloc 41
nc 100
nop 5
dl 0
loc 76
rs 5.5666
c 2
b 1
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Trait WhereTrait
4
 *
5
 * @filesource   WhereTrait.php
6
 * @created      12.06.2017
7
 * @package      chillerlan\Database\Query
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Query;
14
15
/**
16
 * https://xkcd.com/1409/
17
 *
18
 * @implements \chillerlan\Database\Query\Where
19
 *
20
 * @property \chillerlan\Database\Drivers\DriverInterface $db
21
 * @property \chillerlan\Database\Dialects\Dialect        $dialect
22
 * @property array                                        $bindValues
23
 */
24
trait WhereTrait{
25
26
	private array $operators = [
27
		'=', '>=', '>', '<=', '<', '<>', '!=',
28
		'|', '&', '<<', '>>', '+', '-', '*', '/',
29
		'%', '^', '<=>', '~', '!', 'DIV', 'MOD',
30
		'IS', 'IS NOT', 'IN', 'NOT IN', 'LIKE',
31
		'NOT LIKE', 'REGEXP', 'NOT REGEXP',
32
		'EXISTS', 'ANY', 'SOME',
33
//		'BETWEEN', 'NOT BETWEEN',
34
	];
35
36
	private array $joinArgs = ['AND', 'OR', 'XOR'];
37
	protected array $where = [];
38
39
	/**
40
	 * @param mixed       $val1
41
	 * @param mixed|null  $val2
42
	 * @param string|null $operator
43
	 * @param bool|null   $bind
44
	 * @param string|null $join
45
	 *
46
	 * @return $this
47
	 */
48
	public function where($val1, $val2 = null, string $operator = null, bool $bind = null, string $join = null):Statement{
49
		$operator = $operator !== null ? strtoupper(trim($operator)) : '=';
50
		$bind     = $bind ?? true;
51
52
		$join = strtoupper(trim($join));
0 ignored issues
show
Bug introduced by
It seems like $join can also be of type null; however, parameter $string of trim() 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

52
		$join = strtoupper(trim(/** @scrutinizer ignore-type */ $join));
Loading history...
53
		$join = in_array($join, $this->joinArgs, true) ? $join : 'AND';
54
55
		if(in_array($operator, $this->operators, true)){
56
			$where = [
57
				is_array($val1)
58
					? strtoupper($val1[1]).'('.$this->dialect->quote($val1[0]).')'
59
					: $this->dialect->quote($val1)
60
			];
61
62
			if(in_array($operator, ['IN', 'NOT IN', 'ANY', 'SOME',], true)){
63
64
				if(is_array($val2)){
65
66
					if($bind){
67
						$where[] = $operator.'('.implode(',', array_fill(0, count($val2), '?')).')';
68
						$this->bindValues = array_merge($this->bindValues, $val2);
69
					}
70
					else{
71
						$where[] = $operator.'('.implode(',', array_map([$this->db, 'escape'], $val2)).')'; // @todo: quote
72
					}
73
74
				}
75
				else if($val2 instanceof Statement){
76
					$where[] = $operator.'('.$val2->sql().')';
0 ignored issues
show
Bug introduced by
The method sql() does not exist on chillerlan\Database\Query\Statement. It seems like you code against a sub-type of chillerlan\Database\Query\Statement such as anonymous//src/Query/QueryBuilder.php$10 or anonymous//src/Query/QueryBuilder.php$19 or anonymous//src/Query/QueryBuilder.php$13 or anonymous//src/Query/QueryBuilder.php$4 or anonymous//src/Query/QueryBuilder.php$7 or anonymous//src/Query/QueryBuilder.php$12 or anonymous//src/Query/QueryBuilder.php$3 or anonymous//src/Query/QueryBuilder.php$6 or anonymous//src/Query/QueryBuilder.php$14 or anonymous//src/Query/QueryBuilder.php$17 or anonymous//src/Query/QueryBuilder.php$11 or anonymous//src/Query/QueryBuilder.php$8 or anonymous//src/Query/QueryBuilder.php$19 or anonymous//src/Query/QueryBuilder.php$17 or anonymous//src/Query/QueryBuilder.php$10 or anonymous//src/Query/QueryBuilder.php$4 or anonymous//src/Query/QueryBuilder.php$3 or anonymous//src/Query/QueryBuilder.php$11 or anonymous//src/Query/QueryBuilder.php$7 or anonymous//src/Query/QueryBuilder.php$8 or anonymous//src/Query/QueryBuilder.php$6 or anonymous//src/Query/QueryBuilder.php$13 or anonymous//src/Query/QueryBuilder.php$12 or anonymous//src/Query/QueryBuilder.php$14. ( Ignorable by Annotation )

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

76
					$where[] = $operator.'('.$val2->/** @scrutinizer ignore-call */ sql().')';
Loading history...
77
					$this->bindValues = array_merge($this->bindValues, $val2->bindValues());
0 ignored issues
show
Bug introduced by
The method bindValues() does not exist on chillerlan\Database\Query\Statement. ( Ignorable by Annotation )

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

77
					$this->bindValues = array_merge($this->bindValues, $val2->/** @scrutinizer ignore-call */ bindValues());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
				}
79
80
			}
81
//			else if(in_array($operator, ['BETWEEN', 'NOT BETWEEN'], true)){
82
				// @todo
83
//			}
84
			else{
85
				$where[] = $operator;
86
87
				if($val2 instanceof Statement){
88
					$where[] = '('.$val2->sql().')';
89
					$this->bindValues = array_merge($this->bindValues, $val2->bindValues());
90
				}
91
				elseif(is_null($val2)){
92
					$where[] = 'NULL';
93
				}
94
				elseif(is_bool($val2)){
95
					$where[] = $val2 ? 'TRUE' : 'FALSE';
96
				}
97
				elseif(in_array(strtolower($val2), ['null', 'false', 'true', 'unknown'], true)){
98
					$where[] = strtoupper($val2);
99
				}
100
				else {
101
102
					if($bind){
103
						$where[] = '?';
104
						$this->bindValues[] = $val2;
105
					}
106
					else{
107
						if(!empty($val2)){
108
							$where[] = $val2;
109
						}
110
					}
111
112
				}
113
114
			}
115
116
			$this->where[] = [
117
				'join' => $join,
118
				'stmt' => implode(' ', $where),
119
			];
120
121
		}
122
123
		return $this;
124
	}
125
126
	/**
127
	 * @param string|null $join
128
	 *
129
	 * @return $this
130
	 */
131
	public function openBracket(string $join = null):Statement{
132
		$join = strtoupper(trim($join));
0 ignored issues
show
Bug introduced by
It seems like $join can also be of type null; however, parameter $string of trim() 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

132
		$join = strtoupper(trim(/** @scrutinizer ignore-type */ $join));
Loading history...
133
134
		if(in_array($join, $this->joinArgs, true)){
135
			$this->where[] = $join;
136
		}
137
138
		$this->where[] = '(';
139
140
		return $this;
141
	}
142
143
	/**
144
	 * @return $this
145
	 */
146
	public function closeBracket():Statement{
147
		$this->where[] = ')';
148
149
		return $this;
150
	}
151
152
	/**
153
	 * @return string
154
	 */
155
	protected function _getWhere():string{
156
		$where = [];
157
158
		foreach($this->where as $k => $v){
159
			$last = $this->where[$k-1] ?? false;
160
161
			if(in_array($v,  $this->joinArgs + ['(', ')'], true)){
162
				$where[] = $v;
163
164
				continue;
165
			}
166
167
			if(!is_array($v)){
168
				continue;
169
			}
170
171
			if(!$last || $last === '('){
172
				$where[] = $v['stmt'];
173
			}
174
			else{
175
				$where[] = $v['join'].' '.$v['stmt'];
176
			}
177
178
		}
179
180
		return !empty($where) ? 'WHERE '.implode(' ', $where) : '';
181
	}
182
183
}
184