Ticket #16574: 16574.5.diff

File 16574.5.diff, 7.8 KB (added by scribu, 15 months ago)

Introduce _WP_Post_Wrapper class

Line 
1diff --git wp-includes/nav-menu-template.php wp-includes/nav-menu-template.php
2index 1dfc661..4789fc4 100644
3--- wp-includes/nav-menu-template.php
4+++ wp-includes/nav-menu-template.php
5@@ -287,8 +287,6 @@ function _wp_menu_item_classes_by_context( &$menu_items ) {
6                                }
7                        }
8                }
9-       } elseif ( ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) ) {
10-               _get_post_ancestors( $queried_object );
11        } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) {
12                $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy );
13                $term_to_ancestor = array();
14@@ -419,7 +417,7 @@ function _wp_menu_item_classes_by_context( &$menu_items ) {
15                                        'post_type' == $parent_item->type &&
16                                        ! empty( $queried_object->post_type ) &&
17                                        is_post_type_hierarchical( $queried_object->post_type ) &&
18-                                       in_array( $parent_item->object_id, $queried_object->ancestors ) &&
19+                                       in_array( $parent_item->object_id, get_post_ancestors( $queried_object ) ) &&
20                                        $parent_item->object != $queried_object->ID
21                                ) ||
22 
23diff --git wp-includes/post-template.php wp-includes/post-template.php
24index 7a60672..b2a63fa 100644
25--- wp-includes/post-template.php
26+++ wp-includes/post-template.php
27@@ -1035,8 +1035,7 @@ class Walker_Page extends Walker {
28                $css_class = array('page_item', 'page-item-'.$page->ID);
29                if ( !empty($current_page) ) {
30                        $_current_page = get_page( $current_page );
31-                       _get_post_ancestors($_current_page);
32-                       if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) )
33+                       if ( in_array( $page->ID, get_post_ancestors( $current_page ) ) )
34                                $css_class[] = 'current_page_ancestor';
35                        if ( $page->ID == $current_page )
36                                $css_class[] = 'current_page_item';
37diff --git wp-includes/post.php wp-includes/post.php
38index 3fcaa46..253ba43 100644
39--- wp-includes/post.php
40+++ wp-includes/post.php
41@@ -378,7 +378,6 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
42                else
43                        return $null;
44        } elseif ( is_object($post) && empty($post->filter) ) {
45-               _get_post_ancestors($post);
46                $_post = sanitize_post($post, 'raw');
47                wp_cache_add($post->ID, $_post, 'posts');
48        } elseif ( is_object($post) && 'raw' == $post->filter ) {
49@@ -394,7 +393,6 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
50                        $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id));
51                        if ( ! $_post )
52                                return $null;
53-                       _get_post_ancestors($_post);
54                        $_post = sanitize_post($_post, 'raw');
55                        wp_cache_add($_post->ID, $_post, 'posts');
56                }
57@@ -404,6 +402,7 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
58                $_post = sanitize_post($_post, $filter);
59 
60        if ( $output == OBJECT ) {
61+               $_post = new _WP_Post_Wrapper( $_post );
62                return $_post;
63        } elseif ( $output == ARRAY_A ) {
64                $__post = get_object_vars($_post);
65@@ -417,6 +416,41 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
66 }
67 
68 /**
69+ * Wrapper class to preserve back-compat for $post->ancestors
70+ *
71+ * @since 3.4.0
72+ */
73+class _WP_Post_Wrapper {
74+
75+       private $post;
76+
77+       function __construct( $post ) {
78+               $this->post = $post;
79+       }
80+
81+       function __isset( $key ) {
82+               if ( 'ancestors' == $key )
83+                       return true;
84+
85+               return isset( $this->post->$key );
86+       }
87+
88+       function __get( $key ) {
89+               if ( 'ancestors' == $key )
90+                       return get_post_ancestors( $this->post );
91+
92+               return $this->post->$key;
93+       }
94+
95+       function __set( $key, $value ) {
96+               if ( 'ancestors' == $key )
97+                       return;
98+
99+               $this->post->$key = $value;
100+       }
101+}
102+
103+/**
104  * Retrieve ancestors of a post.
105  *
106  * @since 2.5.0
107@@ -424,13 +458,31 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
108  * @param int|object $post Post ID or post object
109  * @return array Ancestor IDs or empty array if none are found.
110  */
111-function get_post_ancestors($post) {
112-       $post = get_post($post);
113+function get_post_ancestors( $post ) {
114+       $post = get_post( $post );
115+
116+       if ( !$post )
117+               return false;
118+
119+       if ( ! $ancestors = wp_cache_get( $post->ID, 'post_ancestors' ) ) {
120+               $ancestors = array();
121+
122+               if ( !empty( $post->post_parent ) && $post->ID != $post->post_parent ) {
123+                       $id = $ancestors[] = $post->post_parent;
124+
125+                       while ( $ancestor = get_post( $id ) ) {
126+                               // Loop detection: If the ancestor has been seen before, break.
127+                               if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) )
128+                                       break;
129 
130-       if ( !empty($post->ancestors) )
131-               return $post->ancestors;
132+                               $id = $ancestors[] = $ancestor->post_parent;
133+                       }
134+               }
135 
136-       return array();
137+               wp_cache_add( $post->ID, $ancestors, 'post_ancestors' );
138+       }
139+
140+       return $ancestors;
141 }
142 
143 /**
144@@ -3300,13 +3352,8 @@ function get_page_uri($page) {
145                $page = get_page($page);
146        $uri = $page->post_name;
147 
148-       // A page cannot be it's own parent.
149-       if ( $page->post_parent == $page->ID )
150-               return $uri;
151-
152-       while ($page->post_parent != 0) {
153-               $page = get_page($page->post_parent);
154-               $uri = $page->post_name . "/" . $uri;
155+       foreach ( $page->ancestors as $parent ) {
156+               $uri = get_page($parent)->post_name . "/" . $uri;
157        }
158 
159        return $uri;
160@@ -4613,45 +4660,6 @@ function _save_post_hook($post_id, $post) {
161 }
162 
163 /**
164- * Retrieve post ancestors and append to post ancestors property.
165- *
166- * Will only retrieve ancestors once, if property is already set, then nothing
167- * will be done. If there is not a parent post, or post ID and post parent ID
168- * are the same then nothing will be done.
169- *
170- * The parameter is passed by reference, so nothing needs to be returned. The
171- * property will be updated and can be referenced after the function is
172- * complete. The post parent will be an ancestor and the parent of the post
173- * parent will be an ancestor. There will only be two ancestors at the most.
174- *
175- * @since 2.5.0
176- * @access private
177- * @uses $wpdb
178- *
179- * @param object $_post Post data.
180- * @return null When nothing needs to be done.
181- */
182-function _get_post_ancestors(&$_post) {
183-       global $wpdb;
184-
185-       if ( isset($_post->ancestors) )
186-               return;
187-
188-       $_post->ancestors = array();
189-
190-       if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent )
191-               return;
192-
193-       $id = $_post->ancestors[] = $_post->post_parent;
194-       while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) {
195-               // Loop detection: If the ancestor has been seen before, break.
196-               if ( ( $ancestor == $_post->ID ) || in_array($ancestor,  $_post->ancestors) )
197-                       break;
198-               $id = $_post->ancestors[] = $ancestor;
199-       }
200-}
201-
202-/**
203  * Determines which fields of posts are to be saved in revisions.
204  *
205  * Does two things. If passed a post *array*, it will return a post array ready
206@@ -5338,4 +5346,4 @@ function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache
207 
208                update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
209        }
210-}
211\ No newline at end of file
212+}
213diff --git wp-includes/taxonomy.php wp-includes/taxonomy.php
214index 6334ee7..3da27dd 100644
215--- wp-includes/taxonomy.php
216+++ wp-includes/taxonomy.php
217@@ -3206,16 +3206,8 @@ function get_ancestors($object_id = 0, $object_type = '') {
218                        $ancestors[] = (int) $term->parent;
219                        $term = get_term($term->parent, $object_type);
220                }
221-       } elseif ( null !== get_post_type_object( $object_type ) ) {
222-               $object = get_post($object_id);
223-               if ( ! is_wp_error( $object ) && isset( $object->ancestors ) && is_array( $object->ancestors ) )
224-                       $ancestors = $object->ancestors;
225-               else {
226-                       while ( ! is_wp_error($object) && ! empty( $object->post_parent ) && ! in_array( $object->post_parent, $ancestors ) ) {
227-                               $ancestors[] = (int) $object->post_parent;
228-                               $object = get_post($object->post_parent);
229-                       }
230-               }
231+       } elseif ( post_type_exists( $object_type ) ) {
232+               $ancestors = get_post_ancestors($object_id);
233        }
234 
235        return apply_filters('get_ancestors', $ancestors, $object_id, $object_type);