Auto-remove custom field with no value on publish

Demilio, unfortunately the WordPress API seems to assume that custom fields do not have an ’empty’ value, in the sense that update_post_meta and delete_post_meta, if given '' as the (previous) meta value perform the update/delete operation for all values for that key.

This makes it difficult, for instance, if a custom field key has multiple values associated with it, some of which are empty and want to be removed.

Below is the basic logic: It will only remove fields where all associated fields are ’empty’. Exactly what ‘empty‘ means, you can decide by specifying a callback to array_filter, by default, as used in the code below this includes ‘0’, false etc.

The hook you are after is save_post. This is fired after the post and all it’s post-meta, has been saved having clicked ‘update”https://wordpress.stackexchange.com/”publish’, but also on auto-saves…

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;
}

As noted above, if a custom field key has multiple values associated with it, some of which are empty – they will not be removed. This will probably be ok for your use. There seems to be no easy ‘WordPress’ way around this. One way would be a custom MYSQL statement.