WordPress.org

Make WordPress Core

Changeset 21559


Ignore:
Timestamp:
08/20/12 19:47:52 (20 months ago)
Author:
ryan
Message:

Introduce WP_Post class. Clean up ancestors handling. Props scribu, toppa. fixes #10381 see #21309

Location:
trunk/wp-includes
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/load.php

    r21484 r21559  
    411411    if ( function_exists( 'wp_cache_add_global_groups' ) ) { 
    412412        wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); 
    413         wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); 
     413        wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins', 'post_ancestors' ) ); 
    414414    } 
    415415} 
  • trunk/wp-includes/nav-menu-template.php

    r21252 r21559  
    287287            } 
    288288        } 
    289     } elseif ( ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) ) { 
    290         _get_post_ancestors( $queried_object ); 
    291289    } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) { 
    292290        $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy ); 
  • trunk/wp-includes/post-template.php

    r21333 r21559  
    10171017        if ( !empty($current_page) ) { 
    10181018            $_current_page = get_page( $current_page ); 
    1019             _get_post_ancestors($_current_page); 
    1020             if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) ) 
     1019            if ( in_array( $page->ID, $_current_page->ancestors ) ) 
    10211020                $css_class[] = 'current_page_ancestor'; 
    10221021            if ( $page->ID == $current_page ) 
  • trunk/wp-includes/post.php

    r21553 r21559  
    376376 * @param string $output Optional, default is Object. Either OBJECT, ARRAY_A, or ARRAY_N. 
    377377 * @param string $filter Optional, default is raw. 
    378  * @return mixed Post data 
    379  */ 
    380 function &get_post(&$post, $output = OBJECT, $filter = 'raw') { 
    381     global $wpdb; 
     378 * @return mixed Post data or null on failure 
     379 */ 
     380function &get_post( &$post, $output = OBJECT, $filter = 'raw' ) { 
    382381    $null = null; 
    383382 
    384     if ( empty($post) ) { 
    385         if ( isset($GLOBALS['post']) ) 
    386             $_post = & $GLOBALS['post']; 
    387         else 
    388             return $null; 
    389     } elseif ( is_object($post) && empty($post->filter) ) { 
    390         _get_post_ancestors($post); 
    391         $_post = sanitize_post($post, 'raw'); 
    392         wp_cache_add($post->ID, $_post, 'posts'); 
    393     } elseif ( is_object($post) && 'raw' == $post->filter ) { 
     383    if ( empty( $post ) && isset( $GLOBALS['post'] ) ) { 
     384        $_post = & $GLOBALS['post']; 
     385    } elseif ( is_a( $post, 'WP_Post' ) ) { 
    394386        $_post = $post; 
     387    } elseif ( is_object( $post ) ) { 
     388        if ( empty( $post->filter ) ) { 
     389            $_post = sanitize_post( $post, 'raw' ); 
     390            wp_cache_add( $post->ID, $_post, 'posts' ); 
     391            $_post = new WP_Post( $_post ); 
     392        } elseif ( 'raw' == $post->filter ) { 
     393            $_post = new WP_Post( $post ); 
     394        } else { 
     395            $_post = WP_Post::get_instance( $post->ID ); 
     396        } 
    395397    } else { 
    396         if ( is_object($post) ) 
    397             $post_id = $post->ID; 
    398         else 
    399             $post_id = $post; 
    400  
    401         $post_id = (int) $post_id; 
    402         if ( ! $_post = wp_cache_get($post_id, 'posts') ) { 
    403             $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id)); 
    404             if ( ! $_post ) 
    405                 return $null; 
    406             _get_post_ancestors($_post); 
    407             $_post = sanitize_post($_post, 'raw'); 
    408             wp_cache_add($_post->ID, $_post, 'posts'); 
    409         } 
    410     } 
    411  
    412     if ($filter != 'raw') 
    413         $_post = sanitize_post($_post, $filter); 
    414  
    415     if ( $output == OBJECT ) { 
    416         return $_post; 
    417     } elseif ( $output == ARRAY_A ) { 
    418         $__post = get_object_vars($_post); 
     398        $_post = WP_Post::get_instance( $post ); 
     399    } 
     400 
     401    if ( !$_post ) 
     402        return $null; 
     403 
     404    $_post = $_post->filter( $filter ); 
     405 
     406    if ( $output == ARRAY_A ) { 
     407        $__post = $_post->to_array(); 
    419408        return $__post; 
    420409    } elseif ( $output == ARRAY_N ) { 
    421         $__post = array_values(get_object_vars($_post)); 
     410        $__post = array_values( $_post->to_array() ); 
    422411        return $__post; 
    423     } else { 
    424         return $_post; 
     412    } 
     413 
     414    return $_post; 
     415} 
     416 
     417/** 
     418 * WordPress Post class. 
     419 * 
     420 * @since 3.5.0 
     421 * 
     422 * @property $ID; 
     423 * @property $post_author; 
     424 * @property $post_date; 
     425 * @property $post_date_gmt; 
     426 * @property $post_content; 
     427 * @property $post_title; 
     428 * @property $post_excerpt; 
     429 * @property $post_status; 
     430 * @property $comment_status; 
     431 * @property $ping_status; 
     432 * @property $post_password; 
     433 * @property $post_name; 
     434 * @property $to_ping; 
     435 * @property $pinged; 
     436 * @property $post_modified; 
     437 * @property $post_modified_gmt; 
     438 * @property $post_content_filtered; 
     439 * @property $post_parent; 
     440 * @property $guid; 
     441 * @property $menu_order; 
     442 * @property $post_type; 
     443 * @property $post_mime_type; 
     444 * @property $comment_count; 
     445 * @property $ancestors; 
     446 */ 
     447final class WP_Post { 
     448 
     449    public $filter; 
     450 
     451    public static function get_instance( $post_id ) { 
     452        global $wpdb; 
     453 
     454        $post_id = (int) $post_id; 
     455        if ( !$post_id ) 
     456            return false; 
     457 
     458        if ( ! $_post = wp_cache_get( $post_id, 'posts' ) ) { 
     459            $_post = $wpdb->get_row( $wpdb->prepare( " 
     460                SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1 
     461            ", $post_id ) ); 
     462 
     463            if ( ! $_post ) 
     464                return false; 
     465 
     466            $_post = sanitize_post( $_post, 'raw' ); 
     467            wp_cache_add( $_post->ID, $_post, 'posts' ); 
     468        } 
     469 
     470        return new WP_Post( $_post ); 
     471    } 
     472 
     473    public function __construct( $post ) { 
     474        foreach ( get_object_vars( $post ) as $key => $value ) 
     475            $this->$key = $value; 
     476    } 
     477 
     478    public function __isset( $key ) { 
     479        if ( 'ancestors' == $key ) 
     480            return true; 
     481 
     482        return metadata_exists( 'post', $this->ID, $key ); 
     483    } 
     484 
     485    public function &__get( $key ) { 
     486        if ( 'ancestors' == $key ) { 
     487            $value = get_post_ancestors( $this ); 
     488        } else { 
     489            $value = get_post_meta( $this->ID, $key, true ); 
     490        } 
     491 
     492        if ( $this->filter ) { 
     493            $value = sanitize_post_field( $key, $value, $this->ID, $this->filter ); 
     494        } 
     495 
     496        return $value; 
     497    } 
     498 
     499    public function filter( $filter ) { 
     500        if ( $this->filter == $filter ) 
     501            return $this; 
     502 
     503        if ( $filter == 'raw' ) 
     504            return self::get_instance( $this->ID ); 
     505 
     506        return sanitize_post( $this, $filter ); 
     507    } 
     508 
     509    public function to_array() { 
     510        $post = get_object_vars( $this ); 
     511        $post['ancestors'] = array(); 
     512 
     513        return $post; 
    425514    } 
    426515} 
     
    434523 * @return array Ancestor IDs or empty array if none are found. 
    435524 */ 
    436 function get_post_ancestors($post) { 
    437     $post = get_post($post); 
    438  
    439     if ( ! isset( $post->ancestors ) ) 
    440         _get_post_ancestors( $post ); 
    441  
    442     if ( ! empty( $post->ancestors ) ) 
    443         return $post->ancestors; 
    444  
    445     return array(); 
     525function get_post_ancestors( $post ) { 
     526    if ( ! $post ) 
     527        return false; 
     528 
     529    $post = get_post( $post ); 
     530 
     531    if ( ! $ancestors = wp_cache_get( $post->ID, 'post_ancestors' ) ) { 
     532        $ancestors = array(); 
     533 
     534        if ( !empty( $post->post_parent ) && $post->ID != $post->post_parent ) { 
     535            $id = $ancestors[] = $post->post_parent; 
     536 
     537            while ( $ancestor = get_post( $id ) ) { 
     538                // Loop detection: If the ancestor has been seen before, break. 
     539                if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) ) 
     540                    break; 
     541 
     542                $id = $ancestors[] = $ancestor->post_parent; 
     543            } 
     544        } 
     545 
     546        wp_cache_add( $post->ID, $ancestors, 'post_ancestors' ); 
     547    } 
     548 
     549    return $ancestors; 
    446550} 
    447551 
     
    461565 * @param id $post Post ID 
    462566 * @param string $context Optional. How to filter the field. Default is display. 
    463  * @return WP_Error|string Value in post field or WP_Error on failure 
     567 * @return bool|string False on failure or returns the value in post field 
    464568 */ 
    465569function get_post_field( $field, $post, $context = 'display' ) { 
    466     $post = (int) $post; 
    467570    $post = get_post( $post ); 
    468571 
    469     if ( is_wp_error($post) ) 
    470         return $post; 
    471  
    472     if ( !is_object($post) ) 
     572    if ( !$post ) 
    473573        return ''; 
    474574 
     
    33643464    $uri = $page->post_name; 
    33653465 
    3366     // A page cannot be it's own parent. 
    3367     if ( $page->post_parent == $page->ID ) 
    3368         return $uri; 
    3369  
    3370     while ($page->post_parent != 0) { 
    3371         $page = get_page($page->post_parent); 
    3372         $uri = $page->post_name . "/" . $uri; 
     3466    foreach ( $page->ancestors as $parent ) { 
     3467        $uri = get_page($parent)->post_name . "/" . $uri; 
    33733468    } 
    33743469 
     
    34243519    if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) { 
    34253520        if ( is_array($cache) && isset( $cache[ $key ] ) ) { 
    3426             $pages = apply_filters('get_pages', $cache[ $key ], $r ); 
    3427             return $pages; 
     3521            // Convert to WP_Post instances 
     3522            $pages = array_map( 'get_post', $cache[ $key ] ); 
     3523 
     3524            return apply_filters( 'get_pages', $pages, $r ); 
    34283525        } 
    34293526    } 
     
    35983695    $cache[ $key ] = $pages; 
    35993696    wp_cache_set( 'get_pages', $cache, 'posts' ); 
     3697 
     3698    // Convert to WP_Post instances 
     3699    $pages = array_map( 'get_post', $pages ); 
    36003700 
    36013701    $pages = apply_filters('get_pages', $pages, $r); 
     
    46324732 
    46334733/** 
    4634  * Retrieve post ancestors and append to post ancestors property. 
    4635  * 
    4636  * Will only retrieve ancestors once, if property is already set, then nothing 
    4637  * will be done. If there is not a parent post, or post ID and post parent ID 
    4638  * are the same then nothing will be done. 
    4639  * 
    4640  * The parameter is passed by reference, so nothing needs to be returned. The 
    4641  * property will be updated and can be referenced after the function is 
    4642  * complete. The post parent will be an ancestor and the parent of the post 
    4643  * parent will be an ancestor. There will only be two ancestors at the most. 
    4644  * 
    4645  * @since 2.5.0 
    4646  * @access private 
    4647  * @uses $wpdb 
    4648  * 
    4649  * @param object $_post Post data. 
    4650  * @return null When nothing needs to be done. 
    4651  */ 
    4652 function _get_post_ancestors(&$_post) { 
    4653     global $wpdb; 
    4654  
    4655     if ( isset($_post->ancestors) ) 
    4656         return; 
    4657  
    4658     $_post->ancestors = array(); 
    4659  
    4660     if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent ) 
    4661         return; 
    4662  
    4663     $id = $_post->ancestors[] = (int) $_post->post_parent; 
    4664     while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) { 
    4665         // Loop detection: If the ancestor has been seen before, break. 
    4666         if ( ( $ancestor == $_post->ID ) || in_array($ancestor,  $_post->ancestors) ) 
    4667             break; 
    4668         $id = $_post->ancestors[] = (int) $ancestor; 
    4669     } 
    4670 } 
    4671  
    4672 /** 
    46734734 * Determines which fields of posts are to be saved in revisions. 
    46744735 * 
  • trunk/wp-includes/query.php

    r21248 r21559  
    26442644            if ( $ids ) { 
    26452645                $this->set_found_posts( $q, $limits ); 
    2646  
    26472646                _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); 
    2648  
    2649                 $this->posts = array_map( 'get_post', $ids ); 
     2647                $this->posts = $ids; 
    26502648            } else { 
     2649                $this->posts = array(); 
    26512650                $this->found_posts = $this->max_num_pages = 0; 
    2652                 $this->posts = array(); 
    26532651            } 
    26542652        } else { 
     
    26562654            $this->set_found_posts( $q, $limits ); 
    26572655        } 
     2656 
     2657        // Convert to WP_Post objects 
     2658        $this->posts = array_map( 'get_post', $this->posts ); 
    26582659 
    26592660        // Raw results filter. Prior to status checks. 
  • trunk/wp-includes/taxonomy.php

    r21553 r21559  
    32223222            $term = get_term($term->parent, $object_type); 
    32233223        } 
    3224     } elseif ( null !== get_post_type_object( $object_type ) ) { 
    3225         $object = get_post($object_id); 
    3226         if ( ! is_wp_error( $object ) && isset( $object->ancestors ) && is_array( $object->ancestors ) ) 
    3227             $ancestors = $object->ancestors; 
    3228         else { 
    3229             while ( ! is_wp_error($object) && ! empty( $object->post_parent ) && ! in_array( $object->post_parent, $ancestors ) ) { 
    3230                 $ancestors[] = (int) $object->post_parent; 
    3231                 $object = get_post($object->post_parent); 
    3232             } 
    3233         } 
     3224    } elseif ( post_type_exists( $object_type ) ) { 
     3225        $ancestors = get_post_ancestors($object_id); 
    32343226    } 
    32353227 
Note: See TracChangeset for help on using the changeset viewer.