Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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 wont 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 doesnt 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
1  
What is the main idea of the code? Provide some explanation on what it's supposed to do. –  Webord Feb 20 '12 at 9:12

2 Answers 2

I 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

share|improve this answer
    
Hi Stephen, thanks for helping me again :) But, it didn't work. What may be worth mentioning is that it does work when I post as super-administrator using one of the user blogs. But when I log inn as a regular user (sub-admin for that blog) it sends 2 custom fields to the main blog with the post. Both named "Image" but one is empty and one got the thumbnail URL in it. This causes that the image wont show. I use the sitewide-tags plugin to get posts from all wpmu-bloggers in to the main blog. And I have your script both in the functions-file in the main theme and the sub-them. Still wont work –  Demilio Feb 21 '12 at 11:58
    
and..... strangly sometimes it work. I got many bloggers and sometimes the image is there. I have no idea what the combination on this is but for some users it wont work. at forst I thought it could be that they had to be a member of the main blog, but that is not the case. The scond idea was that they where using the wordrepss-app for iphone to make posts, and that may still be the solition. But other then that the case today is that for some bloggers it works and for some it wont. And they all use the same theme and setup. –  Demilio Feb 21 '12 at 12:01
    
odd... sounds like you're running a few different plug-ins which could all be interfering (and I've not tested my code on an MU site...). You should look into why you are receiving two 'image' inputs though, rather than trying to delete them. –  Stephen Harris Feb 21 '12 at 14:38
    
yea, I know... and I have done that, but the solution seems to be deeper then my knowlage, so I was hoping to do a shortcut with this script :) –  Demilio Feb 22 '12 at 8:57

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;

} 
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.