WhereAndHavingBuilder::inArray()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 13
c 5
b 0
f 0
dl 0
loc 18
rs 9.8333
cc 2
nc 2
nop 0
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
/**
18
 * Trait WhereAndHavingBuilder
19
 * @package Qpdb\QueryBuilder\Traits
20
 * @property QueryStructure $queryStructure
21
 */
22
trait WhereAndHavingBuilder
23
{
24
25
	/**
26
	 * @var string|array
27
	 */
28
	private $temporaryParam;
29
30
	/**
31
	 * @var string
32
	 */
33
	private $temporaryGlue;
34
35
	/**
36
	 * @var string;
37
	 */
38
	private $temporaryClauseType;
39
40
41
	/**
42
	 * @param $param
43
	 * @param string $glue
44
	 * @param $clauseType
45
	 * @return $this
46
	 * @throws QueryException
47
	 */
48
	protected function createCondition( $param, $glue, $clauseType )
49
	{
50
51
		if ( !is_array( $param ) ) {
52
			$this->queryStructure->setElement( $clauseType, array( 'glue' => $glue, 'body' => trim( $param ), 'type' => 'cond' ) );
53
54
			return $this;
55
		}
56
57
		$this->temporaryParam = $this->validateWhereParam( $param );
58
		$this->temporaryGlue = $glue;
59
		$this->temporaryClauseType = $clauseType;
60
61
		$this->buildCondition();
62
63
		return $this;
64
	}
65
66
	private function buildCondition()
67
	{
68
		$operator = $this->temporaryParam[ 2 ];
69
70
		switch ( $operator ) {
71
			case 'BETWEEN':
72
			case 'NOT BETWEEN':
73
			case '!BETWEEN':
74
				$this->makeBetweenCondition();
75
				break;
76
			case 'IN':
77
			case 'NOT IN':
78
			case '!IN':
79
				$this->makeInCondition();
80
				break;
81
			default:
82
				$valuePdoString = $this->queryStructure->bindParam( $this->temporaryParam[ 0 ], $this->temporaryParam[ 1 ] );
83
				$body = $this->temporaryParam[ 0 ] . ' ' . $operator . ' ' . $valuePdoString;
84
				$this->registerCondition( $body );
85
				break;
86
		}
87
	}
88
89
	private function makeBetweenCondition()
90
	{
91
		$field = $this->temporaryParam[ 0 ];
92
		$value = $this->temporaryParam[ 1 ];
93
		$operator = $this->temporaryParam[ 2 ];
94
95
		$min = $value[ 0 ];
96
		$max = $value[ 1 ];
97
		$body = [
98
			$field,
99
			$operator,
100
			$this->queryStructure->bindParam( 'min', $min ),
101
			'AND',
102
			$this->queryStructure->bindParam( 'max', $max )
103
		];
104
		$body = implode( ' ', $body );
105
		$this->registerCondition( $body );
106
	}
107
108
	private function makeInCondition()
109
	{
110
		if ( is_a( $this->temporaryParam[ 1 ], QuerySelect::class ) )
111
			$this->inQuerySelect();
112
		elseif ( is_array( $this->temporaryParam[ 1 ] ) )
113
			$this->inArray();
114
	}
115
116
	private function inQuerySelect()
117
	{
118
		$field = $this->temporaryParam[ 0 ];
119
		/** @var QuerySelect $subquerySelect */
120
		$subquerySelect = $this->temporaryParam[ 1 ];
121
		$operator = $this->temporaryParam[ 2 ];
122
		$subquerySelectParams = $subquerySelect->getBindParams();
123
		foreach ( $subquerySelectParams as $key => $value ) {
124
			$this->queryStructure->setParams( $key, $value );
125
		}
126
		$body = [
127
			$field,
128
			$operator,
129
			'( ',
130
			$subquerySelect->getSyntax(),
131
			' )'
132
		];
133
		$body = implode( ' ', $body );
134
		$this->registerCondition( $body );
135
136
	}
137
138
	private function inArray()
139
	{
140
		$field = $this->temporaryParam[ 0 ];
141
		$value = $this->temporaryParam[ 1 ];
142
		$operator = $this->temporaryParam[ 2 ];
143
144
		$pdoArray = array();
145
		foreach ( $value as $item ) {
146
			$pdoArray[] = $this->queryStructure->bindParam( 'a', $item );
147
		}
148
		$body = [
149
			$field,
150
			$operator,
151
			'( ' . implode( ', ', $pdoArray ) . ' )'
152
		];
153
		$body = implode( ' ', $body );
154
		$body = QueryHelper::clearMultipleSpaces( $body );
155
		$this->registerCondition( $body );
156
	}
157
158
	/**
159
	 * @param string|array $body
160
	 * @throws QueryException
161
	 */
162
	private function registerCondition( $body )
163
	{
164
		$this->queryStructure->setElement( $this->temporaryClauseType, array( 'glue' => $this->temporaryGlue, 'body' => $body, 'type' => 'cond' ) );
165
	}
166
167
168
	/**
169
	 * @return bool|mixed|string
170
	 */
171
	private function getWhereSyntax()
172
	{
173
		return $this->getWhereAndHavingSyntax( QueryStructure::WHERE );
174
	}
175
176
	/**
177
	 * @return bool|mixed|string
178
	 */
179
	private function getHavingSyntax()
180
	{
181
		return $this->getWhereAndHavingSyntax( QueryStructure::HAVING );
182
	}
183
184
	/**
185
	 * @param $clauseType
186
	 * @return bool|mixed|string
187
	 */
188
	private function getWhereAndHavingSyntax( $clauseType )
189
	{
190
		if ( count( $this->queryStructure->getElement( $clauseType ) ) == 0 )
191
			return '';
192
193
		$where = '';
194
		$last_type = 'where_start';
195
		foreach ( $this->queryStructure->getElement( $clauseType ) as $where_cond ) {
196
			$glue = $where_cond[ 'glue' ];
197
			if ( $last_type == 'where_start' || $last_type == 'start_where_group' ) {
198
				$glue = '';
199
			}
200
			$where .= ' ' . $glue . ' ' . $where_cond[ 'body' ];
201
			$last_type = $where_cond[ 'type' ];
202
		}
203
204
		if ( $this->queryStructure->getElement( $clauseType . '_invert' ) ) {
205
			$where = ' NOT ( ' . $where . ' ) ';
206
		}
207
208
		$where = strtoupper( $clauseType ) . ' ' . $where;
209
210
		return QueryHelper::clearMultipleSpaces( $where );
211
	}
212
213
	/**
214
	 * @param $param
215
	 * @return array
216
	 * @throws QueryException
217
	 */
218
	private function validateWhereParam( $param )
219
	{
220
		if ( count( $param ) < 2 )
221
			throw new QueryException( 'Invalid where array!', QueryException::QUERY_ERROR_WHERE_INVALID_PARAM_ARRAY );
222
223
		if ( count( $param ) == 2 )
224
			$param[] = '=';
225
226
		$param[ 0 ] = $this->queryStructure->prepare( $param[ 0 ] );
227
		$param[ 2 ] = trim( strtoupper( $param[ 2 ] ) );
228
		$param[ 2 ] = QueryHelper::clearMultipleSpaces( $param[ 2 ] );
229
230
		return $param;
231
	}
232
233
}