Search code examples
laravel-5laravel-filesystem

Laravel file upload creates folder with a temp file


I'm trying to get my application to upload files to "public/uploads/documentos/{the-id}" but can't figure out what's wrong with my current setup. Right now, if I upload a file called "myfile.pdf", it creates a folder named "myfile.pdf" and inside of it a *.tmp file. In my database, "{the-id}/myfile.pdf" is saved as the file url but this takes me to the folder view, when what I want is to see the file inside of it.

How can I change it so that when a document is upload, it creates the file "myfile.pdf" directly under "public/uploads/documentos/{the-id}" so that I can access it like that? {the-id} is a folder created based on the patient's id, so all documents belonging to them are saved to the same folder.


Controller

    public function store(Request $request)
    {
        $this->validate($request, [
            'tipo' => 'required|max:100',
            'descripcion' => 'max:200',
            'fecha_documento' => 'max:20',
            'archivo' => 'required|mimes:doc,docx,pdf,jpg,png,jpeg',
            'mascota_id' => 'required',
            'mascota_num' => 'required',
        ]);
                
        $documento = new Documento;
        $documento->mascota_num = $request->input('mascota_num');
        $documento->mascota_id = $request->input('mascota_id');
        $documento->tipo = ucfirst($request->input('tipo'));
        $documento->descripcion = ucfirst($request->input('descripcion'));
        $documento->fecha_documento = $request->input('fecha_documento');
        
        if($request->hasFile('archivo')) {
            $archivo = $request->file('archivo');
            $archivo_folder = public_path('/uploads/documentos/') . $request->input('mascota_num');         
            $archivo_nombre = $archivo->getClientOriginalName();
            $archivo_url = $archivo_folder . '/' . $archivo_nombre;
            
            if (file_exists($archivo_folder)) {
                $archivo->move($archivo_folder . '/' . $archivo_nombre);
            } else {
                File::makeDirectory($archivo_folder, $mode = 0777, true, true);
                $archivo->move($archivo_folder . '/' . $archivo_nombre);
            }
            
            $documento->archivo = $request->input('mascota_num') . '/' . $archivo_nombre;
            $documento->save();
        
            return redirect()->route('mascotas.show', [$request->input('mascota_num')])->with('message', 'Documento agregado exitosamente.');
        }
    }

How my uploaded files look with this code:

uploads/documentos/

-- 1
  -- file.pdf /folder
    -- random_name.tmp /file
-- 2
  -- file.pdf /folder
    -- random_name.tmp /file
  -- otherfile.pdf /folder 
    -- random_name.tmp /file

}

What I want

uploads/documentos/

-- 1
  -- myfile.pdf /file
-- 2
  -- myfile.pdf /file
  -- otherfile.pdf /file

Ideally, I'd like to keep the files private, so I tried to upload them to the storage folder with this code:

Storage::put('documentos/'.$request->input('mascota_num').'/', $archivo_nombre);
$documento->archivo = Storage::url('documentos/'.$request->input('mascota_num').'/'.$archivo_nombre);

but {the-id} folder wasn't created and the files weren't saved, all I got was:

storage/app/documentos/

-- 1 /file without extension
-- 2 /file without extension

I'd settle for making the first part work for now. Thanks in advance for your help.


Solution

  • After much trial and error, I managed to upload files to the storage folder of my application.

    if($request->hasFile('archivo')) {
        $archivo = $request->file('archivo');
    
        Storage::disk('documentos')->put($request->input('mascota_num') . '/' . $archivo->getClientOriginalName(),  File::get($archivo));
                                
        $documento->archivo = $request->input('mascota_num') . '/' . $archivo_nombre;
        $documento->save();
    }
    

    Files are saved to /storage/app/public/documentos/ under the correct patient id folder and with the correct file name.

    I haven't found a way to correctly link to the files from my show blade, Storage::url('documentos/'.$documento->archivo)) shows a 404 error page, even though the file path is correct. Hopefully I can get this working next.