wp/wp-includes/class-wp-meta-query.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
    97 	/**
    97 	/**
    98 	 * Constructor.
    98 	 * Constructor.
    99 	 *
    99 	 *
   100 	 * @since 3.2.0
   100 	 * @since 3.2.0
   101 	 * @since 4.2.0 Introduced support for naming query clauses by associative array keys.
   101 	 * @since 4.2.0 Introduced support for naming query clauses by associative array keys.
   102 	 * @since 5.1.0 Introduced $compare_key clause parameter, which enables LIKE key matches.
   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,
   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.
   104 	 *              which enables the `$key` to be cast to a new data type for comparisons.
   105 	 *
   105 	 *
   106 	 * @param array $meta_query {
   106 	 * @param array $meta_query {
   107 	 *     Array of meta query clauses. When first-order clauses or sub-clauses use strings as
   107 	 *     Array of meta query clauses. When first-order clauses or sub-clauses use strings as
   108 	 *     their array keys, they may be referenced in the 'orderby' parameter of the parent query.
   108 	 *     their array keys, they may be referenced in the 'orderby' parameter of the parent query.
   109 	 *
   109 	 *
   110 	 *     @type string $relation Optional. The MySQL keyword used to join
   110 	 *     @type string $relation Optional. The MySQL keyword used to join the clauses of the query.
   111 	 *                            the clauses of the query. Accepts 'AND', or 'OR'. Default 'AND'.
   111 	 *                            Accepts 'AND' or 'OR'. Default 'AND'.
   112 	 *     @type array  ...$0 {
   112 	 *     @type array  ...$0 {
   113 	 *         Optional. An array of first-order clause parameters, or another fully-formed meta query.
   113 	 *         Optional. An array of first-order clause parameters, or another fully-formed meta query.
   114 	 *
   114 	 *
   115 	 *         @type string $key         Meta key to filter by.
   115 	 *         @type string|string[] $key         Meta key or keys to filter by.
   116 	 *         @type string $compare_key MySQL operator used for comparing the $key. Accepts '=', '!='
   116 	 *         @type string          $compare_key MySQL operator used for comparing the $key. Accepts:
   117 	 *                                   'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'REGEXP', 'NOT REGEXP', 'RLIKE',
   117 	 *                                            - '='
   118 	 *                                   'EXISTS' (alias of '=') or 'NOT EXISTS' (alias of '!=').
   118 	 *                                            - '!='
   119 	 *                                   Default is 'IN' when `$key` is an array, '=' otherwise.
   119 	 *                                            - 'LIKE'
   120 	 *         @type string $type_key    MySQL data type that the meta_key column will be CAST to for
   120 	 *                                            - 'NOT LIKE'
   121 	 *                                   comparisons. Accepts 'BINARY' for case-sensitive regular expression
   121 	 *                                            - 'IN'
   122 	 *                                   comparisons. Default is ''.
   122 	 *                                            - 'NOT IN'
   123 	 *         @type string $value       Meta value to filter by.
   123 	 *                                            - 'REGEXP'
   124 	 *         @type string $compare     MySQL operator used for comparing the $value. Accepts '=',
   124 	 *                                            - 'NOT REGEXP'
   125 	 *                                   '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE',
   125 	 *                                            - 'RLIKE',
   126 	 *                                   'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'REGEXP',
   126 	 *                                            - 'EXISTS' (alias of '=')
   127 	 *                                   'NOT REGEXP', 'RLIKE', 'EXISTS' or 'NOT EXISTS'.
   127 	 *                                            - 'NOT EXISTS' (alias of '!=')
   128 	 *                                   Default is 'IN' when `$value` is an array, '=' otherwise.
   128 	 *                                            Default is 'IN' when `$key` is an array, '=' otherwise.
   129 	 *         @type string $type        MySQL data type that the meta_value column will be CAST to for
   129 	 *         @type string          $type_key    MySQL data type that the meta_key column will be CAST to for
   130 	 *                                   comparisons. Accepts 'NUMERIC', 'BINARY', 'CHAR', 'DATE',
   130 	 *                                            comparisons. Accepts 'BINARY' for case-sensitive regular expression
   131 	 *                                   'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', or 'UNSIGNED'.
   131 	 *                                            comparisons. Default is ''.
   132 	 *                                   Default is 'CHAR'.
   132 	 *         @type string|string[] $value       Meta value or values to filter by.
       
   133 	 *         @type string          $compare     MySQL operator used for comparing the $value. Accepts:
       
   134 	 *                                            - '=',
       
   135 	 *                                            - '!='
       
   136 	 *                                            - '>'
       
   137 	 *                                            - '>='
       
   138 	 *                                            - '<'
       
   139 	 *                                            - '<='
       
   140 	 *                                            - 'LIKE'
       
   141 	 *                                            - 'NOT LIKE'
       
   142 	 *                                            - 'IN'
       
   143 	 *                                            - 'NOT IN'
       
   144 	 *                                            - 'BETWEEN'
       
   145 	 *                                            - 'NOT BETWEEN'
       
   146 	 *                                            - 'REGEXP'
       
   147 	 *                                            - 'NOT REGEXP'
       
   148 	 *                                            - 'RLIKE'
       
   149 	 *                                            - 'EXISTS'
       
   150 	 *                                            - 'NOT EXISTS'
       
   151 	 *                                            Default is 'IN' when `$value` is an array, '=' otherwise.
       
   152 	 *         @type string          $type        MySQL data type that the meta_value column will be CAST to for
       
   153 	 *                                            comparisons. Accepts:
       
   154 	 *                                            - 'NUMERIC'
       
   155 	 *                                            - 'BINARY'
       
   156 	 *                                            - 'CHAR'
       
   157 	 *                                            - 'DATE'
       
   158 	 *                                            - 'DATETIME'
       
   159 	 *                                            - 'DECIMAL'
       
   160 	 *                                            - 'SIGNED'
       
   161 	 *                                            - 'TIME'
       
   162 	 *                                            - 'UNSIGNED'
       
   163 	 *                                            Default is 'CHAR'.
   133 	 *     }
   164 	 *     }
   134 	 * }
   165 	 * }
   135 	 */
   166 	 */
   136 	public function __construct( $meta_query = false ) {
   167 	public function __construct( $meta_query = false ) {
   137 		if ( ! $meta_query ) {
   168 		if ( ! $meta_query ) {
   305 	/**
   336 	/**
   306 	 * Generates SQL clauses to be appended to a main query.
   337 	 * Generates SQL clauses to be appended to a main query.
   307 	 *
   338 	 *
   308 	 * @since 3.2.0
   339 	 * @since 3.2.0
   309 	 *
   340 	 *
   310 	 * @param string $type              Type of meta, eg 'user', 'post'.
   341 	 * @param string $type              Type of meta. Possible values include but are not limited
       
   342 	 *                                  to 'post', 'comment', 'blog', 'term', and 'user'.
   311 	 * @param string $primary_table     Database table where the object being filtered is stored (eg wp_users).
   343 	 * @param string $primary_table     Database table where the object being filtered is stored (eg wp_users).
   312 	 * @param string $primary_id_column ID column for the filtered object in $primary_table.
   344 	 * @param string $primary_id_column ID column for the filtered object in $primary_table.
   313 	 * @param object $context           Optional. The main query object.
   345 	 * @param object $context           Optional. The main query object that corresponds to the type, for
   314 	 * @return array|false {
   346 	 *                                  example a `WP_Query`, `WP_User_Query`, or `WP_Site_Query`.
   315 	 *     Array containing JOIN and WHERE SQL clauses to append to the main query.
   347 	 * @return string[]|false {
       
   348 	 *     Array containing JOIN and WHERE SQL clauses to append to the main query,
       
   349 	 *     or false if no table exists for the requested meta type.
   316 	 *
   350 	 *
   317 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   351 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   318 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   352 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   319 	 * }
   353 	 * }
   320 	 */
   354 	 */
   345 		/**
   379 		/**
   346 		 * Filters the meta query's generated SQL.
   380 		 * Filters the meta query's generated SQL.
   347 		 *
   381 		 *
   348 		 * @since 3.1.0
   382 		 * @since 3.1.0
   349 		 *
   383 		 *
   350 		 * @param array  $sql               Array containing the query's JOIN and WHERE clauses.
   384 		 * @param string[] $sql               Array containing the query's JOIN and WHERE clauses.
   351 		 * @param array  $queries           Array of meta queries.
   385 		 * @param array    $queries           Array of meta queries.
   352 		 * @param string $type              Type of meta.
   386 		 * @param string   $type              Type of meta. Possible values include but are not limited
   353 		 * @param string $primary_table     Primary table.
   387 		 *                                    to 'post', 'comment', 'blog', 'term', and 'user'.
   354 		 * @param string $primary_id_column Primary column ID.
   388 		 * @param string   $primary_table     Primary table.
   355 		 * @param object $context           The main query object.
   389 		 * @param string   $primary_id_column Primary column ID.
       
   390 		 * @param object   $context           The main query object that corresponds to the type, for
       
   391 		 *                                    example a `WP_Query`, `WP_User_Query`, or `WP_Site_Query`.
   356 		 */
   392 		 */
   357 		return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) );
   393 		return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) );
   358 	}
   394 	}
   359 
   395 
   360 	/**
   396 	/**
   363 	 * Called by the public WP_Meta_Query::get_sql(), this method is abstracted
   399 	 * Called by the public WP_Meta_Query::get_sql(), this method is abstracted
   364 	 * out to maintain parity with the other Query classes.
   400 	 * out to maintain parity with the other Query classes.
   365 	 *
   401 	 *
   366 	 * @since 4.1.0
   402 	 * @since 4.1.0
   367 	 *
   403 	 *
   368 	 * @return array {
   404 	 * @return string[] {
   369 	 *     Array containing JOIN and WHERE SQL clauses to append to the main query.
   405 	 *     Array containing JOIN and WHERE SQL clauses to append to the main query.
   370 	 *
   406 	 *
   371 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   407 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   372 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   408 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   373 	 * }
   409 	 * }
   396 	 * @since 4.1.0
   432 	 * @since 4.1.0
   397 	 *
   433 	 *
   398 	 * @param array $query Query to parse (passed by reference).
   434 	 * @param array $query Query to parse (passed by reference).
   399 	 * @param int   $depth Optional. Number of tree levels deep we currently are.
   435 	 * @param int   $depth Optional. Number of tree levels deep we currently are.
   400 	 *                     Used to calculate indentation. Default 0.
   436 	 *                     Used to calculate indentation. Default 0.
   401 	 * @return array {
   437 	 * @return string[] {
   402 	 *     Array containing JOIN and WHERE SQL clauses to append to a single query array.
   438 	 *     Array containing JOIN and WHERE SQL clauses to append to a single query array.
   403 	 *
   439 	 *
   404 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   440 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   405 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   441 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   406 	 * }
   442 	 * }
   482 	 *
   518 	 *
   483 	 * @param array  $clause       Query clause (passed by reference).
   519 	 * @param array  $clause       Query clause (passed by reference).
   484 	 * @param array  $parent_query Parent query array.
   520 	 * @param array  $parent_query Parent query array.
   485 	 * @param string $clause_key   Optional. The array key used to name the clause in the original `$meta_query`
   521 	 * @param string $clause_key   Optional. The array key used to name the clause in the original `$meta_query`
   486 	 *                             parameters. If not provided, a key will be generated automatically.
   522 	 *                             parameters. If not provided, a key will be generated automatically.
   487 	 * @return array {
   523 	 * @return string[] {
   488 	 *     Array containing JOIN and WHERE SQL clauses to append to a first-order query.
   524 	 *     Array containing JOIN and WHERE SQL clauses to append to a first-order query.
   489 	 *
   525 	 *
   490 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   526 	 *     @type string $join  SQL fragment to append to the main JOIN clause.
   491 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   527 	 *     @type string $where SQL fragment to append to the main WHERE clause.
   492 	 * }
   528 	 * }
   689 
   725 
   690 			if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) {
   726 			if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ), true ) ) {
   691 				if ( ! is_array( $meta_value ) ) {
   727 				if ( ! is_array( $meta_value ) ) {
   692 					$meta_value = preg_split( '/[,\s]+/', $meta_value );
   728 					$meta_value = preg_split( '/[,\s]+/', $meta_value );
   693 				}
   729 				}
   694 			} else {
   730 			} elseif ( is_string( $meta_value ) ) {
   695 				$meta_value = trim( $meta_value );
   731 				$meta_value = trim( $meta_value );
   696 			}
   732 			}
   697 
   733 
   698 			switch ( $meta_compare ) {
   734 			switch ( $meta_compare ) {
   699 				case 'IN':
   735 				case 'IN':
   810 			}
   846 			}
   811 
   847 
   812 			$clause_compare  = strtoupper( $clause['compare'] );
   848 			$clause_compare  = strtoupper( $clause['compare'] );
   813 			$sibling_compare = strtoupper( $sibling['compare'] );
   849 			$sibling_compare = strtoupper( $sibling['compare'] );
   814 			if ( in_array( $clause_compare, $compatible_compares, true ) && in_array( $sibling_compare, $compatible_compares, true ) ) {
   850 			if ( in_array( $clause_compare, $compatible_compares, true ) && in_array( $sibling_compare, $compatible_compares, true ) ) {
   815 				$alias = $sibling['alias'];
   851 				$alias = preg_replace( '/\W/', '_', $sibling['alias'] );
   816 				break;
   852 				break;
   817 			}
   853 			}
   818 		}
   854 		}
   819 
   855 
   820 		/**
   856 		/**
   823 		 * @since 4.1.0
   859 		 * @since 4.1.0
   824 		 *
   860 		 *
   825 		 * @param string|false  $alias        Table alias, or false if none was found.
   861 		 * @param string|false  $alias        Table alias, or false if none was found.
   826 		 * @param array         $clause       First-order query clause.
   862 		 * @param array         $clause       First-order query clause.
   827 		 * @param array         $parent_query Parent of $clause.
   863 		 * @param array         $parent_query Parent of $clause.
   828 		 * @param WP_Meta_Query $this         WP_Meta_Query object.
   864 		 * @param WP_Meta_Query $query        WP_Meta_Query object.
   829 		 */
   865 		 */
   830 		return apply_filters( 'meta_query_find_compatible_table_alias', $alias, $clause, $parent_query, $this );
   866 		return apply_filters( 'meta_query_find_compatible_table_alias', $alias, $clause, $parent_query, $this );
   831 	}
   867 	}
   832 
   868 
   833 	/**
   869 	/**