Make WordPress Core


Ignore:
Timestamp:
08/20/2012 07:47:52 PM (14 years ago)
Author:
ryan
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 *
Note: See TracChangeset for help on using the changeset viewer.