warpig's avatar
Level 12

Image uploads, delete old, store and display new

For the sake of code cleanliness im deleting some lines that don't directly associate with the topic.

I want to update an image but i also don't want to keep the old file whenever it's done updating,.

So when it comes to the image on the Controller, all required parameteres were removed, from the front-end and validation, maybe I will introduce a static picture later on, but the below code works.

    public function store(Profile $profile)
    {
        $profile = request()->validate([
            full_name ...
            bio ...
            'profile_pic' => ['image', 'nullable'],
            linkedin_url ...
            optional ...
        ]);
        
        if(request()->has('profile_pic')) {
            $profile['profile_pic'] = request()->file('profile_pic')->store('profiles');
        }

        $profileObject = new Profile($profile);
        $profileObject->save();

        return redirect(....)
    }

No problem there but when I want to update; which means: select new file, delete old file, upload new selected file; the old file is not getting deleted, the new updated file does makes its way into the folder but it doesn't appear in the front-end. There's also no problems or exceptions being thrown.

    public function update(Profile $profile, Request $request)
    {   
        if ($request->has('profile_pic')) {
            Storage::disk('public')->delete('profiles'.$profile->profile_pic);
            $path = Storage::disk('public')->put('profiles', $request->file('profile_pic'));
            $profile->profile_pic = basename($path);
            $profile->save();
        }

        $profile->update($this->validateProfile($request));

        return redirect('/profile')->with('edit_profile', 'You\'ve now changed your profile!');
    }

I dd through all of those lines and this is what I could understand:

  • The file gets received after the if statement.
  • When I added the "delete" statement using Storage facade, the old file is not gone from the folder, and I don't think theres a way for me to know from this below, all I see is the new file which is called "yeehaw.png"
  +files: Symfony\Component\HttpFoundation\FileBag {#49 ▼
    #parameters: array:1 [▼
      "profile_pic" => Symfony\Component\HttpFoundation\File\UploadedFile {#34 ▼
        -test: false
        -originalName: "yeehaw.png"
        -mimeType: "image/png"
        -error: 0
        path: "/private/var/tmp"
        filename: "phpjDE6yD"
        basename: "phpjDE6yD"
        pathname: "/private/var/tmp/phpjDE6yD"
        extension: ""
        realPath: "/private/var/tmp/phpjDE6yD"
        aTime: 2021-12-18 18:47:57
        mTime: 2021-12-18 18:47:57
        cTime: 2021-12-18 18:47:57
        inode: 28435136
        size: 76295
        perms: 0100600
        owner: 501
        group: 0
        type: "file"
        writable: true
        readable: true
        executable: false
        file: true
        dir: false
        link: false
      }
    ]
  }
  • No old file is deleted but the new one makes its way into the folder.
  • Path seems to be the correct one: "profiles/QB9tBwggZOyHRT8IgN38hixkjTYOYwcbRtC4qrq4.png"
  • Once it reaches the last line with the save() I get something like this:
  #original: array:9 [▼
    "id" => 15
    "user_id" => 1
    "full_name" => "Eduardo Robles Coello"
    "bio" => "About me..."
    "profile_pic" => "eE77KiFfwYqQFicW7vyRVRTtCNrbXzjxKFKw8Lao.png"
    "linkedin_url" => "https://www.linkedin.com/in/hola-eduardo"
    "optional" => "Let go and let God"
    "created_at" => "2021-12-18 18:36:02"
    "updated_at" => "2021-12-18 18:52:43"
  ]
0 likes
4 replies
Sergiu17's avatar

eE77KiFfwYqQFicW7vyRVRTtCNrbXzjxKFKw8Lao.png this is the name of the file,

'profiles'.$profile->profile_pic this is what you pass to the delete method, I think a / slash is required between profiles folder and $profile->profile_pic

try this

Storage::disk('public')->delete('profiles/' . $profile->profile_pic);
warpig's avatar
Level 12

The reason why I can't see it on the front-end is because it only sends the file name to the database, and omits the profile folder, like: Zy6ma8SJ21SCgXuDHSl1LeI38D34Dzuzv7Hwu7IM.png

    public function update(Profile $profile, Request $request)
    {   
        $profile->update($this->validateProfile($request));

        if ($request->has('profile_pic')) {
            Storage::disk('public')->delete('profiles/'.$profile->profile_pic);
            $path = Storage::disk('public')->put('profiles/', $request->file('profile_pic'));
            $profile->profile_pic = basename($path);
            $profile->save();
        }

        $profile->save();

        return redirect('/profile')->with('edit_profile', 'You\'ve now changed your profile!');
    }

So that could explain why it's not deleting? I can't see where the error might be I am specifying profiles in there...

Interesting. I dd'ed the $path variable from this line: $profile->profile_pic = basename($path); and got this: "profiles/IgSbdzOicuNwGOFE45iJZMimAxArh9CvFHwYHDZA.png" so that would be the correct path and that would make it work from the database.

I dd $profile from $profile->save(); but the path changes??

"profile_pic" => "b1MW0vtWQx9gP6FOW1osCzzuCZPsbjIeA35F0Y3W.png"

I realize that when the request hits this line:

$profile->profile_pic = basename($path);

At this point the picture is in the tmp_var folder but as far as I can understand the $path has the correct path, so what is going on here? Could someone explain??

warpig's avatar
Level 12

I removed basename from

$profile->profile_pic = basename($path);

Please or to participate in this conversation.