Changeset 46188 for trunk/src/wp-includes/class-wp-meta-query.php
- Timestamp:
- 09/19/2019 03:02:20 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-meta-query.php
r45603 r46188 101 101 * @since 4.2.0 Introduced support for naming query clauses by associative array keys. 102 102 * @since 5.1.0 Introduced $compare_key clause parameter, which enables LIKE key matches. 103 * @since 5.3.0 Increased the number of operators available to $compare_key. Introduced $type_key, 104 * which enables the $key to be cast to a new data type for comparisons. 103 105 * 104 106 * @param array $meta_query { … … 112 114 * 113 115 * @type string $key Meta key to filter by. 114 * @type string $compare_key MySQL operator used for comparing the $key. Accepts '=' and 'LIKE'. 115 * Default '='. 116 * @type string $compare_key MySQL operator used for comparing the $key. Accepts '=', '!=' 117 * 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'REGEXP', 'NOT REGEXP', 'RLIKE', 118 * 'EXISTS' (alias of '=') or 'NOT EXISTS' (alias of '!='). 119 * Default is 'IN' when `$key` is an array, '=' otherwise. 120 * @type string $type_key MySQL data type that the meta_key column will be CAST to for 121 * comparisons. Accepts 'BINARY' for case-sensitive regular expression 122 * comparisons. Default is ''. 116 123 * @type string $value Meta value to filter by. 117 124 * @type string $compare MySQL operator used for comparing the $value. Accepts '=', … … 240 247 */ 241 248 $primary_meta_query = array(); 242 foreach ( array( 'key', 'compare', 'type', 'compare_key' ) as $key ) {249 foreach ( array( 'key', 'compare', 'type', 'compare_key', 'type_key' ) as $key ) { 243 250 if ( ! empty( $qv[ "meta_$key" ] ) ) { 244 251 $primary_meta_query[ $key ] = $qv[ "meta_$key" ]; … … 499 506 } 500 507 501 if ( ! in_array( 502 $clause['compare'], 503 array( 504 '=', 505 '!=', 506 '>', 507 '>=', 508 '<', 509 '<=', 510 'LIKE', 511 'NOT LIKE', 512 'IN', 513 'NOT IN', 514 'BETWEEN', 515 'NOT BETWEEN', 516 'EXISTS', 517 'NOT EXISTS', 518 'REGEXP', 519 'NOT REGEXP', 520 'RLIKE', 521 ) 522 ) ) { 508 $non_numeric_operators = array( 509 '=', 510 '!=', 511 'LIKE', 512 'NOT LIKE', 513 'IN', 514 'NOT IN', 515 'EXISTS', 516 'NOT EXISTS', 517 'RLIKE', 518 'REGEXP', 519 'NOT REGEXP', 520 ); 521 522 $numeric_operators = array( 523 '>', 524 '>=', 525 '<', 526 '<=', 527 'BETWEEN', 528 'NOT BETWEEN', 529 ); 530 531 if ( ! in_array( $clause['compare'], $non_numeric_operators, true ) && ! in_array( $clause['compare'], $numeric_operators, true ) ) { 523 532 $clause['compare'] = '='; 524 533 } 525 534 526 if ( isset( $clause['compare_key'] ) && 'LIKE' === strtoupper( $clause['compare_key'] )) {535 if ( isset( $clause['compare_key'] ) ) { 527 536 $clause['compare_key'] = strtoupper( $clause['compare_key'] ); 528 537 } else { 538 $clause['compare_key'] = isset( $clause['key'] ) && is_array( $clause['key'] ) ? 'IN' : '='; 539 } 540 541 if ( ! in_array( $clause['compare_key'], $non_numeric_operators, true ) ) { 529 542 $clause['compare_key'] = '='; 530 543 } … … 595 608 $sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL'; 596 609 } else { 597 if ( 'LIKE' === $meta_compare_key ) { 598 $sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key LIKE %s", '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%' ); 599 } else { 600 $sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) ); 610 /** 611 * In joined clauses negative operators have to be nested into a 612 * NOT EXISTS clause and flipped, to avoid returning records with 613 * matching post IDs but different meta keys. Here we prepare the 614 * nested clause. 615 */ 616 if ( in_array( $meta_compare_key, array( '!=', 'NOT IN', 'NOT LIKE', 'NOT EXISTS', 'NOT REGEXP' ), true ) ) { 617 // Negative clauses may be reused. 618 $i = count( $this->table_aliases ); 619 $subquery_alias = $i ? 'mt' . $i : $this->meta_table; 620 $this->table_aliases[] = $subquery_alias; 621 622 $meta_compare_string_start = 'NOT EXISTS ('; 623 $meta_compare_string_start .= "SELECT 1 FROM $wpdb->postmeta $subquery_alias "; 624 $meta_compare_string_start .= "WHERE $subquery_alias.post_ID = $alias.post_ID "; 625 $meta_compare_string_end = 'LIMIT 1'; 626 $meta_compare_string_end .= ')'; 601 627 } 628 629 switch ( $meta_compare_key ) { 630 case '=': 631 case 'EXISTS': 632 $where = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 633 break; 634 case 'LIKE': 635 $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%'; 636 $where = $wpdb->prepare( "$alias.meta_key LIKE %s", $meta_compare_value ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 637 break; 638 case 'IN': 639 $meta_compare_string = "$alias.meta_key IN (" . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ')'; 640 $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 641 break; 642 case 'RLIKE': 643 case 'REGEXP': 644 $operator = $meta_compare_key; 645 if ( isset( $clause['type_key'] ) && 'BINARY' === strtoupper( $clause['type_key'] ) ) { 646 $cast = 'BINARY'; 647 } else { 648 $cast = ''; 649 } 650 $where = $wpdb->prepare( "$alias.meta_key $operator $cast %s", trim( $clause['key'] ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 651 break; 652 653 case '!=': 654 case 'NOT EXISTS': 655 $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key = %s " . $meta_compare_string_end; 656 $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 657 break; 658 case 'NOT LIKE': 659 $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key LIKE %s " . $meta_compare_string_end; 660 661 $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%'; 662 $where = $wpdb->prepare( $meta_compare_string, $meta_compare_value ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 663 break; 664 case 'NOT IN': 665 $array_subclause = '(' . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ') '; 666 $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key IN " . $array_subclause . $meta_compare_string_end; 667 $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 668 break; 669 case 'NOT REGEXP': 670 $operator = $meta_compare_key; 671 if ( isset( $clause['type_key'] ) && 'BINARY' === strtoupper( $clause['type_key'] ) ) { 672 $cast = 'BINARY'; 673 } else { 674 $cast = ''; 675 } 676 677 $meta_compare_string = $meta_compare_string_start . "AND $subquery_alias.meta_key REGEXP $cast %s " . $meta_compare_string_end; 678 $where = $wpdb->prepare( $meta_compare_string, $clause['key'] ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 679 break; 680 } 681 682 $sql_chunks['where'][] = $where; 602 683 } 603 684 }
Note: See TracChangeset
for help on using the changeset viewer.