Commit cfdab1a6ba for wordpress.org
commit cfdab1a6ba05cd035fb23049ccbe7fa7b9ef2643
Author: westonruter <westonruter@git.wordpress.org>
Date: Fri Sep 18 03:48:48 2026 +0000
Code Quality: Type the object ID for metadata deletion.
Three of the eight `delete_metadata()` calls in core passed `null` for `$object_id`, all of them the `$delete_all = true` case where the value no longer selects the rows to delete. The other five already wrote `0`. Nothing observed the difference, because `absint()` normalizes the argument on the statement after the guard, so the `delete_{$meta_type}_metadata` filter and the `delete_{$meta_type}_meta` and `deleted_{$meta_type}_meta` actions have always received `0` whichever spelling was used.
The parameter is now annotated `non-negative-int`, which rejects a negative ID that `absint()` would otherwise turn positive and apply to a different object. A `numeric-string` branch is deliberately not added, since it would readmit `'-5'` through the same hole while `-5` stayed rejected. The five per-object wrappers and the two `WP_REST_Meta_Fields` methods that call the function directly are annotated `positive-int` instead, because none of them passes `$delete_all`, so an object ID of `0` always returns `false` there.
The documentation for `$object_id` now describes the `$delete_all` case where a reader looks for it, rather than only on `$delete_all` itself, and the PHPStan baselines are regenerated for the entries this resolves.
Developed in https://github.com/WordPress/wordpress-develop/pull/13577.
Follow-up to r63024, r63618.
Props soean, westonruter, mukesh27.
See #65817, #65860.
Built from https://develop.svn.wordpress.org/trunk@63758
git-svn-id: http://core.svn.wordpress.org/trunk@62930 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/comment.php b/wp-includes/comment.php
index 8293c8b750..03511ee4db 100644
--- a/wp-includes/comment.php
+++ b/wp-includes/comment.php
@@ -548,6 +548,8 @@ function add_comment_meta( $comment_id, $meta_key, $meta_value, $unique = false
* rows will only be removed that match the value.
* Must be serializable if non-scalar. Default empty string.
* @return bool True on success, false on failure.
+ *
+ * @phpstan-param positive-int $comment_id
*/
function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) {
return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value );
diff --git a/wp-includes/meta.php b/wp-includes/meta.php
index 62d28cdbd9..dd28b02721 100644
--- a/wp-includes/meta.php
+++ b/wp-includes/meta.php
@@ -382,7 +382,9 @@ function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_
*
* @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
* 'user', or any other object type with an associated meta table.
- * @param int $object_id ID of the object metadata is for.
+ * @param int $object_id ID of the object metadata is for. Pass 0 when `$delete_all` is true.
+ * The value no longer selects the rows to delete, but is still passed
+ * on to the hooks fired below.
* @param string $meta_key Metadata key.
* @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar.
* If specified, only delete metadata entries with this value.
@@ -395,6 +397,8 @@ function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_
* ignoring the specified object_id. Otherwise, only delete
* matching metadata entries for the specified object_id. Default false.
* @return bool True on successful delete, false on failure.
+ *
+ * @phpstan-param non-negative-int $object_id
*/
function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
global $wpdb;
diff --git a/wp-includes/ms-site.php b/wp-includes/ms-site.php
index 8540b27621..f18189c30d 100644
--- a/wp-includes/ms-site.php
+++ b/wp-includes/ms-site.php
@@ -1060,6 +1060,8 @@ function add_site_meta( $site_id, $meta_key, $meta_value, $unique = false ) {
* rows will only be removed that match the value.
* Must be serializable if non-scalar. Default empty.
* @return bool True on success, false on failure.
+ *
+ * @phpstan-param positive-int $site_id
*/
function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) {
return delete_metadata( 'blog', $site_id, $meta_key, $meta_value );
@@ -1138,7 +1140,7 @@ function update_site_meta( $site_id, $meta_key, $meta_value, $prev_value = '' )
* @return bool Whether the site meta key was deleted from the database.
*/
function delete_site_meta_by_key( $meta_key ) {
- return delete_metadata( 'blog', null, $meta_key, '', true );
+ return delete_metadata( 'blog', 0, $meta_key, '', true );
}
/**
diff --git a/wp-includes/post.php b/wp-includes/post.php
index 89ab25ab93..d36a44bde2 100644
--- a/wp-includes/post.php
+++ b/wp-includes/post.php
@@ -2738,6 +2738,8 @@ function add_post_meta( $post_id, $meta_key, $meta_value, $unique = false ) {
* rows will only be removed that match the value.
* Must be serializable if non-scalar. Default empty.
* @return bool True on success, false on failure.
+ *
+ * @phpstan-param positive-int $post_id
*/
function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
// Make sure meta is deleted from the post, not from a revision.
@@ -2830,7 +2832,7 @@ function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' )
* @return bool Whether the post meta key was deleted from the database.
*/
function delete_post_meta_by_key( $post_meta_key ) {
- return delete_metadata( 'post', null, $post_meta_key, '', true );
+ return delete_metadata( 'post', 0, $post_meta_key, '', true );
}
/**
@@ -6975,7 +6977,7 @@ function wp_delete_attachment( $post_id, $force_delete = false ) {
wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );
// Delete all for any posts.
- delete_metadata( 'post', null, '_thumbnail_id', $post_id, true );
+ delete_metadata( 'post', 0, '_thumbnail_id', $post_id, true );
wp_defer_comment_counting( true );
diff --git a/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php b/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php
index a9c3fbcde8..71be09ec42 100644
--- a/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php
+++ b/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php
@@ -228,6 +228,8 @@ abstract class WP_REST_Meta_Fields {
* @param string $meta_key Key for the field.
* @param string $name Name for the field that is exposed in the REST API.
* @return true|WP_Error True if meta field is deleted, WP_Error otherwise.
+ *
+ * @phpstan-param positive-int $object_id
*/
protected function delete_meta_value( $object_id, $meta_key, $name ) {
$meta_type = $this->get_meta_type();
@@ -275,6 +277,8 @@ abstract class WP_REST_Meta_Fields {
* @param string $name Name for the field that is exposed in the REST API.
* @param array $values List of values to update to.
* @return true|WP_Error True if meta fields are updated, WP_Error otherwise.
+ *
+ * @phpstan-param positive-int $object_id
*/
protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) {
$meta_type = $this->get_meta_type();
diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php
index 56f12f7013..d13a11e655 100644
--- a/wp-includes/taxonomy.php
+++ b/wp-includes/taxonomy.php
@@ -1447,6 +1447,8 @@ function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) {
* rows will only be removed that match the value.
* Must be serializable if non-scalar. Default empty.
* @return bool True on success, false on failure.
+ *
+ * @phpstan-param positive-int $term_id
*/
function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) {
return delete_metadata( 'term', $term_id, $meta_key, $meta_value );
diff --git a/wp-includes/user.php b/wp-includes/user.php
index a13b3f75c0..b4ab594038 100644
--- a/wp-includes/user.php
+++ b/wp-includes/user.php
@@ -1270,6 +1270,8 @@ function add_user_meta( $user_id, $meta_key, $meta_value, $unique = false ) {
* rows will only be removed that match the value.
* Must be serializable if non-scalar. Default empty.
* @return bool True on success, false on failure.
+ *
+ * @phpstan-param positive-int $user_id
*/
function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
return delete_metadata( 'user', $user_id, $meta_key, $meta_value );
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 1eb0d326fe..0667deeb82 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-63757';
+$wp_version = '7.2-alpha-63758';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.