Reputation: 1676
I'm learning my ways with Symfony2 while building a small e-commerce website for a family-run wine importer. Slowly I'm gaining understanding of the Symfony2 concept but while moving on to building a cart bundle, I'm not quite sure what would be the correct (at least according to the Sf2 standards) way to implement this.
i made simple cart bundle based on session.
my problem is when i add product in cart then it work until product id is 0 to 9 and product quantity is increased automatically but after product id is 10 it's quantity is equal to product id while it should be one.and also wrong product information is coming when we want to fetch product information.
I hope this is not a too wide question. I'm well aware of the fact that a truly robust shopping cart implementation is no small job.
<?php
namespace Webmuch\CartBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Response;
use Webmuch\ProductBundle\Entity\Product;
/**
* @Route("/cart")
*/
class CartController extends Controller
{
/**
* @Route("/", name="cart")
*/
public function indexAction()
{
// get the cart from the session
$session = $this->getRequest()->getSession();
// $cart = $session->set('cart', '');
$cart = $session->get('cart', array());
// $cart = array_keys($cart);
// print_r($cart); die;
// fetch the information using query and ids in the cart
if( $cart != '' ) {
foreach( $cart as $id => $quantity ) {
$productIds[] = $id;
}
if( isset( $productIds ) )
{
$em = $this->getDoctrine()->getEntityManager();
$product = $em->getRepository('WebmuchProductBundle:Product')->findById( $productIds );
} else {
return $this->render('WebmuchCartBundle:Cart:index.html.twig', array(
'empty' => true,
));
}
return $this->render('WebmuchCartBundle:Cart:index.html.twig', array(
'product' => $product,
));
} else {
return $this->render('WebmuchCartBundle:Cart:index.html.twig', array(
'empty' => true,
));
}
}
/**
* @Route("/add/{id}", name="cart_add")
*/
public function addAction($id)
{
// fetch the cart
$em = $this->getDoctrine()->getEntityManager();
$product = $em->getRepository('WebmuchProductBundle:Product')->find($id);
//print_r($product->getId()); die;
$session = $this->getRequest()->getSession();
$cart = $session->get('cart', array());
// check if the $id already exists in it.
if ( $product == NULL ) {
$this->get('session')->setFlash('notice', 'This product is not available in Stores');
return $this->redirect($this->generateUrl('cart'));
} else {
if( isset($cart[$id]) ) {
$qtyAvailable = $product->getQuantity();
if( $qtyAvailable >= $cart[$id]['quantity'] + 1 ) {
$cart[$id]['quantity'] = $cart[$id]['quantity'] + 1;
} else {
$this->get('session')->setFlash('notice', 'Quantity exceeds the available stock');
return $this->redirect($this->generateUrl('cart'));
}
} else {
// if it doesnt make it 1
$cart = $session->get('cart', array());
$cart[$id] = $id;
$cart[$id]['quantity'] = 1;
}
$session->set('cart', $cart);
return $this->redirect($this->generateUrl('cart'));
}
}
/**
* @Route("/remove/{id}", name="cart_remove")
*/
public function removeAction($id)
{
// check the cart
$session = $this->getRequest()->getSession();
$cart = $session->get('cart', array());
// if it doesn't exist redirect to cart index page. end
if(!$cart) { $this->redirect( $this->generateUrl('cart') ); }
// check if the $id already exists in it.
if( isset($cart[$id]) ) {
// if it does ++ the quantity
$cart[$id]['quantity'] = '0';
unset($cart[$id]);
//echo $cart[$id]['quantity']; die();
} else {
$this->get('session')->setFlash('notice', 'Go to hell');
return $this->redirect( $this->generateUrl('cart') );
}
$session->set('cart', $cart);
// redirect(index page)
$this->get('session')->setFlash('notice', 'This product is Remove');
return $this->redirect( $this->generateUrl('cart') );
}
}
{% block body %}
<h1>"FLAIRBAG" SHOPPING-CART</h1>
<ul class="thumbnails">
{% if empty %}
<h5>Your shopping cart is empty.</h5>
{% endif %}
{% set cart = app.session.get('cart') %}
{% if product %}
<ul class="thumbnails">
{% if app.session.hasFlash('notice') %}
<divclass="flash-notice">
{{app.session.flash('notice') }}
{{ app.session.removeFlash('notice') }}
</div>
{% endif %}
{% for key, item in cart %}
<p>ID:{{ key }}</p>
<p>Quantity:{{ item }}</p>
<button class="btn btn-primary"><a href="{{ path('cart_remove', {'id': key}) }}">Remove</a></button>
{% for item in product %}
<p>{{ item.title }}</p>
<p>{{ item.preview }}</p>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
</ul>
<a href="{{ path('products') }}">Products</a>
{% endblock %}
Please help me with this.
Thanks! I appreciate your help.
Upvotes: 4
Views: 9096
Reputation: 11351
The problem is in your cart array. According to your template, you expect to have an array with this structure:
cart {
id => quantity
}
i.e, the keys of the array are the ids of the product and the values are the quantities
But then in your controller you do:
$cart[$id] = $id;
$cart[$id]['quantity'] = 1;
Which is a very different thing. You should do:
$cart[$id] = 1;
And in all other places in your controller where you use $cart[$id]['quantity'] use $cart[$id] instead. For example:
$cart[$id] = $cart[$id] + 1;
EDIT:
In your controller do:
$em = $this->getDoctrine()->getEntityManager();
foreach( $cart as $id => $quantity ) {
$product[] = $em->getRepository('WebmuchProductBundle:Product')->findById($id)
}
if( !isset( $product ) )
{
return $this->render('WebmuchCartBundle:Cart:index.html.twig', array(
'empty' => true,
));
}
Upvotes: 3