Impossible to access an attribute ("commande") on a null variable.

Par D_S, il y a 8 ans


Bonjour,
je suis un tuto developpé sous symfony 2 alors que j'utilise la version 3 de symfony.
Il y a beaucoup de differences entre les deux versions. Depuis plusieurs jours je suis confronté à un probleme que jarrive pas à resoudre. Aidez moi svp!
voici l'erreur qui saffiche: "Impossible to access an attribute ("commande") on a null variable"
in src\Ecommerce\EcommerceBundle\Resources\views\Default\panier\layout\validation.html.twig at line 25 -+

  1. {% for produit in commande.commande.produit %}

  2. {{ produit.reference }}

controller Commandes

<?php namespace Ecommerce\EcommerceBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\RedirectResponse; use Ecommerce\EcommerceBundle\Entity\UtilisateursAdresses; use Ecommerce\EcommerceBundle\Entity\Commandes; use Ecommerce\EcommerceBundle\Entity\Produits; class CommandesController extends Controller { public function facture(Request $request) { $em = $this->getDoctrine()->getManager(); $generator = $this->container->get('security.secure_random'); $session = $request->getSession(); $adresse = $session->get('adresse'); $panier = $session->get('panier'); $commande = array(); $totalHT = 0; $totalTTC = 0; $facturation = $em->getRepository('EcommerceBundle:UtilisateursAdresses')->find($adresse['facturation']); $livraison = $em->getRepository('EcommerceBundle:UtilisateursAdresses')->find($adresse['livraison']); $produits = $em->getRepository('EcommerceBundle:Produits')->findArray(array_keys($session->get('panier'))); foreach($produits as $produit) { $prixHT = ($produit->getPrix() * $panier[$produit->getId()]); $prixTTC = ($produit->getPrix() * $panier[$produit->getId()] / $produit->getTva()->getMultiplicate()); $totalHT += $prixHT; $totalTTC += $prixTTC; if (!isset($commande['tva']['%'.$produit->getTva()->getValeur()])) $commande['tva']['%'.$produit->getTva()->getValeur()] = round($prixTTC - $prixHT,2); else $commande['tva']['%'.$produit->getTva()->getValeur()] += round($prixTTC - $prixHT,2); $commande['produit'][$produit->getId()] = array('reference' => $produit->getNom(), 'quantite' => $panier[$produit->getId()], 'prixHT' => round($produit->getPrix(),2), 'prixTTC' => round($produit->getPrix() / $produit->getTva()->getMultiplicate(),2)); } $commande['livraison'] = array('prenom' => $livraison->getPrenom(), 'nom' => $livraison->getNom(), 'telephone' => $livraison->getTelephone(), 'adresse' => $livraison->getAdresse(), 'cp' => $livraison->getCp(), 'ville' => $livraison->getVille(), 'pays' => $livraison->getPays(), 'complement' => $livraison->getComplement()); $commande['facturation'] = array('prenom' => $facturation->getPrenom(), 'nom' => $facturation->getNom(), 'telephone' => $facturation->getTelephone(), 'adresse' => $facturation->getAdresse(), 'cp' => $facturation->getCp(), 'ville' => $facturation->getVille(), 'pays' => $facturation->getPays(), 'complement' => $facturation->getComplement()); $commande['prixHT'] = round($totalHT,2); $commande['prixTTC'] = round($totalTTC,2); $commande['token'] = bin2hex($generator->nextBytes(20)); return $commande; } public function prepareCommandeAction() { $session = $request->getSession(); $em = $this->getDoctrine()->getManager(); if (!$session->has('commande')) $commande = new Commandes(); else $commande = $em->getRepository('EcommerceBundle:Commandes')->find($session->get('commande')); $commande->setDate(new \DateTime()); $commande->setUtilisateur($this->container->get('security.token_storage')->getToken()->getUser()); $commande->setValider(0); $commande->setReference(0); $commande->setCommande($this->facture()); if (!$session->has('commande')) { $em->persist($commande); $session->set('commande',$commande); } $em->flush(); return new Response($commande->getId()); } /* * Cette methode remplace l'api banque. */ public function validationCommandeAction($id, Request $request) { $em = $this->getDoctrine()->getManager(); $commande = $em->getRepository('EcommerceBundle:Commandes')->find($id); if (!$commande || $commande->getValider() == 1) throw $this->createNotFoundException('La commande n\'existe pas'); $commande->setValider(1); $commande->setReference(1); //Service $em->flush(); $session = $request->getSession(); $session->remove('adresse'); $session->remove('panier'); $session->remove('commande'); $this->get('session')->getFlashBag()->add('success','Votre commande est validé avec succès'); return $this->redirect($this->generateUrl('produits')); } }

classe Commandes

<?php namespace Ecommerce\EcommerceBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * Commandes * * @ORM\Table("commandes") * @ORM\Entity(repositoryClass="Ecommerce\EcommerceBundle\Repository\CommandesRepository") */ class Commandes { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\ManyToOne(targetEntity="Utilisateurs\UtilisateursBundle\Entity\Utilisateur", inversedBy="commandes") * @ORM\JoinColumn(nullable=true) */ private $utilisateur; /** * @var boolean * * @ORM\Column(name="valider", type="boolean") */ private $valider; /** * @var \DateTime * * @ORM\Column(name="date", type="datetime") */ private $date; /** * @var integer * * @ORM\Column(name="reference", type="integer") */ private $reference; /** * @var array * * @ORM\Column(name="commande", type="array") */ private $commande; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set valider * * @param boolean $valider * @return Commandes */ public function setValider($valider) { $this->valider = $valider; return $this; } /** * Get valider * * @return boolean */ public function getValider() { return $this->valider; } /** * Set date * * @param \DateTime $date * @return Commandes */ public function setDate($date) { $this->date = $date; return $this; } /** * Get date * * @return \DateTime */ public function getDate() { return $this->date; } /** * Set reference * * @param integer $reference * @return Commandes */ public function setReference($reference) { $this->reference = $reference; return $this; } /** * Get reference * * @return integer */ public function getReference() { return $this->reference; } /** * Set commande * * @param array $commande * @return Commandes */ public function setCommande($commande) { $this->commande = $commande; return $this; } /** * Get commande * * @return array */ public function getCommande() { return $this->commande; } /** * Set utilisateur * * @param \Utilisateurs\UtilisateursBundle\Entity\Utilisateur $utilisateur * @return Commandes */ public function setUtilisateur(\Utilisateurs\UtilisateursBundle\Entity\Utilisateur $utilisateur = null) { $this->utilisateur = $utilisateur; return $this; } /** * Get utilisateur * * @return \Utilisateurs\UtilisateursBundle\Entity\Utilisateur */ public function getUtilisateur() { return $this->utilisateur; } }

Validation.html.twig

{% extends "::layout/layout.html.twig" %} {% block body %} <div class="container"> <div class="row"> <div class="span3"> {% include '::moduleUsed/navigation.html.twig' %} </div> <div class="span9"> <h2>Valider mon panier</h2> <table class="table table-striped table-hover"> <thead> <tr> <th>Références</th> <th>Quantité</th> <th>Prix unitaire</th> <th>Total HT</th> </tr> </thead> <tbody> {% for produit in commande.commande.produit %} <tr> <td>{{ produit.reference }}</td> <td> {{ produit.quantite }} </td> <td>{{ produit.prixHT }} €</td> <td>{{ produit.prixHT * produit.quantite }} €</td> </tr> {% endfor %} </tbody> </table> <dl class="dl-horizontal pull-right"> <dt>Total HT :</dt><dd>{{ commande.commande.prixHT }} €</dd> {% for key, tva in commande.commande.tva %} <dt>TVA {{ key }} :</dt><dd>{{ tva }} €</dd> {% endfor %} <dt>Total TTC :</dt><dd>{{ commande.commande.prixTTC }} €</dd> </dl> <div class="span3 pull-left"> <dl class="pull-left"> <dt><h4>Adresse de livraison</h4></dt> <dt>{{ commande.commande.livraison.prenom }} {{ commande.commande.livraison.nom }}</dt> <dt>{{ commande.commande.livraison.adresse }}</dt> <dt>{{ commande.commande.livraison.cp }} {{ commande.commande.livraison.ville }} - {{ commande.commande.livraison.pays }}</dt> </dl> </div> <div class="span3 pull-left"> <dl class="pull-left"> <dt><h4>Adresse de facturation</h4></dt> <dt>{{ commande.commande.facturation.prenom }} {{ commande.commande.facturation.nom }}</dt> <dt>{{ commande.commande.facturation.adresse }}</dt> <dt>{{ commande.commande.facturation.cp }} {{ commande.commande.facturation.ville }} - {{ commande.commande.facturation.pays }}</dt> </dl> </div> <div class="clearfix"></div> <form action="{{ path('validationCommande', { 'id' : commande.id }) }}" method="POST"/> <input name="token" type="hidden" value="{{ commande.commande.token }}" /> <input name="prix" type="hidden" value="{{ commande.commande.prixTTC }}" /> <input name="date" type="hidden" value="{{ commande.date|date('dmyhms') }}" /> <button type="submit" class="btn btn-success pull-right">Payer</button> </form> <a href="{{ path('livraison') }}" class="btn btn-primary">retour</a> </div> </div> </div> {% endblock %}

4 réponses

Corwin40, il y a 8 ans

Bonjour D_S,

Je te rassure, nous sommes au même niveau.... juste pour te permettre d'avancer un peu plus si tu es toujours bloqué :
la méthode security.secure_random n'est plus soutenue.
Remplace dans ton controleur :
" $generator = $this->container->get('security.secure_random'); " par " $generator = random_bytes(20); "
et
" $commande['token'] = bin2hex($generator->nextBytes(20)); " par " $commande['token'] = $generator; "

Normalement tu devrais pouvoir persister tes données en base et avoir ta vue.
Si tu as pu résoudre tes problèmes je suis preneur de tes solutions.

Elyanor, il y a 8 ans

Hello.

Il nous manque quelques infos, par exemple le controller qui s'occupe d'afficher ton layout validation.html.twig (on ne sait pas quelles variables tu passes à la vue)

Si tu utilises ta méthode "facture" pour dresser ta boucle for alors oui, ta boucle est fausse, car à aucun moment il n'y a la clef commande dans le tableau des commandes :

{% for produit in commande.commande.produit %} {{ produit.reference }}

sera plus (le premier commande avec un s) :

{% for commande in commandes %} {% set produit = commande.produit %} {{ produit.reference }}

Voir même si ça se trouve :

{% for produit in produits %} {{ produit.reference }}

Va falloir que tu nous donnes plus d'info ;-)

Lartak, il y a 8 ans

Bonsoir.
@Elyanor : Je ne sais pas si tu l'as remarqué, mais le sujet date de 6 mois.

Goulitch, il y a 8 ans

UP j'ai aussi le meme probleme que vous si quelqu'un a trouver la solution merci de nous éclairer