Changeset 34704 for trunk/src/wp-includes/query.php
- Timestamp:
- 09/29/2015 09:59:44 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/query.php
r34697 r34704 1302 1302 */ 1303 1303 public $thumbnails_cached = false; 1304 1305 /** 1306 * Whether the term meta cache for matched posts has been primed. 1307 * 1308 * @since 4.4.0 1309 * @access protected 1310 * @var bool 1311 */ 1312 public $updated_term_meta_cache = false; 1304 1313 1305 1314 /** … … 3542 3551 $this->posts = array_map( 'get_post', $this->posts ); 3543 3552 3553 3554 if ( $q['update_post_term_cache'] ) { 3555 add_action( 'get_term_metadata', array( $this, 'lazyload_term_meta' ), 10, 2 ); 3556 } 3557 3544 3558 if ( ! $q['suppress_filters'] ) { 3545 3559 /** … … 4723 4737 } 4724 4738 } 4739 4740 /** 4741 * Lazy-loads termmeta for located posts. 4742 * 4743 * As a rule, term queries (`get_terms()` and `wp_get_object_terms()`) prime the metadata cache for matched 4744 * terms by default. However, this can cause a slight performance penalty, especially when that metadata is 4745 * not actually used. In the context of a `WP_Query` instance, we're able to avoid this potential penalty. 4746 * `update_object_term_cache()`, called from `update_post_caches()`, does not 'update_term_meta_cache'. 4747 * Instead, the first time `get_term_meta()` is called from within a `WP_Query` loop, the current method 4748 * detects the fact, and then primes the metadata cache for all terms attached to all posts in the loop, 4749 * with a single database query. 4750 * 4751 * This method is public so that it can be used as a filter callback. As a rule, there is no need to invoke it 4752 * directly, from either inside or outside the `WP_Query` object. 4753 * 4754 * @since 4.4.0 4755 * @access public 4756 * 4757 * @param null $check The `$check` param passed from the 'pre_term_metadata' hook. 4758 * @param int $term_id ID of the term whose metadata is being cached. 4759 * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be 4760 * another value if filtered by a plugin. 4761 */ 4762 public function lazyload_term_meta( $check, $term_id ) { 4763 /* 4764 * We only do this once per `WP_Query` instance. 4765 * Can't use `remove_action()` because of non-unique object hashes. 4766 */ 4767 if ( $this->updated_term_meta_cache ) { 4768 return $check; 4769 } 4770 4771 // We can only lazyload if the entire post object is present. 4772 $posts = array(); 4773 foreach ( $this->posts as $post ) { 4774 if ( $post instanceof WP_Post ) { 4775 $posts[] = $post; 4776 } 4777 } 4778 $_p = array(); 4779 foreach ( $posts as $post ) { 4780 $_p[] = $post->ID; 4781 } 4782 4783 if ( ! empty( $posts ) ) { 4784 // Fetch cached term_ids for each post. Keyed by term_id for faster lookup. 4785 $term_ids = array(); 4786 foreach ( $posts as $post ) { 4787 $taxonomies = get_object_taxonomies( $post->post_type ); 4788 foreach ( $taxonomies as $taxonomy ) { 4789 // Term cache should already be primed by 'update_post_term_cache'. 4790 $terms = get_object_term_cache( $post->ID, $taxonomy ); 4791 if ( false !== $terms ) { 4792 foreach ( $terms as $term ) { 4793 if ( ! isset( $term_ids[ $term->term_id ] ) ) { 4794 $term_ids[ $term->term_id ] = 1; 4795 } 4796 } 4797 } 4798 } 4799 } 4800 4801 /* 4802 * Only update the metadata cache for terms belonging to these posts if the term_id passed 4803 * to `get_term_meta()` matches one of those terms. This prevents a single call to 4804 * `get_term_meta()` from priming metadata for all `WP_Query` objects. 4805 */ 4806 if ( isset( $term_ids[ $term_id ] ) ) { 4807 update_termmeta_cache( array_keys( $term_ids ) ); 4808 $this->updated_term_meta_cache = true; 4809 } 4810 } 4811 4812 // If no terms were found, there's no need to run this again. 4813 if ( empty( $term_ids ) ) { 4814 $this->updated_term_meta_cache = true; 4815 } 4816 4817 return $check; 4818 } 4725 4819 } 4726 4820
Note: See TracChangeset
for help on using the changeset viewer.