Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Symfony File Validator is not working

I want to use file validator to restrict mime types for file input. Unfortunately this constraint is never used and all files were accepted.

namespace WNC\SoldierBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* WNC\SoldierBundle\Entity\Soldier
*
* @ORM\Table(name="soldier")
* @ORM\Entity(repositoryClass="WNC\SoldierBundle\Entity\SoldierRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Soldier
{

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

    /**
    * @var string $file
    * 
    * @Assert\Image()
    * @Assert\NotBlank()
    */
    public $file;


    public function getAbsolutePath()
    {
        return null === $this->picture ? null : $this->getUploadRootDir().'/'.$this->picture;
    }

    public function getWebPath()
    {
        return null === $this->picture ? null : $this->getUploadDir().'/'.$this->picture;
    }

    protected function getUploadRootDir()
    {
        // the absolute directory path where uploaded documents should be saved
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    protected function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view.
        return 'uploads/pictures';
    }

    /**
    * @ORM\PrePersist()
    * @ORM\PreUpdate()
    */
    public function preUpload()
    {

        if($this->picture && file_exists($this->getAbsolutePath())) {
            unlink($this->getAbsolutePath());
        }

        if (null !== $this->file) {
            // do whatever you want to generate a unique name
            $this->picture = uniqid().'.'.$this->file->guessExtension();
        }

    }

    /**
    * @ORM\PostPersist()
    * @ORM\PostUpdate()
    */
    public function upload()
    {
        if (null === $this->file) {
            return;
        }


        // if there is an error when moving the file, an exception will
        // be automatically thrown by move(). This will properly prevent
        // the entity from being persisted to the database on error
        $this->file->move($this->getUploadRootDir(), $this->picture);

    }

    /**
    * @ORM\PostRemove()
    */
    public function removeUpload()
    {
        if ($file = $this->getAbsolutePath()) {
            unlink($file);
        }
    }
}

Form builder:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('mothers_name')
        ->add('service_end_date', 'date',array(
            'widget' => 'single_text',
            'format' => 'MM/dd/yyyy',
            'attr' => array('class' => 'date six columns')
        ))
        ->add('army_unit')
        ->add('city', 'city_selector')
        ->add('gender', 'choice', array(
            'choices'   => array(0 => 'Male', 1 => 'Female'),
            'required'  => false,
            'expanded' => true,
            'label' => 'Male / Female',
            'data' => 0
        ))
        ->add('file','file', array(
          'data_class' => 'Symfony\Component\HttpFoundation\File\File',
          'label' => 'Picture'
        ))
        ->add('self_description', 'textarea')
        ->add('video', null, array(
            'attr' => array(
            'placeholder' => 'some link here'
        )))
        ->add('wants_to_contact', null, array(
            'label' => Soldier::getLabel('wants_to_contact')
        ))
        ->add('comments', 'textarea')
        ->add('user', new NameFormType('Application\Sonata\UserBundle\Entity\User')) 
        ->add('city', 'city_selector')

    ;


}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => array('Registration'),
        'cascade_validation' => true,
    ));


}

public function getName()
{
    return 'wnc_soldierbundle_soldiertype';
}

Controller:

/**
 * Creates a new Soldier entity.
 *
 * @Route("/create", name="soldier_create")
 * @Method("POST")
 * @Template("WNCSoldierBundle:Soldier:new.html.twig")
 */
public function createAction(Request $request)
{
    $entity  = new Soldier();
    $form = $this->createForm(new SoldierType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('soldier_show', array('id' => $entity->getId())));
    }

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}
like image 999
Luke Adamczewski Avatar asked Aug 28 '12 13:08

Luke Adamczewski


2 Answers

Check out this previous SO question: Symfony2 validation using Assert annotation does not work. You might want to ensure you have met all the recommended configurations to use Symfony2.

Also, it isn't necessary to validate $picture with Image constraint because it isn't a file/image.

/**
 * @var string $picture
 * @Assert\Image()                                        <-- Should be removed
 * @ORM\Column(name="picture", type="string", length=255)
 */
 private $picture; 

/**
 * @var string $file                                      <-- @var UploadedFile $file
 * 
 * @Assert\Image()
 * @Assert\NotBlank()
 */
 public $file;

I was actually able to validate that an uploaded file is an image using the YAML alternative so you might also want to try that if nothing comes up.

like image 54
Czar Pino Avatar answered Oct 24 '22 12:10

Czar Pino


I found the solution. In form definition i am using `'validation_groups' => array('Registration'). I thought that when there is no group for validator it will match to any of them in form definition.

When i have added groups property to validator everything was working finally. So for example using validation.yml:

WNC\SoldierBundle\Entity\Soldier:
    properties:
        file:
            - Image: {groups: [Registration]}
like image 42
Luke Adamczewski Avatar answered Oct 24 '22 14:10

Luke Adamczewski