Ticket #16574: 16574.8.diff

File 16574.8.diff, 7.4 KB (added by scribu, 15 months ago)

&__get()

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