2012-08-28 43 views
9

我想使用文件验证器来限制文件输入的MIME类型。不幸的是,这个约束从来没有使用过,所有的文件都被接受为什么Symfony文件验证器不起作用

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); 
     } 
    } 
} 

表单生成器:

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'; 
} 

控制器:

/** 
* 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(), 
    ); 
} 
+0

不同的主题:我已经注意到你有与路径相同的问题,你可能想检查一下:http://stackoverflow.com/questions/12168086/how-to-deal-with-relative-paths -in-symfony-2 – ChocoDeveloper

+0

谢谢,但保存工作无懈可击,但我无法找到验证无效的原因。也许是因为它只是一个虚拟的字段没有用作db列? –

+0

我刚刚创建了一个使用此断言的测试应用程序,它工作正常。非图像出现错误,图像通过。这是在Symfony2.1上。你的表单构建器是什么样的? – Kris

回答

3

我找到了解决方案。在表单定义我使用`'validation_groups'=>数组('注册')。我认为,当没有验证者组时,它将与表单定义中的任何一个匹配。

当我已经添加组属性验证器一切都最后工作。因此,使用validation.yml例如:

WNC\SoldierBundle\Entity\Soldier: 
    properties: 
     file: 
      - Image: {groups: [Registration]} 
5

退房此之前的SO问题:Symfony2 validation using Assert annotation does not work。您可能需要确保符合所有推荐的配置以使用Symfony2。

另外,不需要验证$pictureImage约束,因为它不是文件/图像。

/** 
* @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; 

实际上,我是能够验证上传的文件是使用YAML替代,所以你可能也想尝试一个形象,如果没有出现。

+0

感谢您的回答,不幸的是您的建议并未解决问题。您提供的链接与我使用的其他验证程序相关。我没有像标准的验证器,如要求,非空等问题,我检查了VichUploaderBundle和删除生命周期注释,但它没有作出改变。你使用什么symfony版本? –

+0

另一方面,yml验证文件在这种情况下也是无效的 –

+0

Hi @LukeAdamczewski,是的,我知道我提供的链接是关于不同的验证器。我认为是有用的,虽然实际上是这个答案http://stackoverflow.com/a/7946408/1349295关于国际扩展。也许确保符合sf2的所有推荐配置?顺便说一句,我在sf2.0上工作。我已经将一些代码从2.1移植到2.0,并且遇到了一些重大变化(并且仍在变化中)。顺便说一下,sf2.1不再处于测试阶段!刚刚检查过。也许尝试升级到最新的发行版。 :) –

0

您可以使用约束这是不适合你的领域。只需在$ file属性上使用File约束即可。

相关问题