mediaflow-laravel maintained by dwivedianuj9118
MediaFlow for Laravel
Universal media management infrastructure, provider-agnostic storage adapters, CDN delivery resolution, modern Blade shortcut input components, on-demand format conversion & compression, and hardware-accelerated 3D upload lifecycle visualization for Laravel applications.
📖 Live Documentation Portal: https://dwivedianuj9118.github.io/mediaflow-laravel/ (or locally at
/mediaflow/docs) for the complete interactive developer guide with 1-click code copying, live component demos, and API reference.
Key Features
- Shortcut Input Component (
<x-mediaflow-input>): Single drop-in tag for form upload boxes with drag & drop, file selection, "Browse Library" picker modal, model pre-population, and hidden media ID binding. - Side Admin Panel & Drawer Compatibility: Built-in
:compact="true"mode engineered for narrow administrative sidebars and drawers (280px–340px) withz-index: 9999999 !important;modal stacking isolation. - Universal PHP Upload API: Single contract for handling uploads in controllers, queued jobs, or API endpoints (
MediaFlow::upload()). - Decoupled Storage & Delivery: Clean separation between physical persistence (Local disk, Amazon S3, Cloudflare R2, MinIO) and URL resolution (Disk URLs, custom CDN domains, or time-limited signed streaming).
- On-Demand Compression & Conversion: Convert images to modern WebP or AVIF format with quality tuning and real-time savings metrics.
- Access Control & Guard Support: Protect media access using Laravel authentication guards (
web,admin,api), roles (admin,editor), Spatie permissions, or custom closure callbacks (MediaFlow::authorize(...)). - 3D Upload Lifecycle Visualizer: Interactive 3D isometric animation illustrating the entire 5-station pipeline (Disk Pick → Quarantine Buffer → UUID Rename → GD/Imagick Variants → Storage & CDN).
- Zero External Dependencies: 100% self-contained vanilla CSS and JavaScript with zero external CDN dependencies, light/dark mode auto-detection, and system theme inheritance.
Requirements
- PHP:
^8.2 | ^8.3(with extensions:fileinfo,gdorimagick,exif) - Laravel Framework:
^11.0 | ^12.0 | ^13.0 - Database: SQLite 3.35+, MySQL 8.0+, or PostgreSQL 14+
Installation
1. Require via Composer
composer require dwivedianuj9118/mediaflow-laravel
2. Publish Configuration, Migrations & Assets
# Publish configuration file (config/mediaflow.php)
php artisan vendor:publish --tag=mediaflow-config
# Publish database migrations
php artisan vendor:publish --tag=mediaflow-migrations
# Publish native CSS/JS assets (to public/vendor/mediaflow)
php artisan vendor:publish --tag=mediaflow-assets
3. Run Migrations & Link Storage
php artisan migrate
php artisan storage:link
Quick Usage: Blade Form Input Box
Drop a complete media upload and library picker box into any Blade form using <x-mediaflow-input>:
<form method="POST" action="/articles">
@csrf
<div class="form-group">
<label>Article Title</label>
<input type="text" name="title" class="form-control" required>
</div>
{{-- Drop-in MediaFlow Input Component --}}
<x-mediaflow-input
name="cover_media_id"
label="Featured Cover Image"
help="Drag & drop an image or select from your media library."
:required="true"
/>
<button type="submit" class="btn btn-primary">Publish</button>
</form>
(Note: The alias <x-mediaflow::input ... /> is also registered and interchangeable.)
Side Admin Panel / Drawer Mode (:compact="true")
When using inside narrow admin sidebars, off-canvas drawers, or column widgets (280px–340px):
<div class="admin-sidebar-drawer" style="width: 320px;">
<h3>Quick Post Settings</h3>
<x-mediaflow-input
name="sidebar_thumbnail_id"
label="Sidebar Thumbnail"
:compact="true"
help="Optimized for narrow sidebars."
/>
</div>
Pre-populating Existing Media on Edit
Pass an existing Media Eloquent model, integer ID, or URL string:
<x-mediaflow-input
name="cover_media_id"
label="Cover Image"
:value="$post->coverMedia ?? old('cover_media_id')"
/>
Component Props Reference
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
'media_id' |
Form field name submitted in POST requests. |
label |
string |
null |
Field label displayed above dropzone. |
value |
mixed |
null |
Initial media selection (Media model, ID integer, or URL). |
compact |
bool |
false |
Adapts layout and dimensions for narrow admin panels (≤ 340px). |
picker |
bool |
true |
Displays "🗂 Browse Library" button to select existing media. |
accept |
string |
'image/*' |
Allowed MIME type filter for file chooser. |
folder |
string |
null |
Target folder slug/UUID for uploads from this field. |
collection |
string |
'default' |
Target media collection classification name. |
required |
bool |
false |
Adds required asterisk indicator and validation flags. |
help |
string |
null |
Helper text rendered beneath the dropzone. |
Assets Directives
Add to your Blade master layout (layouts/app.blade.php):
<head>
@mediaflowStyles
</head>
<body>
@yield('content')
@mediaflowScripts
</body>
Backend Controller & Form Submission
When the user submits the form, $request->input('cover_media_id') contains the selected media.id:
use App\Models\Post;
use Illuminate\Http\Request;
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'cover_media_id' => 'nullable|integer|exists:media,id',
]);
$post = Post::create([
'title' => $validated['title'],
'cover_media_id' => $validated['cover_media_id'],
]);
return redirect()->back()->with('success', 'Post saved!');
}
Standalone Media Gallery Component
To embed the pure media library / gallery inside any custom admin view, modal, or dashboard tab without wrapper navbars:
<div class="my-custom-dashboard-card">
<h2>Media Library</h2>
{{-- Clean standalone media manager component --}}
<x-mediaflow-manager />
</div>
(Note: The alias <x-mediaflow::manager /> is also supported.)
Clean & Embedded Route Modes
The built-in route /mediaflow/manager runs in clean mode with developer navigation hidden by default.
- Headerless / Clean Mode (perfect for iframes or modals):
/mediaflow/manager?clean=1 - Pure Grid Mode (omits top uploader dropzone, shows only folders & files):
/mediaflow/manager?no_uploader=1
PHP Developer API (MediaFlow Facade)
use MediaFlow\Laravel\Facades\MediaFlow;
// 1. Upload a file from HTTP Request
$media = MediaFlow::upload($request->file('photo'), [
'disk' => 'public',
'folder' => 'avatars',
'collection' => 'profiles',
'thumbnails' => true,
]);
// 2. Access resolved delivery URLs and WebP thumbnail presets
$fullUrl = $media->url();
$thumbUrl = $media->thumbnailUrl('thumb'); // 200x200 crop WebP
$mediumUrl = $media->thumbnailUrl('medium'); // 800x800 contain WebP
// 3. Create folder hierarchies
$folder = MediaFlow::createFolder('Campaigns', $parentFolderId = null);
// 4. Move, Rename, Delete
MediaFlow::move($media, $folder->id);
MediaFlow::rename($media, 'hero-banner.webp');
MediaFlow::delete($media); // Deletes record, physical storage objects & variants
// 5. On-demand WebP / AVIF optimization
$result = MediaFlow::optimize($media, 'webp', quality: 80, replaceOriginal: false);
$savings = $result['metrics']['savings_percent']; // e.g. 94.6%
Eloquent Model Relationship
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use MediaFlow\Laravel\Models\Media;
class Post extends Model
{
protected $fillable = ['title', 'cover_media_id'];
public function coverMedia(): BelongsTo
{
return $this->belongsTo(Media::class, 'cover_media_id');
}
}
Access Control, Guards & Roles
Enforce authentication and role restrictions via config/mediaflow.php:
'auth' => [
'enabled' => env('MEDIAFLOW_AUTH_ENABLED', false),
'guard' => env('MEDIAFLOW_AUTH_GUARD', 'web'), // 'web', 'admin', 'api'
'roles' => ['admin', 'editor'], // Checks $user->role or Spatie hasRole()
'permissions' => ['manage-media'], // Optional Gate/permission checks
],
Custom Closure Authorization
Define custom access rules in AppServiceProvider:
use MediaFlow\Laravel\Facades\MediaFlow;
public function boot(): void
{
MediaFlow::authorize(function ($request) {
return $request->user()?->isSuperAdmin() || $request->user()?->can('access-media');
});
}
Cloud Storage & CDN Setup
Amazon S3, Cloudflare R2, MinIO
Configure your storage disk in .env:
MEDIAFLOW_DISK=s3
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your-media-bucket
# For Cloudflare R2 or MinIO (S3-compatible endpoints):
AWS_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
AWS_USE_PATH_STYLE_ENDPOINT=false
CDN Domain Edge Resolver
MEDIAFLOW_DELIVERY_DRIVER=cdn
MEDIAFLOW_CDN_URL=https://media-cdn.yourdomain.com
Time-Limited Signed Private URLs
$privateUrl = $media->temporarySignedUrl(now()->addMinutes(30));
Built-In Web Routes
| Route Name | Path | Description |
|---|---|---|
mediaflow.docs |
/mediaflow/docs |
Interactive Documentation & Code Guide Portal |
mediaflow.manager |
/mediaflow/manager |
Explorer & Media Library Browser |
mediaflow.pipeline |
/mediaflow/pipeline |
Interactive 3D Upload Lifecycle Visualizer |
mediaflow.settings |
/mediaflow/settings |
Configuration Dashboard & Compression Settings |
mediaflow.diagnostics.view |
/mediaflow/diagnostics |
Storage Connection & Latency Health Probes |
Running Automated Tests
composer install
./vendor/bin/phpunit
All 56 tests (327 assertions) pass against Laravel 11/12/13 with PHP 8.2 and 8.3.
Author & Maintainer
Developed and maintained by Anuj Dwivedi:
- GitHub: @dwivedianuj9118
- LinkedIn: Anuj Dwivedi
- Email: dwivedianuj9118@gmail.com
- Website: anujdwivedi.online
License
The MediaFlow package is open-sourced software licensed under the MIT license.