Skip to content

Commit b2e8331

Browse files
authored
Merge branch 'WordPress:trunk' into trunk
2 parents de28a24 + 578d09b commit b2e8331

3 files changed

Lines changed: 129 additions & 16 deletions

File tree

src/wp-includes/class-wp-post.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ final class WP_Post {
218218
*
219219
* @since 3.5.0
220220
* @var string
221+
* @phpstan-var 'raw'|'edit'|'db'|'display'|'attribute'|'js'
221222
*/
222223
public $filter;
223224

@@ -230,6 +231,8 @@ final class WP_Post {
230231
*
231232
* @param int $post_id Post ID.
232233
* @return WP_Post|false Post object, false otherwise.
234+
*
235+
* @phpstan-param int|numeric-string $post_id
233236
*/
234237
public static function get_instance( $post_id ) {
235238
global $wpdb;
@@ -241,15 +244,15 @@ public static function get_instance( $post_id ) {
241244

242245
$_post = wp_cache_get( $post_id, 'posts' );
243246

244-
if ( ! $_post ) {
247+
if ( ! ( $_post instanceof stdClass ) && ! ( $_post instanceof WP_Post ) ) {
245248
$_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id ) );
246249

247250
if ( ! $_post ) {
248251
return false;
249252
}
250253

251254
$_post = sanitize_post( $_post, 'raw' );
252-
wp_cache_add( $_post->ID, $_post, 'posts' );
255+
wp_cache_add( (int) $_post->ID, $_post, 'posts' );
253256
} elseif ( empty( $_post->filter ) || 'raw' !== $_post->filter ) {
254257
$_post = sanitize_post( $_post, 'raw' );
255258
}
@@ -316,7 +319,7 @@ public function __get( $key ) {
316319
$terms = get_the_terms( $this, 'category' );
317320
}
318321

319-
if ( empty( $terms ) ) {
322+
if ( empty( $terms ) || $terms instanceof WP_Error ) {
320323
return array();
321324
}
322325

@@ -328,7 +331,7 @@ public function __get( $key ) {
328331
$terms = get_the_terms( $this, 'post_tag' );
329332
}
330333

331-
if ( empty( $terms ) ) {
334+
if ( empty( $terms ) || $terms instanceof WP_Error ) {
332335
return array();
333336
}
334337

@@ -350,12 +353,22 @@ public function __get( $key ) {
350353
}
351354

352355
/**
353-
* {@Missing Summary}
356+
* Applies the provided context filter for the current post.
357+
*
358+
* If the requested filter was already applied, then it returns without any changes.
359+
*
360+
* If the 'raw' filter is supplied, then a new instance of the post is obtained and this method _may_ return false
361+
* in case the underlying post was deleted.
354362
*
355363
* @since 3.5.0
356364
*
357365
* @param string $filter Filter.
358-
* @return WP_Post
366+
* @return WP_Post|false
367+
*
368+
* @phpstan-param 'raw'|'edit'|'db'|'display'|'attribute'|'js' $filter
369+
* @phpstan-return (
370+
* $filter is 'raw' ? WP_Post|false : WP_Post
371+
* )
359372
*/
360373
public function filter( $filter ) {
361374
if ( $this->filter === $filter ) {
@@ -374,9 +387,10 @@ public function filter( $filter ) {
374387
*
375388
* @since 3.5.0
376389
*
377-
* @return array Object as array.
390+
* @return array<string, mixed> Object as array.
378391
*/
379392
public function to_array() {
393+
/** @var array<string, mixed> $post */
380394
$post = get_object_vars( $this );
381395

382396
foreach ( array( 'ancestors', 'page_template', 'post_category', 'tags_input' ) as $key ) {

src/wp-includes/class-wp-query.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,10 @@ public function rewind_comments() {
39463946
*
39473947
* @param string|array $query URL query string or array of query arguments.
39483948
* @return WP_Post[]|int[] Array of post objects or post IDs.
3949+
*
3950+
* @phpstan-return (
3951+
* $query is array{ fields: 'ids', ... } ? int[] : WP_Post[]
3952+
* )
39493953
*/
39503954
public function query( $query ) {
39513955
$this->init();

src/wp-includes/post.php

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,15 @@ function _wp_relative_upload_path( $path ) {
986986
* correspond to a WP_Post object, an associative array, or a numeric array,
987987
* respectively. Default OBJECT.
988988
* @return WP_Post[]|array[]|int[] Array of post objects, arrays, or IDs, depending on `$output`.
989+
*
990+
* @phpstan-param 'OBJECT'|'ARRAY_A'|'ARRAY_N' $output
991+
* @phpstan-return (
992+
* $args is array{ fields: 'ids', ... } ? int[] : (
993+
* $output is 'ARRAY_A' ? array<int, array<string, mixed>> : (
994+
* $output is 'ARRAY_N' ? array<int, array<int, mixed>> : WP_Post[]
995+
* )
996+
* )
997+
* )
989998
*/
990999
function get_children( $args = '', $output = OBJECT ) {
9911000
$kids = array();
@@ -1110,6 +1119,17 @@ function get_extended( $post ) {
11101119
* or 'display'. Default 'raw'.
11111120
* @return WP_Post|array|null Type corresponding to $output on success or null on failure.
11121121
* When $output is OBJECT, a `WP_Post` instance is returned.
1122+
*
1123+
* @phpstan-param int|numeric-string|WP_Post|null $post
1124+
* @phpstan-param 'OBJECT'|'ARRAY_A'|'ARRAY_N' $output
1125+
* @phpstan-param 'raw'|'edit'|'db'|'display' $filter
1126+
* @phpstan-return (
1127+
* $output is 'ARRAY_A' ? array<string, mixed>|null : (
1128+
* $output is 'ARRAY_N' ? array<int, mixed>|null : (
1129+
* WP_Post|null
1130+
* )
1131+
* )
1132+
* )
11131133
*/
11141134
function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {
11151135
if ( empty( $post ) && isset( $GLOBALS['post'] ) ) {
@@ -1119,25 +1139,31 @@ function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {
11191139
if ( $post instanceof WP_Post ) {
11201140
$_post = $post;
11211141
} elseif ( is_object( $post ) ) {
1142+
/** @var stdClass $post */
11221143
if ( empty( $post->filter ) ) {
11231144
$_post = sanitize_post( $post, 'raw' );
11241145
$_post = new WP_Post( $_post );
11251146
} elseif ( 'raw' === $post->filter ) {
11261147
$_post = new WP_Post( $post );
11271148
} elseif ( isset( $post->ID ) ) {
1128-
$_post = WP_Post::get_instance( $post->ID );
1149+
$_post = WP_Post::get_instance( (int) $post->ID );
11291150
} else {
11301151
$_post = null;
11311152
}
1153+
} elseif ( is_numeric( $post ) ) {
1154+
$_post = WP_Post::get_instance( (int) $post );
11321155
} else {
1133-
$_post = WP_Post::get_instance( $post );
1156+
$_post = null;
11341157
}
11351158

11361159
if ( ! $_post ) {
11371160
return null;
11381161
}
11391162

11401163
$_post = $_post->filter( $filter );
1164+
if ( ! $_post ) {
1165+
return null;
1166+
}
11411167

11421168
if ( ARRAY_A === $output ) {
11431169
return $_post->to_array();
@@ -1202,6 +1228,13 @@ function get_post_ancestors( $post ) {
12021228
* @param string $context Optional. How to filter the field. Accepts 'raw', 'edit', 'db',
12031229
* or 'display'. Default 'display'.
12041230
* @return int|string|int[] The value of the post field on success, empty string on failure.
1231+
*
1232+
* @phpstan-param 'raw'|'edit'|'db'|'display' $context
1233+
* @phpstan-return (
1234+
* $field is 'ID'|'post_parent'|'menu_order' ? int|'' : (
1235+
* $field is 'ancestors' ? non-negative-int[]|'' : string
1236+
* )
1237+
* )
12051238
*/
12061239
function get_post_field( $field, $post = null, $context = 'display' ) {
12071240
$post = get_post( $post );
@@ -1642,6 +1675,7 @@ function get_post_type_object( $post_type ) {
16421675
* element from the array needs to match; 'and' means all elements
16431676
* must match; 'not' means no elements may match. Default 'and'.
16441677
* @return string[]|WP_Post_Type[] An array of post type names or objects.
1678+
* @phpstan-return ( $output is 'names' ? string[] : WP_Post_Type[] )
16451679
*/
16461680
function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) {
16471681
global $wp_post_types;
@@ -2578,6 +2612,10 @@ function is_post_embeddable( $post = null ) {
25782612
* @type bool $suppress_filters Whether to suppress filters. Default true.
25792613
* }
25802614
* @return WP_Post[]|int[] Array of post objects or post IDs.
2615+
*
2616+
* @phpstan-return (
2617+
* $args is array{ fields: 'ids', ... } ? int[] : WP_Post[]
2618+
* )
25812619
*/
25822620
function get_posts( $args = null ) {
25832621
$defaults = array(
@@ -2916,6 +2954,14 @@ function is_sticky( $post_id = 0 ) {
29162954
* 'attribute', or 'js'. Default 'display'.
29172955
* @return object|WP_Post|array The now sanitized post object or array (will be the
29182956
* same type as `$post`).
2957+
*
2958+
* @phpstan-param stdClass|WP_Post|array<string, mixed> $post
2959+
* @phpstan-param 'raw'|'edit'|'db'|'display'|'attribute'|'js' $context
2960+
* @phpstan-return (
2961+
* $post is WP_Post ? WP_Post : (
2962+
* $post is stdClass ? stdClass : array<string, mixed>
2963+
* )
2964+
* )
29192965
*/
29202966
function sanitize_post( $post, $context = 'display' ) {
29212967
if ( is_object( $post ) ) {
@@ -2927,7 +2973,7 @@ function sanitize_post( $post, $context = 'display' ) {
29272973
$post->ID = 0;
29282974
}
29292975
foreach ( array_keys( get_object_vars( $post ) ) as $field ) {
2930-
$post->$field = sanitize_post_field( $field, $post->$field, $post->ID, $context );
2976+
$post->$field = sanitize_post_field( $field, $post->$field, (int) $post->ID, $context );
29312977
}
29322978
$post->filter = $context;
29332979
} elseif ( is_array( $post ) ) {
@@ -2939,7 +2985,7 @@ function sanitize_post( $post, $context = 'display' ) {
29392985
$post['ID'] = 0;
29402986
}
29412987
foreach ( array_keys( $post ) as $field ) {
2942-
$post[ $field ] = sanitize_post_field( $field, $post[ $field ], $post['ID'], $context );
2988+
$post[ $field ] = sanitize_post_field( $field, $post[ $field ], (int) $post['ID'], $context );
29432989
}
29442990
$post['filter'] = $context;
29452991
}
@@ -2962,6 +3008,13 @@ function sanitize_post( $post, $context = 'display' ) {
29623008
* @param string $context Optional. How to sanitize the field. Possible values are 'raw', 'edit',
29633009
* 'db', 'display', 'attribute' and 'js'. Default 'display'.
29643010
* @return mixed Sanitized value.
3011+
*
3012+
* @phpstan-param 'raw'|'edit'|'db'|'display'|'attribute'|'js' $context
3013+
* @phpstan-return (
3014+
* $field is 'ID'|'post_parent'|'menu_order' ? int : (
3015+
* $field is 'ancestors' ? non-negative-int[] : string
3016+
* )
3017+
* )
29653018
*/
29663019
function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
29673020
$int_fields = array( 'ID', 'post_parent', 'menu_order' );
@@ -2972,7 +3025,7 @@ function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
29723025
// Fields which contain arrays of integers.
29733026
$array_int_fields = array( 'ancestors' );
29743027
if ( in_array( $field, $array_int_fields, true ) ) {
2975-
$value = array_map( 'absint', $value );
3028+
$value = array_map( 'absint', (array) $value );
29763029
return $value;
29773030
}
29783031

@@ -4396,6 +4449,11 @@ function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array(
43964449
* Default ARRAY_A.
43974450
* @return array|false Array of recent posts, where the type of each element is determined
43984451
* by the `$output` parameter. Empty array on failure.
4452+
*
4453+
* @phpstan-param 'OBJECT'|'ARRAY_A' $output
4454+
* @phpstan-return (
4455+
* $output is 'ARRAY_A' ? array<int, array<string, mixed>> : WP_Post[]|false
4456+
* )
43994457
*/
44004458
function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
44014459

@@ -4420,14 +4478,17 @@ function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
44204478
'suppress_filters' => true,
44214479
);
44224480

4481+
/** @var array{ fields: null, ... } $parsed_args */
44234482
$parsed_args = wp_parse_args( $args, $defaults );
44244483

44254484
$results = get_posts( $parsed_args );
44264485

44274486
// Backward compatibility. Prior to 3.1 expected posts to be returned in array.
44284487
if ( ARRAY_A === $output ) {
44294488
foreach ( $results as $key => $result ) {
4430-
$results[ $key ] = get_object_vars( $result );
4489+
/** @var array<string, mixed> $object_vars */
4490+
$object_vars = get_object_vars( $result );
4491+
$results[ $key ] = $object_vars;
44314492
}
44324493
return $results ? $results : array();
44334494
}
@@ -4504,6 +4565,10 @@ function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
45044565
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
45054566
* @param bool $fire_after_hooks Optional. Whether to fire the after insert hooks. Default true.
45064567
* @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
4568+
*
4569+
* @phpstan-return (
4570+
* $wp_error is false ? int : int|WP_Error
4571+
* )
45074572
*/
45084573
function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true ) {
45094574
global $wpdb;
@@ -5229,6 +5294,10 @@ function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true )
52295294
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
52305295
* @param bool $fire_after_hooks Optional. Whether to fire the after insert hooks. Default true.
52315296
* @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
5297+
*
5298+
* @phpstan-return (
5299+
* $wp_error is false ? int : int|WP_Error
5300+
* )
52325301
*/
52335302
function wp_update_post( $postarr = array(), $wp_error = false, $fire_after_hooks = true ) {
52345303
if ( is_object( $postarr ) ) {
@@ -6132,6 +6201,17 @@ function get_all_page_ids() {
61326201
* @param string $filter Optional. How the return value should be filtered. Accepts 'raw',
61336202
* 'edit', 'db', 'display'. Default 'raw'.
61346203
* @return WP_Post|array|null WP_Post or array on success, null on failure.
6204+
*
6205+
* @phpstan-param int|numeric-string|WP_Post|null $page
6206+
* @phpstan-param 'OBJECT'|'ARRAY_A'|'ARRAY_N' $output
6207+
* @phpstan-param 'raw'|'edit'|'db'|'display' $filter
6208+
* @phpstan-return (
6209+
* $output is 'ARRAY_A' ? array<string, mixed>|null : (
6210+
* $output is 'ARRAY_N' ? array<int, mixed>|null : (
6211+
* WP_Post|null
6212+
* )
6213+
* )
6214+
* )
61356215
*/
61366216
function get_page( $page, $output = OBJECT, $filter = 'raw' ) {
61376217
return get_post( $page, $output, $filter );
@@ -6150,6 +6230,16 @@ function get_page( $page, $output = OBJECT, $filter = 'raw' ) {
61506230
* respectively. Default OBJECT.
61516231
* @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
61526232
* @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
6233+
*
6234+
* @phpstan-param 'OBJECT'|'ARRAY_A'|'ARRAY_N' $output
6235+
* @phpstan-param string|string[] $post_type
6236+
* @phpstan-return (
6237+
* $output is 'ARRAY_A' ? array<string, mixed>|null : (
6238+
* $output is 'ARRAY_N' ? array<int, mixed>|null : (
6239+
* WP_Post|null
6240+
* )
6241+
* )
6242+
* )
61536243
*/
61546244
function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
61556245
global $wpdb;
@@ -6164,7 +6254,7 @@ function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
61646254
if ( '0' === $cached || 0 === $cached ) {
61656255
return null;
61666256
} else {
6167-
return get_post( $cached, $output );
6257+
return get_post( (int) $cached, $output );
61686258
}
61696259
}
61706260

@@ -6192,7 +6282,8 @@ function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
61926282
AND post_type IN ($post_type_in_string)
61936283
";
61946284

6195-
$pages = $wpdb->get_results( $sql, OBJECT_K );
6285+
/** @var array<object{ ID: string, post_name: string, post_parent: string, post_type: string }> $pages */
6286+
$pages = $wpdb->get_results( $sql, OBJECT_K ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- The escaping has been applied above via esc_sql().
61966287

61976288
$revparts = array_reverse( $parts );
61986289

@@ -6231,7 +6322,7 @@ function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
62316322
wp_cache_set_salted( $cache_key, $found_id, 'post-queries', $last_changed );
62326323

62336324
if ( $found_id ) {
6234-
return get_post( $found_id, $output );
6325+
return get_post( (int) $found_id, $output );
62356326
}
62366327

62376328
return null;
@@ -6650,6 +6741,10 @@ function is_local_attachment( $url ) {
66506741
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
66516742
* @param bool $fire_after_hooks Optional. Whether to fire the after insert hooks. Default true.
66526743
* @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
6744+
*
6745+
* @phpstan-return (
6746+
* $wp_error is false ? int : int|WP_Error
6747+
* )
66536748
*/
66546749
function wp_insert_attachment( $args, $file = false, $parent_post_id = 0, $wp_error = false, $fire_after_hooks = true ) {
66556750
$defaults = array(

0 commit comments

Comments
 (0)