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

v0.5.2 2025-11-19 20:11 UTC

This package is auto-updated.

Last update: 2025-12-20 19:25:31 UTC


README

Build coverage License

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

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.