#14329 closed defect (bug) (fixed)
current_page_ancestor not being set because $post->ancestors is not being cached
Reported by: | layotte | Owned by: | |
---|---|---|---|
Milestone: | 3.1 | Priority: | normal |
Severity: | normal | Version: | 3.0 |
Component: | Cache API | Keywords: | has-patch needs-testing |
Focuses: | Cc: |
Description
I noticed a weird problem where current_page_ancestor class was not being attached to the appropriate <li> from a wp_list_pages on a WPMS site.
I was running this wp_list_pages query:
$children = wp_list_pages("title_li=&child_of=".$ugce."&echo=0&depth=1&sort_column=menu_order"); $ugce is a dynamic parent ID
the current_page_item and current_page_parent classes are being set. However, when I go to a grandchild, the current_page_ancestor is not being set.
I looked through core and found in classes.php (line 1192 - WP3.0) is calling $_current_page = get_page($current_page) and testing if $_current_page->ancestors is set. It isn't set (for some reason), so it skips to the next test.
I went over to post.php to where get_page merely calls get_post, and noticed that at line 337, get_posts checks to see if the $post_id is already in the wp_cache:
if ( ! $_post = wp_cache_get($post_id, 'posts') )
I assume that the current post would be in the wp_cache, so it merely returns the cached results.
That made me think that perhaps the cache does not have the ancestors in it. So I ran a test to find out more.
I setup my theme to output the post ID, the post ancestors, the array from get_post, the array from wp_cache_get and then I cleared the wp_cache and ran the same output to see how it changed.
before the wp_cache_flush(), the get_post and wp_cache_get does not contain the post->ancestors. After the wp_cache_flush() they both contain the post->ancestors.
I suspect that there is a place where the post is being added to cache without the ancestors and then later when the ancestors are being check from the cache it returns as if there are none.
This is my php code:
<?php echo "<strong>Post ID: </strong>" . $post->ID; ?> <?php echo '<br><br><strong>$post->ancestors: </strong>'; print_r($post->ancestors); ?> <?php $page = get_page( $post->ID ); ?> <?php echo "<br><br><strong>print_r get_page: </strong>"; print_r($page); ?> <?php $_page = wp_cache_get($post->ID, 'posts'); ?> <?php echo "<br><br><strong>print_r wp_cache_get: </strong>"; print_r($_page); ?> <?php echo "<br><br><strong>wp_cache_flush</strong"; wp_cache_flush(); ?> <?php echo "<br><br><strong>Post ID: </strong>" . $post->ID; ?> <?php echo '<br><br><strong>$post->ancestors: </strong>'; print_r($post->ancestors); ?> <?php $page = get_page( $post->ID ); ?> <?php echo "<br><br><strong>print_r get_page: </strong>"; print_r($page); ?> <?php $_page = wp_cache_get($post->ID, 'posts'); ?> <?php echo "<br><br><strong>print_r wp_cache_get: </strong>"; print_r($_page); ?>
And this is the output for my given page:
Post ID: 222 $post->ancestors: Array ( [0] => 216 [1] => 21 [2] => 17 ) print_r get_page: stdClass Object ( [ID] => 222 [post_author] => 1 [post_date] => 2010-07-15 19:09:48 [post_date_gmt] => 2010-07-15 19:09:48 [post_content] => Ed.S. [post_title] => Ed.S. [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ed-s [to_ping] => [pinged] => [post_modified] => 2010-07-16 12:10:59 [post_modified_gmt] => 2010-07-16 12:10:59 [post_content_filtered] => [post_parent] => 216 [guid] => http://webdev.coe.uga.edu/lle/ [menu_order] => 0 [post_type] => page [post_mime_type] => [comment_count] => 0 [filter] => raw ) print_r wp_cache_get: stdClass Object ( [ID] => 222 [post_author] => 1 [post_date] => 2010-07-15 19:09:48 [post_date_gmt] => 2010-07-15 19:09:48 [post_content] => Ed.S. [post_title] => Ed.S. [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ed-s [to_ping] => [pinged] => [post_modified] => 2010-07-16 12:10:59 [post_modified_gmt] => 2010-07-16 12:10:59 [post_content_filtered] => [post_parent] => 216 [guid] => http://webdev.coe.uga.edu/lle/ [menu_order] => 0 [post_type] => page [post_mime_type] => [comment_count] => 0 [filter] => raw ) wp_cache_flush Post ID: 222 $post->ancestors: Array ( [0] => 216 [1] => 21 [2] => 17 ) print_r get_page: stdClass Object ( [ID] => 222 [post_author] => 1 [post_date] => 2010-07-15 19:09:48 [post_date_gmt] => 2010-07-15 19:09:48 [post_content] => Ed.S. [post_title] => Ed.S. [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ed-s [to_ping] => [pinged] => [post_modified] => 2010-07-16 12:10:59 [post_modified_gmt] => 2010-07-16 12:10:59 [post_content_filtered] => [post_parent] => 216 [guid] => http://webdev.coe.uga.edu/lle/ [menu_order] => 0 [post_type] => page [post_mime_type] => [comment_count] => 0 [ancestors] => Array ( [0] => 216 [1] => 21 [2] => 17 ) [filter] => raw ) print_r wp_cache_get: stdClass Object ( [ID] => 222 [post_author] => 1 [post_date] => 2010-07-15 19:09:48 [post_date_gmt] => 2010-07-15 19:09:48 [post_content] => Ed.S. [post_title] => Ed.S. [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ed-s [to_ping] => [pinged] => [post_modified] => 2010-07-16 12:10:59 [post_modified_gmt] => 2010-07-16 12:10:59 [post_content_filtered] => [post_parent] => 216 [guid] => http://webdev.coe.uga.edu/lle/ [menu_order] => 0 [post_type] => page [post_mime_type] => [comment_count] => 0 [ancestors] => Array ( [0] => 216 [1] => 21 [2] => 17 ) [filter] => raw )
Attachments (1)
Change History (11)
#2
@
14 years ago
- Keywords needs-patch added; current_page_ancestor $post->ancestors removed
- Milestone changed from Awaiting Review to 3.1
#3
@
14 years ago
Still testing, I tried wp_cache_flush at the beginning of my template file and it still had the same results as above.
I actually have two wp_list_pages() calls in this template. The first is a left sidebar, with a depth=1, so I can get all the immediate children of a specific page. The second is a depth=2, to get all the children of the ancestor page.
In other words my structure is:
Academic Programs
I started moving the wp_cache_flush() down until I got to my second wp_list_pages. If I put wp_cache_flush() immediately after the wp_list_pages then the my first two results (above) include the $post->ancestors...
still digging... just reporting as I find stuff.
@
14 years ago
Well, this is my simple fix... I just added _get_post_ancestors($_current_page); into the start_el function of classes, before testing if ancestors.
#7
@
14 years ago
There are other tickets with patches that fix this down in get_post(), but those are probably too much for 3.1.
WP_Query does some up-front caching of posts and ancestors. We really should cache ancestors only when required.