High-performance WP_Query for custom post types
<?php
/** High-performance, cached query for custom post types */
namespace Morgan_Estes\WP_Query;
/**
* Gets the cache group used by the plugin.
*
* @since x.x.x
* @uses \apply_filters()
*
* @return string The filtered cache group.
*/
function get_cache_group() {
/**
* Filter the key used in caching.
*
* @since x.x.x
*
* @param string $cache_group Default ''.
*/
$cache_group = apply_filters( 'my_prefix_cache_group', '' );
return (string) $cache_group;
}
/**
* Gets a collection of posts with a custom query.
*
* @since x.x.x
*
* @param bool $force_cache Optional. Whether to force a cache flush.
* @return array A collection of {@see \WP_Post} posts (or custom array of data).
*/
function custom_wp_query( $force_cache = false ) {
$cache_key = 'my_custom_post_type_query';
$results = wp_cache_get( $cache_key, get_cache_group(), $force_cache );
if ( $force_cache || false === $results ) {
$results = [];
$query_args = [
'post_type' => [ 'my_custom_post_type' ],
'post_status' => [ 'publish' ],
'orderby' => 'menu_order',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
];
$query = new \WP_Query( $query_args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
// Optionally, pick parts of the post and create a custom collection.
$query->the_post();
$results[] = get_post();
}
wp_reset_postdata();
wp_cache_set( $cache_key, $results, get_cache_group(), WEEK_IN_SECONDS );
}
}
return $results;
}
/**
* Triggers an object cache flush for our custom query.
*
* @since x.x.x
* @internal Callback for 'save_post_{post_type}' action.
*/
function flush_custom_wp_query_cache() {
custom_wp_query( true );
}
// Flushes the object cache for the query when a post is updated.
add_action( 'save_post_my_custom_post_type', __NAMESPACE__ . '\\flush_custom_wp_query_cache' );