#32224 closed defect (bug) (fixed)
delete_post_meta() not working as expected when $meta_value is specified as 0 or '0'
| Reported by: | husobj | Owned by: | boonebgorges |
|---|---|---|---|
| Priority: | normal | Milestone: | 4.3 |
| Component: | Options, Meta APIs | Version: | 4.2.1 |
| Severity: | normal | Keywords: | |
| Cc: | Focuses: |
Description
The [delete_post_meta()](https://codex.wordpress.org/Function_Reference/delete_post_meta) codex says that if $meta_value is specified this is used to differentiate between several fields with the same key. If left blank, all fields with the given key will be deleted.
I have just created an instance where I have multiple numeric meta values stored with the same key.
For example:
$meta = get_post_meta( $post_id, 'my_var' ); print_r( $meta );
outputs:
Array (
[0] => 57
[1] => 103
[2] => 0
[3] => 97
[4] => 4
)
The following works as expected and deletes the meta value 103:
delete_post_meta( $post_id, 'my_var', 103 );
However, if I try to delete the zero value, it deletes all the meta!
delete_post_meta( $post_id, 'my_var', 0 ); // or delete_post_meta( $post_id, 'my_var', '0' );
Is the empty check too strict? It should only be deleting all meta if the value is an empty string, not a zero value.
Change History (12)
#1
@
11 years ago
- Summary delete_post_meta() not working as expect when $meta_value is specified as 0 or '0' → delete_post_meta() not working as expected when $meta_value is specified as 0 or '0'
#3
follow-up:
↓ 4
@
11 years ago
delete_metadata uses this:
if ( $meta_value )
$query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
It should probably be:
if ( '' !== $meta_value && null !== $meta_value )
$query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
#4
in reply to: ↑ 3
@
11 years ago
Replying to sc0ttkclark:
delete_metadata uses this:
if ( $meta_value ) $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );It should probably be:
if ( '' !== $meta_value && null !== $meta_value ) $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
It's possible to add an empty string as metadata, so we don't want to remove the ability to delete empty-string meta values.
If this were the last argument passed to delete_metadata(), we could use func_num_args() to see if a value had been passed at all. But we also want it to be possible to specify falsey values for $meta_value while passing a value for $delete_all. To the unit tests, Batman!
#5
@
11 years ago
Right, this is assuming that $meta_value is by default '' as defined in the function itself currently. func_num_args() would still be tricky since delete_post_meta and other delete_metadata wrappers pass in all arguments, so it would only be available in those functions and not delete_metadata.
#6
@
11 years ago
Yeah, you're right about the wrappers. How about changing the default value of $meta_value to null for delete_metadata() and all wrappers, and then skipping the value clause when is_null( $_meta_value )?
#7
@
11 years ago
Scratch that idea. It'll break every plugin that has its own delete_metadata() wrappers.
There may be no backward-compatible way to fix this bug and also let delete_metadata() work properly with $meta_value = ''. We'll just have to document that quirk.
#8
@
11 years ago
So are we back at this proposed fix, since it still prevents zeros from being deleted?
if ( '' !== $meta_value && null !== $meta_value )
$query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Confirmed. I'll have a look.