Skip to content

Latest commit

 

History

History
238 lines (185 loc) · 7.34 KB

index.md

File metadata and controls

238 lines (185 loc) · 7.34 KB

VichUploaderBundle

The VichUploaderBundle is a simple Symfony2 bundle that attempts to ease file uploads that are attached to an entity. The bundle will automatically name and save the uploaded file according to the configuration specified on a per property basis. It will also load the file back into the entity upon retrieval from the datastore if configured to do so. The bundle also provides templating helpers for generating URLs to the file. The file can also be configured to be removed from the file system upon removal of the entity.

Installation

Get the bundle

To install the bundle, place it in the vendor/bundles/Vich/UploaderBundle directory of your project. You can do this by adding the bundle to your deps file, as a submodule, cloning it, or simply downloading the source.

Add to deps file:

[VichUploaderBundle]
    git=git://github.com/dustin10/VichUploaderBundle.git
    target=/bundles/Vich/UploaderBundle

Or you may add the bundle as a git submodule:

$ git submodule add https://github.com/dustin10/VichUploaderBundle.git vendor/bundles/Vich/UploaderBundle

Add the namespace to your autoloader

Next you should add the Vich namespace to your autoloader:

<?php
// app/autoload.php

$loader->registerNamespaces(array(
    // ...
    'Vich' => __DIR__.'/../vendor/bundles'
));

Initialize the bundle

To start using the bundle, register the bundle in your application's kernel class:

// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Vich\UploaderBundle\VichUploaderBundle(),
    );
)

Configuration

First configure the db_driver option. You must specify either orm or mongodb.

# app/config/config.yml
vich_uploader:
    db_driver: orm # or mongodb

In order to map configuration options to the property of the entity you first need to create a mapping in the bundle configuration. You create these mappings under the mappings key. Each mapping should have a unique name. So, if you wanted to name your mapping product_image, the configuration for this mapping would be similar to:

vich_uploader:
    # ...
    mappings:
        product_image:
            upload_dir: %kernel.root_dir%/../web/images/products

The upload_dir is the only required configuration option for an entity mapping. All options are listed below:

  • upload_dir: The directory to upload the file to
  • namer: The id of the namer service for this entity (See Namers section below)
  • delete_on_remove: Set to true if the file should be deleted from the filesystem when the entity is removed
  • inject_on_load: Set to true if the file should be injected into the uploadable field property when it is loaded from the data store. The object will be an instance of Symfony\Component\HttpFoundation\File\File

Note:

A verbose configuration reference including all configuration options and their default values is included at the bottom of this document.

Annotate Entities

In order for your entity or document to work with the bundle, you need to add a few annotations to it. First, annotate your class with the Uploadable annotation. This lets the bundle know that it should look for files to upload in your class when it is saved, inject the files when it is loaded and check to see if it needs to remove files when it is removed. Next, you should annotate the fields which hold the instance of Symfony\Component\HttpFoundation\File\UploadedFile when the form is submitted with the UploadableField annotation. The UploadableField annotation has a few required options. They are as follows:

  • mapping: The mapping specified in the bundle configuration to use
  • fileNameProperty: The property of the class that will be filled with the file name generated by the bundle

Lets look at an example using a fictional Product ORM entity:

<?php

namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraint as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * @Vich\Uploadable
 */
class Product
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    // ..... other fields

    /**
     * @Assert\File(
     *     maxSize="1M",
     *     mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
     * )
     * @Vich\UploadableField(mapping="property_image", fileNameProperty="imageName")
     *
     * @var File $image
     */
    protected $image;

    /**
     * @ORM\Column(type="string", length=255, name="image_name")
     *
     * @var string $imageName
     */
    protected $imageName;
}

Namers

The bundle uses namers to name the files it saves to the filesystem. A namer implements the Vich\UploaderBundle\Naming\NamerInterface interface. If no namer is configured for a mapping, the bundle will simply use the name of the file that was uploaded. if you would like to change this then you must implement a custom namer.

To create a custom namer, simply implement the Vich\UploaderBundle\Naming\NamerInterface and in the name method of your class return the desired file name. Since your entity is passed to the name method, as well as the field name, you are free to get any information from it to create the name, or inject any other services that you require.

Note: The name returned should include the file extension as well. This can easily be retrieved from the UploadedFile instance using the getExtension or guessExtension depending on what version of PHP you are running.

After you have created your namer and configured it as a service, you simply specify the service id for the namer configuration option of your mapping. An example:

vich_uploader:
    # ...
    mappings:
        product_image:
            upload_dir: %kernel.root_dir%/../web/images/products
            namer: my.namer.product

Here my.namer.product is the configured id of the service.

Generating URLs

To get a url for the file you can use the vich_uploader.templating.helper service as follows:

$entity = // get the entity..
$helper = $this->container->get('vich_uploader.templating.helper');
$path = $helper->asset($entity, 'image');

or in a Twig template you can use the vich_uploader_asset function:

<img src="{{ vich_uploader_asset(product, 'image') }}" alt="{{ product.name }}" />

You must specify the annotated property you wish to get the file path for.

Note: The path returned is relative to the web directory which is specified using the web_dir_name configuration parameter.

Limitations

  • Currently the bundle only supports generating a relative url for the file.
  • Currently the bundle only supports saving/deleting files to the local filesystem.

Configuration Reference

Below is the full default coniguration for the bundle:

# app/config/config.yml
vich_uploader:
    db_driver: orm # or mongodb
    web_dir_name: web
    twig: true
    mappings:
        product_image:
            upload_dir: ~ # required
            namer: ~ # specify a namer service id for this entity, null default
            delete_on_remove: true # determines whether to delete file upon removal of entity
            inject_on_load: true # determines whether to inject a File instance upon load
        # ... more mappings