hasanhawary / media-manager
Flexible Laravel media manager: accept media from UploadedFile, base64, URLs, or local paths and store on any filesystem disk.
Installs: 129
Dependents: 1
Suggesters: 0
Security: 0
Stars: 2
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/hasanhawary/media-manager
Requires
- php: >8.0
- illuminate/support: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
README
A powerful, fluent Laravel package for managing file uploads, replacements, chunked uploads, URL generation, metadata, and safe deletion. Works with any disk (local, public, s3, etc.) and supports multiple input types (UploadedFile, base64, URL, raw content, or local path).
⚡ Installation
composer require hasanhawary/media-manager
Auto-discovered in Laravel.
Facade alias: Media → HasanHawary\MediaManager\Facades\Media.
Ensure your disks are configured in config/filesystems.php.
🟢 Quick Start
Upload a file
use HasanHawary\MediaManager\Facades\Media; $path = Media::upload($request->file('avatar'), 'uploads/avatars'); $url = Media::url($path);
Fluent API:
$path = Media::on('public') ->generateName('uuid') // naming strategy ->visibility('private') // visibility ->fallbackExtension('png') // optional fallback ->upload($file, 'uploads/photos');
🔹 Supported Input Types
| Input Type | Example |
|---|---|
UploadedFile |
$request->file('avatar') |
| Base64 string | $base64Image |
| URL | 'https://example.com/photo.jpg' |
| Raw content | 'Hello world' |
| Local path | storage_path('temp/file.pdf') |
Media::upload($request->file('avatar'), 'uploads/avatars'); Media::upload($base64Image, 'uploads/images'); Media::upload('https://example.com/photo.jpg', 'uploads/images'); Media::upload(file_get_contents('path/to/file.txt'), 'uploads/docs'); Media::upload(storage_path('app/temp/logo.png'), 'uploads/logos');
🔹 Naming Strategies
| Strategy | Description |
|---|---|
uuid |
Default; auto-generated UUID |
hash |
MD5 hash of file contents |
timestamp |
Current timestamp |
original |
Keep the original filename |
custom |
Custom string or closure |
Media::generateName('hash')->upload($file, 'uploads/files'); Media::generateName('timestamp')->upload($file, 'uploads/files'); Media::keepOriginalName()->upload($file, 'uploads/files'); Media::withName(fn() => 'custom_name_' . time())->upload($file, 'uploads/files');
🔹 Replace Existing Files
$path = Media::replace($user->avatar)->upload($request->file('avatar'), 'uploads/avatars'); $user->update(['avatar' => $path]);
| Input Value | Behavior |
|---|---|
null or '' |
Keep old file |
'delete' |
Deletes old file and returns null |
| Same path | Keeps existing file |
| New file | Uploads new file and deletes old safely |
🔹 Chunk Uploads (Media::chunk())
Upload large files in chunks:
Parameters ($data):
| Parameter | Type | Description |
|---|---|---|
file_name |
string | Original file name (with extension) |
chunk_number |
int | Current chunk number (starts at 1) |
chunk_file |
UploadedFile | File chunk |
is_final |
bool (optional) | True if last chunk (merges automatically) |
user_id |
int (optional) | ID of user; defaults to auth()->id() |
directory |
string (optional) | Final file directory (default: uploads) |
$path = Media::chunk([ 'file_name' => $request->file_name, 'chunk_number' => $request->chunk_number, 'chunk_file' => $request->file('chunk_file'), 'is_final' => $request->boolean('is_final'), 'user_id' => $request->user_id, // optional 'directory' => 'videos', // optional ]); if ($request->boolean('is_final')) { echo "Final file saved at: $path"; } else { echo "Chunk {$request->chunk_number} uploaded successfully"; }
🔹 URL Generation
Media::url($path); // Absolute URL Media::on('public')->url($path); // Disk-specific Media::on('s3')->temporaryUrl($path, 10); // Temporary URL (minutes) Media::on('s3')->signedUrl($path, now()->addDay()); // Signed URL
🔹 Metadata
$meta = Media::meta('uploads/docs/report.pdf'); $meta->size(); // bytes $meta->mime(); // mime type $meta->extension(); // file extension $meta->basename(); // file name $meta->dimensions(); // [width, height] $meta->toArray(); // all metadata
🔹 File Operations
Media::exists($path); // Check if file exists Media::delete($path); // Delete file Media::safeDelete($path); // Move to trash
Safe delete moves files to trash/ instead of permanently deleting.
🔹 Advanced Options
Media::on('s3') ->visibility('private') ->generateName('hash') ->fallbackExtension('png') ->safeDelete(true) ->upload($file, 'uploads');
✅ Compatibility
- PHP: 8.0 → 8.5
- Laravel: 8 → 12
🆕 Changelog (v1.2.0)
- Added
chunk()for large file uploads - Added all naming strategies:
uuid,hash,timestamp,original,custom - Fluent API for disk, visibility, fallback extension
- Safe delete (
safeDelete) and metadata support - Improved documentation and examples
📜 License
MIT © Hasan Hawary