ivanhalen's avatar

Uploading a file and do some other tasks: any package that simplifies the job?

Hello, For some of my Models, I need to upload one or more files and store them within my Model: i.e. I need to upload an avatar for the User profile, or an image for each News I create, or attach a .pdf (i.e. a brochure) and a picture for a Product model.

Uploading a file and store its path within a Model it's a trivial task, but this is only half of the work and that's where situation get complicated: i.e. I'd need to:

  1. "slug" the filename: change 'My Product Picture.jpg' to 'my-product-picture.jpg'
  2. check if there's not yet a 'my-product-picture.jpg' file and, in case, change the new uploaded filename to 'my-product-picture_2.jpg' (and so on for subsequent uploads)
  3. create thumbnails and cache them
  4. if I'm updating a Model, well, delete old file(s) - and related thumbnails - before uploading new one(s), so I don't have "orphaned" files in storage
  5. deal with errors: if user tries to upload a file bigger than upload_max_filesize, well, tell him what's the problem (instead of the current generic 'The :attribute failed to upload.' message that ships with Laravel 5.3)

Since Laravel doesn't manage all these tasks (as far I as know), I created a custom UploadTrait that takes care of (almost) all these things, but it's quite a mess.

I'm sure that I ain't the first who has to deal with these tasks, and I was wondering if there is a Laravel package that can simplify the work: do you know any f these, or do you have suggestions?

Thanks

0 likes
4 replies
pmall's avatar
  • 1 & 2 I usually wrap my uploaded files into a storage wrapper so I can generate a suitable name and info for the file :
$wrapper = (new StorageWrapper($request->file))->store();

$wrapper->getName(); // Returns the custom name.

Usually I add a method to my model to associate it with the file :

$wrapper = (new StorageWrapper($request->file))->store();

$my_model->setFile($wrapper);
  • 3 You can use a queued jobs to execute those tasks as they are long running tasks.

  • 4 You can use model observer to handle this before update.

  • 5 You can throw exceptions and handle exceptions as error :

# in your app/Exceptions/Handler.php file
public function render($request, Exception $exception)
{
    // Handle exceptions.
    if ($exception instanceof FileTooBigException) {

        $errors = ['exception' => [$exception->getMessage()]];

         if ($request->wantsJson()) return response()->json($errors, 422);

         return redirect()->back()->withInput()->withErrors($errors);

    }

    return parent::render($request, $exception);
}
jekinney's avatar

Laravel helpers, validation and request object pretty much IMO is the easiest you can get (arguably). If you need to process images, well you'll have to pull in a plugin for that or pay for third party software via API.

Please or to participate in this conversation.