0

I'm trying to use update_value filter hook of Advanced Custom Fields to write a function that when a user deletes an image from the field it will be deleted from the media library of WP as well. So far i haven't managed to make it work i get lots of errors. I need to check if the value of the field is empty then get the previous value (the image) find the ID and delete the attachment? Any ideas?

//Delete image from acf field
function my_acf_update_value( $value, $post_id, $field  )
{

    if (empty($value)){
    $var = get_field($field, $post_id);
    $varid = $var['id'];
    wp_delete_attachment( $var, true );
    }
    // do something else to the $post object via the $post_id
    return $value;
}

add_filter('acf/update_value/type=image', 'my_acf_update_value', 10, 3); 

Error:

Warning: Illegal offset type in isset or empty in /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-includes/meta.php on line 484

Warning: Illegal offset type in isset or empty in /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-includes/meta.php on line 484

Warning: Cannot modify header information - headers already sent by (output started at /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-includes/meta.php:484) in /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-admin/post.php on line 233

Warning: Cannot modify header information - headers already sent by (output started at /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-includes/meta.php:484) in /xxx/xxx/xxx/xxx/xxxxxx/xxxxxxx/xxx.xxxxxxxx.com/html/wp-includes/pluggable.php on line 1179

1

You're close - couple of things:

  1. $field is an array representation of the field, so you need to use $field['name'] which is the name of the field.
  2. get_field will format the value unless you set the third argument to false - we want the ID, not the post object/URL (or whatever setting you configured for your field return value)
  3. Your code won't delete the image if a user replaces it with a new one (only processes if $value is empty)

Here it is revised:

function wpse_83587_delete_image( $value, $post_id, $field  ) {
    $old_value = get_field( $field['name'], $post_id, false /* Don't format the value, we want the raw ID */ );

    if ( $old_value && ( int ) $old_value !== ( int ) $value )
        wp_delete_attachment( $old_value, true );

    return $value;
}

add_filter( 'acf/update_value/type=image', 'wpse_83587_delete_image', 10, 3 );
  • Thanks for your help! I also need the same functionality for the acf gallery. Is there a similar hook which is called? – bengem Aug 28 '15 at 9:35
0

If anyone needs that for repeater fields, the above solution unfortunately does not work, since when the row numbers change, also the field names in the new value change.

For repeaters we have to catch the file fields earlier, when the repeater-updated hooks gets called.

We then compare the old rows with the new rows and for every file field we find in a row, check whether that file still exists in the new rows.

function pg_update_acf_repeater_field( $new_value, $post_id, $field ) {
    $old_value = get_field( $field['name'], $post_id, false );

    // If we changed the repeater fields
    if ( $old_value && ($old_value != $new_value) ) {
        // Go through each row of the old values
        foreach ( $old_value as $row ) {
            // Go through each field of the row and check whether it is a file field
            foreach ( $row as $field_key => $field_value ) {
                // We get the field details of our current field
                $field_data = array_filter( $field['sub_fields'], function( $el ) use ($field_key) {
                    return $el['key'] == $field_key;
                });

                // If we find a file, we check whether it is still present in the new repeater rows as well
                if ( $field_data && in_array( array_values($field_data)[0]['type'], array('image', 'file')) ) {
                    $found = false;
                    if ( $new_value ) {
                        foreach ( $new_value as $row ) {
                            if ( $row[$field_key] == $field_value ) $found = true;
                        }
                    }
                    if ( !$found ) {
                        wp_delete_attachment( $field_value );
                    }
                }
            }
        }
    }
    return $new_value;
}
add_filter( 'acf/update_value/type=repeater', 'pg_update_acf_repeater_field', 10, 3 );
  • This no longer works as $new_value returns a count rather than the array. – James May 21 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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