@@ 423-487 (lines=65) @@ | ||
420 | * @type string $where SQL fragment to append to the main WHERE clause. |
|
421 | * } |
|
422 | */ |
|
423 | protected function get_sql_for_query( &$query, $depth = 0 ) { |
|
424 | $sql_chunks = array( |
|
425 | 'join' => array(), |
|
426 | 'where' => array(), |
|
427 | ); |
|
428 | ||
429 | $sql = array( |
|
430 | 'join' => '', |
|
431 | 'where' => '', |
|
432 | ); |
|
433 | ||
434 | $indent = ''; |
|
435 | for ( $i = 0; $i < $depth; $i++ ) { |
|
436 | $indent .= " "; |
|
437 | } |
|
438 | ||
439 | foreach ( $query as $key => &$clause ) { |
|
440 | if ( 'relation' === $key ) { |
|
441 | $relation = $query['relation']; |
|
442 | } elseif ( is_array( $clause ) ) { |
|
443 | ||
444 | // This is a first-order clause. |
|
445 | if ( $this->is_first_order_clause( $clause ) ) { |
|
446 | $clause_sql = $this->get_sql_for_clause( $clause, $query, $key ); |
|
447 | ||
448 | $where_count = count( $clause_sql['where'] ); |
|
449 | if ( ! $where_count ) { |
|
450 | $sql_chunks['where'][] = ''; |
|
451 | } elseif ( 1 === $where_count ) { |
|
452 | $sql_chunks['where'][] = $clause_sql['where'][0]; |
|
453 | } else { |
|
454 | $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; |
|
455 | } |
|
456 | ||
457 | $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); |
|
458 | // This is a subquery, so we recurse. |
|
459 | } else { |
|
460 | $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); |
|
461 | ||
462 | $sql_chunks['where'][] = $clause_sql['where']; |
|
463 | $sql_chunks['join'][] = $clause_sql['join']; |
|
464 | } |
|
465 | } |
|
466 | } |
|
467 | ||
468 | // Filter to remove empties. |
|
469 | $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); |
|
470 | $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); |
|
471 | ||
472 | if ( empty( $relation ) ) { |
|
473 | $relation = 'AND'; |
|
474 | } |
|
475 | ||
476 | // Filter duplicate JOIN clauses and combine into a single string. |
|
477 | if ( ! empty( $sql_chunks['join'] ) ) { |
|
478 | $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); |
|
479 | } |
|
480 | ||
481 | // Generate a single WHERE clause with proper brackets and indentation. |
|
482 | if ( ! empty( $sql_chunks['where'] ) ) { |
|
483 | $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; |
|
484 | } |
|
485 | ||
486 | return $sql; |
|
487 | } |
|
488 | ||
489 | /** |
|
490 | * Generate SQL JOIN and WHERE clauses for a first-order query clause. |
@@ 327-391 (lines=65) @@ | ||
324 | * @type string $where SQL fragment to append to the main WHERE clause. |
|
325 | * } |
|
326 | */ |
|
327 | protected function get_sql_for_query( &$query, $depth = 0 ) { |
|
328 | $sql_chunks = array( |
|
329 | 'join' => array(), |
|
330 | 'where' => array(), |
|
331 | ); |
|
332 | ||
333 | $sql = array( |
|
334 | 'join' => '', |
|
335 | 'where' => '', |
|
336 | ); |
|
337 | ||
338 | $indent = ''; |
|
339 | for ( $i = 0; $i < $depth; $i++ ) { |
|
340 | $indent .= " "; |
|
341 | } |
|
342 | ||
343 | foreach ( $query as $key => &$clause ) { |
|
344 | if ( 'relation' === $key ) { |
|
345 | $relation = $query['relation']; |
|
346 | } elseif ( is_array( $clause ) ) { |
|
347 | ||
348 | // This is a first-order clause. |
|
349 | if ( $this->is_first_order_clause( $clause ) ) { |
|
350 | $clause_sql = $this->get_sql_for_clause( $clause, $query ); |
|
351 | ||
352 | $where_count = count( $clause_sql['where'] ); |
|
353 | if ( ! $where_count ) { |
|
354 | $sql_chunks['where'][] = ''; |
|
355 | } elseif ( 1 === $where_count ) { |
|
356 | $sql_chunks['where'][] = $clause_sql['where'][0]; |
|
357 | } else { |
|
358 | $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; |
|
359 | } |
|
360 | ||
361 | $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); |
|
362 | // This is a subquery, so we recurse. |
|
363 | } else { |
|
364 | $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); |
|
365 | ||
366 | $sql_chunks['where'][] = $clause_sql['where']; |
|
367 | $sql_chunks['join'][] = $clause_sql['join']; |
|
368 | } |
|
369 | } |
|
370 | } |
|
371 | ||
372 | // Filter to remove empties. |
|
373 | $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); |
|
374 | $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); |
|
375 | ||
376 | if ( empty( $relation ) ) { |
|
377 | $relation = 'AND'; |
|
378 | } |
|
379 | ||
380 | // Filter duplicate JOIN clauses and combine into a single string. |
|
381 | if ( ! empty( $sql_chunks['join'] ) ) { |
|
382 | $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); |
|
383 | } |
|
384 | ||
385 | // Generate a single WHERE clause with proper brackets and indentation. |
|
386 | if ( ! empty( $sql_chunks['where'] ) ) { |
|
387 | $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; |
|
388 | } |
|
389 | ||
390 | return $sql; |
|
391 | } |
|
392 | ||
393 | /** |
|
394 | * Generate SQL JOIN and WHERE clauses for a "first-order" query clause. |
@@ 623-687 (lines=65) @@ | ||
620 | * @type string $where SQL fragment to append to the main WHERE clause. |
|
621 | * } |
|
622 | */ |
|
623 | protected function get_sql_for_query( $query, $depth = 0 ) { |
|
624 | $sql_chunks = array( |
|
625 | 'join' => array(), |
|
626 | 'where' => array(), |
|
627 | ); |
|
628 | ||
629 | $sql = array( |
|
630 | 'join' => '', |
|
631 | 'where' => '', |
|
632 | ); |
|
633 | ||
634 | $indent = ''; |
|
635 | for ( $i = 0; $i < $depth; $i++ ) { |
|
636 | $indent .= " "; |
|
637 | } |
|
638 | ||
639 | foreach ( $query as $key => $clause ) { |
|
640 | if ( 'relation' === $key ) { |
|
641 | $relation = $query['relation']; |
|
642 | } elseif ( is_array( $clause ) ) { |
|
643 | ||
644 | // This is a first-order clause. |
|
645 | if ( $this->is_first_order_clause( $clause ) ) { |
|
646 | $clause_sql = $this->get_sql_for_clause( $clause, $query ); |
|
647 | ||
648 | $where_count = count( $clause_sql['where'] ); |
|
649 | if ( ! $where_count ) { |
|
650 | $sql_chunks['where'][] = ''; |
|
651 | } elseif ( 1 === $where_count ) { |
|
652 | $sql_chunks['where'][] = $clause_sql['where'][0]; |
|
653 | } else { |
|
654 | $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; |
|
655 | } |
|
656 | ||
657 | $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); |
|
658 | // This is a subquery, so we recurse. |
|
659 | } else { |
|
660 | $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); |
|
661 | ||
662 | $sql_chunks['where'][] = $clause_sql['where']; |
|
663 | $sql_chunks['join'][] = $clause_sql['join']; |
|
664 | } |
|
665 | } |
|
666 | } |
|
667 | ||
668 | // Filter to remove empties. |
|
669 | $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); |
|
670 | $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); |
|
671 | ||
672 | if ( empty( $relation ) ) { |
|
673 | $relation = 'AND'; |
|
674 | } |
|
675 | ||
676 | // Filter duplicate JOIN clauses and combine into a single string. |
|
677 | if ( ! empty( $sql_chunks['join'] ) ) { |
|
678 | $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); |
|
679 | } |
|
680 | ||
681 | // Generate a single WHERE clause with proper brackets and indentation. |
|
682 | if ( ! empty( $sql_chunks['where'] ) ) { |
|
683 | $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; |
|
684 | } |
|
685 | ||
686 | return $sql; |
|
687 | } |
|
688 | ||
689 | /** |
|
690 | * Turns a single date clause into pieces for a WHERE clause. |