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

Files Res Laravel Package

baks-dev/files-res

Laravel/PHP пакет для управления файловыми ресурсами: загрузка и хранение в public/upload, настройка прав доступа, асинхронная обработка через очередь Messenger (async_files_resources). Поддерживает пережатие и конвертацию изображений в WebP через отдельный CDN-сервер.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require baks-dev/files-res
    

    Ensure your project uses PHP 8.4+ and Laravel/Symfony 7.4+.

  2. Configure Storage Directory:

    mkdir -p public/upload
    chown -R www-data:www-data public/upload  # Adjust user/group as needed
    

    Update config/filesystems.php to include a disk for uploads (e.g., upload_disk):

    'disks' => [
        'upload_disk' => [
            'driver' => 'local',
            'root' => public_path('upload'),
        ],
    ],
    
  3. First Use Case: File Upload Inject the FilesResourceManager service (if available) or use Laravel’s Storage facade directly:

    use Illuminate\Support\Facades\Storage;
    
    $path = Storage::disk('upload_disk')->putFile('images', $request->file('image'));
    
  4. Async Processing Setup: Ensure the messenger:consume command is running for background tasks:

    php artisan queue:work --queue=resources
    

    (Note: Symfony Messenger may require additional Laravel queue adapters.)


Implementation Patterns

Core Workflows

  1. File Upload and Storage:

    • Use Laravel’s Storage facade for consistency:
      $filePath = Storage::disk('upload_disk')->putFileAs(
          'user_avatars',
          $request->file('avatar'),
          'user_' . auth()->id() . '.webp'
      );
      
    • Pattern: Wrap upload logic in a service class (e.g., FileUploader) to handle validation, path generation, and disk selection.
  2. Image Optimization (WebP Conversion):

    • Option A: Use spatie/image-optimizer for local conversion:
      use Spatie\ImageOptimizer\OptimizerChainFactory;
      
      $optimizer = OptimizerChainFactory::create()->webp();
      $optimizer->optimize($originalPath, $optimizedPath);
      
    • Option B: Offload to a CDN (e.g., Cloudflare Polish) via baks-dev/files-cdn (if required).
  3. Async Processing:

    • Replace Symfony Messenger jobs with Laravel Jobs:
      namespace App\Jobs;
      
      use Illuminate\Bus\Queueable;
      use Illuminate\Contracts\Queue\ShouldQueue;
      
      class ConvertToWebPJob implements ShouldQueue
      {
          use Queueable;
      
          public function handle()
          {
              // Logic to convert image to WebP
          }
      }
      
    • Dispatch jobs after upload:
      ConvertToWebPJob::dispatch($filePath)->onQueue('resources');
      
  4. Integration with baks-dev/core (if applicable):

    • If using baks-dev/core, extend its ResourceManager trait or service bindings to integrate file resources:
      use BaksDev\Core\Traits\ResourceManager;
      
      class FileResourceService
      {
          use ResourceManager;
      
          public function upload(...)
          {
              // Custom logic using FilesResourceManager
          }
      }
      

Laravel-Specific Patterns

  • Service Providers: Register custom bindings for FilesResourceManager (if needed) in AppServiceProvider:

    public function register()
    {
        $this->app->bind(
            \BaksDev\FilesRes\FilesResourceManager::class,
            fn($app) => new \BaksDev\FilesRes\FilesResourceManager(
                $app->make(\Illuminate\Filesystem\Filesystem::class),
                config('files-res')
            )
        );
    }
    
  • Middleware for File Access: Restrict access to uploads via middleware:

    public function handle($request, Closure $next)
    {
        if ($request->is('upload/*') && !auth()->check()) {
            abort(403);
        }
        return $next($request);
    }
    
  • Event Listeners: Trigger events post-upload (e.g., FileUploaded) to notify other services:

    event(new FileUploaded($filePath, $request->user()));
    

Gotchas and Tips

Pitfalls

  1. Symfony Messenger Compatibility:

    • Issue: The package uses Symfony Messenger, which may conflict with Laravel’s queue system.
    • Fix: Use Laravel’s ShouldQueue interface and manually map jobs. Avoid direct dependency on Messenger.
    • Debug Tip: Check for Symfony\Component\Messenger\* in composer.json and replace with Laravel’s queue adapters.
  2. Undocumented baks-dev/core Dependency:

    • Issue: The package may silently depend on baks-dev/core, which lacks release notes.
    • Fix: Audit composer.json for hidden dependencies. Replace core functionality with Laravel’s Illuminate\Foundation\Application or Illuminate\Support services.
    • Debug Tip: Run composer why-not baks-dev/core to check for indirect dependencies.
  3. Path Handling Quirks:

    • Issue: The package may hardcode paths (e.g., public/upload) without Laravel’s storage abstraction.
    • Fix: Override path logic in a custom service:
      $path = Storage::disk('upload_disk')->path($relativePath);
      
    • Debug Tip: Use Storage::disk('upload_disk')->url($path) to verify URLs.
  4. WebP Conversion Without CDN:

    • Issue: The package recommends a separate CDN for WebP conversion, which may not be feasible.
    • Fix: Use spatie/image-optimizer or Intervention\Image for local conversion:
      composer require spatie/image-optimizer
      
    • Debug Tip: Test conversion on large files to avoid memory issues.
  5. Async Job Failures:

    • Issue: Symfony Messenger jobs may fail silently in Laravel’s queue system.
    • Fix: Implement a fallback queue driver (e.g., database) and log failures:
      ConvertToWebPJob::dispatch($filePath)
          ->onQueue('resources')
          ->catch(fn($e) => Log::error('WebP conversion failed', ['error' => $e]));
      

Tips

  1. Leverage Laravel’s Storage:

    • Prefer Laravel’s Storage facade over direct filesystem calls for consistency:
      // Instead of:
      $path = 'public/upload/' . $filename;
      // Use:
      $path = Storage::disk('upload_disk')->putFile('subdir', $file);
      
  2. Custom Disk Configuration:

    • Extend config/filesystems.php to support dynamic disks:
      'disks' => [
          'upload_disk' => [
              'driver' => 'local',
              'root' => storage_path('app/public/upload'),
              'url' => env('APP_URL') . '/storage/upload',
              'visibility' => 'public',
          ],
      ],
      
    • Symlink the storage directory:
      php artisan storage:link
      
  3. Queue Monitoring:

    • Monitor the resources queue for stuck jobs:
      php artisan queue:failed-table
      php artisan queue:work --queue=resources --sleep=3 --tries=3
      
  4. Testing File Uploads:

    • Use Laravel’s UploadedFile for testing:
      $file = UploadedFile::fake()->image('avatar.jpg');
      $this->post('/upload', ['file' => $file]);
      
    • Verify storage:
      $this->assertTrue(Storage::disk('upload_disk')->exists('avatars/user_1.jpg'));
      
  5. Performance Optimization:

    • For large files, use chunked uploads with Symfony\Component\HttpFoundation\File\UploadedFile or libraries like league/flysystem-aws-s3-v3.
    • Cache WebP conversions to avoid reprocessing:
      if (!Storage::disk('upload_disk')->exists($webpPath)) {
          ConvertToWebPJob::dispatch($originalPath, $webpPath);
      }
      
  6. Security:

    • Validate file types and sizes before upload:
      $request->validate([
          'file' => 'required|file|mimes:jpg,png|max:2048',
      ]);
      
    • Sanitize filenames to prevent path traversal:
      $filename = Str::slug($request->user()->name) . '.' . $file->getClientOriginalExtension();
      
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata