Problems with VichUploaderBundle render image using twig

Mauro Alvarez picture Mauro Alvarez · Feb 28, 2015 · Viewed 7.8k times · Source

I have a problem with VichUploaderBundle, I followed all the instructions and I could make it upload an image, now I don't know how to render the images using twig. I have a Product entity which has a OneToOne relation with Photo (I use entity photo with VichUploaderBundle).

My html.twig file

{% for product in products %}

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

This gives me the following error,

 An exception has been thrown during the rendering of a template ("Impossible to determine the class name. Either specify it explicitly or give an object") in products/list_all_products.html.twig at line 9.

So I added to the img tag the following

  <img src="{{ vich_uploader_asset(product, 'image','AppBundle\Entity\Product') }}" alt="{{ product.nombre }}" />

and throws me this error

An exception has been thrown during the rendering of a template ("Class AppBundleEntityProduct does not exist") in products/list_all_products.html.twig at line 9.

My entities are stored in AppBundle\Entity\ * and also it removes the slashes.

I also tried to add this with no success.

<img src="{{ vich_uploader_asset(product.photo, 'image','AppBundle\Entity\Product') }}" alt="{{ product.nombre }}" />

My Photo entity (It's a copy & paste from the instructions of the bundle)

<?php 
 //src/AppBundle/Entity/Photo.php

 namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collection\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

 /**
  * @ORM\Entity
  * @ORM\Table(name="photo")
  * @Vich\Uploadable
  */

/*
This class represents the images 
*/


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

/**
* @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName") 
* 
* @var File $imageFile
*/
protected $imageFile;

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

/**
 * @ORM\Column(type="datetime")
 *
 * @var \DateTime $updatedAt
 */
protected $updatedAt;

/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 * of 'UploadedFile' is injected into this setter to trigger the  update. If this
 * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
 * must be able to accept an instance of 'File' as the bundle will inject one here
 * during Doctrine hydration.
 *
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
 */
public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}

/**
 * @return File
 */
public function getImageFile()
{
    return $this->imageFile;
}

/**
 * @param string $imageName
 */
public function setImageName($imageName)
{
    $this->imageName = $imageName;
}

/**
 * @return string
 */
public function getImageName()
{
    return $this->imageName;
}
}

And here's my Product entity

<?php
 //src/AppBundle/Entity/Product.php

 /*
  This class represents a product, for instance, we'll be using
  only product.
 */

 namespace AppBundle\Entity;

 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\ArrayCollection;

/**
  * @ORM\Entity
  * @ORM\Table(name="product")
* ORM\Entity(repositoryClass="AppBundle\Repositories\ProductRepository")
*/

 //extends objComercio has been removed for simplicity.
class Product
{

public function __construct()
{

    $this->photos = new ArrayCollection();
}

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $nombre;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $descripcion;

/**
* @ORM\Column(type="integer",nullable=false)
*/
protected $precio;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $empresa;

/**
* @ORM\OneToOne(targetEntity="Photo", cascade={"persist"})
*/
protected $photo; 

/**
* @ORM\ManyToOne(targetEntity="Store",inversedBy="products")
*/
protected $store_product;


public function getPhoto()
{
    return $this->photo;
}
public function setPhoto(\AppBundle\Entity\Photo $photo)
{
    $this->photo = $photo;
}
public function getPrecio()
{
    return $this->precio;
}
public function setPrecio($aPrice)
{
    $this->precio = $aPrice;
}
public function getEmpresa()
{
    return $this->empresa;
}
public function setEmpresa($anEnterprise)
{
    $this->empresa = $anEnterprise;
}




/**
 * Set store_product
 *
 * @param \AppBundle\Entity\Store $storeProduct
 * @return Product
 */
public function setStoreProduct(\AppBundle\Entity\Store $storeProduct = null)
{
    $this->store_product = $storeProduct;

    return $this;
}

/**
 * Get store_product
 *
 * @return \AppBundle\Entity\Store 
 */
public function getStoreProduct()
{
    return $this->store_product;
}

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set nombre
 *
 * @param string $nombre
 * @return Product
 */
public function setNombre($nombre)
{
    $this->nombre = $nombre;

    return $this;
}

/**
 * Get nombre
 *
 * @return string 
 */
public function getNombre()
{
    return $this->nombre;
}

/**
 * Set descripcion
 *
 * @param string $descripcion
 * @return Product
 */
public function setDescripcion($descripcion)
{
    $this->descripcion = $descripcion;

    return $this;
}

/**
 * Get descripcion
 *
 * @return string 
 */
public function getDescripcion()
{
    return $this->descripcion;
}
}

I printed everything using {{}}, and it's all working fine.

I don't what else to do.

Thanks in advance!

Answer

StefanNch picture StefanNch · Aug 15, 2017

I know this is really old, but for Google is still pretty relevant. I think this should work:

  • put 'imageFile' instead of 'image';
  • double the slashes for the className;

    {{ vich_uploader_asset(product, 'imageFile', 'AppBundle\\Entity\\Product') }}