I am trying to use annotations for Symfony form validation but I can't get it to work. No matter the constraint, the form always reports as valid. I am running on PHP 7.3 with doctrine/annotations 1.13, symfony/validator 5.1 and Symfony 5.1.5.
Here is the basic setup:
ProductionDependentCost.php
...
use Symfony\Component\Validator\Constraints as Assert;
...
/**
* @var float
* @ORM\Column(type="float")
* @Assert\NotNull
* @Assert\Positive
*/
private $costPerKW = 0;
...
ProductionDependentCostController.php
...
/**
* @Route("/plant/{id}/productiondependentcosts", name="update_plant_production_dependent_costs", methods={"POST"})
*/
public function updatePlantProductionDependentCosts(Plant $plant, Request $request): JsonResponse
{
$this->denyAccessUnlessGranted('view', $plant);
$form = $this->createForm(ProductionDependentCostCollectionType::class, $plant, ['csrf_token_id' => 'vue-token']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->flush();
return $this->json('saved!');
} elseif ($form->isSubmitted()) {
return $this->json(ErrorUtil::parseErrors($form->getErrors(true)), Response::HTTP_BAD_REQUEST);
}
return $this->json('this should not be reached!', Response::HTTP_BAD_REQUEST);
}
...
config/packages/framework.yaml
framework:
...
validation:
{
enable_annotations: true
}
I have many more annotation constraints but included only one in this example to not bloat the code snippet. No matter what I enter in the form (e.g -1000 for costPerKW), it will always return with 'saved!'. I have looked everywhere, but can't seem to find a solution. Really hope that someone knows the answer to this problem.
The form uses a CollectionType on a mapped collection field of Plant.php. The collection entries are entities of ProductionDependentCost.php and the corresponding FormType uses a simple mapped field for costPerKW.
I found the solution to my problem. Symfony Forms do not automatically validate entities inside collections. As my ProductionDependentCost is part of a collection inside my form, I have to add a "Valid" constraint to my collection field:
class Plant
{
...
/**
* @var ProductionDependentCost[]|Collection
* @ORM\OneToMany(targetEntity=ProductionDependentCost::class, mappedBy="plant", orphanRemoval=true, cascade={"persist",
* "remove"})
* @Assert\Valid
*/
private $productionDependentCosts;
...
}
class ProductionDependentCostCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('productionDependentCosts', CollectionType::class,
[
...
'constraints' => [
new Valid(),
],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Plant::class,
]);
}
}
This will validate every collection entity individually.