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

Doctrine Flysystem Bundle Laravel Package

ashleydawson/doctrine-flysystem-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle:

    composer require ashleydawson/doctrine-flysystem-bundle:0.8.*
    

    Register in AppKernel.php:

    new Oneup\FlysystemBundle\OneupFlysystemBundle(),
    new AshleyDawson\DoctrineFlysystemBundle\AshleyDawsonDoctrineFlysystemBundle(),
    
  2. Configure Flysystem (config.yml):

    oneup_flysystem:
        adapters:
            local:
                local:
                    directory: %kernel.project_dir%/var/uploads
        filesystems:
            uploads:
                adapter: local
                mount: uploads
    
  3. Apply Trait to Entity:

    use AshleyDawson\DoctrineFlysystemBundle\ORM\StorableTrait;
    
    class Product {
        use StorableTrait;
    
        public function getFilesystemMountPrefix() {
            return 'uploads';
        }
    }
    
  4. Update Schema:

    php bin/console doctrine:schema:update --force
    

First Use Case

Create a form to upload a file:

$builder->add('file', 'file', ['required' => false]);

Submit the form, and the bundle automatically:

  • Stores metadata (fileName, fileStoragePath, fileMimeType, fileSize) in the DB.
  • Persists the file to the configured Flysystem adapter.

Implementation Patterns

Workflows

  1. File Upload Handling:

    • Use the trait’s setUploadedFile() method in controllers or form types.
    • Example:
      $product->setUploadedFile($request->files->get('file'));
      $em->persist($product);
      $em->flush();
      
  2. Accessing File Data:

    • Retrieve metadata via getter methods (getFileName(), getFileStoragePath(), etc.).
    • Generate URLs using Flysystem’s url() method:
      $filesystem = $this->get('oneup_flysystem.filesystem.uploads');
      $url = $filesystem->url($product->getFileStoragePath());
      
  3. Multi-Filesystem Support:

    • Return an array in getFilesystemMountPrefix() to duplicate files across adapters:
      public function getFilesystemMountPrefix() {
          return ['uploads', 'backups'];
      }
      
  4. Event-Driven Customization:

    • Subscribe to events (e.g., ashleydawson.doctrine_flysystem_bundle.pre_store) to modify file paths or metadata:
      $dispatcher->addListener(StorageEvents::PRE_STORE, function (StoreEvent $event) {
          $event->setFileStoragePath('custom/' . $event->getFileStoragePath());
      });
      

Integration Tips

  • Symfony Forms: Use the file field type and map it to uploaded_file (or a custom setter).
  • Validation: Add constraints to fileSize or fileMimeType in your entity.
  • Doctrine Lifecycle: Override prePersist/preUpdate to trigger file operations manually if needed.

Gotchas and Tips

Pitfalls

  1. Schema Mismatch:

    • Forgetting to run doctrine:schema:update after adding the trait will cause errors.
    • Fix: Always update the schema after modifying entities.
  2. File Deletion:

    • By default, old files are deleted on update (delete_old_file_on_update: true). Disable this in config.yml if needed:
      ashley_dawson_doctrine_flysystem:
          delete_old_file_on_update: false
      
  3. Event Order:

    • Events like PRE_STORE fire before the file is written. Modify paths/metadata before this event if you need to influence storage.
  4. Multi-Filesystem Collisions:

    • Using multiple filesystems may lead to duplicate files. Ensure unique paths or handle conflicts in PRE_STORE.

Debugging

  • Check File Paths:
    • Log $event->getFileStoragePath() in PRE_STORE to verify paths are correct.
  • Verify Flysystem Config:
    • Ensure mount names in getFilesystemMountPrefix() match those in oneup_flysystem.filesystems.
  • Permissions:
    • Flysystem adapters (e.g., local) require write permissions on the target directory.

Extension Points

  1. Custom Field Mapping:

    • Implement StorableFieldMapperInterface to change column names/types (e.g., for fileSize to use bigint).
    • Register your mapper in services.yml:
      ashley_dawson.doctrine_flysystem.storable_field_mapper.class: AppBundle\ORM\Flysystem\CustomMapper
      
  2. Pre/Post-Processing:

    • Use events to:
      • Rename files (e.g., append UUIDs).
      • Validate file types before storage.
      • Log file operations.
  3. Doctrine Events:

    • Listen to onFlush to batch file operations for performance:
      $dispatcher->addListener(Doctrine\ORM\Events::onFlush, function () {
          // Custom logic for bulk file handling
      });
      

Pro Tips

  • Soft Deletes:
    • Add a isDeleted flag to entities and handle file deletion in PRE_DELETE events.
  • Cloud Storage:
    • Use Flysystem’s aws, rackspace, or s3 adapters for remote storage (configured in oneup_flysystem).
  • Testing:
    • Mock Flysystem adapters in tests to avoid I/O operations:
      $adapter = $this->createMock(\League\Flysystem\AdapterInterface);
      $filesystem = new \League\Flysystem\Filesystem($adapter);
      $this->get('oneup_flysystem.filesystem.uploads')->setAdapter($adapter);
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui