atlas-php / assets
Atlas Assets is a standalone Laravel package for centralized asset storage and retrieval.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/atlas-php/assets
Requires
- php: ^8.2
- atlas-php/core: ^0.3.0
- illuminate/filesystem: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.15
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.24|^9.0
- phpunit/phpunit: ^10.5
README
Atlas Assets is a unified Laravel system for uploading, organizing, and retrieving files with a consistent API, predictable metadata, and configurable pathing. It removes scattered file-handling logic and replaces it with a clean, reliable Assets service.
Table of Contents
- Overview
- Installation
- Uploading Files
- Restricting File Extensions
- Limiting File Size
- Retrieving Files
- Managing Assets
- Sorting Assets
- Custom Pathing
- Also See
- Contributing
- License
Overview
Atlas Assets provides a single Asset model and service layer for all file operations in Laravel. Every file uploaded becomes a fully‑tracked asset with consistent metadata, optional model/user associations, configurable sorting, and customizable storage paths. It works with any Laravel filesystem disk and includes first‑class support for temporary URLs, polymorphic relationships, and per‑upload validation rules.
Installation
composer require atlas-php/assets
Publish configuration and migrations:
php artisan vendor:publish --tag=atlas-assets-config php artisan vendor:publish --tag=atlas-assets-migrations
Atlas Assets automatically follows your application's default filesystem disk (via FILESYSTEM_DISK/filesystems.default), so it works with local storage, S3, Spaces, or any driver Laravel supports. Override it per-environment using ATLAS_ASSETS_DISK.
Full steps: Install Guide
Uploading Files
Basic upload
$asset = Assets::upload($request->file('file'));
Upload and attach to a model
$asset = Assets::uploadForModel($post, $request->file('image'));
Upload with custom attributes
Define your own PHP backed enum to keep type values readable while storing compact integers:
enum DocumentAssetType: int { case Hero = 1; case Gallery = 2; case Invoice = 3; }
$asset = Assets::upload($request->file('file'), [ 'group_id' => $request->input('account_id'), 'label' => 'cover', 'category' => 'images', 'type' => DocumentAssetType::Hero->value, 'sort_order' => 2, ]);
- group_id: scope assets to multi‑tenant entities (accounts, teams, organizations).
- type: unsigned tinyint (0‑255). Back it with a PHP enum to document meaning and keep values consistent.
- sort_order: override auto-sorting when manual control is needed.
Restricting File Extensions
Global configuration (config/atlas-assets.php):
'uploads' => [ 'allowed_extensions' => ['pdf', 'png', 'jpg'], 'blocked_extensions' => ['exe', 'bat'], ],
Per‑upload override:
Assets::upload($file, [ 'allowed_extensions' => ['csv'], ]);
Blocklists always take precedence.
Limiting File Size
Default max size: 10 MB.
Global override:
'uploads' => [ 'max_file_size' => 20 * 1024 * 1024, ];
Per‑upload:
Assets::upload($file, [ 'max_upload_size' => 50 * 1024 * 1024, ]);
Disable per upload:
Assets::upload($file, [ 'max_upload_size' => null, ]);
Retrieving Files
Find an asset
$asset = Assets::find($id);
Get files for a model
$images = Assets::forModel($post)->get();
Temporary URL
$url = Assets::temporaryUrl($asset, 10);
Download file contents
$content = Assets::download($asset);
Stream fallback route
When your storage disk cannot generate temporary URLs, Assets falls back to a signed route named atlas-assets.stream. Customize or disable that route through config/atlas-assets.php:
'routes' => [ 'stream' => [ 'enabled' => true, 'uri' => 'atlas-assets/stream/{asset}', 'name' => 'atlas-assets.stream', 'middleware' => ['signed', SubstituteBindings::class], ], ],
Environment overrides:
ATLAS_ASSETS_STREAM_ROUTE_ENABLED=true
ATLAS_ASSETS_STREAM_ROUTE_URI=media/assets/{asset}
ATLAS_ASSETS_STREAM_ROUTE_NAME=media.assets.stream
Disable the built-in route when you prefer to register your own streaming endpoint (be sure to keep the configured route name in sync so signed URLs resolve correctly).
Managing Assets
Update asset metadata
Assets::update($asset, ['label' => 'hero']);
Replace file while keeping metadata
Assets::replace($asset, $request->file('new'));
Delete and purge
Assets::delete($asset); // soft delete + optional file removal via config Assets::delete($asset, true); // hard delete record + storage file immediately Assets::purge(); // permanently delete soft-deleted assets + files
Sorting Assets
Atlas Assets automatically assigns sort_order values based on configured scopes:
'sort' => [ 'scopes' => ['model_type', 'model_id', 'type'], ]
Customize scope or register a custom resolver:
'sort' => [ 'scopes' => ['group_id'], 'resolver' => function ($model, array $context) { return ($context['group_id'] ?? 0) * 10; }, ];
Disable auto-sorting:
'sort' => ['scopes' => null];
Manual override:
Assets::update($asset, ['sort_order' => 12]);
Custom Pathing
Pattern-based example
'path' => [ 'pattern' => '{model_type}/{model_id}/{uuid}.{extension}', ],
Configured callback example
'path' => [ 'resolver' => function (?Illuminate\Database\Eloquent\Model $model, Illuminate\Http\UploadedFile $file, array $attrs): string { return 'uploads/' . ($attrs['user_id'] ?? 'anon') . '/' . uniqid() . '.' . $file->extension(); }, ],
Reset to pattern behavior:
'path' => ['resolver' => null];
Also See
Contributing
See the Contributing Guide.
License
MIT — see LICENSE.