luchavez/simple-files

A simple approach to adding polymorphic files such as images to any Eloquent models in Laravel 9|10

1.4.1 2024-02-13 13:54 UTC

README

Latest Version on Packagist Total Downloads GitHub Repo stars Discord Twitter Follow

Simple Files Banner

Introduction

Implementing a public-private filesystem structure to your Laravel application can be a hassle. But with "luchavez/simple-files", it's easy! This package is built with that in mind so that you can proceed with more important things in your project. It's perfect for Laravel applications that need to work with files. And the best part? It can process not only uploaded files but also Base64 strings and image URLs! Plus, it's especially effective on AWS S3 buckets. Try it out today and see how it can help you!

Check out the examples below to get a clearer picture.

Installation

Via Composer

$ composer require luchavez/simple-files:^1.0.0

Setting Up

  1. Add the HasFilesTrait trait to all the Eloquent models that can own files.

  2. Run the migrations to add the files and fileables tables.

  3. Add these variables to .env file if you want to override the default values.

Usage

SimpleFiles

The package provides a service called SimpleFiles which you can use by calling its helper functions:

  1. simpleFiles()
  2. simple_files()

Here's the list of its available methods.

HasFilesTrait

The package also provides HasFilesTrait which you can use on Eloquent models that you want to have files or images.

  • If a User model needs profile pictures...
use Luchavez\SimpleFiles\Traits\HasFilesTrait;

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasFilesTrait;
...
  • Or, if a Company model needs logos...
use Luchavez\SimpleFiles\Traits\HasFilesTrait;

class Company extends Model
{
    use HasFactory, HasFilesTrait;
...
  • Or, if a Food model needs some Instagram-worthy images...
use Luchavez\SimpleFiles\Traits\HasFilesTrait;

class Food extends Model
{
    use HasFactory, HasFilesTrait;
...

Here's the list of methods that will be added to Eloquent models.

Examples

Note: In case you did not specify the user who uploaded the file, it will try to get the authenticated user via auth()->user().

Here are the .env variables used in this example:

SF_FILESYSTEM_DISK=s3
SF_PUBLIC_DIRECTORY=public/dev/dummy
SF_PRIVATE_DIRECTORY=private/dev/dummy
SF_EXPIRE_AFTER=1 day

Uploading files

Let's start first by creating a public route /api/files. Use storePublicly() and storePrivately() methods of simpleFiles() global helper function to store the files on public/dev/dummy and private/dev/dummy directories respectively.

  • Using storePublicly() with $request->user() as uploader.
Route::post('/files', function (Request $request) {
    $file = $request->file;
    $user = $request->user();
    
    return simpleFiles()->storePublicly(file: $file, user: $user)->toArray();
});
  • Using storePrivately() with $request->user() as uploader.
Route::post('/files', function (Request $request) {
    $file = $request->file;
    $user = $request->user();
    
    return simpleFiles()->storePrivately(file: $file, user: $user)->toArray();
});

Once that is set up, we can use Postman to upload files to the route above.

  • Here's an example of normal FormData file upload using storePublicly().

img.png

  • Here's an example of normal FormData file upload using storePrivately().

img.png

  • Here's an example of Base64 encoded file upload using storePublicly().

img.png

  • Here's an example of Base64 encoded file upload using storePrivately().

img.png

  • Here's an example of file upload from URL using storePublicly().

img.png

  • Here's an example of file upload from URL using storePrivately().

img.png

Note: If you will open an expired url, you'll receive a Request has expired error.

img.png

Attaching files

To attach an uploaded file to a model, use the attachFiles() method from HasFilesTrait.

  • If a User model needs profile pictures...
Route::post('upload-files', function (Request $request) {
    $user = \App\Models\User::query()->first();
    $for_upload = $request->file;
    
    // You can attach like this...
    $file = simpleFiles()->storePublicly(file: $for_upload);
    $user->attachFiles(file: $file);
    
    // Or using a one-liner...
    $user->attachPublicFiles(file: $for_upload)
    
    return simpleResponse()->message('Successfully attached files.')->generate();
});
  • Or, if a Company model needs logos...
Route::post('upload-files', function (Request $request) {
    $company = \App\Models\Company::query()->first();
    $for_upload = $request->file;
    
    // You can attach like this...
    $file = simpleFiles()->storePublicly(file: $for_upload);
    $company->attachFiles(file: $file);
    
    // Or using a one-liner...
    $company->attachPublicFiles(file: $for_upload)
    
    return simpleResponse()->message('Successfully attached files.')->generate();
});
  • Or, if a Food model needs some Instagram-worthy images...
Route::post('upload-files', function (Request $request) {
    $food = \App\Models\Food::query()->first();
    $for_upload = $request->file;
    
    // You can attach like this...
    $file = simpleFiles()->storePublicly(file: $for_upload);
    $food->attachFiles(file: $file);
    
    // Or using a one-liner...
    $food->attachPublicFiles(file: $for_upload)
    
    return simpleResponse()->message('Successfully attached files.')->generate();
});

Change log

Please see the changelog for more information on what has changed recently.

Testing

$ composer test

Contributing

Please see contributing.md for details and a todolist.

Security

If you discover any security related issues, please email author@email.com instead of using the issue tracker.

Credits

License

MIT. Please see the license file for more information.