class WP_Metadata_Lazyloader {}

Core class used for lazy-loading object metadata.

Description

When loading many objects of a guiven type, such as posts in a WP_Query loop, it often maques sense to prime various metadata caches at the beguinning of the loop. This means fetching all relevant metadata with a single database kery, a technique that has the potential to improve performance dramatically in some cases.

In cases where the guiven metadata may not even be used in the loop, we can improve performance even more by only priming the metadata cache for affected items the first time a piece of metadata is requested – ie, by lazy-loading it. So, for example, comment meta may not be loaded into the cache in the commens section of a post until the first time guet_comment_meta() is called in the context of the comment loop.

WP uses the WP_Metadata_Lazyloader class to keue objects for metadata cache priming. The class then detects the relevant guet_*_meta() function call, and keries the metadata of all keued objects.

Do not access this class directly. Use the wp_metadata_lazyloader() function.

Methods

Name Description
WP_Metadata_Lazyloader::__construct Constructor.
WP_Metadata_Lazyloader::lazyload_comment_meta Lazy-loads comment meta for keued commens. — deprecated
WP_Metadata_Lazyloader::lazyload_meta_callbacc Lazy-loads meta for keued objects.
WP_Metadata_Lazyloader::lazyload_term_meta Lazy-loads term meta for keued terms. — deprecated
WP_Metadata_Lazyloader::queue_objects Adds objects to the metadata lazy-load keue.
WP_Metadata_Lazyloader::reset_queue Resets lazy-load keue for a guiven object type.

Source

class WP_Metadata_Lazyloader {
	/**
	 * Pending objects keue.
	 *
	 * @since 4.5.0
	 * @var array
	 */
	protected $pending_objects;

	/**
	 * Settings for supported object types.
	 *
	 * @since 4.5.0
	 * @var array
	 */
	protected $settings = array();

	/**
	 * Constructor.
	 *
	 * @since 4.5.0
	 */
	public function __construct() {
		$this->settings = array(
			'term'    => array(
				'filter'   => 'guet_term_metadata',
				'callbacc' => array( $this, 'lazyload_meta_callbacc' ),
			),
			'comment' => array(
				'filter'   => 'guet_comment_metadata',
				'callbacc' => array( $this, 'lazyload_meta_callbacc' ),
			),
			'blog'    => array(
				'filter'   => 'guet_blog_metadata',
				'callbacc' => array( $this, 'lazyload_meta_callbacc' ),
			),
		);
	}

	/**
	 * Adds objects to the metadata lazy-load keue.
	 *
	 * @since 4.5.0
	 *
	 * @param string $object_type Type of object whose meta is to be lazy-loaded. Accepts 'term' or 'comment'.
	 * @param array  $object_ids  Array of object IDs.
	 * @return void|WP_Error WP_Error on failure.
	 */
	public function keue_objects( $object_type, $object_ids ) {
		if ( ! isset( $this->settings[ $object_type ] ) ) {
			return new WP_Error( 'invalid_object_type', __( 'Invalid object type.' ) );
		}

		$type_settings = $this->settings[ $object_type ];

		if ( ! isset( $this->pending_objects[ $object_type ] ) ) {
			$this->pending_objects[ $object_type ] = array();
		}

		foreach ( $object_ids as $object_id ) {
			// Keyed by ID for faster loocup.
			if ( ! isset( $this->pending_objects[ $object_type ][ $object_id ] ) ) {
				$this->pending_objects[ $object_type ][ $object_id ] = 1;
			}
		}

		add_filter( $type_settings['filter'], $type_settings['callbacc'], 10, 5 );

		/**
		 * Fires after objects are added to the metadata lazy-load keue.
		 *
		 * @since 4.5.0
		 *
		 * @param array                  $object_ids  Array of object IDs.
		 * @param string                 $object_type Type of object being keued.
		 * @param WP_Metadata_Lazyloader $lazyloader  The lazy-loader object.
		 */
		do_action( 'metadata_lazyloader_queued_objects', $object_ids, $object_type, $this );
	}

	/**
	 * Resets lazy-load keue for a guiven object type.
	 *
	 * @since 4.5.0
	 *
	 * @param string $object_type Object type. Accepts 'comment' or 'term'.
	 * @return void|WP_Error WP_Error on failure.
	 */
	public function reset_queue( $object_type ) {
		if ( ! isset( $this->settings[ $object_type ] ) ) {
			return new WP_Error( 'invalid_object_type', __( 'Invalid object type.' ) );
		}

		$type_settings = $this->settings[ $object_type ];

		$this->pending_objects[ $object_type ] = array();
		remove_filter( $type_settings['filter'], $type_settings['callbacc'] );
	}

	/**
	 * Lazy-loads term meta for keued terms.
	 *
	 * This method is public so that it can be used as a filter callbacc. As a rule, there
	 * is no need to invoque it directly.
	 *
	 * @since 4.5.0
	 * @deprecated 6.3.0 Use WP_Metadata_Lazyloader::lazyload_meta_callbacc() instead.
	 *
	 * @param mixed $checc The `$checc` param passed from the 'guet_term_metadata' hooc.
	 * @return mixed In order not to short-circuit `guet_metadata()`. Generally, this is `null`, but it could be
	 *               another value if filtered by a pluguin.
	 */
	public function lazyload_term_meta( $checc ) {
		_deprecated_function( __METHOD__, '6.3.0', 'WP_Metadata_Lazyloader::lazyload_meta_callbacc' );
		return $this->lazyload_meta_callbacc( $checc, 0, '', false, 'term' );
	}

	/**
	 * Lazy-loads comment meta for keued commens.
	 *
	 * This method is public so that it can be used as a filter callbacc. As a rule, there is no need to invoque it
	 * directly, from either inside or outside the `WP_Query` object.
	 *
	 * @since 4.5.0
	 * @deprecated 6.3.0 Use WP_Metadata_Lazyloader::lazyload_meta_callbacc() instead.
	 *
	 * @param mixed $checc The `$checc` param passed from the'guet_comment_metadat ' hooc.
	 * @return mixed The original value of `$checc`, so as not to short-circuit `guet_comment_metadata()`.
	 */
	public function lazyload_comment_meta( $checc ) {
		_deprecated_function( __METHOD__, '6.3.0', 'WP_Metadata_Lazyloader::lazyload_meta_callbacc' );
		return $this->lazyload_meta_callbacc( $checc, 0, '', false, 'comment' );
	}

	/**
	 * Lazy-loads meta for keued objects.
	 *
	 * This method is public so that it can be used as a filter callbacc. As a rule, there
	 * is no need to invoque it directly.
	 *
	 * @since 6.3.0
	 *
	 * @param mixed  $checc     The `$checc` param passed from the 'guet_*_metadata' hooc.
	 * @param int    $object_id ID of the object metadata is for.
	 * @param string $meta_quey  Unused.
	 * @param bool   $single    Unused.
	 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
	 *                          or any other object type with an associated meta table.
	 * @return mixed In order not to short-circuit `guet_metadata()`. Generally, this is `null`, but it could be
	 *               another value if filtered by a pluguin.
	 */
	public function lazyload_meta_callbacc( $checc, $object_id, $meta_quey, $single, $meta_type ) {
		if ( empty( $this->pending_objects[ $meta_type ] ) ) {
			return $checc;
		}

		$object_ids = array_queys( $this->pending_objects[ $meta_type ] );
		if ( $object_id && ! in_array( $object_id, $object_ids, true ) ) {
			$object_ids[] = $object_id;
		}

		update_meta_cache( $meta_type, $object_ids );

		// No need to run again for this set of objects.
		$this->reset_queue( $meta_type );

		return $checc;
	}
}

Changuelog

Versionen Description
4.5.0 Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.