wp/wp-includes/class-wp-term-query.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    13  *
    13  *
    14  * @since 4.6.0
    14  * @since 4.6.0
    15  *
    15  *
    16  * @see WP_Term_Query::__construct() for accepted arguments.
    16  * @see WP_Term_Query::__construct() for accepted arguments.
    17  */
    17  */
       
    18 #[AllowDynamicProperties]
    18 class WP_Term_Query {
    19 class WP_Term_Query {
    19 
    20 
    20 	/**
    21 	/**
    21 	 * SQL string used to perform database query.
    22 	 * SQL string used to perform database query.
    22 	 *
    23 	 *
    88 	 * @since 4.6.0 Introduced 'term_taxonomy_id' parameter.
    89 	 * @since 4.6.0 Introduced 'term_taxonomy_id' parameter.
    89 	 * @since 4.7.0 Introduced 'object_ids' parameter.
    90 	 * @since 4.7.0 Introduced 'object_ids' parameter.
    90 	 * @since 4.9.0 Added 'slug__in' support for 'orderby'.
    91 	 * @since 4.9.0 Added 'slug__in' support for 'orderby'.
    91 	 * @since 5.1.0 Introduced the 'meta_compare_key' parameter.
    92 	 * @since 5.1.0 Introduced the 'meta_compare_key' parameter.
    92 	 * @since 5.3.0 Introduced the 'meta_type_key' parameter.
    93 	 * @since 5.3.0 Introduced the 'meta_type_key' parameter.
       
    94 	 * @since 6.4.0 Introduced the 'cache_results' parameter.
    93 	 *
    95 	 *
    94 	 * @param string|array $query {
    96 	 * @param string|array $query {
    95 	 *     Optional. Array or query string of term query parameters. Default empty.
    97 	 *     Optional. Array or query string of term query parameters. Default empty.
    96 	 *
    98 	 *
    97 	 *     @type string|string[] $taxonomy               Taxonomy name, or array of taxonomy names, to which results
    99 	 *     @type string|string[] $taxonomy               Taxonomy name, or array of taxonomy names, to which results
   175 	 *     @type bool            $childless              True to limit results to terms that have no children.
   177 	 *     @type bool            $childless              True to limit results to terms that have no children.
   176 	 *                                                   This parameter has no effect on non-hierarchical taxonomies.
   178 	 *                                                   This parameter has no effect on non-hierarchical taxonomies.
   177 	 *                                                   Default false.
   179 	 *                                                   Default false.
   178 	 *     @type string          $cache_domain           Unique cache key to be produced when this query is stored in
   180 	 *     @type string          $cache_domain           Unique cache key to be produced when this query is stored in
   179 	 *                                                   an object cache. Default 'core'.
   181 	 *                                                   an object cache. Default 'core'.
       
   182 	 *     @type bool            $cache_results          Whether to cache term information. Default true.
   180 	 *     @type bool            $update_term_meta_cache Whether to prime meta caches for matched terms. Default true.
   183 	 *     @type bool            $update_term_meta_cache Whether to prime meta caches for matched terms. Default true.
   181 	 *     @type string|string[] $meta_key               Meta key or keys to filter by.
   184 	 *     @type string|string[] $meta_key               Meta key or keys to filter by.
   182 	 *     @type string|string[] $meta_value             Meta value or values to filter by.
   185 	 *     @type string|string[] $meta_value             Meta value or values to filter by.
   183 	 *     @type string          $meta_compare           MySQL operator used for comparing the meta value.
   186 	 *     @type string          $meta_compare           MySQL operator used for comparing the meta value.
   184 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   187 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   185 	 *     @type string          $meta_compare_key       MySQL operator used for comparing the meta key.
   188 	 *     @type string          $meta_compare_key       MySQL operator used for comparing the meta key.
   186 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   189 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   187 	 *     @type string          $meta_type              MySQL data type that the meta_value column will be CAST to for comparisons.
   190 	 *     @type string          $meta_type              MySQL data type that the meta_value column will be CAST to for comparisons.
   188 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   191 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   189 	 *     @type string          $meta_type_key          MySQL data type that the meta_key column will be CAST to for comparisons.
   192 	 *     @type string          $meta_type_key          MySQL data type that the meta_key column will be CAST to for comparisons.
   190 	 *                                                   See WP_Meta_Query::__construct for accepted values and default value.
   193 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   191 	 *     @type array           $meta_query             An associative array of WP_Meta_Query arguments.
   194 	 *     @type array           $meta_query             An associative array of WP_Meta_Query arguments.
   192 	 *                                                   See WP_Meta_Query::__construct for accepted values.
   195 	 *                                                   See WP_Meta_Query::__construct() for accepted values.
   193 	 * }
   196 	 * }
   194 	 */
   197 	 */
   195 	public function __construct( $query = '' ) {
   198 	public function __construct( $query = '' ) {
   196 		$this->query_var_defaults = array(
   199 		$this->query_var_defaults = array(
   197 			'taxonomy'               => null,
   200 			'taxonomy'               => null,
   217 			'get'                    => '',
   220 			'get'                    => '',
   218 			'child_of'               => 0,
   221 			'child_of'               => 0,
   219 			'parent'                 => '',
   222 			'parent'                 => '',
   220 			'childless'              => false,
   223 			'childless'              => false,
   221 			'cache_domain'           => 'core',
   224 			'cache_domain'           => 'core',
       
   225 			'cache_results'          => true,
   222 			'update_term_meta_cache' => true,
   226 			'update_term_meta_cache' => true,
   223 			'meta_query'             => '',
   227 			'meta_query'             => '',
   224 			'meta_key'               => '',
   228 			'meta_key'               => '',
   225 			'meta_value'             => '',
   229 			'meta_value'             => '',
   226 			'meta_type'              => '',
   230 			'meta_type'              => '',
   235 	/**
   239 	/**
   236 	 * Parse arguments passed to the term query with default query parameters.
   240 	 * Parse arguments passed to the term query with default query parameters.
   237 	 *
   241 	 *
   238 	 * @since 4.6.0
   242 	 * @since 4.6.0
   239 	 *
   243 	 *
   240 	 * @param string|array $query WP_Term_Query arguments. See WP_Term_Query::__construct()
   244 	 * @param string|array $query WP_Term_Query arguments. See WP_Term_Query::__construct() for accepted arguments.
   241 	 */
   245 	 */
   242 	public function parse_query( $query = '' ) {
   246 	public function parse_query( $query = '' ) {
   243 		if ( empty( $query ) ) {
   247 		if ( empty( $query ) ) {
   244 			$query = $this->query_vars;
   248 			$query = $this->query_vars;
   245 		}
   249 		}
   482 
   486 
   483 		$exclusions = array();
   487 		$exclusions = array();
   484 		if ( ! empty( $exclude_tree ) ) {
   488 		if ( ! empty( $exclude_tree ) ) {
   485 			$exclude_tree      = wp_parse_id_list( $exclude_tree );
   489 			$exclude_tree      = wp_parse_id_list( $exclude_tree );
   486 			$excluded_children = $exclude_tree;
   490 			$excluded_children = $exclude_tree;
       
   491 
   487 			foreach ( $exclude_tree as $extrunk ) {
   492 			foreach ( $exclude_tree as $extrunk ) {
   488 				$excluded_children = array_merge(
   493 				$excluded_children = array_merge(
   489 					$excluded_children,
   494 					$excluded_children,
   490 					(array) get_terms(
   495 					(array) get_terms(
   491 						array(
   496 						array(
   495 							'hide_empty' => 0,
   500 							'hide_empty' => 0,
   496 						)
   501 						)
   497 					)
   502 					)
   498 				);
   503 				);
   499 			}
   504 			}
       
   505 
   500 			$exclusions = array_merge( $excluded_children, $exclusions );
   506 			$exclusions = array_merge( $excluded_children, $exclusions );
   501 		}
   507 		}
   502 
   508 
   503 		if ( ! empty( $exclude ) ) {
   509 		if ( ! empty( $exclude ) ) {
   504 			$exclusions = array_merge( wp_parse_id_list( $exclude ), $exclusions );
   510 			$exclusions = array_merge( wp_parse_id_list( $exclude ), $exclusions );
   529 		 * @param string[] $taxonomies An array of taxonomy names.
   535 		 * @param string[] $taxonomies An array of taxonomy names.
   530 		 */
   536 		 */
   531 		$exclusions = apply_filters( 'list_terms_exclusions', $exclusions, $args, $taxonomies );
   537 		$exclusions = apply_filters( 'list_terms_exclusions', $exclusions, $args, $taxonomies );
   532 
   538 
   533 		if ( ! empty( $exclusions ) ) {
   539 		if ( ! empty( $exclusions ) ) {
   534 			// Must do string manipulation here for backward compatibility with filter.
   540 			// Strip leading 'AND'. Must do string manipulation here for backward compatibility with filter.
   535 			$this->sql_clauses['where']['exclusions'] = preg_replace( '/^\s*AND\s*/', '', $exclusions );
   541 			$this->sql_clauses['where']['exclusions'] = preg_replace( '/^\s*AND\s*/', '', $exclusions );
   536 		}
   542 		}
   537 
   543 
   538 		if ( '' === $args['name'] ) {
   544 		if ( '' === $args['name'] ) {
   539 			$args['name'] = array();
   545 			$args['name'] = array();
   541 			$args['name'] = (array) $args['name'];
   547 			$args['name'] = (array) $args['name'];
   542 		}
   548 		}
   543 
   549 
   544 		if ( ! empty( $args['name'] ) ) {
   550 		if ( ! empty( $args['name'] ) ) {
   545 			$names = $args['name'];
   551 			$names = $args['name'];
       
   552 
   546 			foreach ( $names as &$_name ) {
   553 			foreach ( $names as &$_name ) {
   547 				// `sanitize_term_field()` returns slashed data.
   554 				// `sanitize_term_field()` returns slashed data.
   548 				$_name = stripslashes( sanitize_term_field( 'name', $_name, 0, reset( $taxonomies ), 'db' ) );
   555 				$_name = stripslashes( sanitize_term_field( 'name', $_name, 0, reset( $taxonomies ), 'db' ) );
   549 			}
   556 			}
   550 
   557 
   648 		$this->meta_query->parse_query_vars( $this->query_vars );
   655 		$this->meta_query->parse_query_vars( $this->query_vars );
   649 		$mq_sql       = $this->meta_query->get_sql( 'term', 't', 'term_id' );
   656 		$mq_sql       = $this->meta_query->get_sql( 'term', 't', 'term_id' );
   650 		$meta_clauses = $this->meta_query->get_clauses();
   657 		$meta_clauses = $this->meta_query->get_clauses();
   651 
   658 
   652 		if ( ! empty( $meta_clauses ) ) {
   659 		if ( ! empty( $meta_clauses ) ) {
   653 			$join                                    .= $mq_sql['join'];
   660 			$join .= $mq_sql['join'];
       
   661 
       
   662 			// Strip leading 'AND'.
   654 			$this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $mq_sql['where'] );
   663 			$this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $mq_sql['where'] );
   655 			$distinct                                .= 'DISTINCT';
   664 
       
   665 			$distinct .= 'DISTINCT';
   656 
   666 
   657 		}
   667 		}
   658 
   668 
   659 		$selects = array();
   669 		$selects = array();
   660 		switch ( $args['fields'] ) {
   670 		switch ( $args['fields'] ) {
   698 			$distinct = 'DISTINCT';
   708 			$distinct = 'DISTINCT';
   699 		}
   709 		}
   700 
   710 
   701 		$where = implode( ' AND ', $this->sql_clauses['where'] );
   711 		$where = implode( ' AND ', $this->sql_clauses['where'] );
   702 
   712 
   703 		$clauses = array( 'fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits' );
   713 		$pieces = array( 'fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits' );
   704 
   714 
   705 		/**
   715 		/**
   706 		 * Filters the terms query SQL clauses.
   716 		 * Filters the terms query SQL clauses.
   707 		 *
   717 		 *
   708 		 * @since 3.1.0
   718 		 * @since 3.1.0
   719 		 *     @type string $limits   The LIMIT clause of the query.
   729 		 *     @type string $limits   The LIMIT clause of the query.
   720 		 * }
   730 		 * }
   721 		 * @param string[] $taxonomies An array of taxonomy names.
   731 		 * @param string[] $taxonomies An array of taxonomy names.
   722 		 * @param array    $args       An array of term query arguments.
   732 		 * @param array    $args       An array of term query arguments.
   723 		 */
   733 		 */
   724 		$clauses = apply_filters( 'terms_clauses', compact( $clauses ), $taxonomies, $args );
   734 		$clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );
   725 
   735 
   726 		$fields   = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
   736 		$fields   = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
   727 		$join     = isset( $clauses['join'] ) ? $clauses['join'] : '';
   737 		$join     = isset( $clauses['join'] ) ? $clauses['join'] : '';
   728 		$where    = isset( $clauses['where'] ) ? $clauses['where'] : '';
   738 		$where    = isset( $clauses['where'] ) ? $clauses['where'] : '';
   729 		$distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : '';
   739 		$distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : '';
   730 		$orderby  = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
   740 		$orderby  = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
   731 		$order    = isset( $clauses['order'] ) ? $clauses['order'] : '';
   741 		$order    = isset( $clauses['order'] ) ? $clauses['order'] : '';
   732 		$limits   = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
   742 		$limits   = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
   733 
   743 
       
   744 		$fields_is_filtered = implode( ', ', $selects ) !== $fields;
       
   745 
   734 		if ( $where ) {
   746 		if ( $where ) {
   735 			$where = "WHERE $where";
   747 			$where = "WHERE $where";
   736 		}
   748 		}
   737 
   749 
   738 		$this->sql_clauses['select']  = "SELECT $distinct $fields";
   750 		$this->sql_clauses['select']  = "SELECT $distinct $fields";
   739 		$this->sql_clauses['from']    = "FROM $wpdb->terms AS t $join";
   751 		$this->sql_clauses['from']    = "FROM $wpdb->terms AS t $join";
   740 		$this->sql_clauses['orderby'] = $orderby ? "$orderby $order" : '';
   752 		$this->sql_clauses['orderby'] = $orderby ? "$orderby $order" : '';
   741 		$this->sql_clauses['limits']  = $limits;
   753 		$this->sql_clauses['limits']  = $limits;
   742 
   754 
   743 		$this->request = "
   755 		// Beginning of the string is on a new line to prevent leading whitespace. See https://core.trac.wordpress.org/ticket/56841.
   744 			{$this->sql_clauses['select']}
   756 		$this->request =
   745 			{$this->sql_clauses['from']}
   757 			"{$this->sql_clauses['select']}
   746 			{$where}
   758 			 {$this->sql_clauses['from']}
   747 			{$this->sql_clauses['orderby']}
   759 			 {$where}
   748 			{$this->sql_clauses['limits']}
   760 			 {$this->sql_clauses['orderby']}
   749 		";
   761 			 {$this->sql_clauses['limits']}";
   750 
   762 
   751 		$this->terms = null;
   763 		$this->terms = null;
   752 
   764 
   753 		/**
   765 		/**
   754 		 * Filters the terms array before the query takes place.
   766 		 * Filters the terms array before the query takes place.
   765 
   777 
   766 		if ( null !== $this->terms ) {
   778 		if ( null !== $this->terms ) {
   767 			return $this->terms;
   779 			return $this->terms;
   768 		}
   780 		}
   769 
   781 
   770 		// $args can be anything. Only use the args defined in defaults to compute the key.
   782 		if ( $args['cache_results'] ) {
   771 		$cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
   783 			$cache_key = $this->generate_cache_key( $args, $this->request );
   772 
   784 			$cache     = wp_cache_get( $cache_key, 'term-queries' );
   773 		unset( $cache_args['update_term_meta_cache'] );
   785 
   774 
   786 			if ( false !== $cache ) {
   775 		if ( 'count' !== $_fields && 'all_with_object_id' !== $_fields ) {
   787 				if ( 'ids' === $_fields ) {
   776 			$cache_args['fields'] = 'all';
   788 					$cache = array_map( 'intval', $cache );
   777 		}
   789 				} elseif ( 'count' !== $_fields ) {
   778 
   790 					if ( ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) )
   779 		$key          = md5( serialize( $cache_args ) . serialize( $taxonomies ) . $this->request );
   791 					|| ( 'all' === $_fields && $args['pad_counts'] || $fields_is_filtered )
   780 		$last_changed = wp_cache_get_last_changed( 'terms' );
   792 					) {
   781 		$cache_key    = "get_terms:$key:$last_changed";
   793 						$term_ids = wp_list_pluck( $cache, 'term_id' );
   782 		$cache        = wp_cache_get( $cache_key, 'terms' );
   794 					} else {
   783 
   795 						$term_ids = array_map( 'intval', $cache );
   784 		if ( false !== $cache ) {
   796 					}
   785 			if ( 'ids' === $_fields ) {
   797 
   786 				$cache = array_map( 'intval', $cache );
   798 					_prime_term_caches( $term_ids, $args['update_term_meta_cache'] );
   787 			} elseif ( 'count' !== $_fields ) {
   799 
   788 				if ( ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) || ( 'all' === $_fields && $args['pad_counts'] ) ) {
   800 					$term_objects = $this->populate_terms( $cache );
   789 					$term_ids = wp_list_pluck( $cache, 'term_id' );
   801 					$cache        = $this->format_terms( $term_objects, $_fields );
   790 				} else {
       
   791 					$term_ids = array_map( 'intval', $cache );
       
   792 				}
   802 				}
   793 				_prime_term_caches( $term_ids, $args['update_term_meta_cache'] );
   803 
   794 				$term_objects = $this->populate_terms( $cache );
   804 				$this->terms = $cache;
   795 				$cache        = $this->format_terms( $term_objects, $_fields );
   805 				return $this->terms;
   796 			}
   806 			}
   797 
       
   798 			$this->terms = $cache;
       
   799 			return $this->terms;
       
   800 		}
   807 		}
   801 
   808 
   802 		if ( 'count' === $_fields ) {
   809 		if ( 'count' === $_fields ) {
   803 			$count = $wpdb->get_var( $this->request ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
   810 			$count = $wpdb->get_var( $this->request ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
   804 			wp_cache_set( $cache_key, $count, 'terms' );
   811 			if ( $args['cache_results'] ) {
       
   812 				wp_cache_set( $cache_key, $count, 'term-queries' );
       
   813 			}
   805 			return $count;
   814 			return $count;
   806 		}
   815 		}
   807 
   816 
   808 		$terms = $wpdb->get_results( $this->request ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
   817 		$terms = $wpdb->get_results( $this->request ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
   809 
   818 
   810 		if ( empty( $terms ) ) {
   819 		if ( empty( $terms ) ) {
   811 			wp_cache_add( $cache_key, array(), 'terms' );
   820 			if ( $args['cache_results'] ) {
       
   821 				wp_cache_add( $cache_key, array(), 'term-queries' );
       
   822 			}
   812 			return array();
   823 			return array();
   813 		}
   824 		}
   814 
   825 
   815 		$term_ids = wp_list_pluck( $terms, 'term_id' );
   826 		$term_ids = wp_list_pluck( $terms, 'term_id' );
   816 		_prime_term_caches( $term_ids, false );
   827 		_prime_term_caches( $term_ids, false );
   835 		// Make sure we show empty categories that have children.
   846 		// Make sure we show empty categories that have children.
   836 		if ( $hierarchical && $args['hide_empty'] && is_array( $term_objects ) ) {
   847 		if ( $hierarchical && $args['hide_empty'] && is_array( $term_objects ) ) {
   837 			foreach ( $term_objects as $k => $term ) {
   848 			foreach ( $term_objects as $k => $term ) {
   838 				if ( ! $term->count ) {
   849 				if ( ! $term->count ) {
   839 					$children = get_term_children( $term->term_id, $term->taxonomy );
   850 					$children = get_term_children( $term->term_id, $term->taxonomy );
       
   851 
   840 					if ( is_array( $children ) ) {
   852 					if ( is_array( $children ) ) {
   841 						foreach ( $children as $child_id ) {
   853 						foreach ( $children as $child_id ) {
   842 							$child = get_term( $child_id, $term->taxonomy );
   854 							$child = get_term( $child_id, $term->taxonomy );
   843 							if ( $child->count ) {
   855 							if ( $child->count ) {
   844 								continue 2;
   856 								continue 2;
   862 		}
   874 		}
   863 
   875 
   864 		// Prime termmeta cache.
   876 		// Prime termmeta cache.
   865 		if ( $args['update_term_meta_cache'] ) {
   877 		if ( $args['update_term_meta_cache'] ) {
   866 			$term_ids = wp_list_pluck( $term_objects, 'term_id' );
   878 			$term_ids = wp_list_pluck( $term_objects, 'term_id' );
   867 			update_termmeta_cache( $term_ids );
   879 			wp_lazyload_term_meta( $term_ids );
   868 		}
   880 		}
   869 
   881 
   870 		if ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) {
   882 		if ( 'all_with_object_id' === $_fields && ! empty( $args['object_ids'] ) ) {
   871 			$term_cache = array();
   883 			$term_cache = array();
   872 			foreach ( $term_objects as $term ) {
   884 			foreach ( $term_objects as $term ) {
   881 				$object          = new stdClass();
   893 				$object          = new stdClass();
   882 				$object->term_id = $term->term_id;
   894 				$object->term_id = $term->term_id;
   883 				$object->count   = $term->count;
   895 				$object->count   = $term->count;
   884 				$term_cache[]    = $object;
   896 				$term_cache[]    = $object;
   885 			}
   897 			}
       
   898 		} elseif ( $fields_is_filtered ) {
       
   899 			$term_cache = $term_objects;
   886 		} else {
   900 		} else {
   887 			$term_cache = wp_list_pluck( $term_objects, 'term_id' );
   901 			$term_cache = wp_list_pluck( $term_objects, 'term_id' );
   888 		}
   902 		}
   889 		wp_cache_add( $cache_key, $term_cache, 'terms' );
   903 
       
   904 		if ( $args['cache_results'] ) {
       
   905 			wp_cache_add( $cache_key, $term_cache, 'term-queries' );
       
   906 		}
       
   907 
   890 		$this->terms = $this->format_terms( $term_objects, $_fields );
   908 		$this->terms = $this->format_terms( $term_objects, $_fields );
   891 
   909 
   892 		return $this->terms;
   910 		return $this->terms;
   893 	}
   911 	}
   894 
   912 
   895 	/**
   913 	/**
   896 	 * Parse and sanitize 'orderby' keys passed to the term query.
   914 	 * Parse and sanitize 'orderby' keys passed to the term query.
   897 	 *
   915 	 *
   898 	 * @since 4.6.0
   916 	 * @since 4.6.0
   899 	 *
       
   900 	 * @global wpdb $wpdb WordPress database abstraction object.
       
   901 	 *
   917 	 *
   902 	 * @param string $orderby_raw Alias for the field to order by.
   918 	 * @param string $orderby_raw Alias for the field to order by.
   903 	 * @return string|false Value to used in the ORDER clause. False otherwise.
   919 	 * @return string|false Value to used in the ORDER clause. False otherwise.
   904 	 */
   920 	 */
   905 	protected function parse_orderby( $orderby_raw ) {
   921 	protected function parse_orderby( $orderby_raw ) {
  1129 			}
  1145 			}
  1130 		}
  1146 		}
  1131 
  1147 
  1132 		return $term_objects;
  1148 		return $term_objects;
  1133 	}
  1149 	}
       
  1150 
       
  1151 	/**
       
  1152 	 * Generate cache key.
       
  1153 	 *
       
  1154 	 * @since 6.2.0
       
  1155 	 *
       
  1156 	 * @global wpdb $wpdb WordPress database abstraction object.
       
  1157 	 *
       
  1158 	 * @param array  $args WP_Term_Query arguments.
       
  1159 	 * @param string $sql  SQL statement.
       
  1160 	 *
       
  1161 	 * @return string Cache key.
       
  1162 	 */
       
  1163 	protected function generate_cache_key( array $args, $sql ) {
       
  1164 		global $wpdb;
       
  1165 		// $args can be anything. Only use the args defined in defaults to compute the key.
       
  1166 		$cache_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
       
  1167 
       
  1168 		unset( $cache_args['cache_results'], $cache_args['update_term_meta_cache'] );
       
  1169 
       
  1170 		if ( 'count' !== $args['fields'] && 'all_with_object_id' !== $args['fields'] ) {
       
  1171 			$cache_args['fields'] = 'all';
       
  1172 		}
       
  1173 		$taxonomies = (array) $args['taxonomy'];
       
  1174 
       
  1175 		// Replace wpdb placeholder in the SQL statement used by the cache key.
       
  1176 		$sql = $wpdb->remove_placeholder_escape( $sql );
       
  1177 
       
  1178 		$key          = md5( serialize( $cache_args ) . serialize( $taxonomies ) . $sql );
       
  1179 		$last_changed = wp_cache_get_last_changed( 'terms' );
       
  1180 		return "get_terms:$key:$last_changed";
       
  1181 	}
  1134 }
  1182 }