[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> class-wp-metadata-lazyloader.php (source)

   1  <?php
   2  /**
   3   * Meta API: WP_Metadata_Lazyloader class
   4   *
   5   * @package WordPress
   6   * @subpackage Meta
   7   * @since 4.5.0
   8   */
   9  
  10  /**
  11   * Core class used for lazy-loading object metadata.
  12   *
  13   * When loading many objects of a given type, such as posts in a WP_Query loop, it often makes
  14   * sense to prime various metadata caches at the beginning of the loop. This means fetching all
  15   * relevant metadata with a single database query, a technique that has the potential to improve
  16   * performance dramatically in some cases.
  17   *
  18   * In cases where the given metadata may not even be used in the loop, we can improve performance
  19   * even more by only priming the metadata cache for affected items the first time a piece of metadata
  20   * is requested - ie, by lazy-loading it. So, for example, comment meta may not be loaded into the
  21   * cache in the comments section of a post until the first time get_comment_meta() is called in the
  22   * context of the comment loop.
  23   *
  24   * WP uses the WP_Metadata_Lazyloader class to queue objects for metadata cache priming. The class
  25   * then detects the relevant get_*_meta() function call, and queries the metadata of all queued objects.
  26   *
  27   * Do not access this class directly. Use the wp_metadata_lazyloader() function.
  28   *
  29   * @since 4.5.0
  30   */
  31  #[AllowDynamicProperties]
  32  class WP_Metadata_Lazyloader {
  33      /**
  34       * Pending objects queue.
  35       *
  36       * @since 4.5.0
  37       * @var array
  38       */
  39      protected $pending_objects;
  40  
  41      /**
  42       * Settings for supported object types.
  43       *
  44       * @since 4.5.0
  45       * @var array
  46       */
  47      protected $settings = array();
  48  
  49      /**
  50       * Constructor.
  51       *
  52       * @since 4.5.0
  53       */
  54  	public function __construct() {
  55          $this->settings = array(
  56              'term'    => array(
  57                  'filter'   => 'get_term_metadata',
  58                  'callback' => array( $this, 'lazyload_meta_callback' ),
  59              ),
  60              'comment' => array(
  61                  'filter'   => 'get_comment_metadata',
  62                  'callback' => array( $this, 'lazyload_meta_callback' ),
  63              ),
  64              'blog'    => array(
  65                  'filter'   => 'get_blog_metadata',
  66                  'callback' => array( $this, 'lazyload_meta_callback' ),
  67              ),
  68          );
  69      }
  70  
  71      /**
  72       * Adds objects to the metadata lazy-load queue.
  73       *
  74       * @since 4.5.0
  75       *
  76       * @param string $object_type Type of object whose meta is to be lazy-loaded. Accepts 'term' or 'comment'.
  77       * @param array  $object_ids  Array of object IDs.
  78       * @return void|WP_Error WP_Error on failure.
  79       */
  80  	public function queue_objects( $object_type, $object_ids ) {
  81          if ( ! isset( $this->settings[ $object_type ] ) ) {
  82              return new WP_Error( 'invalid_object_type', __( 'Invalid object type.' ) );
  83          }
  84  
  85          $type_settings = $this->settings[ $object_type ];
  86  
  87          $this->pending_objects[ $object_type ] ??= array();
  88  
  89          foreach ( $object_ids as $object_id ) {
  90              // Keyed by ID for faster lookup.
  91              $this->pending_objects[ $object_type ][ $object_id ] ??= 1;
  92          }
  93  
  94          add_filter( $type_settings['filter'], $type_settings['callback'], 10, 5 );
  95  
  96          /**
  97           * Fires after objects are added to the metadata lazy-load queue.
  98           *
  99           * @since 4.5.0
 100           *
 101           * @param array                  $object_ids  Array of object IDs.
 102           * @param string                 $object_type Type of object being queued.
 103           * @param WP_Metadata_Lazyloader $lazyloader  The lazy-loader object.
 104           */
 105          do_action( 'metadata_lazyloader_queued_objects', $object_ids, $object_type, $this );
 106      }
 107  
 108      /**
 109       * Resets lazy-load queue for a given object type.
 110       *
 111       * @since 4.5.0
 112       *
 113       * @param string $object_type Object type. Accepts 'comment' or 'term'.
 114       * @return void|WP_Error WP_Error on failure.
 115       */
 116  	public function reset_queue( $object_type ) {
 117          if ( ! isset( $this->settings[ $object_type ] ) ) {
 118              return new WP_Error( 'invalid_object_type', __( 'Invalid object type.' ) );
 119          }
 120  
 121          $type_settings = $this->settings[ $object_type ];
 122  
 123          $this->pending_objects[ $object_type ] = array();
 124          remove_filter( $type_settings['filter'], $type_settings['callback'] );
 125      }
 126  
 127      /**
 128       * Lazy-loads term meta for queued terms.
 129       *
 130       * This method is public so that it can be used as a filter callback. As a rule, there
 131       * is no need to invoke it directly.
 132       *
 133       * @since 4.5.0
 134       * @deprecated 6.3.0 Use WP_Metadata_Lazyloader::lazyload_meta_callback() instead.
 135       *
 136       * @param mixed $check The `$check` param passed from the 'get_term_metadata' hook.
 137       * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be
 138       *               another value if filtered by a plugin.
 139       */
 140  	public function lazyload_term_meta( $check ) {
 141          _deprecated_function( __METHOD__, '6.3.0', 'WP_Metadata_Lazyloader::lazyload_meta_callback' );
 142          return $this->lazyload_meta_callback( $check, 0, '', false, 'term' );
 143      }
 144  
 145      /**
 146       * Lazy-loads comment meta for queued comments.
 147       *
 148       * This method is public so that it can be used as a filter callback. As a rule, there is no need to invoke it
 149       * directly, from either inside or outside the `WP_Query` object.
 150       *
 151       * @since 4.5.0
 152       * @deprecated 6.3.0 Use WP_Metadata_Lazyloader::lazyload_meta_callback() instead.
 153       *
 154       * @param mixed $check The `$check` param passed from the {@see 'get_comment_metadata'} hook.
 155       * @return mixed The original value of `$check`, so as not to short-circuit `get_comment_metadata()`.
 156       */
 157  	public function lazyload_comment_meta( $check ) {
 158          _deprecated_function( __METHOD__, '6.3.0', 'WP_Metadata_Lazyloader::lazyload_meta_callback' );
 159          return $this->lazyload_meta_callback( $check, 0, '', false, 'comment' );
 160      }
 161  
 162      /**
 163       * Lazy-loads meta for queued objects.
 164       *
 165       * This method is public so that it can be used as a filter callback. As a rule, there
 166       * is no need to invoke it directly.
 167       *
 168       * @since 6.3.0
 169       *
 170       * @param mixed  $check     The `$check` param passed from the 'get_*_metadata' hook.
 171       * @param int    $object_id ID of the object metadata is for.
 172       * @param string $meta_key  Unused.
 173       * @param bool   $single    Unused.
 174       * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
 175       *                          or any other object type with an associated meta table.
 176       * @return mixed In order not to short-circuit `get_metadata()`. Generally, this is `null`, but it could be
 177       *               another value if filtered by a plugin.
 178       */
 179  	public function lazyload_meta_callback( $check, $object_id, $meta_key, $single, $meta_type ) {
 180          if ( empty( $this->pending_objects[ $meta_type ] ) ) {
 181              return $check;
 182          }
 183  
 184          $object_ids = array_keys( $this->pending_objects[ $meta_type ] );
 185          if ( $object_id && ! in_array( $object_id, $object_ids, true ) ) {
 186              $object_ids[] = $object_id;
 187          }
 188  
 189          update_meta_cache( $meta_type, $object_ids );
 190  
 191          // No need to run again for this set of objects.
 192          $this->reset_queue( $meta_type );
 193  
 194          return $check;
 195      }
 196  }


Generated : Fri Sep 18 08:20:28 2026 Cross-referenced by PHPXref