448 lines
8.6 KiB
PHP
448 lines
8.6 KiB
PHP
<?php
|
|
/**
|
|
* Post API: WP_Post class
|
|
*
|
|
* @package WordPress
|
|
* @subpackage Post
|
|
* @since 4.4.0
|
|
*/
|
|
|
|
/**
|
|
* Core class used to implement the WP_Post object.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @property string $page_template
|
|
*
|
|
* @property-read list<non-negative-int> $ancestors
|
|
* @property-read list<non-negative-int> $post_category
|
|
* @property-read list<non-empty-string> $tags_input
|
|
*
|
|
* @phpstan-type Data_Array array{
|
|
* ID: non-negative-int,
|
|
* post_author: numeric-string|'',
|
|
* post_date: string,
|
|
* post_date_gmt: string,
|
|
* post_content: string,
|
|
* post_title: string,
|
|
* post_excerpt: string,
|
|
* post_status: non-empty-string,
|
|
* comment_status: non-empty-string,
|
|
* ping_status: non-empty-string,
|
|
* post_password: string,
|
|
* post_name: string,
|
|
* to_ping: string,
|
|
* pinged: string,
|
|
* post_modified: string,
|
|
* post_modified_gmt: string,
|
|
* post_content_filtered: string,
|
|
* post_parent: non-negative-int,
|
|
* guid: string,
|
|
* menu_order: int,
|
|
* post_type: non-empty-string,
|
|
* post_mime_type: string,
|
|
* comment_count: numeric-string,
|
|
* filter: 'raw'|'edit'|'db'|'display'|'attribute'|'js'|'sample'|null,
|
|
* ancestors: list<non-negative-int>,
|
|
* page_template: string,
|
|
* post_category: list<non-negative-int>,
|
|
* tags_input: list<non-empty-string>,
|
|
* ...
|
|
* }
|
|
*/
|
|
#[AllowDynamicProperties]
|
|
final class WP_Post {
|
|
|
|
/**
|
|
* Post ID.
|
|
*
|
|
* @since 3.5.0
|
|
* @var int
|
|
* @phpstan-var non-negative-int
|
|
*/
|
|
public $ID;
|
|
|
|
/**
|
|
* ID of post author.
|
|
*
|
|
* A numeric string, for compatibility reasons. May be an empty string for a
|
|
* default post that has not yet been assigned an author.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var numeric-string|''
|
|
*/
|
|
public $post_author = '0';
|
|
|
|
/**
|
|
* The post's local publication time.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_date = '0000-00-00 00:00:00';
|
|
|
|
/**
|
|
* The post's GMT publication time.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_date_gmt = '0000-00-00 00:00:00';
|
|
|
|
/**
|
|
* The post's content.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_content = '';
|
|
|
|
/**
|
|
* The post's title.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_title = '';
|
|
|
|
/**
|
|
* The post's excerpt.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_excerpt = '';
|
|
|
|
/**
|
|
* The post's status.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var non-empty-string
|
|
*/
|
|
public $post_status = 'publish';
|
|
|
|
/**
|
|
* Whether comments are allowed.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var non-empty-string
|
|
*/
|
|
public $comment_status = 'open';
|
|
|
|
/**
|
|
* Whether pings are allowed.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var non-empty-string
|
|
*/
|
|
public $ping_status = 'open';
|
|
|
|
/**
|
|
* The post's password in plain text.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_password = '';
|
|
|
|
/**
|
|
* The post's slug.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_name = '';
|
|
|
|
/**
|
|
* URLs queued to be pinged.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $to_ping = '';
|
|
|
|
/**
|
|
* URLs that have been pinged.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $pinged = '';
|
|
|
|
/**
|
|
* The post's local modified time.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_modified = '0000-00-00 00:00:00';
|
|
|
|
/**
|
|
* The post's GMT modified time.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_modified_gmt = '0000-00-00 00:00:00';
|
|
|
|
/**
|
|
* A utility DB field for post content.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_content_filtered = '';
|
|
|
|
/**
|
|
* ID of a post's parent post.
|
|
*
|
|
* @since 3.5.0
|
|
* @var int
|
|
* @phpstan-var non-negative-int
|
|
*/
|
|
public $post_parent = 0;
|
|
|
|
/**
|
|
* The unique identifier for a post, not necessarily a URL, used as the feed GUID.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $guid = '';
|
|
|
|
/**
|
|
* A field used for ordering posts.
|
|
*
|
|
* @since 3.5.0
|
|
* @var int
|
|
*/
|
|
public $menu_order = 0;
|
|
|
|
/**
|
|
* The post's type, like post or page.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var non-empty-string
|
|
*/
|
|
public $post_type = 'post';
|
|
|
|
/**
|
|
* An attachment's mime type.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
*/
|
|
public $post_mime_type = '';
|
|
|
|
/**
|
|
* Cached comment count.
|
|
*
|
|
* A numeric string, for compatibility reasons.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string
|
|
* @phpstan-var numeric-string
|
|
*/
|
|
public $comment_count = '0';
|
|
|
|
/**
|
|
* Stores the post object's sanitization level.
|
|
*
|
|
* Does not correspond to a DB field.
|
|
*
|
|
* The 'sample' value is set exclusively by {@see get_sample_permalink()} and is read during permalink previewing.
|
|
*
|
|
* @since 3.5.0
|
|
* @var string|null
|
|
* @phpstan-var 'raw'|'edit'|'db'|'display'|'attribute'|'js'|'sample'|null
|
|
*/
|
|
public $filter;
|
|
|
|
/**
|
|
* Retrieve WP_Post instance.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @global wpdb $wpdb WordPress database abstraction object.
|
|
*
|
|
* @param int $post_id Post ID.
|
|
* @return WP_Post|false Post object, false otherwise.
|
|
*
|
|
* @phpstan-param int|numeric-string $post_id
|
|
*/
|
|
public static function get_instance( $post_id ) {
|
|
global $wpdb;
|
|
|
|
$post_id = (int) $post_id;
|
|
if ( $post_id <= 0 ) {
|
|
return false;
|
|
}
|
|
|
|
$_post = wp_cache_get( $post_id, 'posts' );
|
|
|
|
if ( ! ( $_post instanceof stdClass ) && ! ( $_post instanceof WP_Post ) ) {
|
|
$_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id ) );
|
|
|
|
if ( ! $_post ) {
|
|
return false;
|
|
}
|
|
|
|
$_post = sanitize_post( $_post, 'raw' );
|
|
wp_cache_add( (int) $_post->ID, $_post, 'posts' );
|
|
} elseif ( empty( $_post->filter ) || 'raw' !== $_post->filter ) {
|
|
$_post = sanitize_post( $_post, 'raw' );
|
|
}
|
|
|
|
return new WP_Post( $_post );
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @param object $post Post object.
|
|
*/
|
|
public function __construct( $post ) {
|
|
foreach ( get_object_vars( $post ) as $key => $value ) {
|
|
$this->$key = $value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Isset-er.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @param string $key Property to check if set.
|
|
* @return bool
|
|
*/
|
|
public function __isset( $key ) {
|
|
if ( 'ancestors' === $key ) {
|
|
return true;
|
|
}
|
|
|
|
if ( 'page_template' === $key ) {
|
|
return true;
|
|
}
|
|
|
|
if ( 'post_category' === $key ) {
|
|
return true;
|
|
}
|
|
|
|
if ( 'tags_input' === $key ) {
|
|
return true;
|
|
}
|
|
|
|
return metadata_exists( 'post', $this->ID, $key );
|
|
}
|
|
|
|
/**
|
|
* Getter.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @param string $key Key to get.
|
|
* @return mixed
|
|
*/
|
|
public function __get( $key ) {
|
|
if ( 'page_template' === $key && $this->__isset( $key ) ) {
|
|
return get_post_meta( $this->ID, '_wp_page_template', true );
|
|
}
|
|
|
|
if ( 'post_category' === $key ) {
|
|
if ( is_object_in_taxonomy( $this->post_type, 'category' ) ) {
|
|
$terms = get_the_terms( $this, 'category' );
|
|
}
|
|
|
|
if ( empty( $terms ) || $terms instanceof WP_Error ) {
|
|
return array();
|
|
}
|
|
|
|
return wp_list_pluck( $terms, 'term_id' );
|
|
}
|
|
|
|
if ( 'tags_input' === $key ) {
|
|
if ( is_object_in_taxonomy( $this->post_type, 'post_tag' ) ) {
|
|
$terms = get_the_terms( $this, 'post_tag' );
|
|
}
|
|
|
|
if ( empty( $terms ) || $terms instanceof WP_Error ) {
|
|
return array();
|
|
}
|
|
|
|
return wp_list_pluck( $terms, 'name' );
|
|
}
|
|
|
|
// Rest of the values need filtering.
|
|
if ( 'ancestors' === $key ) {
|
|
$value = get_post_ancestors( $this );
|
|
} else {
|
|
$value = get_post_meta( $this->ID, $key, true );
|
|
}
|
|
|
|
if ( $this->filter ) {
|
|
$value = sanitize_post_field( $key, $value, $this->ID, $this->filter );
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Applies the provided context filter for the current post.
|
|
*
|
|
* If the requested filter was already applied, then it returns without any changes.
|
|
*
|
|
* If the 'raw' filter is supplied, then a new instance of the post is obtained and this method _may_ return false
|
|
* in case the underlying post was deleted.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @param string $filter Filter.
|
|
* @return WP_Post|false
|
|
*
|
|
* @phpstan-param 'raw'|'edit'|'db'|'display'|'attribute'|'js' $filter
|
|
* @phpstan-return (
|
|
* $filter is 'raw' ? WP_Post|false : WP_Post
|
|
* )
|
|
*/
|
|
public function filter( $filter ) {
|
|
if ( $this->filter === $filter ) {
|
|
return $this;
|
|
}
|
|
|
|
if ( 'raw' === $filter ) {
|
|
return self::get_instance( $this->ID );
|
|
}
|
|
|
|
return sanitize_post( $this, $filter );
|
|
}
|
|
|
|
/**
|
|
* Convert object to array.
|
|
*
|
|
* @since 3.5.0
|
|
*
|
|
* @return array<string, mixed> Object as array.
|
|
*
|
|
* @phpstan-return Data_Array
|
|
*/
|
|
public function to_array() {
|
|
$post = get_object_vars( $this );
|
|
|
|
foreach ( array( 'ancestors', 'page_template', 'post_category', 'tags_input' ) as $key ) {
|
|
if ( $this->__isset( $key ) ) {
|
|
$post[ $key ] = $this->__get( $key );
|
|
}
|
|
}
|
|
|
|
/** @var Data_Array $post */
|
|
return $post;
|
|
}
|
|
}
|