Symfony 3 - VichUploaderBundle - 映射错误

时间:2016-12-13 09:26:28

标签: symfony

我正在尝试使用VichUploaderBundle上传我的图片但是当我尝试创建新产品时出现以下错误

  

找不到字段“imageName”的映射

我按照https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md

上的说明进行操作

Parameters.yml

parameters:
    .....
    upload_folder: uploads

config.yml

vich_uploader:
    db_driver: orm
    mappings:
        product_image:
            uri_prefix:         /images/products
            upload_destination: '%kernel.root_dir%/../web/%upload_folder%/images/products'
            inject_on_load: false
            delete_on_update: true
            delete_on_remove: true

Product.php

namespace Car\MaintenanceBundle\Entity;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Doctrine\ORM\Mapping as ORM;

/**
 * Product
 *
 * @ORM\Table(name="product")
 * 
 * @ORM\Entity(repositoryClass="Car\MaintenanceBundle\Repository\ProductRepository")
 * @Vich\Uploadable
 */
class Product
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="product_name", type="string", length=255)
     */
    private $productName;

    /**
     * @var string
     *
     * @ORM\Column(name="brochure", type="string", length=255, nullable=true)
     */
    private $brochure;

    /**
    * NOTE: This is not a mapped field of entity metadata, just a simple property.
    *
    * @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
    *
    * @var File
    */
    private $imageFile;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="update_at", type="datetime")
     */
    private $updateAt;

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set productName
     *
     * @param string $productName
     *
     * @return Product
     */
    public function setProductName($productName)
    {
        $this->productName = $productName;

        return $this;
    }

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

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

        return $this;
    }

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

    /**
    *
    * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
    *
    * @return Product
    */
    public function setImageFile(File $image = null)
    {
      $this->imageFile = $image;
      if ($image) {
        $this->updatedAt = new \DateTime('now');
      }
      return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Set updateAt
     *
     * @param \DateTime $updateAt
     *
     * @return Product
     */
    public function setUpdateAt($updateAt)
    {
        $this->updateAt = $updateAt;

        return $this;
    }

    /**
     * Get updateAt
     *
     * @return \DateTime
     */
    public function getUpdateAt()
    {
        return $this->updateAt;
    }
}

ProductType.php

namespace Car\MaintenanceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Vich\UploaderBundle\Form\Type\VichFileType;

class ProductType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
      ->add('productName', TextType::class)
      ->add('brochure', TextType::class)
      ->add('imageName', VichFileType::class, array(
        'required'      => false,
        'allow_delete'  => true, // not mandatory, default is true
        'download_link' => true, // not mandatory, default is true
      ))
      ->add('imageFile', FileType::class)
      ->add('updateAt', DateType::class)
    ;
}

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Car\MaintenanceBundle\Entity\Product'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'car_maintenancebundle_product';
    }
}

ProductController.php

public function newAction(Request $request)
    {
        $product = new Product();

        //$helper = $this->container->get('vich_uploader.templating.helper.uploader_helper');
        //$path = $helper->asset($product, 'imageName');

        $form = $this->createForm('Car\MaintenanceBundle\Form\ProductType', $product);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($product);
            $em->flush($product);

            return $this->redirectToRoute('product_show', array('id' => $product->getId()));
        }

我无法弄清问题是什么。

2 个答案:

答案 0 :(得分:1)

我只是在表单构建器中更改:

$builder->add('**imageName**', VichFileType::class, array(
          'required' => false,
          'allow_delete' => true, // not mandatory, default is true
          'download_uri' => true, // not mandatory, default is true
      ));

$builder->add('**imageFile**', VichFileType::class, array(
          'required' => false,
          'allow_delete' => true, // not mandatory, default is true
          'download_uri' => true, // not mandatory, default is true
      ));

它的工作,非常奇怪....;)

答案 1 :(得分:0)

我认为问题来自于将您的产品实体与您的文件实体混合在一起。它们应该不同(这就是我自己使用Vich的方式)。

您应该拥有ProductImage实体:

namespace Car\MaintenanceBundle\Entity;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Doctrine\ORM\Mapping as ORM;

/**
 * Product
 *
 * @ORM\Table(name="product_image")
 * 
 * @ORM\Entity()
 * @Vich\Uploadable
 */
class ProductImage
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
*
* @var File
*/
private $imageFile;

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

/**
 * @var \DateTime
 *
 * @ORM\Column(name="update_at", type="datetime")
 */
private $updateAt;

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

然后在您的产品实体中添加一个属性$ image

/**
 * @ORM\OneToOne(targetEntity="Car\MaintenanceBundle\Entity\ProductImage", cascade={"persist"})
 * @ORM\JoinColumn(name= "image", referencedColumnName="id", nullable=true, onDelete="SET NULL")
 */
private $image;

最后,在你的ProductType班级

$builder
  ->add('productName', TextType::class)
  ->add('brochure', TextType::class)
  ->add('image', ProductImageType::class, array(
    'required'      => false,
  ))
;

使用ProductImageType

// ...
use Symfony\Component\Form\Extension\Core\Type\FileType;

class ProductImageType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('imageFile', FileType::class, array(
                'label' => false
            ));
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'CarMaintenanceBundle\Entity\ProductImage'
        ));
    }