antishov / StofDoctrineExtensionsBundle

Integration bundle for DoctrineExtensions by l3pp4rd in Symfony
https://symfony.com/doc/master/bundles/StofDoctrineExtensionsBundle/index.html
MIT License
220 stars 20 forks source link

After Enable Symfony Automatic validation Timestampable Entity always fail form validation #4

Open stayeronglass opened 5 years ago

stayeronglass commented 5 years ago

https://symfony.com/blog/new-in-symfony-4-3-automatic-validation

if ($form->isSubmitted() && $form->isValid()) - always fail after enable Automatic validation

mpiot commented 4 years ago

Hi @stayeronglass, this error could be fix in the 4.4, with an annotation @Assert\DisableAutoMapping. But for the moment this is not possible. (https://github.com/symfony/symfony/pull/32107/files#diff-c8c4635301b6afd5d4c935ba49c24313R74)

The fact is, when the data are sent with the form, the validator try to validate the Entity, but with auto validation, because Timestampable Trait (if youy use it) required to be not null, but because you're not already in the pre persist doctrine event. The updatedAt and createdAt property are null.

You actually can authorize this properties to be null to avoid the auto validation on this properties. Then in 4.4, you can add the special Assertion. But, I'm not sure the Traits are not in this Bundle but in the Gedmo extension.

nickicool commented 4 years ago

I try update project from SF 4.3 -> SF5.1.2 and have same problem (but only on update entity, create is well)...

2020-07-07_18-27-44

Fields created_at and updated_at has no in form (in class PageType), but validation too... I tried use annotation @Assert\DisableAutoMapping in entity and on property, but this has no effect. If anyone could find a solution, please share it.

BoShurik commented 4 years ago

Do you have any constraints on these fields?

Looks like the problem is in DateTime constraint. In 5.0 you need to use Type("\DateTime") constraint See https://github.com/symfony/symfony/blob/master/UPGRADE-5.0.md

Removed support for validating instances of \DateTimeInterface in DateTimeValidator, DateValidator and TimeValidator. Use Type instead or remove the constraint if the underlying model is type hinted to \DateTimeInterface already.

nickicool commented 4 years ago

@BoShurik Thank you for the answer, and a tip where to look for the problem!!!

As I said earlier, PageType class does not have the createdAt and updatedAt fields at all. These fields are fully controlled via behavior Timestampable. But in trait, which these fields were added to entity, the validation rule was specified @Assert\DateTime().

/**
 * @ORM\Column(type="datetime", nullable=true)
 * @Gedmo\Mapping\Annotation\Timestampable(on="update")
 * @Assert\DateTime()
 * @var \DateTimeInterface
 */
private $updatedAt;

public function getUpdatedAt(): ?\DateTimeInterface
{
    return $this->updatedAt;
}

public function setUpdatedAt(?\DateTimeInterface $dateTime): self
{
    $this->updatedAt = $dateTime;
    return $this;
}

In my case, deleting the annotation @Assert\DateTime() helped fix the code. Using annotation @Assert\DisableAutoMapping has no effect at all.

I don't know it works right or not, and how disabling should work right... I think it's a little crooked:

BoShurik commented 4 years ago

As I said earlier, PageType class does not have the createdAt and updatedAt fields at all.

symfony/form does not validate data itself, it delegate this functionality to symfony/validator which don't know about PageType and just validate Page entity (model passed as data to a form)

As I said you need to replace @Assert\DateTime() to @Assert\Type("\DateTime"). It's a BC brake introduced in Symfony 5.0

nickicool commented 4 years ago

As I said you need to replace @Assert\DateTime() to @Assert\Type("\DateTime"). It's a BC brake introduced in Symfony 5.0

Yes, everything works! That's great! Thanks!!!