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

Storage Bundle Laravel Package

1tomany/storage-bundle

Symfony bundle for uploading files to remote storage (Amazon S3/R2, GCS, Azure) with a simple client-based config. Includes an Amazon S3-compatible client plus a mock client for fast, offline testing, and optional custom URLs for CDN/public buckets.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Pros:

    • Symfony-first design aligns with Laravel’s ecosystem (Symfony components are foundational in Laravel). The bundle’s contract-based architecture (ClientInterface, ActionInterface) mirrors Laravel’s service container patterns (e.g., Storage facade, Filesystem contracts).
    • Decoupled actions (upload/download/delete) enable modular integration with Laravel’s event system (e.g., Uploading, Deleted events) or job queues (e.g., UploadFileJob).
    • Mock support simplifies testing in CI/CD pipelines, critical for Laravel’s test-driven workflows.
    • Custom URL routing addresses Laravel’s CDN/asset pipeline needs (e.g., overriding S3 URLs with Cloudflare R2 domains).
  • Cons:

    • Symfony-centric abstractions may require Laravel-specific wrappers (e.g., converting Symfony’s UploadRequest to Laravel’s UploadedFile or SplFileInfo).
    • No native Laravel facade: Requires manual binding to Laravel’s service container (e.g., app()->bind('uploadAction', fn() => app(UploadActionInterface::class))).
    • Limited Laravel integrations: No out-of-the-box support for Laravel’s FilesystemManager, Vapor, or Forge services.

Integration Feasibility

  • Laravel Compatibility:

    • High: The bundle’s Symfony dependencies (e.g., aws/aws-sdk-php-symfony) are compatible with Laravel via symfony/flex or manual configuration.
    • AWS SDK: Laravel’s fruitcake/laravel-aws or spatie/laravel-aws can coexist if configured to share the same s3_client_service_id.
    • Cloudflare R2: Works seamlessly with Laravel’s .env and config/services.php (see Laravel R2 docs).
  • Key Integration Points:

    • Service Provider: Register the bundle in config/app.php or a custom provider.
    • Configuration: Merge onetomany_storage.yaml with Laravel’s config/filesystems.php (e.g., alias the bundle’s client to Laravel’s disks).
    • Request Handling: Adapt Symfony’s UploadRequest to Laravel’s Request object (e.g., using Symfony\Component\HttpFoundation/FileBag).

Technical Risk

  • Medium:

    • Dependency Conflicts: Risk of version mismatches with Laravel’s Symfony components (e.g., symfony/http-foundation). Mitigate via composer.json overrides or Laravel’s config/extra.php.
    • Testing Overhead: Mocking ClientInterface in Laravel’s PHPUnit tests requires custom test doubles (e.g., Mockery or Laravel\Pest\Mock).
    • Performance: No benchmarks for Laravel-specific use cases (e.g., chunked uploads). Profile with spatie/laravel-activitylog or laravel-debugbar.
    • Maintenance: Bundle is unmaintained (last release 2026, but MIT license allows forks). Risk: Deprecation of Symfony 8.x features in future Laravel versions.
  • Mitigation:

    • Fork the Bundle: Extend ClientInterface to implement Laravel’s Filesystem contract for seamless integration.
    • Wrapper Package: Create a laravel-storage-bundle facade (e.g., Storage::disk('s3')->upload()).
    • CI Validation: Add composer validate and phpstan checks for Symfony/Laravel compatibility.

Key Questions

  1. Does this replace or complement Laravel’s built-in Storage facade?

    • Use case: If you need multi-cloud abstraction (e.g., S3 + Backblaze + local), this bundle’s ClientInterface could unify them under a single facade.
    • Tradeoff: Laravel’s Storage is more mature for local filesystems (e.g., Filesystem::put()).
  2. How will we handle Laravel’s UploadedFile vs. Symfony’s UploadedFile?

  3. What’s the fallback for unsupported Laravel features?

    • Example: Laravel’s Filesystem::temporaryUrl() isn’t exposed. Implement a custom TemporaryUrlActionInterface.
  4. How will we manage secrets (AWS keys) in Laravel’s .env?

    • Recommendation: Use Laravel’s Vapor or Envoy for secret rotation, or integrate with spatie/laravel-envoy.

Integration Approach

Stack Fit

  • Primary Use Cases:

    • Media Uploads: Replace Storage::put() for S3/R2 with the bundle’s UploadActionInterface (e.g., user avatars, documents).
    • CDN Optimization: Override S3 URLs with custom domains (e.g., custom_url: "https://cdn.app.com").
    • Testing: Use the mock_client for unit/integration tests (e.g., Storage::fake() alternative).
    • Multi-Cloud: Abstract away cloud-specific logic (e.g., switch from S3 to Backblaze without code changes).
  • Laravel-Specific Adaptations:

    Bundle Feature Laravel Equivalent Integration Strategy
    UploadRequest Illuminate\Http\UploadedFile Create a LaravelUploadRequest adapter.
    ClientInterface Illuminate\Contracts\Filesystem Implement Filesystem contract in a wrapper.
    UploadActionInterface Storage::put() Bind to Laravel’s service container.
    Mock client Storage::fake() Extend bundle’s mock to support Laravel assertions.

Migration Path

  1. Phase 1: Proof of Concept (1–2 weeks)

    • Install the bundle in a sandbox project:
      composer require 1tomany/storage-bundle aws/aws-sdk-php-symfony
      
    • Configure config/packages/onetomany_storage.yaml and .env for AWS/R2.
    • Test basic uploads/downloads with Laravel’s Http\Testing\File:
      use OneToMany\StorageBundle\Contract\Action\UploadActionInterface;
      use Illuminate\Http\UploadedFile;
      
      $uploadAction = app(UploadActionInterface::class);
      $response = $uploadAction->act(new UploadRequest(
          UploadedFile::fake()->image('avatar.png'),
          'png',
          'avatars/user1.png'
      ));
      
  2. Phase 2: Laravel Wrapper (2–3 weeks)

    • Create a LaravelStorageBundle facade:
      // app/Providers/AppServiceProvider.php
      public function register(): void
      {
          $this->app->bind('uploadAction', fn() => $this->app->make(UploadActionInterface::class));
          Storage::extend('onetomany', fn() => new OnetomanyFilesystem(
              $this->app->make(ClientInterface::class)
          ));
      }
      
    • Implement OnetomanyFilesystem extending Illuminate\Filesystem\Filesystem.
  3. Phase 3: Full Integration (3–4 weeks)

    • Replace Storage::put() calls with the bundle’s actions:
      // Before
      Storage::disk('s3')->put('file.txt', $content);
      
      // After
      $uploadAction->act(new UploadRequest(
          $filePath,
          'txt',
          'file.txt'
      ));
      
    • Add Laravel events (e.g., storage.uploaded) to trigger notifications or analytics.
    • Configure CI to test both real and mock clients.

Compatibility

  • Laravel Versions: Tested with Symfony 8.x → Compatible with Laravel 10+ (PHP 8.2+).
  • Cloud Providers:
    • S3-Compatible: Works with MinIO, DigitalOcean Spaces, etc.
    • Non-S3: Requires custom ClientInterface implementations (e.g., for Google Cloud Storage).
  • Existing Laravel Packages:
    • Conflict Risk: Low with spatie/laravel-medialibrary or intervention/image (use separate disks).
    • Synergy: Pair with spatie/laravel-activitylog to log storage actions.

Sequencing

  1. Start with Non-Critical Features:
    • Begin with the mock client for testing, then migrate real uploads.
  2. Prioritize High-Impact Areas:
    • User uploads (avatars, profiles) → Media libraries (videos, documents) → Backups.
  3. Rollback Plan:
    • Main
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime