【问题标题】:How to use mimeType Assert with VichUploader?如何将 mimeType Assert 与 VichUploader 一起使用?
【发布时间】:2015-12-01 11:33:25
【问题描述】:

当使用VichUploaderBundle 上传任何文件时,此断言正在通过 Symfony 的表单验证:

/**
 * @Vich\UploadableField(mapping="product_media", fileNameProperty="path")
 * @Assert\File(
 *     mimeTypes = {"image/jpeg", "image/gif", "image/png", "video/mp4", "video/quicktime", "video/avi"},
 *     mimeTypesMessage = "Wrong file type (jpg,gif,png,mp4,mov,avi)"
 * )
 * @var File $pathFile
 */
protected $pathFile;

我看不出断言有什么问题。如何使用 VichUploader 验证文件类型?

【问题讨论】:

    标签: symfony assert vichuploaderbundle


    【解决方案1】:

    对于 Symfony 4.0,您需要导入 Validator 组件

    composer require validator
    

    现在在您的实体类中,您可以使用@Assert 注释。

    // src/Entity/Author.php
    
    // ...
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Author
    {
        /**
         * @Assert\NotBlank()
         */
        public $name;
    }
    

    您可能需要在 config/packages/framework.yaml 文件中添加一些配置。无论如何,这一切都在 Symfony 官方文档中得到了完美的解释。

    http://symfony.com/doc/current/validation.html

    要检查 mime 类型,您需要使用文件约束 http://symfony.com/doc/current/reference/constraints/File.html

    这是一个工作示例

    /**
     * @ORM\Column(type="string", length=255)
     * @var string
     */
    private $cvFilename;
    
    /**
     * @Assert\File(
     *     maxSize = "2048k",
     *     mimeTypes = {"application/pdf", "application/x-pdf"},
     *     mimeTypesMessage = "Please upload a valid PDF"
     * )
     * @Vich\UploadableField(mapping="cv", fileNameProperty="cvFilename")
     * @var File
     */
    private $cvFile;
    

    现在@Vich\UploadableField 注释中确实有一个 mime 和大小选项,如此处所述https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md#step-2-link-the-upload-mapping-to-an-entity 但我无法让它发挥作用。

    @Assert 注释会生成表单错误,您可以在 Twig 中检索它们以提供反馈。

    关键是使用:form_errors(candidature_form.cvFile)

    这是一个工作示例:

     {% set error_flag = form_errors(candidature_form.cvFile) %}
    
            <label class=" {% if error_flag %}has-error{% endif %}">
                Curriculum Vitae (PDF)
            </label>
            {{ form_widget(candidature_form.cvFile) }}
            {% if error_flag %}
                <div class="has-error">
                    {{ form_errors(candidature_form.cvFile) }}
                </div>
            {% endif %}
    

    【讨论】:

    【解决方案2】:

    您可以使用验证回调来解决此问题。

    /**
     * @ORM\Entity(repositoryClass="AppBundle\Entity\Repository\EntityRepository")
     * @ORM\Table(name="entity")
     * @Assert\Callback(methods={"validate"})
     * @Vich\Uploadable
     */
    class Entity
    {
        /**
         * @Assert\File(maxSize="10M")
         * @Vich\UploadableField(mapping="files", fileNameProperty="fileName")
         *
         * @var File $file
         */
        protected $file;
    
        /**
         * @ORM\Column(type="string", length=255, name="file_name", nullable=true)
         *
         * @var string $fileName
         */
        protected $fileName;
    
    ...
    
        /**
         * @param ExecutionContextInterface $context
         */
        public function validate(ExecutionContextInterface $context)
        {
            if (! in_array($this->file->getMimeType(), array(
                'image/jpeg',
                'image/gif',
                'image/png',
                'video/mp4',
                'video/quicktime',
                'video/avi',
            ))) {
                $context
                    ->buildViolation('Wrong file type (jpg,gif,png,mp4,mov,avi)')
                    ->atPath('fileName')
                    ->addViolation()
                ;
            }
        }
    }
    

    【讨论】:

    【解决方案3】:

    对于 Symfony 4.x,此解决方案不起作用。我不知道为什么断言或事件验证器从不调用...

    我找到了这个解决方案:Validation doesn't work on relation fields

             use Symfony\Component\Validator\Constraints\File;
            /* ... */
            ->add('ba_file', VichFileType::class, [
                    'label' => 'Bon d\'adhésion (PDF file)',
                    'required' => false,
                    'constraints' => [
                        new File([
                            'maxSize' => '5M',
                            'mimeTypes' => [
                                'image/jpeg',
                                'image/gif',
                                'image/png',
                            ]
                        ])
                    ]
                ])
    

    【讨论】:

    • 您是否能够找出为什么 @assert/Valid 无法按预期工作?
    【解决方案4】:

    对于 Symfony 3.0+,只需要做两件事:

    • 添加use语句导入ExecutionContextInterface

    • 回调注解必须直接添加到方法/函数而不是类。

      use Symfony\Component\Validator\Context\ExecutionContextInterface;
      
      /**
      * @Assert\File(maxSize="2M")
      * @Vich\UploadableField(mapping="profile_image", fileNameProperty="avatar")
      * @var File
      */
      private $imageFile;
      
      /**
      * @ORM\Column(length=255, nullable=true)
      * @var string $avatar
      */
      protected $avatar;
      
      /**
      * @Assert\Callback
      * @param ExecutionContextInterface $context
      */
      public function validate(ExecutionContextInterface $context, $payload)
      {
         // do your own validation
         if (! in_array($this->imageFile->getMimeType(), array(
             'image/jpeg',
             'image/gif',
             'image/png'
      ))) {
          $context
              ->buildViolation('Wrong file type (only jpg,gif,png allowed)')
              ->atPath('imageFile')
              ->addViolation();
         }
      }
      

    【讨论】:

      猜你喜欢
      • 2020-07-27
      • 2015-03-11
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 2023-03-13
      • 2014-09-25
      • 2016-01-30
      • 2015-12-13
      相关资源
      最近更新 更多