Passed
Push — master ( 7ff405...d0230e )
by Adrian
01:39
created

WhereAndHavingBuilder::createCondition()   C

Complexity

Conditions 10
Paths 14

Size

Total Lines 49
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 49
rs 5.5471
c 0
b 0
f 0
cc 10
eloc 35
nc 14
nop 3

How to fix   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
 * Created by PhpStorm.
4
 * User: Adrian Dumitru
5
 * Date: 9/29/2017
6
 * Time: 4:20 PM
7
 */
8
9
namespace Qpdb\QueryBuilder\Traits;
10
11
12
use Qpdb\QueryBuilder\Dependencies\QueryException;
13
use Qpdb\QueryBuilder\Dependencies\QueryHelper;
14
use Qpdb\QueryBuilder\Dependencies\QueryStructure;
15
use Qpdb\QueryBuilder\Statements\QuerySelect;
16
17
trait WhereAndHavingBuilder
18
{
19
20
	use Objects;
21
22
23
	/**
24
	 * @param $param
25
	 * @param string $glue
26
	 * @param $clauseType
27
	 * @return $this
28
	 */
29
	protected function createCondition( $param, $glue = 'AND', $clauseType )
30
	{
31
32
		if ( !is_array( $param ) ) {
33
			$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => trim( $param ), 'type' => 'cond' ) );
34
35
			return $this;
36
		}
37
38
		$param = $this->validateWhereParam( $param );
39
40
		$field = $param[ 0 ];
41
		$value = $param[ 1 ];
42
		$operator = $param[ 2 ];
43
44
		switch ( $operator ) {
45
			case 'BETWEEN':
46
			case 'NOT BETWEEN':
47
			case '!BETWEEN':
48
				$min = $value[ 0 ];
49
				$max = $value[ 1 ];
50
				$body = [
51
					$field,
52
					$operator,
53
					$this->queryStructure->bindParam( 'min', $min ),
54
					'AND',
55
					$this->queryStructure->bindParam( 'max', $max )
56
				];
57
				$body = implode( ' ', $body );
58
				$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => $body, 'type' => 'cond' ) );
59
				break;
60
61
			case 'IN':
62
			case 'NOT IN':
63
			case '!IN':
64
				if ( is_a( $value, QuerySelect::class ) )
65
					return $this->inSelectObject( $field, $value, $operator, $glue, $clauseType );
66
				elseif ( is_array( $value ) )
67
					return $this->inArray( $field, $value, $operator, $glue, $clauseType );
68
				break;
69
70
			default:
71
				$valuePdoString = $this->queryStructure->bindParam( $field, $value );
72
				$body = $field . ' ' . $operator . ' ' . $valuePdoString;
73
				$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => $body, 'type' => 'cond' ) );
74
75
		}
76
77
		return $this;
78
79
	}
80
81
82
	/**
83
	 * @param $field
84
	 * @param QuerySelect $subquerySelect
85
	 * @param $operator
86
	 * @param string $glue
87
	 * @param $clauseType
88
	 * @return $this
89
	 */
90
	private function inSelectObject( $field, QuerySelect $subquerySelect, $operator, $glue = 'AND', $clauseType )
91
	{
92
		$subquerySelectParams = $subquerySelect->getBindParams();
93
		foreach ( $subquerySelectParams as $key => $value ) {
94
			$this->queryStructure->setParams( $key, $value );
95
		}
96
		$body = [
97
			$field,
98
			$operator,
99
			'( ',
100
			$subquerySelect->getSyntax(),
101
			' )'
102
		];
103
		$body = implode( ' ', $body );
104
		$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => $body, 'type' => 'cond' ) );
105
106
		return $this;
107
	}
108
109
	/**
110
	 * @param $field
111
	 * @param array $value
112
	 * @param $operator
113
	 * @param $glue
114
	 * @param $clauseType
115
	 * @return $this
116
	 */
117
	private function inArray( $field, array $value, $operator, $glue, $clauseType )
118
	{
119
		$pdoArray = array();
120
		foreach ( $value as $item ) {
121
			$pdoArray[] = $this->queryStructure->bindParam( 'a', $item );
122
		}
123
		$body = [
124
			$field,
125
			$operator,
126
			'( ' . implode( ', ', $pdoArray ) . ' )'
127
		];
128
		$body = implode( ' ', $body );
129
		$body = QueryHelper::clearMultipleSpaces( $body );
130
		$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => $body, 'type' => 'cond' ) );
131
132
		return $this;
133
	}
134
135
136
	/**
137
	 * @return bool|mixed|string
138
	 */
139
	private function getWhereSyntax()
140
	{
141
		return $this->getWhereAndHavingSyntax( QueryStructure::WHERE );
142
	}
143
144
	/**
145
	 * @return bool|mixed|string
146
	 */
147
	private function getHavingSyntax()
148
	{
149
		return $this->getWhereAndHavingSyntax( QueryStructure::HAVING );
150
	}
151
152
	/**
153
	 * @param $clauseType
154
	 * @return bool|mixed|string
155
	 */
156
	private function getWhereAndHavingSyntax( $clauseType )
157
	{
158
		if ( count( $this->queryStructure->getElement( $clauseType ) ) == 0 )
159
			return '';
160
161
		$where = '';
162
		$last_type = 'where_start';
163
		foreach ( $this->queryStructure->getElement( $clauseType ) as $where_cond ) {
164
			$glue = $where_cond[ 'glue' ];
165
			if ( $last_type == 'where_start' || $last_type == 'start_where_group' ) {
166
				$glue = '';
167
			}
168
			$where .= ' ' . $glue . ' ' . $where_cond[ 'body' ];
169
			$last_type = $where_cond[ 'type' ];
170
		}
171
172
		if ( $this->queryStructure->getElement( $clauseType . '_invert' ) ) {
173
			$where = ' NOT ( ' . $where . ' ) ';
174
		}
175
176
		$where = 'WHERE ' . $where;
177
178
		return QueryHelper::clearMultipleSpaces( $where );
179
	}
180
181
	/**
182
	 * @param $param
183
	 * @return array
184
	 * @throws QueryException
185
	 */
186
	private function validateWhereParam( $param )
187
	{
188
		if ( count( $param ) < 2 )
189
			throw new QueryException( 'Invalid where array!', QueryException::QUERY_ERROR_WHERE_INVALID_PARAM_ARRAY );
190
191
		if ( count( $param ) == 2 )
192
			$param[] = '=';
193
194
		$param[ 2 ] = trim( strtoupper( $param[ 2 ] ) );
195
		$param[ 2 ] = QueryHelper::clearMultipleSpaces( $param[ 2 ] );
196
197
		return $param;
198
	}
199
200
}