New

Just launched: Vueblocks, a brand-new search engine for Vue packages! Explore Vueblocks →

esign/laravel-model-files

Associate files with your Laravel Models
13,202
Install
composer require esign/laravel-model-files
Latest Version:1.8.0
PHP:^8.1
Laravel:11 · 12 · 13
Older releases:8 · 9 · 10
License:MIT
Last Updated:Mar 24, 2026
Links: GitHub  ·  Packagist
Maintainer: esign

Associate files with your Laravel Models

Latest Version on Packagist Total Downloads GitHub Actions

This package allows you to store files for models in an opinionated way.

Installation

You can install the package via composer:

composer require esign/laravel-model-files

Usage

Preparing your model

To associate files with your model you need to use the Esign\ModelFiles\Concerns\HasFiles trait on the model.

use Esign\ModelFiles\Concerns\HasFiles;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFiles;
}

The database structure should look like the following:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->boolean('file')->default(0);
    $table->string('file_filename')->nullable();
    $table->string('file_mime')->nullable();
});

Configuring the disk

By default, the files will be associated with the default disk configured in your config/filesystems.php file. You may override this by defining the getFileDisk method on your model.

use Esign\ModelFiles\Concerns\HasFiles;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFiles;

    public function getFileDisk(): string
    {
        return 'public';
    }
}

Storing files

To store files you may use the storeFile method. This method accepts instances of both the Illuminate\Http\File and Illuminate\Http\UploadedFile classes.

$post->storeFile('file', $request->file('attachment'));

To store raw string content, use the storeFileFromString method.

$post->storeFileFromString('file', 'Hello world');

$post->storeFileFromString('file', '{"key":"value"}');

Retrieving file info

$post->hasFile('file'); // returns true/false
$post->getFolderPath('file'); // returns posts/file
$post->getFilePath('file'); // returns posts/file/1.pdf
$post->getFilePathOnDisk('file'); // returns /path/to/storage/app/public/posts/file/1.pdf
$post->getFileMime('file'); // returns application/pdf
$post->getFileExtension('file'); // returns pdf
$post->getFileUrl('file'); // returns https://www.example.com/storage/posts/file/1.pdf
$post->getVersionedFileUrl('file'); // returns https://www.example.com/storage/posts/file/1.pdf?t=1675776047

Deleting files

$post->deleteFile('file');

Using with underscore translatable

This package ships with support for the underscore translatable package.

Make sure to include the file, filename and mime columns within the translatable array:

use Esign\ModelFiles\Concerns\HasFiles;
use Esign\UnderscoreTranslatable\UnderscoreTranslatable;
use Illuminate\Database\Eloquent\Model;

class UnderscoreTranslatablePost extends Model
{
    use HasFiles;
    use UnderscoreTranslatable;

    public $translatable = [
        'document',
        'document_filename',
        'document_mime',
    ];
}

Next up, your migrations should look like the following:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->boolean('document_en')->default(0);
    $table->boolean('document_nl')->default(0);
    $table->string('document_filename_en')->nullable();
    $table->string('document_filename_nl')->nullable();
    $table->string('document_mime_en')->nullable();
    $table->string('document_mime_nl')->nullable();
});

You may now use the internal methods using the default or the specific locale:

$post->hasFile('document'); // returns true/false
$post->getFolderPath('document'); // returns posts/document_en
$post->getFilePath('document'); // returns posts/document_en/1.pdf
$post->getFileMime('document'); // returns application/pdf
$post->getFileExtension('document'); // returns pdf
$post->getFileUrl('document'); // returns https://www.example.com/storage/posts/document_en/1.pdf
$post->getVersionedFileUrl('document'); // returns https://www.example.com/storage/posts/document_en/1.pdf?t=1675776047
$post->hasFile('document_en'); // returns true/false
$post->getFolderPath('document_en'); // returns posts/document_en
$post->getFilePath('document_en'); // returns posts/document_en/1.pdf
$post->getFileMime('document_en'); // returns application/pdf
$post->getFileExtension('document_en'); // returns pdf
$post->getFileUrl('document_en'); // returns https://www.example.com/storage/posts/document_en/1.pdf
$post->getVersionedFileUrl('document_en'); // returns https://www.example.com/storage/posts/document_en/1.pdf?t=1675776047

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.

Related Packages

esign/laravel-email-whitelisting

Whitelist outgoing email

24,913 4
esign/laravel-linkable

Dynamically link Laravel models

21,423 0
esign/laravel-query-filters

Apply filters to Laravel's query builder.

15,201 0
esign/laravel-breadcrumbs

Manage breadcrumbs within your Laravel application

14,534 0
esign/laravel-sentry-throttling

Throttle exceptions being sent to Sentry

10,430 0

Version History

Version Released PHP Laravel License
1.8.0 ^8.1 ^11.0|^12.0|^13.0 MIT
1.7.0 ^8.1 ^11.0|^12.0|^13.0 MIT
1.6.0 ^8.1 ^10.0|^11.0|^12.0 MIT
1.5.0 ^8.0 ^8.0|^9.0|^10.0|^11.0 MIT
1.4.0 ^8.0 ^8.0|^9.0|^10.0|^11.0 MIT