The code you see below only works sometimes. I'm no pro on PHP so can anyone help me improve this code? I use it in my functions-php file in my WordPress mu setup.
The biggest problem is that it won't remove duplicate fileds. i.e. if I have 2 custom fields named Image and one is empty I want this script to remove this empty field, but it doesn't work
add_action('save_post','my_cf_check');
function my_cf_check($post_id) {
// verify this is not an auto save routine.
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;
//authentication checks
if (!current_user_can('edit_post', $post_id)) return;
//obtain custom field meta for this post
$custom_fields = get_post_custom($post_id);
if(!$custom_fields) return;
foreach($custom_fields as $key=>$custom_field):
//$custom_field is an array of values associated with $key - even if there is only one value.
//Filter to remove empty values.
//Be warned this will remove anything that casts as false, e.g. 0 or false
//- if you don't want this, specify a callback.
//See php documentation on array_filter
$values = array_filter($custom_field);
//After removing 'empty' fields, is array empty?
if(empty($values)):
delete_post_meta($post_id,$key); //Remove post's custom field
endif;
endforeach;
return;
}
The code you see below only works sometimes. I'm no pro on PHP so can anyone help me improve this code? I use it in my functions-php file in my WordPress mu setup.
The biggest problem is that it won't remove duplicate fileds. i.e. if I have 2 custom fields named Image and one is empty I want this script to remove this empty field, but it doesn't work
add_action('save_post','my_cf_check');
function my_cf_check($post_id) {
// verify this is not an auto save routine.
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;
//authentication checks
if (!current_user_can('edit_post', $post_id)) return;
//obtain custom field meta for this post
$custom_fields = get_post_custom($post_id);
if(!$custom_fields) return;
foreach($custom_fields as $key=>$custom_field):
//$custom_field is an array of values associated with $key - even if there is only one value.
//Filter to remove empty values.
//Be warned this will remove anything that casts as false, e.g. 0 or false
//- if you don't want this, specify a callback.
//See php documentation on array_filter
$values = array_filter($custom_field);
//After removing 'empty' fields, is array empty?
if(empty($values)):
delete_post_meta($post_id,$key); //Remove post's custom field
endif;
endforeach;
return;
}
Share
Improve this question
edited Aug 24, 2019 at 17:18
Lazar Momcilovic
1831 silver badge6 bronze badges
asked Feb 20, 2012 at 9:02
DemilioDemilio
8836 gold badges16 silver badges29 bronze badges
1
- 1 What is the main idea of the code? Provide some explanation on what it's supposed to do. – Webord Commented Feb 20, 2012 at 9:12
2 Answers
Reset to default 1I believe this was my solution to a previous question you had.
I mentioned in that answer that the code didn't deal with the eventuality of a key with multiple values and only some of which are empty. The reason why is how WordPress treats delete_post_meta
...
When using delete_post_meta
, the first two arguments specify the post and the key of the custom field. You have a third optional argument, which can be used to specify a key-value pair. So...
//Delete all post meta with key $key
delete_post_meta($post_id,$key)
//Delete all post meta with key $key AND value $value
delete_post_meta($post_id,$key,$value)
The problem is that if $value
is empty it treats it like the first case and deletes all post meta for that post and key.
There is a workaround (and perhaps a non-WordPress based one would be more efficient here), the logic is as follows;
- Identify a key with an empty-value
- Retrieve all non-empty values
- Delete the key
- Re-insert the key, adding only non-empty values
The edited foreach loop;
foreach($custom_fields as $key=>$values):
//$values is an array of values associated with $key - even if there is only one value.
//Filter to remove empty values.
//Be warned this will remove anything that casts as false, e.g. 0 or false
//- if you don't want this, specify a callback.
//See php documentation on array_filter
$nonemptyvalues = array_filter($values);
//If the $nonemptyvalues doesn't match $values then we removed an empty value(s).
if($nonemptyvalues!=$values):
//delete key
delete_post_meta($post_id,$key);
//re-add key and insert only non-empty values
foreach($nonemptyvalues as $nonemptyvalue){
add_post_meta($post_id,$key,$nonemptyvalue);
}
endif;
endforeach;
The above is untested
See what you think of this:
add_action('save_post','my_cf_check');
function my_cf_check($post_id) {
// verify this is not an auto save routine.
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;
//authentication checks
if (!current_user_can('edit_post', $post_id)) return;
//obtain custom field meta for this post
$custom_fields = get_post_custom($post_id);
if( !$custom_fields ) return;
foreach ( $custom_fields as $key => $val_arr ):
if ( empty($val_arr) )
delete_post_meta($post_id, $key); // if it's empty, delete the field.
elseif ( is_array($val_arr) && 1 < count($val_arr) ) {
foreach ($val_arr as $value) {
// check each value, and delete the post meta if it's empty
if ( empty( $value ) )
delete_post_meta($post_id, $key, $value);
}
} else {
// it's an array with a single non-empty value, or it's a non-empty string
}
endforeach;
}