Вопрос: Подтверждение формы Symfony3 не используется для использования в полевых условиях модельным трансформатором


Изменить: вот GitHub  с полным кодом для воспроизведения проблемы

У меня есть следующая сущность

class Place
{
    use Traits\HasId;

    /**
     * Used for form.
     *
     * @Assert\Image(
     *     mimeTypes = {"image/png", "image/jpeg"},
     *     minWidth = 50,
     *     maxWidth = 1000,
     *     minHeight = 50,
     *     maxHeight = 1000,
     *     maxSize = "1M"
     * )
     */
    private $imageFile = null;

    /**
     * @ORM\OneToOne(targetEntity="MyImage", orphanRemoval=true, cascade={"persist"})
     */
    protected $image;

}

В следующем виде

class AdminPlaceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new HasImageTransformer();
        $builder->add('imageFile')->addModelTransformer($transformer);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['data_class' => 'AppBundle\Entity\Place']);
    }
}

И следующий модельный трансформатор

class HasImageTransformer implements DataTransformerInterface
{   
    public function transform($hasImage)
    {
        return $hasImage;
    }

    /**
     * reverse transforms.
     */
    public function reverseTransform($hasImage)
    {   
        $file = $hasImage->getImageFile();
        $myImage = new MyImage();
        $myImage->setData(file_get_contents($file->getPathName()))
        $myImage->setMimeType($file->getMimeType());

        $hasImage->setImage($myImage);
    }
}

Я могу загрузить правильное изображение, и форма будет правильно сохранена в базе данных.

Однако, если я отправляю неверное изображение (например, файл .txt), форма сохраняется в базе данных без какой-либо ошибки

Однако, если я удалю addModelTransformer из формы, то я получил правильную ошибку проверки

Этот файл не является допустимым.

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

Я использую php7 и symfony3.3.4


5


источник


Ответы:


Ответ был на самом деле довольно глупым

Причина в том, что я забыл о возвращении в reverseTransform 

/**
 * reverse transforms.
 */
public function reverseTransform($hasImage)
{   
    $file = $hasImage->getImageFile();
    $myImage = new MyImage();
    $myImage->setData(file_get_contents($file->getPathName()))
    $myImage->setMimeType($file->getMimeType());

    $hasImage->setImage($myImage);
    // this was missing :(
    return $hasImage;
}

Это вызывало всю сущность в форме модели  для преобразования как «null», но сам объект не был уничтожен, потому что я все еще ссылался на него в контроллере, поскольку он был создан через стандартный

  public function createAction(Request $request)
  {   
      $place = new Place();

      $form = $this->createForm(AdminPlaceType::class, $place);
      $form->handleRequest($request);
  }

Итак $place содержал правильные данные, а форма, имеющая null это не вызвало валидацию ....


3



Ваш трансформатор заменяет UploadFile или File объект по MyImage организация. Я предполагаю, что MyImage не распространяется File или UploadFile, Это не предназначено для трансформатора. Трансформатор меняет один вход на другой тип входа.

я рекомендовал бы снять трансформатор  и добавьте код трансформатора в Place->setImageFile, Затем вы будете иметь валидацию imageFile как ожидалось, и каждый раз, когда вы меняете изображение другим файлом, вы воссоздаете свой MyImage даже если вы не используете форму.

Если вы действительно хотите сделать это в коде формы, а не в коде объекта Place, вы должны использовать FormEvents   https://symfony.com/doc/current/form/events.html   FormEvents :: POST_SET_DATA


2



Чтобы вызвать ошибку проверки, введите исключение TransformationFailedException. Но сообщение, которое вы передаете этому исключению, не будет показано пользователю. Вы установите это сообщение с опцией invalid_message (см. Ниже). https://symfony.com/doc/current/form/data_transformers.html


0