My function lets users delete their uploaded images in the front-end. However, they're only deleted in the Media Library. That means that they're still in wp-content/uploads/.

     public static function removePhoto($ID, $attachment) {
     if(isset(self::$data['user']['photos'][$attachment])) {
        core:updateUserMeta($ID, 'photos', self::$data['user']['photos']);

This is how how the images are added:

public static function uploadImage($file) {
    $attachment=array('ID' => 0);
        if(JBSUser::$data['user']['membership']['photos']<=0) {
        JBSInterface::$messages[]=__('You have exceeded the number of photos', 'epic');
         return $file;


    if(!empty($file['name'])) {
        $filetype=wp_check_filetype($file['name'], null);
        $filename=wp_unique_filename($uploads['path'], 'image-1.'.$filetype['ext']);

            //validate file
        if (!in_array($filetype['ext'], array('jpg', 'JPG', 'jpeg', 'JPEG', 'png', 'PNG'))) {
            JBSInterface::$messages[]=__('Only JPG and PNG images are allowed.', 'epic');
        } else if(move_uploaded_file($file['tmp_name'], $filepath)) {

                //upload image
                    'guid' => $uploads['url'].'/'.$filename,
                    'post_mime_type' => $filetype['type'],
                    'post_title' => sanitize_title(current(explode('.', $filename))),
                    'post_content' => '',
                    'post_status' => 'inherit',
                    'post_author' => get_current_user_id(),

                //add image
                $attachment['ID']=wp_insert_attachment($attachment, $attachment['guid'], 0);
                update_post_meta($attachment['ID'], '_wp_attached_file', substr($uploads['subdir'], 1).'/'.$filename);

                //add thumbnails
                $metadata=wp_generate_attachment_metadata($attachment['ID'], $filepath);
                wp_update_attachment_metadata($attachment['ID'], $metadata);

        } else {
            JBSInterface::$messages[]=__('This image is too large for uploading.','epic');

    return $attachment;

Update: Setting wp_delete_attachment, true - does not work.

I'm suspicious of: substr($uploads['subdir'], 1).'/'.$filename); Which seems to upload the files to subfolder. But the images are still uploaded to the wp-content/uploads/ regardless if the "organize" setting is on or off.

Should this really effect the wp_delete_attachment?

  • 1
    I have the same problem. I think it's because you are not adding the image via wp_handle_upload. When I add it via wp_handle_upload wp_delete_attachment works. But when adding via file_put_contents or something else it does not. Did you figure this out otherwise? I tried unlink(), but you need to provide all thumbnail images then (300x300 etc..) – trainoasis Nov 16 '15 at 9:09
  • @trainoasis Doesnt work for me either, I am adding files throughmedia_handle_upload though (after sanitization) - which basically calls wp_handle_upload inside – jave.web Oct 10 '18 at 9:46

You need to provide wp_delete_attachment a value of true for it's second argument force_delete. Your code needs to change to wp_delete_attachment( $attachment, true );

  • Adding the value true to wp_delete_attachment doesnt fix the issue. The uploaded file is still in wp_content/uploads – dkl Mar 21 '15 at 16:43
  • What do you think about the substr($uploads['subdir'], 1).'/'.$filename); in the upload function? – dkl Apr 14 '15 at 8:06

You forgot to add second parameter for the function wp_delete_attachment

 <?php wp_delete_attachment( $attachmentid, $force_delete ); ?> 

(integer) (required) The ID of the attachment you would like to delete.
Default: None

$force_delete (bool) (optional) Whether to bypass trash and force deletion (added in WordPress 2.9).
Default: false

  • 2
    Thank you for the reply. But adding force_delete does not fix the issue. – dkl Mar 21 '15 at 16:39
  • What do you think about the substr($uploads['subdir'], 1).'/'.$filename); in the upload function? – dkl Apr 14 '15 at 8:06

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