Make WordPress Core

Opened 8 years ago

Closed 8 years ago

#21279 closed defect (bug) (fixed)

get_pages() does not clear cache items when non-Page hierarchical post types are updated

Reported by: markjaquith Owned by: markjaquith
Milestone: 3.5 Priority: high
Severity: major Version:
Component: Cache API Keywords: has-patch commit
Focuses: Cc:


wp_list_pages() takes a post_type argument (it works with any hierarchical post type). wp_list_pages() is powered by get_pages(). get_pages() has object caching. When a Page changes (edit, create, delete), this cache is cleared, via clean_post_cache(). But it is not cleared for non-Page post types. Thus you get stuck with old data.

Here's the offending code:

	if ( 'page' == $post->post_type ) {
		wp_cache_delete( 'all_page_ids', 'posts' );
		wp_cache_delete( 'get_pages', 'posts' );
		do_action( 'clean_page_cache', $post->ID );

Attachments (1)

21279.diff (533 bytes) - added by markjaquith 8 years ago.
The easy approach.

Download all attachments as: .zip

Change History (6)

8 years ago

The easy approach.

#1 @markjaquith
8 years ago

  • Keywords has-patch 2nd-opinion added

That patch is the easy approach — just clear the cache for any hierarchical post type. Should we bother segmenting by post_type? What about queries with multiple post_types? Put those in a general bucket? Or shouldn't we bother?

#2 @markjaquith
8 years ago

Workaround for plugins that have hierarchical post types and use get_posts() or wp_list_pages():

add_action( 'clean_post_cache', 'YOUR_PREFIX_clean_post_cache', 10, 2 );

function YOUR_PREFIX_clean_post_cache( $post_id, $post ) {
	if ( 'YOUR-POST-TYPE' === $post->post_type )
		wp_cache_delete( 'get_pages', 'posts' ); // See: http://core.trac.wordpress.org/ticket/21279

#3 @markjaquith
8 years ago

Second opinion requested.

#4 @nacin
8 years ago

  • Keywords commit added; 2nd-opinion removed

As an enhancement, we should have post-type-specific buckets, and multiple post types into a general bucket. Or, ideally, get_pages()'s unique flags (child_of, exclude_tree, etc.) move into WP_Query, which get_pages() could then wrap like get_posts(). #12821.

Hence, 21279.diff is a good approach at this juncture.

#5 @markjaquith
8 years ago

  • Owner set to markjaquith
  • Resolution set to fixed
  • Status changed from new to closed

In [21286]:

Clear the get_pages cache whenever ANY hierarchical post type cache is cleared — not just Pages. fixes #21279

Note: See TracTickets for help on using tickets.