Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Livewire Media Selector Laravel Package

drpshtiwan/livewire-media-selector

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**
   ```bash
   composer require drpshtiwan/livewire-media-selector

Publish the config:

php artisan vendor:publish --provider="Drpshtiwan\LivewireMediaSelector\ServiceProvider"
  1. Basic Usage Add the component to your Blade view:

    <livewire:media-selector />
    

    Configure allowed disks and file types in config/livewire-media-selector.php:

    'disks' => ['public', 's3'],
    'allowed_mime_types' => ['image/jpeg', 'image/png', 'application/pdf'],
    
  2. First Use Case Use the component to select a single image for a blog post:

    <livewire:media-selector
        wire:model="post.image"
        :allowed-mime-types="['image/jpeg', 'image/png']"
        :max-files="1"
    />
    

Implementation Patterns

Common Workflows

  1. Single Media Selection Bind to a Livewire property:

    <livewire:media-selector
        wire:model="user.avatar"
        :allowed-mime-types="['image/*']"
    />
    

    Access selected media in your Livewire component:

    public $avatar;
    
    public function mount()
    {
        $this->avatar = $this->user->avatar ?? null;
    }
    
  2. Multiple Media Selection

    <livewire:media-selector
        wire:model="gallery.images"
        :allowed-mime-types="['image/*']"
        :max-files="10"
        multiple
    />
    
  3. Custom Storage Integration Extend the MediaSelector class to add custom logic:

    use Drpshtiwan\LivewireMediaSelector\MediaSelector;
    
    class CustomMediaSelector extends MediaSelector
    {
        public function getMedia()
        {
            $media = parent::getMedia();
            return $media->filter(fn ($item) => $item->is_public);
        }
    }
    
  4. Integration with File Uploads Use the upload event to process files after selection:

    <livewire:media-selector
        @upload="processUpload($event)"
    />
    

Advanced Patterns

  1. Dynamic Configuration Pass dynamic config via props:

    <livewire:media-selector
        :disks="['public', 'private']"
        :allowed-mime-types="['image/*', 'video/*']"
        :max-file-size="5" // in MB
    />
    
  2. Custom Thumbnail Generation Override the getThumbnailUrl method in a custom component:

    public function getThumbnailUrl($media)
    {
        return Storage::disk('public')->url("custom/thumbs/{$media->path}");
    }
    
  3. Media Metadata Handling Use the media-selected event to process metadata:

    <livewire:media-selector
        @media-selected="handleMediaSelection($event)"
    />
    
    public function handleMediaSelection($event)
    {
        $this->processMedia($event->media);
    }
    
  4. Bulk Operations Implement bulk actions (e.g., delete) via custom props:

    <livewire:media-selector
        :selected-media="old('selected_media', [])"
        @bulk-delete="deleteSelectedMedia"
    />
    

Gotchas and Tips

Common Pitfalls

  1. File Size Limits

    • Ensure max-file-size in config matches your server’s upload_max_filesize and post_max_size in php.ini.
    • Default is 5MB; adjust in config or via props:
      'max_file_size' => 10, // MB
      
  2. Disk Permissions

    • Verify storage disks are writable:
      php artisan storage:link
      
    • For S3/Cloud storage, ensure credentials are configured in .env.
  3. CORS Issues

    • If using custom domains (e.g., S3), configure CORS headers:
      <CORSConfiguration>
          <CORSRule>
              <AllowedOrigin>*</AllowedOrigin>
              <AllowedMethod>GET</AllowedMethod>
          </CORSRule>
      </CORSConfiguration>
      
  4. Livewire Property Binding

    • Ensure the bound property in your Livewire component matches the expected type (e.g., string for file paths, array for multiple files).
    • Example:
      public $image; // For single file
      public $images = []; // For multiple files
      
  5. Media Not Updating

    • Clear Livewire cache if changes aren’t reflected:
      php artisan cache:clear
      php artisan view:clear
      
    • Ensure wire:model is correctly bound to a public property.

Debugging Tips

  1. Log Media Queries Temporarily enable debug mode in config:

    'debug' => true,
    

    Check logs for SQL queries or disk operations.

  2. Check Disk Contents Verify files exist on the disk:

    ls storage/app/public
    
  3. Validate MIME Types Use dd($event->media->mime_type) in the media-selected event to debug MIME type issues.

  4. Livewire Wire:Key Conflicts If using multiple instances, ensure unique wire:key:

    <livewire:media-selector wire:key="'selector-1'" />
    

Extension Points

  1. Custom Media Models Extend the Media model to add custom fields:

    use Drpshtiwan\LivewireMediaSelector\Models\Media;
    
    class CustomMedia extends Media
    {
        protected $casts = [
            'alt_text' => 'string',
            'custom_metadata' => 'json',
        ];
    }
    
  2. Override Media Listing Replace the default media listing logic:

    public function getMedia()
    {
        return CustomMedia::query()
            ->where('user_id', auth()->id())
            ->get();
    }
    
  3. Add Custom Tabs Extend the component to include additional tabs (e.g., "Collections"):

    <livewire:media-selector>
        <x-slot name="tabs">
            <x-media-selector.tab name="collections">Collections</x-media-selector.tab>
        </x-slot>
    </livewire:media-selector>
    
  4. Localization Override default labels in your Blade view:

    <livewire:media-selector>
        <x-slot name="labels">
            <x-media-selector.label upload="Upload Custom Label" />
        </x-slot>
    </livewire:media-selector>
    
  5. Event Customization Listen to internal events (e.g., media-uploading):

    <livewire:media-selector
        @media-uploading="logUploadEvent($event)"
    />
    

Performance Tips

  1. Lazy Loading Use pagination for large media libraries:

    public function getMedia()
    {
        return CustomMedia::query()->paginate(20);
    }
    
  2. Thumbnail Optimization Generate thumbnails asynchronously using queues:

    public function handleMediaSelection($event)
    {
        GenerateThumbnailJob::dispatch($event->media);
    }
    
  3. Caching Cache media listings if they rarely change:

    public function getMedia()
    {
        return Cache::remember('media-list', now()->addHours(1), function () {
            return CustomMedia::all();
        });
    }
    
  4. Disk Indexing For large disks, implement a database index for path or filename in the media table.


```markdown
## Configuration Deep Dive

### Key Config Options
| Option               | Default                          | Description                                                                 |
|----------------------|----------------------------------|-----------------------------------------------------------------------------|
| `disks`              | `['public']`                    | Array of storage disks to scan.                                            |
| `allowed_mime_types` | `['image/*']`                   | MIME types allowed for uploads.                                             |
| `max_file_size`      | `5` (MB)                        | Maximum file size in MB.                                                    |
| `max_files`          | `null`                          | Maximum files to select (use `0` for unlimited).                            |
| `thumbnail_size`     | `['width' => 150, 'height' => 150]| Thumbnail dimensions.                                                       |
| `sort_by`            | `'created_at desc'`             | Default sorting for media listings.                                          |
| `debug`              | `false`                         | Enable debug logging.                                                       |

### Environment-Specific Config
Override config per environment in `.env`:
```env
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle