PluginProbe ʕ •ᴥ•ʔ
Admin Columns / 3.0.5
Admin Columns v3.0.5
7.1.4 7.0.19 2.3.5 2.4 2.4.1 2.4.10 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.6.1 2.5.6.2 2.5.6.3 2.5.6.4 3.0 3.0.1 3.0.2 3.0.3 3.0.5 3.0.7 3.1 3.1.1 3.1.10 3.1.2 3.1.3 3.1.5 3.2.3 3.2.7 3.3.1 3.4.1 3.4.6 3.4.8 4.0.1 4.0.3 4.1.6 4.2.2 4.2.5 4.3 4.3.2 4.4.1 4.4.4 4.4.5 4.5.5 4.6.1 4.7.18 4.7.19 4.7.20 4.7.7 7.0.13 7.0.14 7.0.16 trunk 1.0 1.1 1.1.3 1.2 1.2.1 1.3 1.3.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.5.1 1.4.6 1.4.6.1 1.4.6.2 1.4.6.3 1.4.6.4 1.4.7 1.4.8 1.4.9 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.1.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.5.1 2.2.6 2.2.6.1 2.2.6.2 2.2.6.3 2.2.6.4 2.2.7 2.2.8 2.2.8.1 2.2.9 2.3.1 2.3.2 2.3.3
codepress-admin-columns / classes / Meta / Query.php
codepress-admin-columns / classes / Meta Last commit date
Query.php 8 years ago QueryColumn.php 8 years ago
Query.php
471 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 class AC_Meta_Query {
8
9 /**
10 * @var WP_Meta_Query
11 */
12 private $query;
13
14 /**
15 * @var string
16 */
17 private $sql;
18
19 /**
20 * @var array
21 */
22 private $select = array();
23
24 /**
25 * @var string|false
26 */
27 private $count = false;
28
29 /**
30 * @var bool
31 */
32 private $distinct = false;
33
34 /**
35 * @var bool
36 */
37 private $join = false;
38
39 /**
40 * @var array
41 */
42 private $join_where = array();
43
44 /**
45 * @var array
46 */
47 private $where = array();
48
49 /**
50 * @var array
51 */
52 private $group_by = array();
53
54 /**
55 * @var array
56 */
57 private $order_by = array();
58
59 /**
60 * @param string $meta_type
61 */
62 public function __construct( $meta_type ) {
63 $this->set_query( $meta_type );
64 }
65
66 /**
67 * Add a single field or multiple comma separated
68 *
69 * @param string $field e.g. id or id, meta_value
70 *
71 * @return $this
72 */
73 public function select( $field ) {
74 $fields = explode( ',', $field );
75
76 foreach ( $fields as $field ) {
77 $this->select[] = trim( $field );
78 }
79
80 return $this;
81 }
82
83 /**
84 * Add a COUNT clause AS count
85 *
86 * @param string $field
87 *
88 * @return $this
89 */
90 public function count( $field ) {
91 $this->count = $field;
92
93 return $this;
94 }
95
96 /**
97 * Group by an aggregated column.
98 *
99 * Supports: count
100 *
101 * @param string $field
102 *
103 * @return $this
104 */
105 public function group_by( $field ) {
106 $this->group_by = $field;
107
108 return $this;
109 }
110
111 public function join( $type = 'inner' ) {
112 $this->join = strtoupper( $type );
113
114 return $this;
115 }
116
117 public function left_join() {
118 return $this->join( 'left' );
119 }
120
121 /**
122 * @see get_where_clause()
123 *
124 * @return $this
125 */
126 public function join_where( $field, $operator = null, $value = null, $boolean = 'AND' ) {
127 // set default join
128 if ( ! $this->join ) {
129 $this->join();
130 }
131
132 $this->join_where[] = $this->get_where_clause( $field, $operator, $value, $boolean );
133
134 return $this;
135 }
136
137 public function order_by( $order_by, $order = 'asc' ) {
138 $parts = explode( ',', $order_by );
139
140 foreach ( $parts as $order_by ) {
141 $this->order_by[] = array(
142 'order_by' => trim( $order_by ),
143 'order' => strtoupper( $order ),
144 );
145 }
146
147 return $this;
148 }
149
150 public function distinct() {
151 $this->distinct = true;
152
153 return $this;
154 }
155
156 /**
157 * Set a where clause
158 *
159 * @param string|array $field
160 * @param string $operator
161 * @param string|int|array $value
162 * @param string $type
163 *
164 * @return array
165 */
166 private function get_where_clause( $field, $operator = null, $value = null, $boolean = 'AND' ) {
167 // allows to omit operator
168 if ( null === $value ) {
169 $value = $operator;
170 $operator = '=';
171 }
172
173 $where = array(
174 'nested' => false,
175 'boolean' => strtoupper( $boolean ),
176 'field' => $field,
177 'operator' => strtoupper( $operator ),
178 'value' => $value,
179 );
180
181 // set default join
182 if ( $field === 'post_type' && ! $this->join ) {
183 $this->join();
184 }
185
186 $nested = array();
187
188 if ( is_array( $field ) ) {
189 for ( $i = 0; $i < count( $field ); $i++ ) {
190 $nested[] = array_pop( $this->where );
191 }
192 }
193
194 if ( $nested ) {
195 $where['nested'] = true;
196 $where['field'] = array_reverse( $nested );
197 }
198
199 return $where;
200 }
201
202 /**
203 * @see get_where_clause()
204 *
205 * @return $this
206 */
207 public function remove_where( $field, $operator = null, $value = null, $boolean = 'AND' ) {
208 $where = $this->get_where_clause( $field, $operator, $value, $boolean );
209
210 foreach ( $this->where as $k => $v ) {
211 if ( $v == $where ) {
212 unset( $this->where[ $k ] );
213 }
214 }
215
216 return $this;
217 }
218
219 /**
220 * @see get_where_clause()
221 *
222 * @return $this
223 */
224 public function where( $field, $operator = null, $value = null, $boolean = 'AND' ) {
225 $this->where[] = $this->get_where_clause( $field, $operator, $value, $boolean );
226
227 return $this;
228 }
229
230 /**
231 * @see get_where_clause()
232 *
233 * @return $this
234 */
235 public function or_where( $field, $operator = null, $value = null ) {
236 return $this->where( $field, $operator, $value, 'OR' );
237 }
238
239 /**
240 * @param array $in
241 *
242 * @return $this
243 */
244 public function where_in( array $in ) {
245 return $this->where( 'id', 'in', $in );
246 }
247
248 public function where_is_null( $field ) {
249 return $this->where( $field, '', 'IS NULL' );
250 }
251
252 public function where_post_type( $post_type ) {
253 return $this->where( 'post_type', '=', $post_type );
254 }
255
256 private function parse_field( $field ) {
257 switch ( $field ) {
258 case 'id':
259 $field = $this->join ? 'pt.' . $this->query->primary_id_column : 'mt' . $this->query->meta_id_column;
260
261 break;
262 case 'meta_key':
263 case 'meta_value':
264 $field = 'mt.' . $field;
265
266 break;
267 case 'taxonomy':
268 case 'post_type':
269 $field = 'pt.' . $field;
270
271 break;
272 }
273
274 return $field;
275 }
276
277 private function parse_where( $where, $clauses ) {
278 global $wpdb;
279
280 foreach ( $clauses as $clause ) {
281
282 if ( $clause['nested'] ) {
283 $clause['field'][0]['boolean'] = null;
284
285 $where .= sprintf( ' %s ( %s ) ', $clause['boolean'], $this->parse_where( '', $clause['field'] ) );
286 } else {
287 switch ( $clause['operator'] ) {
288 case 'IN':
289 $clause['value'] = sprintf( ' ( %s ) ', implode( ', ', array_map( 'intval', $clause['value'] ) ) );
290
291 break;
292 default:
293 $valid_raw = array( 'IS NULL', 'IS NOT NULL' );
294
295 if ( ! in_array( $clause['value'], $valid_raw ) ) {
296 $clause['value'] = $wpdb->prepare( '%s', $clause['value'] );
297 }
298 }
299
300 $clause['field'] = $this->parse_field( $clause['field'] );
301
302 $where .= implode( ' ', $clause );
303 }
304
305 }
306
307 return $where;
308 }
309
310 /**
311 * @return array
312 */
313 public function get() {
314 global $wpdb;
315
316 if ( ! $this->query ) {
317 return array();
318 }
319
320 // parse SELECT
321 $select = 'SELECT ';
322 $select .= $this->distinct ? 'DISTINCT ' : '';
323
324 if ( empty( $this->select ) ) {
325 $this->select( 'id' );
326 }
327
328 $fields = array();
329
330 foreach ( $this->select as $field ) {
331 $parsed = $this->parse_field( $field );
332
333 // output 'id' in the results
334 if ( 'id' === $field ) {
335 $parsed .= ' AS id';
336 }
337
338 $fields[] = $parsed;
339 }
340
341 if ( $this->count ) {
342 $fields[] = sprintf( 'COUNT(%s) AS count', $this->parse_field( $this->count ) );
343 }
344
345 $select .= implode( ', ', $fields );
346
347 // parse FROM
348 $from_tpl = ' FROM %s AS %s';
349
350 $from = sprintf( $from_tpl, $this->query->meta_table, 'mt' );
351 $join = '';
352
353 if ( $this->join ) {
354 $from = sprintf( $from_tpl, $this->query->primary_table, 'pt' );
355 $join = sprintf( ' %s JOIN %s AS mt ON mt.%s = pt.%s %s',
356 $this->join,
357 $this->query->meta_table,
358 $this->query->meta_id_column,
359 $this->query->primary_id_column,
360 $this->parse_where( '', $this->join_where )
361 );
362 }
363
364 // parse WHERE
365 $where = $this->parse_where( ' WHERE 1=1', $this->where );
366
367 // parse GROUP BY
368 $group_by = '';
369
370 if ( $this->group_by ) {
371 $group_by = ' GROUP BY ' . $this->parse_field( $this->group_by );
372 }
373
374 // parse ORDER BY
375 $order_by = '';
376
377 if ( ! empty( $this->order_by ) ) {
378 $order_by_clauses = array();
379
380 foreach ( $this->order_by as $order_by_clause ) {
381 $order_by_clauses[] = $this->parse_field( $order_by_clause['order_by'] ) . ' ' . $order_by_clause['order'];
382 }
383
384 $order_by = ' ORDER BY ' . implode( ', ', $order_by_clauses );
385 }
386
387 // build query and store it
388 $sql = $select . $from . $join . $where . $group_by . $order_by;
389
390 $this->set_sql( $sql );
391
392 $results = $wpdb->get_results( $sql );
393
394 if ( ! is_array( $results ) ) {
395 return array();
396 }
397
398 $return = $results;
399
400 if ( count( $fields ) === 1 ) {
401 $return = array();
402 $field = $this->select[0];
403
404 foreach ( $results as $result ) {
405 $return[] = $result->$field;
406 }
407 }
408
409 return $return;
410 }
411
412 /**
413 * Return last sql that was queried
414 *
415 * @return string
416 */
417 public function get_sql() {
418 $sql = preg_replace( '/ +/', ' ', $this->sql );
419 $sql = preg_replace( '/(SELECT|FROM|LEFT|INNER|WHERE|(AND|OR) \(|(AND|OR) (?!\()|ORDER BY|GROUP BY)/', "\n$1", $sql );
420
421 return $sql . "\n";
422 }
423
424 private function set_sql( $sql ) {
425 $this->sql = $sql;
426 }
427
428 /**
429 * @return WP_Meta_Query
430 */
431 public function get_query() {
432 return $this->query;
433 }
434
435 private function set_query( $type ) {
436 global $wpdb;
437
438 switch ( $type ) {
439 case 'user':
440 $table = $wpdb->users;
441 $id = 'ID';
442
443 break;
444 case 'comment':
445 $table = $wpdb->comments;
446 $id = 'comment_ID';
447
448 break;
449 case 'post':
450 $table = $wpdb->posts;
451 $id = 'ID';
452
453 break;
454 case 'term':
455 $table = $wpdb->terms;
456 $id = 'term_id';
457
458 break;
459
460 default:
461 return false;
462 }
463
464 $this->query = new WP_Meta_Query();
465 $this->query->get_sql( $type, $table, $id );
466
467 return true;
468 }
469
470 }
471