Как использовать mimeType Assert с VichUploader?

Это утверждение проходит проверку формы Symfony при загрузке любого файла с помощью VichUploaderBundle:

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


person TMichel    schedule 01.12.2015    source источник


Ответы (4)


Вы можете использовать обратный вызов проверки, чтобы решить эту проблему.

/**
 * @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()
            ;
        }
    }
}
person Mikhail Prosalov    schedule 15.12.2015
comment
Проверка тихо завершается ошибкой на symfony 2.7 - person SudarP; 19.04.2016
comment
В более новых версиях Symfony аннотацию обратного вызова необходимо добавлять в блок документации методов, а не в класс: symfony.com/doc/current/reference/constraints/ - person Jonny; 27.07.2016
comment
Примечание. Мне нужно было добавить аннотацию @Assert\Callback для функции validate(), чтобы это работало. См.: symfony.com/doc/current/reference/constraints/ - person Yes Barry; 13.11.2016

Для Symfony 4.0 вам нужно импортировать компонент Validator.

composer require validator

Теперь в вашем классе Entity вы можете использовать аннотацию @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, вам нужно использовать ограничение File 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 и size, как описано здесь https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md#step-2-link-the-upload-mapping-to-an-entity, но я не смог заставить это работать.

Аннотация @Assert будет генерировать ошибки Forms, которые вы можете извлечь в 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 %}
person Kaizoku Gambare    schedule 16.01.2018
comment
Можно ли i18n сообщения, установленные в аннотациях? Если нет, то это решение не так уж и велико... - person Shautieh; 25.10.2018
comment
Я думаю, это нормально. Я не проверял это, хотя symfony.com/doc/current/validation/translations.html - person Kaizoku Gambare; 26.10.2018

Для Symfony 4.x это решение не работает. я не знаю, почему валидатор утверждений или событий никогда не вызывает...

Я нашел это решение: Проверка не работает в полях отношений

         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',
                        ]
                    ])
                ]
            ])
person Sinelc    schedule 17.01.2019
comment
Удалось ли вам выяснить, почему это не работает должным образом с @assert/Valid ? - person Miles M.; 22.04.2020

Для Symfony 3.0+ нужно сделать всего две вещи:

  • Добавьте оператор использования для импорта 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();
       }
    }
    
person Niket Pathak    schedule 14.03.2017