[wp-trac] [WordPress Trac] #63975: wp_delete_auto_drafts passes post ID as string instead of as int
WordPress Trac
noreply at wordpress.org
Thu Sep 18 17:39:35 UTC 2025
#63975: wp_delete_auto_drafts passes post ID as string instead of as int
-----------------------------------------------+---------------------------
Reporter: kkmuffme | Owner: kkmuffme
Type: defect (bug) | Status: assigned
Priority: normal | Milestone: Awaiting
| Review
Component: Posts, Post Types | Version: 3.4
Severity: trivial | Resolution:
Keywords: has-patch changes-requested close | Focuses:
-----------------------------------------------+---------------------------
Comment (by westonruter):
@kkmuffme Thank you for providing a test case that would cause the fatal
error.
You suggested making this change to `wp_delete_auto_drafts()`:
{{{#!diff
- wp_delete_post( $delete, true );
+ wp_delete_post( (int) $delete, true );
}}}
But to actually fix the problem in a more robust way, any such casting
should be done in `wp_delete_post()` instead where `do_action()` is
called:
{{{#!diff
- do_action( 'before_delete_post', $post_id, $post );
+ do_action( 'before_delete_post', (int) $post_id, $post );
}}}
Or, even better, to coerce the `$post_id` at the top of the function so
that all usages thereafter for all filters and actions will get the
expected type passed:
{{{#!diff
$post = get_post( $post );
+ $post_id = $post->ID;
}}}
This will then ensure that `int` is passed to the
`delete_post_{$post->post_type}`, `delete_post`,
`deleted_post_{$post->post_type}`, `deleted_post`, and `after_delete_post`
actions. Then we wouldn't have ensure the proper type being passed into
`wp_delete_post()` every time it is called. We only update it once in
`wp_delete_post()` itself.
The issue here is somewhat distinct from the related issues with the data
types being passed into filters, per #51525 and Peter's
[https://peterwilson.cc/type-declarations-with-wordpress-filters/ blog
post], where the ''initial'' value in the filter callback cannot be
strictly typed because themes and plugins can do bad things and return
arbitrary values. I similarly advocate for a
[https://github.com/westonruter/wp-plugin-
template/blob/main/.gemini/styleguide.md#php convention] to used `mixed`
as the type for the initial arg passed to a filter callback, for example:
{{{#!php
<?php
/**
* Filters foo.
*
* @param string|mixed $foo Foo.
* @return string Foo.
*/
function filter_foo( mixed $foo, int $post_id ): string {
if ( ! is_string( $foo ) ) {
$foo = '';
}
/**
* Because plugins do bad things.
*
* @var string $foo
*/
// Filtering logic goes here.
return $foo;
}
add_filter( 'foo', 'filter_foo', 10, 2 );
}}}
But the issue here are ''actions'' not filters. Even in my example here,
you see I have `int $post_id` because I'm expecting that the phpdoc which
documents this hypothetical filter `foo` is correct in that an `int` is
always passed. This then also applies to all arguments passed to actions,
which cannot have their values manipulated by callbacks. The phpdoc for
the action should be a contract for what value is expected when the
arguments are passed to the callback.
I support this change to ensure that `$post_id` gets programmatically
coerced to `int` at the top of `wp_delete_post()`, if you want to prepare
a patch.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/63975#comment:23>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list