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

vich/uploader-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require vich/uploader-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
    ];
    
  2. Configure Storage: Define upload paths in config/packages/vich_uploader.yaml:

    vich_uploader:
        db_driver: orm  # or 'mongodb', 'phpcr'
        storage: '%kernel.project_dir%/public/uploads'
    
  3. First Use Case:

    • Create an entity (e.g., Product) with a file field:
      use Vich\UploaderBundle\Mapping\Annotation as Vich;
      
      class Product {
          /**
           * @Vich\UploadableField(mapping="product_images", fileDir="products/")
           */
          private $imageFile;
      }
      
    • Run migrations (php bin/console make:migration).
    • Use in a form:
      $builder->add('imageFile', FileType::class);
      

Implementation Patterns

Common Workflows

  1. Entity Mapping:

    • Use annotations (@Vich\UploadableField) or YAML/XML for configuration.
    • Example for multiple files:
      /**
       * @Vich\UploadableField(mapping="documents", fileDir="documents/")
       */
      private $documentFile;
      
  2. Handling Uploads:

    • Controller:
      $product->setImageFile($request->files->get('imageFile'));
      $em->persist($product);
      $em->flush();
      
    • PrePersist/PreUpdate: Automatically triggers upload logic via lifecycle callbacks.
  3. Public URLs:

    • Generate URLs in templates:
      {{ vich_uploader_asset(product.imageFile) }}
      
    • Or in PHP:
      $this->get('vich_uploader.templating.helper')->getUrl($product->getImageFile());
      
  4. Batch Processing:

    • Use Vich\UploaderBundle\Handler\UploadHandler for custom logic:
      $handler = $this->get('vich_uploader.upload_handler');
      $handler->upload($product, 'imageFile');
      
  5. MongoDB/PHPCR:

    • Replace db_driver in config and adjust mappings (e.g., @Vich\UploadableField for documents).

Integration Tips

  • Symfony Forms:

    • Use FileType for single files, CollectionType for multiple files.
    • Example for multiple files:
      $builder->add('documents', CollectionType::class, [
          'entry_type' => FileType::class,
          'allow_add' => true,
          'allow_delete' => true,
      ]);
      
  • Validation:

    • Add constraints to file fields:
      use Symfony\Component\Validator\Constraints as Assert;
      
      /**
       * @Assert\File(maxSize="1024k")
       * @Vich\UploadableField(mapping="images", fileDir="images/")
       */
       private $imageFile;
      
  • Custom Storage:

    • Extend Vich\UploaderBundle\Storage\StorageInterface for cloud storage (e.g., S3):
      vich_uploader:
         storage: vich_uploader.storage.s3
      
      Register service in services.yaml:
      services:
         Vich\UploaderBundle\Storage\StorageInterface vich_uploader.storage.s3:
             class: App\Storage\S3Storage
             arguments: ['@aws_s3.client']
      
  • Events:

    • Listen to vich_uploader.pre_upload or vich_uploader.post_upload:
      $eventDispatcher->addListener('vich_uploader.pre_upload', function (UploadEvent $event) {
          // Custom logic before upload
      });
      

Gotchas and Tips

Pitfalls

  1. File Deletion:

    • Issue: Files may not delete if the entity is soft-deleted or the preRemove lifecycle callback is bypassed.
    • Fix: Ensure preRemove is called or manually trigger deletion:
      $handler->remove($entity, 'fieldName');
      
  2. Circular Dependencies:

    • Issue: Circular references in entities can break uploads.
    • Fix: Avoid bidirectional associations with @Vich\UploadableField.
  3. Case Sensitivity:

    • Issue: File paths are case-sensitive on some systems (e.g., Linux).
    • Fix: Normalize paths in custom storage or use fileDir consistently.
  4. Large Files:

    • Issue: Default PHP settings (upload_max_filesize, post_max_size) may block large uploads.
    • Fix: Adjust php.ini or use chunked uploads (e.g., Symfony Uploader).
  5. Doctrine Proxy Classes:

    • Issue: Proxy classes may cause issues with file uploads if not handled properly.
    • Fix: Use getRealPath() or ensure entities are initialized before upload.

Debugging

  1. Logs:

    • Enable debug mode to see upload events:
      monolog:
          handlers:
              main:
                  level: debug
      
    • Check var/log/dev.log for VichUploaderBundle entries.
  2. Common Errors:

    • "File not found": Verify fileDir paths are correct and writable.
    • "No file uploaded": Ensure the form field name matches the entity property.
    • "Permission denied": Set proper permissions on the upload directory:
      chmod -R 775 public/uploads
      
  3. Database Mismatch:

    • Issue: File paths in the database don’t match the filesystem.
    • Fix: Use vich_uploader.db_driver consistently (e.g., orm for Doctrine).

Configuration Quirks

  1. Dynamic FileDirs:

    • Use placeholders (e.g., %kernel.project_dir%) or services for dynamic paths:
      vich_uploader:
          storage: '%app.upload_dir%'
      
      Define in parameters.yaml:
      app.upload_dir: '%kernel.project_dir%/public/custom_uploads'
      
  2. Naming Strategies:

    • Customize filename generation via namer:
      vich_uploader:
          db_driver: orm
          storage: public/uploads
          namers:
              product_images: Vich\UploaderBundle\Naming\SmartUniqueNamer
      
    • Or create a custom namer:
      class CustomNamer implements NamerInterface {
          public function name($object, $field, $originalName) {
              return 'custom_' . uniqid() . '.' . pathinfo($originalName, PATHINFO_EXTENSION);
          }
      }
      
  3. Asset Helper:

    • Issue: vich_uploader_asset fails if the file is not uploaded yet.
    • Fix: Check for null or use a fallback:
      {% if product.imageFile %}
          {{ vich_uploader_asset(product.imageFile) }}
      {% else %}
          {{ asset('images/default.png') }}
      {% endif %}
      

Extension Points

  1. Custom Storage:

    • Implement Vich\UploaderBundle\Storage\StorageInterface for cloud storage (e.g., S3, GCS):
      class S3Storage implements StorageInterface {
          public function store($object, $field, $file) { /* ... */ }
          public function delete($object, $field) { /* ... */ }
          public function update($object, $field, $newFile, $oldFile) { /* ... */ }
      }
      
  2. Event Subscribers:

    • Extend upload behavior via events:
      class CustomUploadSubscriber implements EventSubscriberInterface {
          public static function getSubscribedEvents() {
              return [
                  UploadEvent::PRE_UPLOAD => 'onPreUpload',
                  UploadEvent::POST_UPLOAD => 'onPostUpload',
              ];
          }
      
          public function onPreUpload(UploadEvent $event) {
              // Modify file before upload
          }
      }
      
  3. Doctrine Lifecycle Callbacks:

    • Override default behavior by implementing Vich\UploaderBundle\Event\EventDispatcherInterface:
      $dispatcher->addListener('vich_uploader.pre_remove', function (UploadEvent $event) {
          // Custom logic before file deletion
      });
      
  4. Twig Extensions:

    • Extend the asset helper for custom URL generation:
      class CustomTwigExtension extends \Twig_Extension {
          public function getFunctions() {
              return [
                  new \Twig_SimpleFunction('custom_asset', [$this
      
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