PHPackages                             hasanhawary/media-manager - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. hasanhawary/media-manager

ActiveLibrary[File &amp; Storage](/categories/file-storage)

hasanhawary/media-manager
=========================

Flexible Laravel media manager: accept media from UploadedFile, base64, URLs, or local paths and store on any filesystem disk.

v1.3.0(3mo ago)42941MITPHPPHP &gt;8.0CI failing

Since Sep 20Pushed 3mo agoCompare

[ Source](https://github.com/hasanhawary/media-manager)[ Packagist](https://packagist.org/packages/hasanhawary/media-manager)[ Docs](https://github.com/hasanhawary/media-manager)[ RSS](/packages/hasanhawary-media-manager/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (11)Used By (1)

Media Manager
=============

[](#media-manager)

[![Latest Stable Version](https://camo.githubusercontent.com/b21cbd7c3d0c330f201fe8e7730ef84da12a9899ee7abf9a4096804e3fbbe0af/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f686173616e6861776172792f6d656469612d6d616e616765722e737667)](https://packagist.org/packages/hasanhawary/media-manager)[![Total Downloads](https://camo.githubusercontent.com/b3bf8f1b6a138fe0a52cc7523071ff8a4f023db749bef09b374c3dcc1d7a0edb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f686173616e6861776172792f6d656469612d6d616e616765722e737667)](https://packagist.org/packages/hasanhawary/media-manager)[![PHP Version](https://camo.githubusercontent.com/f2aed7f9fd1e1dc13489ffd5fe580a8d36a0a2c535f90f37806e54582cd4fdfd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f686173616e6861776172792f6d656469612d6d616e616765722e737667)](https://packagist.org/packages/hasanhawary/media-manager)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

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
--------------

[](#-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
-------------

[](#-quick-start)

### Upload a file

[](#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
-----------------------

[](#-supported-input-types)

Input TypeExample`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
-------------------

[](#-naming-strategies)

StrategyDescription`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
------------------------

[](#-replace-existing-files)

```
$path = Media::replace($user->avatar)->upload($request->file('avatar'), 'uploads/avatars');
$user->update(['avatar' => $path]);
```

Input ValueBehavior`null` or `''`Keep old file`'delete'`Deletes old file and returns `null`Same pathKeeps existing fileNew fileUploads new file and deletes old safely---

🔹 Chunk Uploads (`Media::chunk()`)
----------------------------------

[](#-chunk-uploads-mediachunk)

Upload large files in chunks:

**Parameters (`$data`)**:

ParameterTypeDescription`file_name`stringOriginal file name (with extension)`chunk_number`intCurrent chunk number (starts at 1)`chunk_file`UploadedFileFile 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
----------------

[](#-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
----------

[](#-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
-----------------

[](#-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
------------------

[](#-advanced-options)

```
Media::on('s3')
    ->visibility('private')
    ->generateName('hash')
    ->fallbackExtension('png')
    ->safeDelete(true)
    ->upload($file, 'uploads');
```

---

✅ Compatibility
---------------

[](#-compatibility)

- **PHP:** 8.0 → 8.5
- **Laravel:** 8 → 12

---

🆕 Changelog (v1.2.0)
--------------------

[](#-changelog-v120)

- 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
---------

[](#-license)

MIT © [Hasan Hawary](https://github.com/hasanhawary)

---

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance82

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Total

9

Last Release

92d ago

PHP version history (2 changes)v1.0.0PHP ^8.0

v1.0.2PHP &gt;8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/33836947?v=4)[Hassan Elhawary](/maintainers/hasanhawary)[@hasanhawary](https://github.com/hasanhawary)

---

Top Contributors

[![hasanhawary](https://avatars.githubusercontent.com/u/33836947?v=4)](https://github.com/hasanhawary "hasanhawary (5 commits)")[![hassanmuhammd](https://avatars.githubusercontent.com/u/126090873?v=4)](https://github.com/hassanmuhammd "hassanmuhammd (1 commits)")

---

Tags

filesystemlaravelfilesstoragemediaupload

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hasanhawary-media-manager/health.svg)

```
[![Health](https://phpackages.com/badges/hasanhawary-media-manager/health.svg)](https://phpackages.com/packages/hasanhawary-media-manager)
```

###  Alternatives

[sausin/laravel-ovh

OVH Object Storage driver for laravel

40153.5k](/packages/sausin-laravel-ovh)[zing/laravel-flysystem-obs

Flysystem Adapter for OBS

1211.2k](/packages/zing-laravel-flysystem-obs)[gaspertrix/laravel-backpack-dropzone-field

Add Dropzone support for Laravel Backpack

172.2k](/packages/gaspertrix-laravel-backpack-dropzone-field)[dereuromark/cakephp-file-storage

This plugin is giving you the possibility to store files in virtually any kind of storage backend. This plugin is wrapping the Gaufrette library (https://github.com/KnpLabs/Gaufrette) library in a CakePHP fashion and provides a simple way to use the storage adapters through the StorageManager class.

104.1k](/packages/dereuromark-cakephp-file-storage)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
