| @@ 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. |
|