Z4n3tti
Z4n3tti

Reputation: 115

File storage issue

I have recently started to work with laravel voyager admin package, and I have an issue about file upload mechanism.

Firstly, I have create a folder on media menu "contacts": https://i.sstatic.net/qom28.png

After that, I have made a controller to deal with the contact form and which they can upload their curriculum vitae: https://i.sstatic.net/XIJ2d.png

In my ContactController, I have made some validations regarding the uploaded file, and some modifications on the name of the uploaded file if the user send the post request:

<?php

namespace App\Http\Controllers;

use App\Contact;
use Illuminate\Http\Request;
use App\Rules\Captcha;

class ContactController extends Controller
{
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function PostContact(Request $request) {
        //
        $this->validate($request, [
            'nom' => 'required|min:2|max:50',
            'prenom' => 'required|min:2|max:50',
            'email' => 'required|email',
            'organisme' => 'required',
            'fonction' => 'required',
            'pays' => 'required',
            'ville' => 'required',
            'telephone' => 'required|numeric|',
            'objet' => 'required',
            'fichier' => 'sometimes|nullable|mimes:doc,docx,pdf',
            'g-recaptcha-response' => new Captcha(),
            'message' => 'required|min:10']);

        $contact = new Contact;

        $contact->nom = $request->input('nom');
        $contact->prenom = $request->input('prenom');
        $contact->organisme = $request->input('organisme');
        $contact->fonction = $request->input('fonction');
        $contact->pays = $request->input('pays');
        $contact->ville = $request->input('ville');     
        $contact->email = $request->input('email');
        $contact->telephone = $request->input('telephone');
        $contact->objet = $request->objet;

        if ($request->hasFile('fichier')) {

            $filenameWithExt = $request->file('fichier')->getClientOriginalName();

            $filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);

            $extension = $request->file('fichier')->getClientOriginalExtension();

            $fileNameToStore = $filename.'_'.time().'.'.$extension;

            $path = $request->file('fichier')->storeAs('contacts', $fileNameToStore);

            $contact->fichier = $path;
        }

        $contact->message = $request->input('message');

        $contact->save();

        return redirect('contact')->with('status', 'Votre message a été envoyé avec succès !!');
    }
}

The CV file is successfully uploaded but not in the right destination, and contacts folder is creation in storage\app: https://i.sstatic.net/xMpfl.png https://i.sstatic.net/v44qn.png

When I create a new contact via voyager admin panel (contact bread) https://i.sstatic.net/lYnlo.png, the file uploaded goes into public\contacts\month-year-folder (May2019)\ and this is what I hope to do also using my contact form. https://i.sstatic.net/CUbS4.png

Can someone help me solving this issue?

PS: the command php artisan storage:link indicate that the "public/storage" directory already exists.

Also, I will show any file content if needed

Thanks.

Upvotes: 1

Views: 993

Answers (2)

Z4n3tti
Z4n3tti

Reputation: 115

Regarding @Leonardo Rossi's comment, I have resolved this issue by adding this into my config/filesystem.php:

        'contacts' => [
        'driver' => 'local',
        'root' => storage_path('app/public/contacts'),
        'url' => '/contacts',
        'visibility' => 'public',
    ],

and in the controller, because the file was stored in the correct folder, I have tried to get the path and then store it in database field (fichier) like that:

        if ($request->hasFile('fichier')) {

        $filenameWithExt = $request->file('fichier')->getClientOriginalName();

        $filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);

        $extension = $request->file('fichier')->getClientOriginalExtension();

        $fileNameToStore = $filename.'_'.time().'.'.$extension;

        /* $path = $request->file('fichier')->storeAs(public_path('contacts'), $fileNameToStore); */
        $now = new \DateTime('now'); //Datetime
        $monthNum = $now->format('m');
        $dateObj   = DateTime::createFromFormat('!m', $monthNum);
        $monthName = $dateObj->format('F'); // Month
        $year = $now->format('Y'); // Year

        $monthYear = $monthName.$year;

        Storage::disk('contacts')->putFileAs($monthYear, $request->file('fichier'), $fileNameToStore);

        $path = Storage::disk('contacts')->url($monthYear.'/'.$fileNameToStore);

        $contact->fichier = $path; 
    }

You can also have an idea of how can you create a folder using datetime elements (Month+Year) for my case.

Thanks.

Upvotes: 0

Leonardo Rossi
Leonardo Rossi

Reputation: 3022

First add a new entry in disks section of config/filesystem.php file

'contacts' => [
    'driver' => 'local',
    'root' => public_path('contacts'),
    'url' => env('APP_URL').'/contacts',
    'visibility' => 'public',
],

Then in your controller change the line

$path = $request->file('fichier')->storeAs('contacts', $fileNameToStore);

to

Storage::disk('contacts')->putFileAs($monthYear, $request->file('fichier'), $filename)

Of course you have to calculate your $monthYear variable to compute the subfolder name.

Upvotes: 1

Related Questions