symfony3.4 (проблема загрузки изображения) - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь загрузить изображение в виде поля данных формы вместе с другими полями.Я следую за документацией Symphony по этой ссылке Я использую FosRestBundle и jms-сериализатор.Проблема в том, что он возвращает: Bad Request, потому что не может прочитать поле изображения, оно всегда пустое.

Я пробовал это с Postman и Symfony, но в любом случае он не возвращает положительный отзыв.

config.yml

images_directory: '%kernel.project_dir%/web/uploads/images'

service.yml

services:

   app.image_uploader:
        class: AppBundle\ImageUpload
        arguments: ['%images_directory%']

   app.doctrine_image_listener:
        class: AppBundle\EventListener\UploadImageListener
        arguments: ['@app.image_uploader']
        tags:
            - { name: doctrine.event_listener, event: prePersist }
            - { name: doctrine.event_listener, event: preUpdate }
            - { name: doctrine.event_listener, event: postLoad }

ImageUpload.php

<?php


namespace AppBundle;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\Exception\FileException;

class ImageUpload
{
    private $targetDir;

    public function __construct($targetDir)
    {
        $this->targetDir = $targetDir;
    }

    public function upload(UploadedFile $file)
    {
        $fileName = md5(uniqid()).'.'.$file->guessExtension();

        try {
            $file->move($this->getTargetDir(), $fileName);
        } catch (FileException $e) {
            // ... handle exception if something happens during file upload
        }

        return $fileName;
    }

    public function getTargetDir()
    {
        return $this->targetDir;
    }
}

ImageUploadListener.php

<?php

namespace AppBundle\EventListener;


use AppBundle\Entity\Meuble;
use AppBundle\ImageUpload;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\File;

class UploadImageListener
{

    private $uploader;

    public function __construct(ImageUpload $uploader)
    {
        $this->uploader = $uploader;
    }

    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        $this->uploadFile($entity);
    }

    public function preUpdate(PreUpdateEventArgs $args)
    {
        $entity = $args->getEntity();

        $this->uploadFile($entity);
    }

    private function uploadFile($entity)
    {
        // upload only works for Product entities
        if (!$entity instanceof Meuble) {
            return;
        }

        $file = $entity->getImage();

        // only upload new files
        /*if (!$file instanceof UploadedFile) {
            return;
        }*/
        if ($file instanceof UploadedFile) {
            $fileName = $this->uploader->upload($file);
            $entity->setImage($fileName);
        }elseif ($file instanceof File) {
            // prevents the full file path being saved on updates
            // as the path is set on the postLoad listener
            $entity->setImage($file->getFilename());
        }
    }

    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if (!$entity instanceof Meuble) {
            return;
        }

        if ($fileName = $entity->getImage()) {
            $entity->setImage(new File($this->uploader->getTargetDir().'/'.$fileName));
        }
    }
}

entity meuble.php

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * Meuble
 *
 * @ORM\Table(name="meuble")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MeubleRepository")
 */
class Meuble
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Piece", inversedBy="meubles")
     * @var Piece
     */
    private $piece;

    /**
     * @var int
     *
     * @ORM\Column(name="volume", type="integer")
     */
    private $volume;

    /**
     * @var string
     *
     * @ORM\Column(name="image",type="string")
     * @Assert\NotBlank(message="Please, upload the photo.")
     * @Assert\File(
     *     mimeTypes={ "image/png", "image/jpg", "image/jpeg" },
     *     mimeTypesMessage="Please upload a valid image")
     */
    private $image;

    public function getImage()
    {
        return $this->image;
    }

    public function setImage($image)
    {
        $this->image = $image;

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

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Meuble
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

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

    /**
     * @return mixed
     */
    public function getVolume()
    {
        return $this->volume;
    }

    /**
     * @param mixed $volume
     */
    public function setVolume($volume)
    {
        $this->volume = $volume;
    }

    /**
     * @return Piece
     */
    public function getPiece()
    {
        return $this->piece;
    }

    /**
     * @param Piece $piece
     */
    public function setPiece($piece)
    {
        $this->piece = $piece;
    }



}

MeubleType.php

<?php
/**
 * Created by PhpStorm.
 * User: KHALED
 * Date: 13/03/2019
 * Time: 15:34
 */

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MeubleType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');
        $builder->add('volume');
        $builder->add('image', FileType::class, ['label' => 'Image (JPG ou PNG)']);
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Meuble',
            'csrf_protection' => false

        ));
    }

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


}

controller.php

 /**
     * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"meuble"})
     * @Rest\Post("/{id}/meuble/new")
     */
    public function addMeubleAction(Request $request)
    {
        $piece = $this->get('doctrine.orm.entity_manager')
            ->getRepository('AppBundle:Piece')
            ->find($request->get('id'));
        /* @var $piece Piece */

        if (empty($piece)) {
            return $this->pieceNotFound();
        }

        $meuble = new Meuble();
        $meuble->setPiece($piece);
        //$meuble->setImage($request->files->all()['image']);

       /* $uploadedImage=$request->files->get('file');
        $meuble->setImage($uploadedImage);*/
        //$meuble->setImage($request->files->all()['image']);
        $form = $this->createForm(MeubleType::class, $meuble);
        // Le paramétre false dit à Symfony de garder les valeurs dans notre
        // entité si l'utilisateur n'en fournit pas une dans sa requête

        $form->submit($request->request->all());
        //$form->handleRequest($request);

        //if ($form->isValid()&& $form->isSubmitted()) {
        if ($form->isValid()) {

            /*
             * /**
             * @var UploadedFile $file
             *
             * $file=$meuble->getImage();

            $fileName = md5(uniqid()).'.'.$file->guessExtension();
            $file->move($this->getParameter('images_directory'), $fileName);
            $meuble->setImage($fileName);*/


            /*$file = $meuble->getImage();
            $fileName = $imageUpload->upload($file);
            $meuble->setImage($fileName);*/
            $em = $this->get('doctrine.orm.entity_manager');
            $em->persist($meuble);
            $em->flush();
            return $meuble;
        } else {
            return $form;
        }
    }

Сериализация Entity.Meuble.yml

AppBundle\Entity\Meuble:
  exclusion_policy: none
  properties:
    id:
      groups: ['quantite','meuble','devis','piece']
    name:
      groups: ['quantite','meuble','devis','piece']
    volume:
      groups: ['quantite','meuble','devis','piece']
    image:
      groups: ['quantite','meuble','devis','piece']
    piece:
      groups: ['meuble']

Я ожидаю, что выходной сигнал будет 200 в порядке, изображение сохранено, и я могу его визуализировать, но фактический вывод - это 400 "message": "Validation Failed" ответ почтальона

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...