Validateur et Formulaire



la validation avec symfony

faire une sauvegarde de l’entité en la copiant dans un fichier src/Entity/Produit.php.v1.txt

Le but est de tester l’exemple de la documentation du lien suivant : https://symfony.com/doc/current/validation.html

use Symfony\Component\Validator\Constraints as Assert;
........
* @Assert\NotBlank(message="saisir un nom")                                                       
* @Assert\Length(min=2, minMessage = "votre nom doit être composé de {{ limit }} caractères minimum")
........
private $nom;
........
* @Assert\NotBlank(message = "Saisir un prix ")                                           //***
* @Assert\Type(type="numeric",message =  "La valeur {{ value }} n'est pas valide, le type est {{ type }} ")
* @Assert\Regex(
*     pattern = "/^[0-9]{1,}\,{0,1}[0-9]{0,}$/",
*     message = "Seulement un entier positif."
*     )
........
private $prix;
........
* @ORM\Column(type="date", nullable=true)
* @Assert\NotBlank(
*      message= "Donner une date"
* )
........
private dateLancement;
........

* @ORM\Column(name="photo", type="string", length=255, nullable=true)
* @Assert\NotBlank(
*      message= "Sélectionner une photo"
* )
* Assert\File(
*     maxSize = "1024k",
*     mimeTypes={ "image/png" ,"image/jpg","image/jpeg"},
*     mimeTypesMessage = "Inserer une image valide (png,jpg,jpeg)"
* )

........
private $photo;
........
* @Assert\NotBlank(
*      message= "Sélectionner un type"
* )
........
private $typeProduit;
........



L’objectif est d’utiliser cet objet :

use Symfony\Component\Validator\Validator\ValidatorInterface;
    public function addProduit(Request $request, ValidatorInterface $validator)


        $donnees['nom']=$_POST['nom'];
        $donnees['prix']=$_POST['prix'];
        $donnees['dateLancement']=$request->request->get('dateLancement');
        //$dateLancement=$request->request->get('dateLancement');
        $donnees['dateLancement'] = $request->request->get('dateLancement');
        $donnees['stock']=$request->request->get('stock');
        $donnees['disponible']=$request->request->get('disponible');
        $donnees['photo']=$request->request->get('photo');
        $donnees['id']=$request->request->get('id');
        $donnees['typeProduit_id']=$request->request->get('typeProduit_id');


        $produit = new Produit();
        $produit->setNom($request->request->get('nom'));
        $typeProduit=$this->getDoctrine()->getRepository(TypeProduit::class)->find($request->request->get('typeProduit_id'));
        $produit->setTypeProduit($typeProduit);

        $dateLancement=\DateTime::createFromFormat('d/m/Y',$request->request->get('dateLancement'));
        if($dateLancement == false) $dateLancement=null;

        $produit->setDateLancement($dateLancement);
        $produit->setPrix($request->request->get('prix'));
        if($request->request->get('disponible') == 'false')  $produit->setDisponible(false);
        else $produit->setDisponible(true);
        $produit->setPhoto($request->request->get('photo'));
        $stock=$request->request->get('stock');
        if($stock=="" OR ! is_numeric($stock))$stock=null;
        $produit->setStock($stock);
        $typeProduit_id=$request->request->get('typeProduit_id');
        $typeProduit_entity=$this->getDoctrine()->getRepository(TypeProduit::class)->find($typeProduit_id);

        dump($typeProduit_id);dump($typeProduit_entity);

        $produit->setTypeProduit($typeProduit_entity);
$erreurs_validator=$validator->validate($produit);
// dump($erreurs_validator);
// dump($produit);
if( count($erreurs_validator) ==0)
{
    $this->getDoctrine()->getManager()->persist($produit);
    $this->getDoctrine()->getManager()->flush();
    return $this->redirectToRoute('admin_produitv2_show');
}
$erreurs=[];
foreach ($erreurs_validator as $erreur_validator){
     $erreurs[$erreur_validator->getPropertyPath()]=$erreur_validator->getMessage();
}


Cette solution est compliquée, c’est parce que les annotations de contraintes sont prévues pour fonctionner avec les formulaires de symfony.

utiliser un validateur dans le contrôleur

il est possible d’utiliser le validateur de symfony autrement que avec les annotations documentation de symfony

L’objectif est de suivre la documentation de l’exemple ci-dessus pour la méthode editProduit

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Validation;
    /**
     * @var ValidatorInterface
     */
    private $validationProduit;

    public function __construct()
    {
        $this->validationProduit = Validation::createValidator();
    }
       public function validatorProduitV2($donnees)
    {
        // $donnees['dateLancement'] = \DateTime::createFromFormat('d-m-Y', $donnees['dateLancement']);
        // $donnees['dateLancement']= $donnees['dateLancement']->format('Y-m-d');

        $constraint = new Assert\Collection([
            'nom' => [
                new Assert\NotBlank(['message' => 'saisir un nom']),
                new Assert\Length(['min' => 2, 'minMessage' => "votre nom doit être composé de {{ limit }} caractères minimum"]),
            ],
            'prix' => [
                new Assert\NotBlank(['message' => 'Saisir un prix ']),
                new Assert\Type(['type' => 'numeric', 'message' => 'La valeur {{ value }} n\'est pas valide, le type est {{ type }} ']),
                new Assert\Regex(['pattern' => '/^[0-9]{1,}\.{0,1}[0-9]{0,}$/','message' => 'le prix n\'est pas au bon format 99,99']),
            ],
            'stock' => [
                new Assert\NotBlank(['message' => 'Saisir un prix ']),
                new Assert\Type(['type' => 'numeric', 'message' => 'La valeur {{ value }} n\'est pas valide, le type est {{ type }} ']),
            ],

            'photo' => [
                new Assert\NotBlank(['message' => 'saisir une photo']),
            ],
            'typeProduit_id' => [
                new Assert\NotBlank(['message' => 'selectionner un type']),
            ],
            'id'=> [
                new Assert\NotBlank(['message' => 'pb avec id']),
            ],
            'disponible'=> [
                new Assert\NotBlank(['message' => 'pb disponible']),
            ],
            'dateLancement' => [
                new Assert\NotBlank(['message' => 'pb disponible']),
               // new Assert\Date(['message' => 'La date doit avoir un format d/m/Y et ne peut pas être vide, veuillez ressayez s\'il vous plaît']),
            ],

        ]);
        return $this->validationProduit->validate($donnees, $constraint);
    }
$donnees['nom']=$_POST['nom'];
$donnees['prix']=$_POST['prix'];
$donnees['dateLancement']=$request->request->get('dateLancement');
$donnees['stock']=$request->request->get('stock');
$donnees['disponible']=$request->request->get('disponible');
$donnees['photo']=$request->request->get('photo');
$donnees['typeProduit_id']=$request->request->get('typeProduit_id');

  
$errors_validator = $this->validatorProduitV2($donnees);
dump($errors_validator);
       dump($errors_validator);
        if( count($errors_validator) ==0)
        {
            $produit = $entityManager->getRepository(Produit::class)->find($donnees['id']);
            if (!$produit)  throw $this->createNotFoundException('No produit found for id '.$donnees['id']);

            $produit->setNom($donnees['nom']);
            $typeProduit=$entityManager->getRepository(TypeProduit::class)->find($donnees['typeProduit_id']);
            if (!$typeProduit)  throw $this->createNotFoundException('No produit found for id '.$donnees['id']);
            $produit->setTypeProduit($typeProduit);
            $produit->setDateLancement(\DateTime::createFromFormat('d/m/Y',$donnees['dateLancement']));
            $produit->setPrix($donnees['prix']);
            if($donnees['disponible'] == 'false')  $produit->setDisponible(false);
            else $produit->setDisponible(true);
            if($donnees['photo'] != "")
                $produit->setPhoto($donnees['photo']);
            $produit->setStock($donnees['stock']);

            $entityManager->persist($produit);
            $entityManager->flush();
            return $this->redirectToRoute('admin_produitv2_show');
        }
       if (count($errors_validator) > 0) {
            foreach ($errors_validator as $erreur)
                $erreurs[str_replace(array('[', ']'), '', $erreur->getPropertyPath())] = $erreur->getMessage();
        }
        dump($erreurs);

exercice





entité : annotation pour placer des contraintes sur les champs des colonnes
entité : annotation pour placer des contraintes sur les champs des colonnes

ANNEXES

https://www.christophe-meneses.fr/article/bonnes-pratiques-symfony-organiser-sa-logique-metier

https://numa-bord.com/miniblog/category/developpement/symfony/

https://openclassrooms.com/fr/courses/5489656-construisez-un-site-web-a-l-aide-du-framework-symfony-4/5517036-qu-est-ce-qu-un-code-de-qualite

https://stackoverflow.com/questions/51499463/symfony-format-date-in-assert-message

https://stackoverflow.com/questions/10470735/validation-an-integer-input-from-a-form