laravel-admin/media-manager
Laravel Media Manager adds an Eloquent Media model for your storage, auto 1‑n media relations via a trait, image styles with caching, and Vue (Bootstrap 3) components for browsing/uploading. Includes upload helper with pluggable drivers and multi-disk support.
Installation:
composer require laravel-admin/media-manager
php artisan vendor:publish --provider="LaravelAdmin\MediaManager\MediaManagerProvider"
php artisan migrate
Add the provider to config/app.php:
LaravelAdmin\MediaManager\MediaManagerProvider::class
Basic Upload:
use LaravelAdmin\MediaManager\Upload;
$media = Upload::handle($request, 'file'); // 'file' is the request field name
First Use Case:
enctype="multipart/form-data".$media->url.config/media-manager.php (upload drivers, storage, image styles).resources/js/bootstrap.js (integrate MediaBrowser.vue).Traits\MediaTrait (for automatic media relations).Uploading Media:
// Default storage (local)
$media = Upload::handle($request, 'avatar');
// Custom storage (e.g., S3)
$media = Upload::storage('s3')->handle($request, 'avatar');
// Replace existing media
$media = Upload::update($existingMedia)->handle($request, 'avatar');
Model Relations:
media_id to your model’s migration and use the MediaTrait:
use LaravelAdmin\MediaManager\Traits\MediaTrait;
class Post extends Model {
use MediaTrait;
}
$post->mediaUrl(); // Public URL
$post->imagestyle('thumbnail'); // Styled URL
Image Styles:
config/media-manager.php under image_styles.<img src="{{ $post->imagestyle('thumbnail') }}">
Vue Media Browser:
import MediaBrowser from '../../../vendor/laravel-admin/media-manager/resources/js/bootstrap';
<media-browser @selected="handleMediaSelect"></media-browser>
Laravel Admin Integration:
Use the MediaItem field in CRUD modules:
$form->addField([
'type' => 'media',
'name' => 'header_image',
'label' => 'Header Image',
'upload' => true,
]);
Custom Drivers:
Implement LaravelAdmin\Mediamanager\Contracts\UploadDriver for non-standard uploads (e.g., YouTube URLs):
class YouTubeDriver implements UploadDriver {
public function upload($request, $field, $media) { ... }
}
Register in config/media-manager.php:
'drivers' => [
'url' => \App\Drivers\YouTubeDriver::class,
],
API Endpoints:
Leverage the built-in AjaxController for media operations:
Route::resource('media/ajax', \LaravelAdmin\MediaManager\Http\Controllers\AjaxController::class)->only(['destroy']);
Vue Dependency:
npm install dropzone --save-dev).app.js includes:
require('../../../vendor/laravel-admin/media-manager/resources/js/bootstrap.js');
Storage Configuration:
storage method assumes a configured filesystem in config/filesystems.php.local if unspecified.Linked-Object Deletion:
destroy method checks for linked objects (e.g., posts.media_id = media.id).axios.delete('/media/ajax/1')
.catch(error => {
if (error.response.status === 409) {
alert('Media is linked to other objects!');
}
});
Image Style Caching:
php artisan cache:clear
Migration Conflicts:
media table. Ensure no naming conflicts with existing tables.Upload Failures:
Check config/media-manager.php for allowed_filetypes or max_filesize limits.
Log errors in Upload::handle():
try {
$media = Upload::handle($request, 'file');
} catch (\Exception $e) {
\Log::error($e->getMessage());
}
Vue Component Issues: Verify Dropzone is initialized only once per browser instance (fixed in v1.0.4). Check browser console for errors like:
Dropzone is not defined
Solution: Ensure bootstrap.js is loaded after Vue and Dropzone.
Style Generation: If styles fail, ensure Intervention Image is installed:
composer require intervention/image
Rebuild config cache:
php artisan config:clear
Custom Media Fields: Override the trait’s relation name:
class Post extends Model {
use MediaTrait;
protected $mediaRelation = 'custom_media';
}
Event Listeners:
Listen for media events (e.g., media.created):
\Event::listen('media.created', function ($media) {
\Log::info("New media uploaded: {$media->id}");
});
Admin Panel Customization: Publish and modify views:
php artisan vendor:publish --tag=media-manager-views
Edit resources/views/vendor/media-manager/....
Bulk Operations:
Extend the AjaxController for batch deletes:
public function destroyBatch(Request $request) {
$ids = $request->input('ids');
foreach ($ids as $id) {
$this->destroy($id);
}
}
How can I help you explore Laravel packages today?