1<?php
2/**
3 * Post API: WP_Post class
4 *
5 * @package WordPress
6 * @subpackage Post
7 * @since 4.4.0
8 */
9
10/**
11 * Core class used to implement the WP_Post object.
12 *
13 * @since 3.5.0
14 *
15 * @property string $page_template
16 *
17 * @property-read int[] $ancestors
18 * @property-read int[] $post_category
19 * @property-read string[] $tags_input
20 */
21#[AllowDynamicProperties]
22final class WP_Post {
23
24 /**
25 * Post ID.
26 *
27 * @since 3.5.0
28 * @var int
29 */
30 public $ID;
31
32 /**
33 * ID of post author.
34 *
35 * A numeric string, for compatibility reasons.
36 *
37 * @since 3.5.0
38 * @var string
39 */
40 public $post_author = '0';
41
42 /**
43 * The post's local publication time.
44 *
45 * @since 3.5.0
46 * @var string
47 */
48 public $post_date = '0000-00-00 00:00:00';
49
50 /**
51 * The post's GMT publication time.
52 *
53 * @since 3.5.0
54 * @var string
55 */
56 public $post_date_gmt = '0000-00-00 00:00:00';
57
58 /**
59 * The post's content.
60 *
61 * @since 3.5.0
62 * @var string
63 */
64 public $post_content = '';
65
66 /**
67 * The post's title.
68 *
69 * @since 3.5.0
70 * @var string
71 */
72 public $post_title = '';
73
74 /**
75 * The post's excerpt.
76 *
77 * @since 3.5.0
78 * @var string
79 */
80 public $post_excerpt = '';
81
82 /**
83 * The post's status.
84 *
85 * @since 3.5.0
86 * @var string
87 */
88 public $post_status = 'publish';
89
90 /**
91 * Whether comments are allowed.
92 *
93 * @since 3.5.0
94 * @var string
95 */
96 public $comment_status = 'open';
97
98 /**
99 * Whether pings are allowed.
100 *
101 * @since 3.5.0
102 * @var string
103 */
104 public $ping_status = 'open';
105
106 /**
107 * The post's password in plain text.
108 *
109 * @since 3.5.0
110 * @var string
111 */
112 public $post_password = '';
113
114 /**
115 * The post's slug.
116 *
117 * @since 3.5.0
118 * @var string
119 */
120 public $post_name = '';
121
122 /**
123 * URLs queued to be pinged.
124 *
125 * @since 3.5.0
126 * @var string
127 */
128 public $to_ping = '';
129
130 /**
131 * URLs that have been pinged.
132 *
133 * @since 3.5.0
134 * @var string
135 */
136 public $pinged = '';
137
138 /**
139 * The post's local modified time.
140 *
141 * @since 3.5.0
142 * @var string
143 */
144 public $post_modified = '0000-00-00 00:00:00';
145
146 /**
147 * The post's GMT modified time.
148 *
149 * @since 3.5.0
150 * @var string
151 */
152 public $post_modified_gmt = '0000-00-00 00:00:00';
153
154 /**
155 * A utility DB field for post content.
156 *
157 * @since 3.5.0
158 * @var string
159 */
160 public $post_content_filtered = '';
161
162 /**
163 * ID of a post's parent post.
164 *
165 * @since 3.5.0
166 * @var int
167 */
168 public $post_parent = 0;
169
170 /**
171 * The unique identifier for a post, not necessarily a URL, used as the feed GUID.
172 *
173 * @since 3.5.0
174 * @var string
175 */
176 public $guid = '';
177
178 /**
179 * A field used for ordering posts.
180 *
181 * @since 3.5.0
182 * @var int
183 */
184 public $menu_order = 0;
185
186 /**
187 * The post's type, like post or page.
188 *
189 * @since 3.5.0
190 * @var string
191 */
192 public $post_type = 'post';
193
194 /**
195 * An attachment's mime type.
196 *
197 * @since 3.5.0
198 * @var string
199 */
200 public $post_mime_type = '';
201
202 /**
203 * Cached comment count.
204 *
205 * A numeric string, for compatibility reasons.
206 *
207 * @since 3.5.0
208 * @var string
209 */
210 public $comment_count = '0';
211
212 /**
213 * Stores the post object's sanitization level.
214 *
215 * Does not correspond to a DB field.
216 *
217 * @since 3.5.0
218 * @var string
219 */
220 public $filter;
221
222 /**
223 * Retrieve WP_Post instance.
224 *
225 * @since 3.5.0
226 *
227 * @global wpdb $wpdb WordPress database abstraction object.
228 *
229 * @param int $post_id Post ID.
230 * @return WP_Post|false Post object, false otherwise.
231 */
232 public static function get_instance( $post_id ) {
233 global $wpdb;
234
235 $post_id = (int) $post_id;
236 if ( $post_id <= 0 ) {
237 return false;
238 }
239
240 $_post = wp_cache_get( $post_id, 'posts' );
241
242 if ( ! $_post ) {
243 $_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id ) );
244
245 $_post = apply_filters('godaddy/wp_post/get_instance', $_post);
246
247 if ( ! $_post ) {
248 return false;
249 }
250
251 $_post = sanitize_post( $_post, 'raw' );
252 wp_cache_add( $_post->ID, $_post, 'posts' );
253 } elseif ( empty( $_post->filter ) || 'raw' !== $_post->filter ) {
254 $_post = sanitize_post( $_post, 'raw' );
255 }
256
257 return new WP_Post( $_post );
258 }
259
260 /**
261 * Constructor.
262 *
263 * @since 3.5.0
264 *
265 * @param WP_Post|object $post Post object.
266 */
267 public function __construct( $post ) {
268 foreach ( get_object_vars( $post ) as $key => $value ) {
269 $this->$key = $value;
270 }
271 }
272
273 /**
274 * Isset-er.
275 *
276 * @since 3.5.0
277 *
278 * @param string $key Property to check if set.
279 * @return bool
280 */
281 public function __isset( $key ) {
282 if ( 'ancestors' === $key ) {
283 return true;
284 }
285
286 if ( 'page_template' === $key ) {
287 return true;
288 }
289
290 if ( 'post_category' === $key ) {
291 return true;
292 }
293
294 if ( 'tags_input' === $key ) {
295 return true;
296 }
297
298 return metadata_exists( 'post', $this->ID, $key );
299 }
300
301 /**
302 * Getter.
303 *
304 * @since 3.5.0
305 *
306 * @param string $key Key to get.
307 * @return mixed
308 */
309 public function __get( $key ) {
310 if ( 'page_template' === $key && $this->__isset( $key ) ) {
311 return get_post_meta( $this->ID, '_wp_page_template', true );
312 }
313
314 if ( 'post_category' === $key ) {
315 if ( is_object_in_taxonomy( $this->post_type, 'category' ) ) {
316 $terms = get_the_terms( $this, 'category' );
317 }
318
319 if ( empty( $terms ) ) {
320 return array();
321 }
322
323 return wp_list_pluck( $terms, 'term_id' );
324 }
325
326 if ( 'tags_input' === $key ) {
327 if ( is_object_in_taxonomy( $this->post_type, 'post_tag' ) ) {
328 $terms = get_the_terms( $this, 'post_tag' );
329 }
330
331 if ( empty( $terms ) ) {
332 return array();
333 }
334
335 return wp_list_pluck( $terms, 'name' );
336 }
337
338 // Rest of the values need filtering.
339 if ( 'ancestors' === $key ) {
340 $value = get_post_ancestors( $this );
341 } else {
342 $value = get_post_meta( $this->ID, $key, true );
343 }
344
345 if ( $this->filter ) {
346 $value = sanitize_post_field( $key, $value, $this->ID, $this->filter );
347 }
348
349 return $value;
350 }
351
352 /**
353 * {@Missing Summary}
354 *
355 * @since 3.5.0
356 *
357 * @param string $filter Filter.
358 * @return WP_Post
359 */
360 public function filter( $filter ) {
361 if ( $this->filter === $filter ) {
362 return $this;
363 }
364
365 if ( 'raw' === $filter ) {
366 return self::get_instance( $this->ID );
367 }
368
369 return sanitize_post( $this, $filter );
370 }
371
372 /**
373 * Convert object to array.
374 *
375 * @since 3.5.0
376 *
377 * @return array Object as array.
378 */
379 public function to_array() {
380 $post = get_object_vars( $this );
381
382 foreach ( array( 'ancestors', 'page_template', 'post_category', 'tags_input' ) as $key ) {
383 if ( $this->__isset( $key ) ) {
384 $post[ $key ] = $this->__get( $key );
385 }
386 }
387
388 return $post;
389 }
390}
391