[Symfony] exporter données formulaire collection à dompdf

a marqué ce sujet comme résolu.

Bonjour , depuis quelque jours je suis bloqué, si quelqu’un peut m’aider avec la bonne pratique, j’explique :

Je veux récupérer des données dans la base données : entité (expression_besoin) contient les informations d’une demande avec ref , demandeur … et l’entité besoin_article contient les articles demandé dans l’entité précédente, il y une relation OneToMany entre les deux entité.

l’objectif c’est de récupérer les plusieurs expression besoin d’articles dans un formulaire afin de modifier si il faut les quantité ou les supprimer , ensuite pouvoir générer un fichier PDF qui contient toutes les besoins et les articles qui leur correspond.

le controller :

/**
     * @Route("/extraire_commandes", name="export_commandes", methods={"GET","POST"})
     */
    public function exportCommandes(ExBesoinRepository $exBesoinRepository, Request $request): Response
    {       
        $datas = new FiltreBesoin();
        $form = $this->createForm(FiltreBesoinType::class, $datas);
        $form->handleRequest($request);
        $exBesoin = $exBesoinRepository->exportCommande($datas);    
        $valueFournisseur = $form['fournisseur']->getData();

        $formExport = $this->createFormBuilder(array('besoin' => $exBesoin));
        $formExport->add('besoin', CollectionType::class, array(
            'entry_type' => ExBesoinToCommandeType::class,  
        ));

        $formExport = $formExport->getForm();
        $formExport->handleRequest($request);           
        $formValue = $formExport->getData();
        if ($formExport->isSubmitted() && $formExport->isValid()) {

            $html = $this->renderView('admin/besoins/epicerie/exportPdf.html.twig', [
                'besoins' => $formValue,
            ]);
            $html .= '<link rel="stylesheet" href="/build/css/app.css"> ';
            $html .= '<script src="/build/vendors~js/app.js"></script><script src="/build/runtime.js"></script><script src="/build/vendors-node_modules_popperjs_core_lib_index_js-node_modules_symfony_stimulus-bridge_dist_ind-f4bfca.js"></script>';
            $name = 'test';
            $options = new Options();
            $options->set('isHtml5ParserEnabled', true);
            $options->set('isRemoteEnabled', true);
            $dompdf = new Dompdf($options);
            $dompdf->loadHtml($html);
            // (Optional) Setup the paper size and orientation
            $dompdf->setPaper('A4', 'portrait');
            // Render the HTML as PDF
            $dompdf->render();
            // Output the generated PDF to Browser
            $dompdf->stream($name, array('Attachment' => 0));
            return new Response('', 200, [
                'Content-Type' => 'application/pdf',
            ]);
        }

        return $this->render('admin/besoins/epicerie/export.html.twig', [
            'besoins' => $exBesoin,
            'form' => $form->createView(),
            'valueFournisseur' => $valueFournisseur,
            //'idBesoin' => $idBesoin,
            'formExport' => $formExport->createView(),
            'valu'=> $formValue
        ]);
    }

Mes formType

class ExBesoinToCommandeType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('besoinArs', CollectionType::class, [
                'entry_type' => BesoinArToCommandeType::class,                
                'allow_delete' => true,
                //'allow_add' => false,
                'prototype'    => true,
                'by_reference' => false,
                'delete_empty' => true,
                'entry_options' => [
                    'label' => true,
                ]
            ]) 

        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => ExBesoin::class,
        ]);
    }

    public function getBlockPrefix()
    {
        return 'ExBesoinToCommandeType';
    }
}
class BesoinArToCommandeType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('article', EntityType::class, [
                'class' => Article::class,
                'label' => false,
                'attr' =>[
                    'class' => 'arSelect form-control-sm',
                    'data-live-search' => 'true',
                ],
                'placeholder' => 'Selectionner un article ',
                'query_builder' => function (EntityRepository  $er) {
                    $qb = $er->createQueryBuilder('a')
                    ->innerJoin('a.category', 'c')
                    ->where('c.is_legume = 0')
                    ;                         
                    return $qb;
                },
                'group_by' => function (Article $article) {
                    return $article->getCategory()->getLibele();
                }
            ])
            ->add('quantity', TextType::class, [
                'label' => ' ',
                'attr' =>[
                    'class' => 'quantity form-control-sm'
                ]
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => BesoinAr::class,
        ]);
    }

   public function getBlockPrefix()
    {
        return 'BesoinArToCommandeType';
    }
}

Jusqu’à la je récupère mes données sans problème, les getData() du formulaire contient toutes mes données avant le submit, mais quand je valide pour générer mon fichier pdf , il ne contient pas toutes les données. j’utilise un système de filtre qui me permets de selection les expression de besoin entre deux dates, par demandeur ou par fournisseur, et le problème est lié à ce filtre car quand je génère le pdf des données sans filtre ça fonctionne mais quand je filtre mes données c’est là où mes données change et je ne récupère pas les données filtrés , je serai reconnaissant si quelqu’un me débloque ou me dire d’où le problème provient

Salut Ymox : ma requete dans ExBesoinRepository :

 /**
     * @return ExBesoin[] Returns an array of ExBesoin objects
     */
    public function exportCommande(FiltreBesoin $filtre): array
    {
        $start_week = date("Y-m-d",strtotime('monday this week'));
        $end_week = date("Y-m-d",strtotime('sunday this week'));

        $query = $this
            ->createQueryBuilder('p');   

            if (empty($filtre->minDate) && empty($filtre->minDate)) {
                $query = $query
                    ->where('p.date_emis >= :start')
                    ->andWhere('p.date_emis <= :end')
                    ->setParameter('start',$start_week)                      
                    ->setParameter('end',$end_week) ;
            }
                

            if (!empty($filtre->minDate)) {
                $query = $query
                    ->andWhere('p.date_emis >= :minDate')
                    ->setParameter('minDate', $filtre->minDate);
            }
    
            if (!empty($filtre->maxDate)) {
                $query = $query
                    ->andWhere('p.date_emis <= :maxDate')
                    ->setParameter('maxDate', $filtre->maxDate);
            } 

            if (!empty($filtre->type)) {
                $query = $query
                    ->andWhere('p.is_legume IN (:type)')
                    ->setParameter('type',  array_values($filtre->type));
            }

            if (!empty($filtre->labo)) {
                $query = $query
                    ->addSelect('l')
                    ->join('p.labo', 'l')
                    ->andWhere('l.id IN (:labo)')
                    ->setParameter('labo' ,  array_values($filtre->labo));
            }

            if (!empty($filtre->fournisseur)) {
                $query = $query
                    ->addSelect('a, f, b')
                    ->innerJoin('p.besoinArs','b')
                    ->innerJoin('b.article','a')
                    ->join('a.fournisseur', 'f')
                    ->andWhere('f.id IN (:fournisseur)')
                    ->setParameter('fournisseur' , array_values($filtre->fournisseur));
            }
            
            $query = $query        
            ->andWhere('p.is_legume = 0')
            ->andWhere('p.is_draft = 0')
            ->orderBy('p.dateLivraison' , 'ASC');
        return $query
            ->getQuery()->getResult();
    }

et mon FiltreBesoin

 namespace App\Data ;

    use App\Entity\Labo;
    
    use App\Entity\Fournisseur;

    Class FiltreBesoin
    {
        /**
         * @var null|Date
         */
        public $minDate;

        /**
         * @var null|Date
         */
        public $maxDate;

        /**
         * @var string
         */
        public $statut ;
                
        /**
         * @var Labo[]
         */
        public $labo = [];

        /**
         * @var Fournisseur[]
         */
        public $fournisseur = [];
        
        /**
         * @var Site[]
         */
        public $site = [];

    }

et mon formulaire de filtre :

class FiltreBesoinType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        
        $builder
            ->add('minDate')
            ->add('maxDate')
            ->add('statut')
            ->add('labo')
            ->add('site')
            ->add('fournisseur')
        ;
    }

le filtre fonctionne bien , il m’affiche bien les données que je filtre, je pense le soucis c’est quand je submit il perd ces données

+0 -0

Avant le return $query->getQuery()->getResult(), ajoute un $query->getQuery()->getSql() et fournis la requête qui devrait ainsi s’afficher dans la barre de débogage avec un nouvel "onglet".

Pour le premier if, tu pourrais utiliser l’opérateur BETWEEN :start AND :end plutôt que deux comparaisons. BETWEEN inclut bien les deux bornes.
Aussi, plutôt que date($1, strtotime($2)), tu devrais pouvoir utiliser new \DateTime($2). Pas besoin de formater expressément sous forme de chaîne.

+1 -0

Ymox, Merci pour tes correction, j’ai fait que tu m’as dit , ça ne règle pas mon soucis, je perds mes data dès que je clique sur submit , le dump me retourne un array vide , tu as une idée sur la bonne manière que je conserve mes donnée après le submit ?

Oups, désolé, j’ai oublié de mettre le dump(…) autour du $query->getQuery()->getSql(). Ce qui m’étonne, c’est que justement tu parles d’un dump(), mais je ne le vois nulle part dans le code fourni ?!

Sinon, as-tu bien regardé ce que contenait $formValue ? C’est justement cela qui est vide ? D’après ce que je vois du code, c’est censé être une liste de ExBesoin, vu qu’on a un formulaire avec une collection de ExBesoinToCommandeType qui stocke ses données dans ExBesoin.
Tu ne devrais pas justement utiliser les données du filtre ? En fait, j’ai de la peine à comprendre le fait que le filtre fonctionne, mais tu utilises apparemment un autre formulaire pour faire l’export, et te demande pourquoi les données du filtre ne sont pas prises en compte…

Edit

OK, alors dans un de mes projets, j’ai un truc qui pourrait rejoindre ce que tu tentes de m’expliquer.

+0 -0

mon filtre permets de filtrer mes exBesoin , et le formulaire me permets de modifier ces exbesoins avant de générer un fichier pdf, il ne stock pas les données dans la bases de données, l’objectif c’est juste un de récupérer les données, si besoin de filtrer ces données on fait par apport la date , ou le demandeur (labo) ou par apport un fournisseur, ensuite si besoin modifier les quantité si besois( d’où l’intérêt de formulaire) ensuite générer un fichier pdf et ça s’arrête la, y a pas de modification dans la base de données.

Et pour les autres question, qu’en est-il ?

Edit

Pour ma part, j’ai effectivement découvert qu’un formulaire basé sur un unique champ CollectionType avec des objets sous-jacents ne collectait plus les informations des éléments lors d’un handleRequest() (cf. ici). Quelle version de Symfony utilises-tu, et quelle version de PHP ?

+0 -0

Pour ce projet c’est symfony 5.4 et php c’est 7.4, de mon côté je pense c’est mon filtre qui pose problème car quand je récupère les données sans passé par le filtre ça ne pose aucun problème j’ai tout mais dès que j’utilise mon filtre ça me pose problème.

Voilà mon dump($formvalue) avant submit

array:1 [▼
  "besoin" => array:2 [▼
    0 => App\Entity\ExBesoin {#1822 ▼
      -id: 772
      -slug: "BC3923021138"
      -date_emis: DateTime @1675641600 {#1783 ▶}
      -dateLivraison: DateTime @1676332800 {#1527 ▶}
      -note: null
      -accord: "validé"
      -labo: Proxies\__CG__\App\Entity\Labo {#1819 ▶}
      -besoinArs: Doctrine\ORM\PersistentCollection {#1806 ▶}
      -is_legume: false
      -created: DateTime @1675683525 {#1833 ▶}
      -is_valide: true
      -user: App\Entity\User {#810 ▶}
      -is_draft: false
      -site: Proxies\__CG__\App\Entity\Site {#1018 ▶}
    }
    1 => App\Entity\ExBesoin {#1901 ▼
      -id: 774
      -slug: "BC3923021146"
      -date_emis: DateTime @1675641600 {#1796 ▶}
      -dateLivraison: DateTime @1676505600 {#1795 ▶}
      -note: null
      -accord: "validé"
      -labo: Proxies\__CG__\App\Entity\Labo {#1902 ▶}
      -besoinArs: Doctrine\ORM\PersistentCollection {#1904 ▶}
      -is_legume: false
      -created: DateTime @1675683974 {#1794 ▶}
      -is_valide: true
      -user: App\Entity\User {#810 ▶}
      -is_draft: false
      -site: Proxies\__CG__\App\Entity\Site {#1018 ▶ …2}
    }
  ]
]

et voila mon dump après submit

array:1 [▼
  "besoin" => array:2 [▼
    0 => App\Entity\ExBesoin {#1513 ▼
      -id: 773
      -slug: "BC3923021141"
      -date_emis: DateTime @1676246400 {#1518 ▶}
      -dateLivraison: DateTime @1677024000 {#1519 ▶}
      -note: null
      -accord: "validé"
      -labo: Proxies\__CG__\App\Entity\Labo {#1500 ▶}
      -besoinArs: Doctrine\ORM\PersistentCollection {#1517 ▶}
      -is_legume: false
      -created: DateTime @1676288486 {#1516 ▶}
      -is_valide: true
      -user: App\Entity\User {#810 ▶}
      -is_draft: false
      -site: Proxies\__CG__\App\Entity\Site {#1018 ▶}
    }
    1 => App\Entity\ExBesoin {#969 ▼
      -id: 775
      -slug: "BC3923021147"
      -date_emis: DateTime @1676246400 {#964 ▶}
      -dateLivraison: DateTime @1677024000 {#965 ▶}
      -note: null
      -accord: "nouveau"
      -labo: Proxies\__CG__\App\Entity\Labo {#984 ▶}
      -besoinArs: Doctrine\ORM\PersistentCollection {#1009 ▶}
      -is_legume: false
      -created: DateTime @1676288831 {#967 ▶}
      -is_valide: true
      -user: App\Entity\User {#810 ▶}
      -is_draft: false
      -site: Proxies\__CG__\App\Entity\Site {#1018 ▶ …2}
    }
  ]
]

le dump avant submit me donne bien les valeurs filtré que je veux exporter vers le pdf , et après le submit me donne les valeur sans filtre, et du coup mon pdf contiendra que les valeur sans filtre

+0 -0

Je ne comprends toujours pas pourquoi tu as des valeurs correctes dans $exBesoin, mais tu les repasses dans une moulinette qui, en l’occurrence, ne te retourne pas ce que tu veux alors que tu me dis avoir ce que tu veux ailleurs/avant…

Donc : pourquoi ne pas utiliser $exBesoin plutôt que $formValue ligne 23 ?

+0 -0

Pour mieux comprendre ma requête: les utilisateurs crée leur ex_besoin ( Produits épicerie et produits frais - dans mon exemple c’est des produits épicerie), à la fin de la semaine une personne valide ces demandes, et l’objectif de mon exemple c’est récupéré toute les exbesoins et générer un fichier pdf en affichant seulement les produits du même fournisseur (d’où le trie par founrisseur), afin de créer une commande fournisseur, il arrive toute fois qu’il doit revenir sur des demande de la semaine précédente par exemple pour générer ce pdf car pour x raison n’a pas pu faire à temps ( d’où le trie par date). donc sur ma requête si les champs maxdate et minDate sont vide afficher les demandes de la semaine en cours si non par date choisi , et pareil si le champs labo est renseigné affiché seulement les demandes de ce labo et par fournisseur …. donc quand je vais sur ma page /extraire_commandes bien évidement il m’affiche par défaut les demandes de le semaine en cours, donc le cas précédent les( id: 773 et 775), quand je fait un trie par date de la semaine précédente ça me donne le résultat 772 et 774 , tous vas bien jusqu’à ici. au moment que je submit je perds les données trié et je ne récupère que les données par défaut.

$html = $this->renderView('admin/besoins/epicerie/exportPdf.html.twig', [
             besoins' => $formValue,
         ]);

le $formValue à la place de $exBesoin c’est juste en cas de modification, par exemple si je dois supprimer une ligne ou modifier une quantité avant de génerer le fichier pdf. et même en utilisant le $exBesoin c’est le même soucis , je ne récupère pas mes données filtré.

Je ne suis toujours pas certain de comprendre la technique mise en place pour le besoin. De ce que je perçois, on a un formulaire qui récupère les données de filtre, et un autre qui permettrait de modifier les trucs qui ont été filtrés

J’aimerais voir aussi la vue, j’ai une dernière piste avant que je ne retourne sur ma précédente et que je n’en trouve ensuite une autre.

A savoir cependant qu’un formulaire "brut" avec une collection d’objets à éditer risque de poser problème lors de la persistance : l’ID des enregistrements modifiés ou à modifier est perdu. Il pourrait être plus simple de créer le formulaire avec le fournisseur comme structure de données sous-jacente et le champ comme s’il était la propriété contenant les ExBesoins filtrés.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte