jonhassall/has-uploaded-file
Composer 安装命令:
composer require jonhassall/has-uploaded-file
包简介
Trait for Laravel Eloquent models that manage uploaded files across storage disks
README 文档
README
A Laravel package that provides a reusable trait for Eloquent models that manage uploaded files. It standardizes upload state, file metadata, download helpers, streaming responses, and automatic cleanup when a model is deleted.
Features
HasUploadedFile Trait
Attach this trait to any model whose primary responsibility is tracking a stored file.
Key Features:
- Upload State Tracking: Consistent
uploaded_atandfile_sizehandling - Automatic Cleanup: Deletes the stored file when the model is deleted
- Query Scopes: Filter uploaded and not-yet-uploaded records
- Download Helpers: Binary download, inline view, stream download, and storage response helpers
- Storage Agnostic: Works across local and remote Laravel disks
- Migration Helpers: Add or remove the standard columns from migrations
Requirements
- Laravel: 10.x through 13.x
- PHP: 8.1 or higher
Installation
Option 1: Via Packagist
Install the package via Composer:
composer require jonhassall/has-uploaded-file
Option 2: Install Directly from GitHub
Add this to your composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/jonhassall/HasUploadedFile.git"
}
],
"require": {
"jonhassall/has-uploaded-file": "dev-main"
}
}
Then run:
composer install
Versioning and Branches
- Stable releases use semantic version tags, for example:
v1.0.0 - The
mainbranch is the primary development branch - Composer branch alias maps
dev-mainto1.x-devfor users tracking development - Patch releases should branch from
main, then be tagged and pushed
Release example:
git checkout main
git pull origin main
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin main --tags
Full release checklist: RELEASE_CHECKLIST.md
Quick Start
Step 1: Add the Required Columns
Create or update your migration:
use App\Models\Document; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; Schema::create('documents', function (Blueprint $table) { $table->id(); $table->string('path'); $table->string('disk')->default('public'); Document::addUploadedFileColumns($table); $table->timestamps(); });
Step 2: Add the Trait to Your Model
namespace App\Models; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use JonHassall\HasUploadedFile\HasUploadedFile; class Document extends Model { use HasUploadedFile; protected $fillable = ['path', 'disk']; protected function filePath(): Attribute { return Attribute::make( get: fn () => $this->path, ); } protected function storageDiskName(): Attribute { return Attribute::make( get: fn () => $this->disk, ); } }
Usage Examples
Marking Upload State
$document->markAsUploaded(true); $document->markAsNotUploaded(true); if ($document->is_uploaded) { // File is marked as uploaded }
Querying Uploaded Records
$uploaded = Document::uploaded()->get(); $pending = Document::notUploaded()->get();
Checking Storage State
if ($document->fileExists()) { // Trust the cached uploaded flag } if ($document->fileExists(true)) { // Check the underlying storage disk } $size = $document->getFileSize(true); $url = $document->getFileUrl();
Returning File Responses
return $document->downloadFile('report.pdf'); return $document->streamDownload('report.pdf'); return $document->viewFile('report.pdf'); return $document->getFileResponse('report.pdf');
Moving a File Between Disks
$document->moveFileToDisk('s3', function ($model, $targetDisk) { $model->disk = $targetDisk; $model->save(); });
Soft Deletes
By default, the package does not delete files during a soft delete. Files are deleted when the model is force deleted.
If you want files removed on soft delete as well, override this method in your model:
protected function deleteUploadedFileOnSoftDelete(): bool { return true; }
Notes and Caveats
filePath()andstorageDiskName()are required accessors.- The trait expects
uploaded_atandfile_sizecolumns on the model table. streamWithRanges()supports byte range streaming for local files automatically. For remote disks, range requests are only honored when the stream is seekable; otherwise it falls back to a normal streamed response.getFileResponse()may load more data into memory depending on the storage driver implementation. PreferstreamDownload()orviewFile()for larger files.
Releasing
Use RELEASE_CHECKLIST.md for the release workflow.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-15