Symfony2 form field not updated when validation error occurs

后端 未结 2 424
不知归路
不知归路 2021-01-05 12:56

Here is my form type:

class TestFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $         


        
相关标签:
2条回答
  • 2021-01-05 13:47

    Also there is another way using callbacks. Here i give you a generic class to uploads image and generate the thumbnails. I hope this work for you. This class manage the files generated automatically when you create update o delete the entity.

    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    use Symfony\Component\Validator\Constraints as Assert;
    use App\MyBundleBundle\Util\Util;
    
    /**
     * Image
     *
     * @ORM\Table(name="image")
     * @ORM\Entity()
     * @ORM\HasLifecycleCallbacks
     */
    class Image
    {
    
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         *
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="name", type="string")
         * @Assert\NotBlank()
         */
        private $name;
    
    
        private $temp;
    
        /**
         * @ORM\Column(type="string", length=255)
         */
        protected $path;
    
        /**
         * @Assert\Image(maxSize="5M")
         */
        private $file;
    
        /**
         * Sets file.
         *
         * @param UploadedFile $file
         */
        public function setFile(UploadedFile $file = null)
        {
            $this->file= $file;
    
            if (isset($this->path)) {
                $this->temp = $this->path;
                $this->path= null;
            } else {
                $this->path= 'initial';
            }
        }
    
        /**
         * Get file.
         *
         * @return UploadedFile
         */
        public function getFile()
        {
            return $this->file;
        }
    
        /**
         * @ORM\PrePersist()
         * @ORM\PreUpdate()
         */
        public function preUpload()
        {
            if (null !== $this->getFile()) {
                // do whatever you want to generate a unique name
                $filename = Util::getSlug($this->name) . uniqid() . '.' . $this->file->guessExtension();
                $this->path = $filename;
            }
        }
    
        /**
         * @ORM\PostPersist()
         * @ORM\PostUpdate()
         */
        public function upload()
        {
            if (null === $this->getFile()) {
                return;
            }
    
            $this->getFile()->move($this->getUploadRootDir(), $this->path);
            if (isset($this->temp)) {
                if (file_exists($this->getUploadRootDir() .'/'. $this->temp)) {
                    unlink($this->getUploadRootDir() . '/' . $this->temp);
                }
                $this->temp = null;
            }
            $this->file= null;
            //create a dir to save de thumbnails
            if (!file_exists($this->getUploadRootDir() . '/thumbnails')) {
                mkdir($this->getUploadRootDir() . '/thumbnails');
            }
    
            //call a method in util class to generate the thumbnails
            Util::redim($this->getUploadRootDir() . '/' . $this->path, $this->getUploadRootDir() . '/thumbnails/' . $this->path, 128, 128);
        }
    
        /**
         * @ORM\PostRemove()
         */
        public function removeUpload()
        {
            //This is to remove the files when the entity is delete
            if ($file = $this->getAbsolutePath()) {
                if (file_exists($file)) {
                    unlink($file);
                    $thumb = $this->getUploadRootDir() . '/thumbnails/' . $this->getPath();
                    if (file_exists($thumb)) {
                        unlink($thumb);
                    }
                }
            }
        }
    
        public function getAbsolutePath()
        {
            return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
        }
    
        public function getWebPath()
        {
            return null === $this->path? null :
                $this->getUploadDir() . '/' . $this->path;
        }
    
        protected function getUploadRootDir()
        {
            return $this->getUploadDir();
        }
    
        protected function getUploadDir()
        {
            return 'uploads/image/';
        }
    
        /**
         * Get id
         *
         * @return integer
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Set nombre
         *
         * @param string $name
         * @return Image
         */
        public function setName($name)
        {
            $this->name= $name;
    
            return $this;
        }
    
        /**
         * Get nombre
         *
         * @return string
         */
        public function getName()
        {
            return $this->name;
        }
    
    
        /**
         * Set path
         *
         * @param string $path
         * @return Imagen
         */
        public function setPath($path)
        {
            $this->path= $path;
    
            return $this;
        }
    
        /**
         * Get path
         *
         * @return string
         */
        public function getPath()
        {
            return $this->path;
        }
    
        public function __toString()
        {
            return $this->getName();
        }
    }
    
    0 讨论(0)
  • 2021-01-05 13:49

    I cannot exactly solve your problem, because in my opinion you're doing it the wrong way. A data class is actually only responsibly for keeping your data, so your method set/getThumbnailData should look like this

    <?php
    // ...
    private $thumbnailData;
    
    public function setThumbnailData(UploadedFile $thumbnailData) {
        $this->thumbnailData = $thumbnailData;
    }
    
    public function getThumbnailData() {
        return $this->thumbnailData;
    }
    

    In your controller you have something like this:

    <?php
    // ...
    public function formAction() {
    
        $form = // ... 
        $form->handleRequest($request);
        if($form->isValid()) {
            $test = $form->getData();
            /* @var $test Test */
            $thumbnailUploader = $this->get('thumbnail_uploader');
            /* @var $thumbnailUploader ThumbnailUploadService */
    
            $file = $test->getThumbnailData();
            $filename = $file->getClientOriginalName();
            $thumbnailUploader->upload($filename, $file);
    
            // ...
        }
    }
    

    I recommend to move all logic which has nothing to do with forms or requests into services. Your service in this case can be more generic handle any symfony files with a given filename.

    <?php
    class ThumbnailUploadService {
        /**
         * @param $file Symfony\Component\HttpFoundation\File\File
         *
         */
        public function upload($filename, File $file) {
            // ...
        }
    }
    
    0 讨论(0)
提交回复
热议问题