WordPress.org

Make WordPress Core

Ticket #43446: 43446.1.diff

File 43446.1.diff, 4.3 KB (added by soulseekah, 17 months ago)

!=, NOT LIKE, IN, NOT IN

  • src/wp-includes/class-wp-meta-query.php

    diff --git src/wp-includes/class-wp-meta-query.php src/wp-includes/class-wp-meta-query.php
    index d9234c2..abe98f4 100644
    class WP_Meta_Query { 
    521521                        $clause['compare'] = '=';
    522522                }
    523523
    524                 if ( isset( $clause['compare_key'] ) && 'LIKE' === strtoupper( $clause['compare_key'] ) ) {
     524                if ( isset( $clause['compare_key'] ) ) {
    525525                        $clause['compare_key'] = strtoupper( $clause['compare_key'] );
    526526                } else {
     527                        $clause['compare_key'] = isset( $clause['key'] ) && is_array( $clause['key'] ) ? 'IN' : '=';
     528                }
     529
     530                if ( ! in_array(
     531                        $clause['compare_key'], array(
     532                                '=',
     533                                '!=',
     534                                'LIKE',
     535                                'NOT LIKE',
     536                                'IN',
     537                                'NOT IN',
     538                                // @todo
     539                                // 'EXISTS',
     540                                // 'NOT EXISTS',
     541                                // 'REGEXP',
     542                                // 'NOT REGEXP',
     543                                // 'RLIKE',
     544                        )
     545                ) ) {
    527546                        $clause['compare_key'] = '=';
    528547                }
    529548
    class WP_Meta_Query { 
    592611                        if ( 'NOT EXISTS' === $meta_compare ) {
    593612                                $sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL';
    594613                        } else {
    595                                 if ( 'LIKE' === $meta_compare_key ) {
    596                                         $sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key LIKE %s", '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%' );
    597                                 } else {
    598                                         $sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) );
     614                                switch ( $meta_compare_key ) {
     615                                        case '=':
     616                                                $where = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) );
     617                                                break;
     618                                        case 'LIKE':
     619                                                $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%';
     620                                                $where = $wpdb->prepare( "$alias.meta_key LIKE %s", $meta_compare_value );
     621                                                break;
     622                                        case 'IN':
     623                                                $operator = $meta_compare_key;
     624                                                $meta_compare_string = "$alias.meta_key $operator (" . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ')';
     625                                                $where = $wpdb->prepare( $meta_compare_string, $clause['key'] );
     626                                                break;
     627
     628                                        /**
     629                                         * In joined clauses negative operators have to be nested
     630                                         * into a NOT EXISTS clause and flipped. Otherwise, non-matching results
     631                                         * containing the post_IDs will be returned, rendering the
     632                                         * operator ineffective.
     633                                         */
     634                                        case '!=':
     635                                                $i     = count( $this->table_aliases );
     636                                                $subquery_alias = $i ? 'mt' . $i : $this->meta_table;
     637                                                $this->table_aliases[] = $subquery_alias;
     638
     639                                                $meta_compare_string = "NOT EXISTS (";
     640                                                $meta_compare_string      .= "SELECT 1 FROM $wpdb->postmeta $subquery_alias ";
     641                                                $meta_compare_string      .= "WHERE $subquery_alias.post_ID = $alias.post_ID ";
     642                                                $meta_compare_string      .= "AND $subquery_alias.meta_key = %s ";
     643                                                $meta_compare_string      .= 'LIMIT 1';
     644                                                $meta_compare_string .= ")";
     645
     646                                                $where = $wpdb->prepare( $meta_compare_string, $clause['key'] );
     647                                                break;
     648                                        case 'NOT LIKE':
     649                                                $i     = count( $this->table_aliases );
     650                                                $subquery_alias = $i ? 'mt' . $i : $this->meta_table;
     651                                                $this->table_aliases[] = $subquery_alias;
     652
     653                                                $meta_compare_value = '%' . $wpdb->esc_like( trim( $clause['key'] ) ) . '%';
     654
     655                                                $meta_compare_string = "NOT EXISTS (";
     656                                                $meta_compare_string      .= "SELECT 1 FROM $wpdb->postmeta $subquery_alias ";
     657                                                $meta_compare_string      .= "WHERE $subquery_alias.post_ID = $alias.post_ID ";
     658                                                $meta_compare_string      .= "AND $subquery_alias.meta_key LIKE %s ";
     659                                                $meta_compare_string      .= 'LIMIT 1';
     660                                                $meta_compare_string .= ")";
     661
     662                                                $where = $wpdb->prepare( $meta_compare_string, $meta_compare_value );
     663                                                break;
     664                                        case 'NOT IN':
     665                                                $i     = count( $this->table_aliases );
     666                                                $subquery_alias = $i ? 'mt' . $i : $this->meta_table;
     667                                                $this->table_aliases[] = $subquery_alias;
     668
     669                                                $meta_compare_string = "NOT EXISTS (";
     670                                                $meta_compare_string      .= "SELECT 1 FROM $wpdb->postmeta $subquery_alias ";
     671                                                $meta_compare_string      .= "WHERE $subquery_alias.post_ID = $alias.post_ID ";
     672                                                $meta_compare_string      .= "AND $subquery_alias.meta_key IN ";
     673                                                $meta_compare_string      .= '(' . substr( str_repeat( ',%s', count( $clause['key'] ) ), 1 ) . ') ';
     674                                                $meta_compare_string      .= 'LIMIT 1';
     675                                                $meta_compare_string .= ")";
     676
     677                                                $where = $wpdb->prepare( $meta_compare_string, $clause['key'] );
     678                                                break;
    599679                                }
     680
     681                                $sql_chunks['where'][] = $where;
    600682                        }
    601683                }
    602684