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


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.

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 ;-)

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

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