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

Uploader Bundle Laravel Package

atom-php/uploader-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require atom-php/uploader-bundle
    

    Publish the default configuration:

    php artisan vendor:publish --provider="Atom\UploaderBundle\UploaderBundle" --tag=config
    
  2. Basic Configuration Edit config/uploader.php to define storage adapters (e.g., local, s3, ftp). Example:

    'adapters' => [
        'local' => [
            'driver' => 'local',
            'root'   => storage_path('app/uploads'),
        ],
        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'bucket' => 'my-bucket',
        ],
    ],
    
  3. First Upload Inject the UploaderInterface into a controller/service and use it:

    use Atom\UploaderBundle\Uploader\UploaderInterface;
    
    public function uploadFile(Request $request, UploaderInterface $uploader)
    {
        $file = $request->file('file');
        $path = $uploader->upload($file, 'local'); // 'local' is the adapter name
        return response()->json(['path' => $path]);
    }
    
  4. File Validation Use Laravel’s built-in validation to ensure files meet requirements before uploading:

    $request->validate([
        'file' => 'required|file|max:10240', // 10MB max
    ]);
    

Implementation Patterns

Common Workflows

  1. Multi-Adapter Uploads Dynamically switch adapters based on business logic (e.g., upload to S3 for production, local for staging):

    $adapter = config('app.env') === 'production' ? 's3' : 'local';
    $path = $uploader->upload($file, $adapter);
    
  2. Custom Storage Paths Override the default path per adapter in the config or dynamically:

    $path = $uploader->upload($file, 'local', [
        'path' => 'custom/folder/' . $user->id,
    ]);
    
  3. File Processing Chain file operations (e.g., resize, rename) using the UploaderInterface:

    $path = $uploader->upload($file, 'local', [
        'rename' => true, // Auto-generate filename
        'processors' => [
            'resize' => ['width' => 800, 'height' => 600],
        ],
    ]);
    
  4. Batch Uploads Process multiple files in a loop:

    foreach ($request->file('files') as $file) {
        $path = $uploader->upload($file, 'local');
        // Store path in DB or queue for further processing
    }
    
  5. Integration with Laravel Filesystem Use the returned path with Laravel’s Storage facade:

    $url = Storage::disk('local')->url($path);
    

Integration Tips

  • Events Listen to Atom\UploaderBundle\Events\FileUploaded for post-upload actions (e.g., notifications, DB updates):

    event(new FileUploaded($path, $adapter, $file));
    
  • Middleware Restrict uploads to authenticated users or roles via middleware:

    Route::middleware(['auth', 'upload.access'])->post('/upload', ...);
    
  • Testing Mock the UploaderInterface in tests:

    $this->partialMock(UploaderInterface::class, function ($mock) {
        $mock->shouldReceive('upload')->andReturn('fake/path.jpg');
    });
    

Gotchas and Tips

Pitfalls

  1. Adapter Configuration

    • Issue: Forgetting to define adapters in config/uploader.php or misconfiguring credentials (e.g., missing AWS_SECRET_ACCESS_KEY).
    • Fix: Validate config with php artisan config:clear after changes. Use .env for sensitive data.
  2. File Overwrites

    • Issue: Uploading files with duplicate names without rename: true will overwrite existing files.
    • Fix: Always use rename: true or implement a custom naming strategy:
      'rename' => function ($file) {
          return 'custom-' . Str::uuid() . '.' . $file->extension();
      }
      
  3. Permissions

    • Issue: Local adapter fails with "Permission denied" errors.
    • Fix: Ensure the storage directory is writable:
      chmod -R 775 storage/app/uploads
      
  4. Large Files

    • Issue: Timeouts or memory issues with large uploads.
    • Fix: Increase PHP limits in php.ini:
      upload_max_filesize = 20M
      post_max_size = 20M
      max_execution_time = 300
      
    • Use chunked uploads for files >10MB.
  5. Processor Conflicts

    • Issue: Custom processors (e.g., resize) fail silently or corrupt files.
    • Fix: Test processors in isolation. Log errors:
      try {
          $uploader->upload($file, 'local', ['processors' => [...]]);
      } catch (\Exception $e) {
          Log::error('Upload failed: ' . $e->getMessage());
      }
      

Debugging Tips

  • Enable Verbose Logging Add to config/uploader.php:

    'debug' => env('APP_DEBUG', false),
    

    Check logs in storage/logs/laravel.log.

  • Check Returned Paths Always log or dump the returned path to verify the file was saved:

    dd($uploader->upload($file, 'local')); // Debug path
    
  • Validate Adapters Test each adapter manually:

    $uploader->testAdapter('s3'); // Returns boolean
    

Extension Points

  1. Custom Adapters Extend the bundle by creating a new adapter:

    namespace App\Uploader;
    
    use Atom\UploaderBundle\Uploader\AdapterInterface;
    
    class CustomAdapter implements AdapterInterface {
        public function upload($file, array $options) { ... }
        public function delete($path) { ... }
    }
    

    Register it in config/uploader.php:

    'adapters' => [
        'custom' => [
            'driver' => 'custom',
            'class' => App\Uploader\CustomAdapter::class,
        ],
    ],
    
  2. Custom Processors Add new processors (e.g., watermark) by extending the Processor class:

    namespace App\Uploader\Processors;
    
    use Atom\UploaderBundle\Uploader\Processor;
    
    class WatermarkProcessor extends Processor {
        public function process($filePath) { ... }
    }
    

    Use it in the upload options:

    'processors' => [
        'watermark' => ['text' => 'Confidential'],
    ],
    
  3. Event Customization Override default event behavior by binding to the event in a service provider:

    public function boot()
    {
        event(new FileUploaded($path, $adapter, $file));
    }
    
  4. Queue Uploads Offload uploads to a queue for async processing:

    dispatch(new HandleUpload($file, $adapter, $options));
    

    Create a job:

    namespace App\Jobs;
    
    use Atom\UploaderBundle\Uploader\UploaderInterface;
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class HandleUpload implements ShouldQueue {
        use Queueable;
    
        public function handle(UploaderInterface $uploader) {
            $uploader->upload($this->file, $this->adapter, $this->options);
        }
    }
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware