VichUploaderBundle Documentation

repository·master·Indexed 24 days ago

https://github.com/dustin10/vichuploaderbundle

A Symfony bundle for managing file uploads attached to ORM entities, MongoDB ODM documents, or PHPCR ODM documents. It handles automatic naming, storage, filesystem cleanup, and URL generation. Key features include entity injection of files, custom directory naming via DirectoryNamerInterface, file serving through DownloadHandler, and a flexible event system for hooking into the upload and removal lifecycle.

Tokens
22.4K
Snippets
61
Records
101
Agent score
78%

What's inside VichUploaderBundle

  1. Overview of VichUploaderBundle

    master

    VichUploaderBundle is a Symfony bundle designed to simplify file uploads attached to ORM entities, MongoDB ODM documents, or PHPCR ODM documents.

    Key features include:

    • Automatic File Management: Automatically names and saves files to a configured directory.
    • Entity Injection: Injects the file back into the entity/document as a Symfony\Component\HttpFoundation\File\File instance when loaded from the datastore.
    • Automatic Cleanup: Deletes the file from the filesystem when the associated entity or document is removed from the datastore.
    • Templating Helpers: Provides helpers to generate public URLs for the uploaded files.

    The bundle is fully configurable to support application-specific customization.

  2. Configure Directory Namers

    master

    Directory namers allow you to customize the subdirectory structure where files are stored.

    Crucial Requirement: Directory namers MUST be stateless. They are called during upload and also when retrieving paths/URLs later. They must rely only on the mapping or the entity data.

    If no directory_namer is configured, the bundle uses the upload_destination value directly.

  3. Determine YAML file naming for entity mappings

    master

    When using custom directories, the Fully Qualified Class Name (FQCN) of your entity is determined by combining the namespace_prefix with the filename.

    For an entity with the FQCN MyApp\MyBundle\Entity\Customer, you can use either of these patterns:

    1. namespace_prefix: 'MyApp\MyBundle' with filename Entity.Customer.yaml
    2. namespace_prefix: 'MyApp\MyBundle\Entity' with filename Customer.yaml
  4. Handle upload and removal errors

    master

    VichUploaderBundle provides specific error events to handle failures:

    • UPLOAD_ERROR (Events::UPLOAD_ERROR): Fired when writing a file fails, occurring before an exception is thrown.
    • REMOVE_ERROR (Events::REMOVE_ERROR): Fired if an error occurs while removing a file.

    Important: Failures during file removal do not trigger exceptions automatically. If you want the application to throw an exception when a removal fails, you must catch the error in a listener for the REMOVE_ERROR event and manually throw the exception provided by the ErrorEvent.

    <?php
    
    namespace App\EventListener;
    
    use Vich\UploaderBundle\Event\ErrorEvent;
    use Vich\UploaderBundle\Event\Event;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Vich\UploaderBundle\Event\Events;
    
    class RemoveErrorEventListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(){
                return [
                Events::REMOVE_ERROR => 'onUploadError',
            ]
        }
        public function onUploadError(ErrorEvent $errorEvent)
        {
            $object = $event->getObject();
            $mapping = $event->getMapping();
            $exception = $errorEvent->getThrowable();
            
            throw $exception;
        }
    
    }
  5. How the FileRequired validator works

    master

    The FileRequired validator checks for file presence using the following priority order:

    1. Existing File: If the property specified by target contains a file with a name, validation passes.
    2. New Upload: If the upload field contains a valid UploadedFile, validation passes.
    3. Replacing File: If the upload field contains a ReplacingFile, validation passes.
    4. Fallback: If none of the above are met, it falls back to standard Symfony NotBlank validation logic.
  6. Set up automatic YAML mapping discovery

    master

    To use automatic discovery for YAML mappings, place your configuration files in the config/vich_uploader directory of your Symfony application.

    For discovery to work, the root namespace of your entities must be the standard App namespace. Third-party bundles should place their files in their own specific directory following the same pattern.

  7. Use VichFileType in Symfony forms

    master

    To simplify file uploads, deletions, and downloads within a Symfony form, use the VichFileType class. You can configure various options to control how the file is handled and displayed in the UI.

    use Vich\UploaderBundle\Form\Type\VichFileType;
    
    // Inside your buildForm method:
    $builder->add('genericFile', VichFileType::class, [
        'required' => false,
        'allow_delete' => true,
        'delete_label' => '...',
        'download_uri' => '...',
        'download_label' => '...',
        'asset_helper' => true,
    ]);
  8. Enable VichUploaderBundle

    master

    If your project uses Symfony Flex, the bundle is automatically enabled via a recipe and requires no manual action.

    If you are not using Flex, you must manually register the bundle in your application's kernel class (typically app/AppKernel.php or similar).

    // app/AppKernel.php (your kernel class may be defined in a different class/path)
    class AppKernel extends Kernel
    {
        public function registerBundles()
        {
            $bundles = [
                // ...
                new Vich\UploaderBundle\VichUploaderBundle(),
                // ...
            ];
        }
    }
  9. Configure an upload mapping

    master

    To handle file uploads, you must first define a mapping in your configuration. A mapping specifies where files are stored (upload_destination), their web accessibility path (uri_prefix), and a unique name for the mapping.

    Minimal configuration requires defining the db_driver (e.g., orm), metadata type (e.g., attribute), and the mappings collection. If upload_destination is omitted, it defaults to %kernel.project_dir%/public combined with the uri_prefix value.

    # config/packages/vich_uploader.yaml or app/config/config.yml
    vich_uploader:
        db_driver: orm
    
        metadata:
            type: attribute
    
        mappings:
            products:
                uri_prefix: /images/products
                upload_destination: '%kernel.project_dir%/public/images/products'
                namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
  10. Configure File Namers

    master

    The bundle uses namers to determine the filename of uploaded files. A namer must implement Vich\UploaderBundle\Naming\NamerInterface. You can use any of the provided namers or implement a custom one.

    To use a namer, specify it under the namer key in your mapping configuration. If the namer requires options, use the service and options syntax.

    vich_uploader:
        mappings:
            products:
                upload_destination: products_fs
                namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
  11. Use VichImageType for image uploads and management

    master

    The VichImageType is a custom form type designed to simplify the process of uploading, deleting, and downloading images within Symfony forms. It provides built-in support for generating URIs, handling deletions, and integrating with image transformation bundles like LiipImagineBundle.

    To use it, add the field to your FormBuilderInterface using VichImageType::class.

    use Vich\UploaderBundle\Form\Type\VichImageType;
    
    // ...
    class Form extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options): void
        {
            // ...
            $builder->add('imageFile', VichImageType::class, [
                'required' => false,
                'allow_delete' => true,
                'delete_label' => '...',
                'download_label' => '...',
                'download_uri' => true,
                'image_uri' => true,
                'imagine_pattern' => '...',
                'asset_helper' => true,
            ]);
        }
    }