drpshtiwan/livewire-media-selector
composer require drpshtiwan/livewire-media-selector
php artisan vendor:publish --tag=media-selector-config
php artisan vendor:publish --tag=media-selector-migrations
php artisan migrate
php artisan storage:link
wire:model binding:
<livewire:media-selector wire:model="media" collection="gallery" />
click event):
<button wire:click="$emit('openMediaSelector')">Select Media</button>
User Profile Avatar Upload:
collection="avatars" attribute to group media.avatar field:
public $avatar;
public function updatedAvatar($value) {
$this->user->update(['avatar' => $value]);
}
Media Selection:
wire:model="postImage").wire:model="galleryImages" and ensure the parent model accepts an array.collection="product_gallery").Upload Handling:
config/media-selector.php:
'allowed_extensions' => ['jpg', 'png', 'gif'],
'max_upload_kb' => 2048,
'disk' => 'public',
<livewire:media-selector :can-upload="false" />
Model Integration:
HasMediaSelector trait for Eloquent models:
use Drpshtiwan\MediaSelector\Traits\HasMediaSelector;
class Post extends Model {
use HasMediaSelector;
}
$post->attachMedia($mediaId, 'gallery');
$post->syncMedia($mediaIds, 'gallery');
Event Listeners:
$dispatch or JavaScript:
window.addEventListener('media-uploaded', (event) => {
console.log('Uploaded:', event.detail);
});
Custom Styling: Publish views and override Tailwind classes:
php artisan vendor:publish --tag=media-selector-views
Modify resources/views/vendor/media-selector/....
Authorization:
Use Livewire’s authorize method or Laravel Gates to restrict actions:
public function authorizeDeleteMedia() {
return auth()->user()->can('delete-media');
}
Localization: Publish translations and extend:
php artisan vendor:publish --tag=media-selector-lang
Add custom language files to resources/lang/vendor/media-selector.
Performance:
perPage attribute or config).show-thumbnails="false" for large libraries to reduce render time.Testing: Mock the Livewire component in PHPUnit:
$this->livewire(MediaSelector::class)
->emit('openMediaSelector')
->assertSee('Media Selector');
Livewire Version Mismatch:
Disk Configuration:
public disk must be linked (php artisan storage:link). Missing symlinks cause "File not found" errors.config/filesystems.php and run storage:link.Media Model Scope:
Media model’s scope* methods are correctly defined.Media model if needed:
class Media extends \Drpshtiwan\MediaSelector\Models\Media {
public function scopeForUser($query) {
return $query->where('user_id', auth()->id());
}
}
Thumbnail Generation:
Storage facade. Large images may cause timeouts.MEDIA_SELECTOR_THUMBNAIL_SIZE in config or use a queue for async generation.RTL Support:
dir="rtl" to the modal container if needed.Event Dispatching:
media-uploaded are dispatched via Livewire’s $dispatch. Ensure your frontend listens correctly.wire:key to avoid event conflicts:
<livewire:media-selector wire:key="'media-selector-{{ $id }}'" />
Soft Deletes:
SoftDeletes trait on the Media model. Ensure the migration includes deleted_at.php artisan vendor:publish --tag=media-selector-migrations
php artisan migrate
Log Upload Errors:
Enable Livewire logging in config/livewire.php:
'log' => env('LIVEWIRE_LOG', true),
Check storage/logs/livewire.log for upload validation failures.
Inspect Payloads:
Dump the wire:model payload to verify data structure:
public function updatedMedia($value) {
\Log::info('Selected media:', $value);
}
Expected format:
["path/to/file.jpg", "path/to/file.png"]
Check Disk Permissions:
Verify the storage/app/public directory is writable:
chmod -R 755 storage/app/public
Custom Media Cards:
Override the thumbnail template by publishing views and extending the media-card component:
@extends('vendor.media-selector::media-card')
@section('custom-content')
<div class="custom-meta">{{ $media->size }} KB</div>
@endsection
Pluggable Uploads:
Extend the UploadHandler class to add pre-upload logic (e.g., virus scanning):
namespace App\Services;
use Drpshtiwan\MediaSelector\Services\UploadHandler as BaseUploadHandler;
class CustomUploadHandler extends BaseUploadHandler {
public function validate($file) {
parent::validate($file);
// Add custom validation
}
}
Bind the handler in config/media-selector.php:
'upload_handler' => \App\Services\CustomUploadHandler::class,
Dynamic Collections: Fetch collections dynamically via a Livewire property:
public $collections = ['gallery', 'documents', 'avatars'];
Bind to the component:
<livewire:media-selector :collections="$collections" />
Bulk Actions:
Use Livewire’s $emit to trigger custom JavaScript for bulk operations:
window.addEventListener('bulk-action', (event) => {
const ids = event.detail.ids;
// Call API for bulk delete/move
});
Dispatch from Livewire:
$this->dispatch('bulk-action', ids: $selectedIds);
Accessibility: Add ARIA labels or keyboard navigation by extending the modal template:
<div class="modal" role="dialog" aria-label="Media Library">
<!-- Content -->
</div>
show_thumbnails:
MEDIA_SELECTOR_SHOW_THUMBNAILS = false).:show-thumbnails="false".can_upload:
How can I help you explore Laravel packages today?