shopping cart with symfony3 and jquery

0

I need to keep the shopping cart updated with the products that are added. With jQuery I could find the way to add them locally but I can not persist them and / or keep them in a session. What I need is that when surfing, keep those products and only ask me to login when wanting to "checkout" the added products.

I'll give you the community code, thank you.

controller.php

/**
 * @Route("/ajax", name="ajax")
 * @Method({"GET"})
 */
public function ajaxAction(Request $request)
{
    if($request->isXmlHttpRequest())
    {
        $encoders = array(new JsonEncoder());
        $normalizers = array(new ObjectNormalizer());

        $serializer = new Serializer($normalizers, $encoders);

        $em = $this->getDoctrine()->getManager();
        $items =  $em->getRepository('AppBundle:Cart')->findOneBy(array('id'=> $this->getUser()->getId()));
        if ($items){
            $response = new JsonResponse();
            $response->setStatusCode(200);
            $response->setData(array(
                'response' => 'success',
                'items' => $serializer->serialize($items, 'json')
            ));

            return $response;
        }
    }
    return new Response('No ajax', 400);
}

/**
 * @Route("/ajax_save", name="ajax_save")
 * @Method({"GET","POST"})
 */
public function ajaxsaveAction(Request $request)
{

    if ($request->isXMLHttpRequest()) {
        $user = $this->getUser();
        if ($user){
            $em = $this->getDoctrine()->getManager();
            $content = $request->getContent();
            $params = json_decode($content, true);
            $cart = $em->getRepository('AppBundle:Cart')->findOneBy(array('user'=> $user, 'product'=> $params['id']));

            if ($cart){
                $cart->setQuantity($cart->getQuantity() + $params['quantity']);
                $em->persist($cart);
                $em->flush();

            } else {
                $cart_new = new Cart();
                $cart_new->setUser($user);
                $cart_new->setQuantity($params['quantity']);
                $cart_new->setProduct($em->getRepository('AppBundle:Product')->find($params['id']));
                $em->persist($cart_new);
                $em->flush();
            }
        }

        return new JsonResponse(array('data' => 'OK'));
    }

    return new Response('No es ajax!', 400);

}

base.html.twig

$(function () {
                    $.ajax({
                        method: "GET",
                        url: "{{ path('ajax') }}",
                        dataType: 'json',
                        success: function (data) {
                            console.log(data);
                        }
                    });

                    var goToCartIcon = function($addTocartBtn){
                        var $cartIcon = $(".my-cart-icon");
                        var $image = $('<img width="40px" height="40px" src="' + $addTocartBtn.data("image") + '"/>').css({"position": "fixed", "z-index": "999"});
                        $addTocartBtn.prepend($image);
                        var position = $cartIcon.position();
                        $image.animate({
                            top: position.top,
                            left: position.left
                        }, 800 , "linear", function() {
                            $image.remove();
                        });
                    };

                    window.prod = [];

                    $('.my-cart-btn').myCart({
                        currencySymbol: '$',
                        classCartIcon: 'my-cart-icon',
                        classCartBadge: 'my-cart-badge',
                        classProductQuantity: 'my-product-quantity',
                        classProductRemove: 'my-product-remove',
                        classCheckoutCart: 'my-cart-checkout',
                        affixCartIcon: true,
                        showCheckoutModal: true,
                        numberOfDecimals: 2,
                        cartItems: [

                        ],

                        clickOnAddToCart: function($addTocart){
                            goToCartIcon($addTocart);

                        },
                        afterAddOnCart: function(products, totalPrice, totalQuantity) {
                            console.log("despues de adherir", products, totalPrice, totalQuantity);
                            $.ajax({
                                type: "POST",
                                url: "{{ path('ajax_save') }}",
                                data: {
                                    id: this.id, name: this.name, summary: this.summary, price: this.price, quantity: this.quantity, image: this.image
                                },
                                dataType: "json",
                                success: function(data) {
                                    console.log(data);

                                }
                            });
                        },
                        clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {
                            console.log("cart icon clicked", $cartIcon, products, totalPrice, totalQuantity);
                        },
                        checkoutCart: function(products, totalPrice, totalQuantity) {
                            var checkoutString = "Total Price: " + totalPrice + "\nTotal Quantity: " + totalQuantity;
                            checkoutString += "\n\n id \t name \t summary \t price \t quantity \t image path";
                            $.each(products, function(){
                                checkoutString += ("\n " + this.id + " \t " + this.name + " \t " + this.summary + " \t " + this.price + " \t " + this.quantity + " \t " + this.image);
                            });
                            alert(checkoutString);
                            console.log("checking out", products, totalPrice, totalQuantity);

                        },
                        getDiscountPrice: function(products, totalPrice, totalQuantity) {
                            console.log("calculando descuento", products, totalPrice, totalQuantity);
                            return totalPrice;
                        }
                    });

                });

jqueryMyCart.js

(function ($) {

"use strict";

var OptionManager = (function () {     var objToReturn = {};

var _options = null;
var DEFAULT_OPTIONS = {
  currencySymbol: '$',
  classCartIcon: 'my-cart-icon',
  classCartBadge: 'my-cart-badge',
  classProductQuantity: 'my-product-quantity',
  classProductRemove: 'my-product-remove',
  classCheckoutCart: 'my-cart-checkout',
  affixCartIcon: true,
  showCheckoutModal: true,
  numberOfDecimals: 2,
  cartItems: [],
  clickOnAddToCart: function($addTocart) { },
  afterAddOnCart: function(products, totalPrice, totalQuantity) { },
  clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) { },
  checkoutCart: function(products, totalPrice, totalQuantity) { },
  getDiscountPrice: function(products, totalPrice, totalQuantity) { return null; }
};


var loadOptions = function (customOptions) {
  _options = $.extend({}, DEFAULT_OPTIONS);
  if (typeof customOptions === 'object') {
    $.extend(_options, customOptions);
  }
}
var getOptions = function () {
  return _options;
}

objToReturn.loadOptions = loadOptions;
objToReturn.getOptions = getOptions;
return objToReturn;

} ());

var MathHelper = (function () {     var objToReturn = {};     var getRoundedNumber = function (number) {       var options = OptionManager.getOptions ();       return number.toFixed (options.numberOfDecimals);     }     objToReturn.getRoundedNumber = getRoundedNumber;     return objToReturn;   } ());

var ProductManager = (function () {     var objToReturn = {};

/*
PRIVATE
*/
localStorage.products = localStorage.products ? localStorage.products : "";
var getIndexOfProduct = function(id){
  var productIndex = -1;
  var products = getAllProducts();
  $.each(products, function(index, value){
    if(value.id == id){
      productIndex = index;
      return;
    }
  });
  return productIndex;
}
var setAllProducts = function(products){
  localStorage.products = JSON.stringify(products);
}
var addProduct = function(id, name, summary, price, quantity, image) {
  var products = getAllProducts();
  products.push({
    id: id,
    name: name,
    summary: summary,
    price: price,
    quantity: quantity,
    image: image
  });
  setAllProducts(products);
}

/*
PUBLIC
*/
var getAllProducts = function(){
  try {
    var products = JSON.parse(localStorage.products);
    return products;
  } catch (e) {
    return [];
  }
}
var updatePoduct = function(id, quantity) {
  var productIndex = getIndexOfProduct(id);
  if(productIndex < 0){
    return false;
  }
  var products = getAllProducts();
  products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity;
  setAllProducts(products);
  return true;
}
var setProduct = function(id, name, summary, price, quantity, image) {
  if(typeof id === "undefined"){
    console.error("id requerido")
    return false;
  }
  if(typeof name === "undefined"){
    console.error("nombre requerido")
    return false;
  }
  if(typeof image === "undefined"){
    console.error("imagen requerida")
    return false;
  }
  if(!$.isNumeric(price)){
    console.error("el precio no es un número")
    return false;
  }
  if(!$.isNumeric(quantity)) {
    console.error("cantidad no es un número");
    return false;
  }
  summary = typeof summary === "undefined" ? "" : summary;

  if(!updatePoduct(id)){
    addProduct(id, name, summary, price, quantity, image);
  }
}
var clearProduct = function(){
  setAllProducts([]);
}
var removeProduct = function(id){
  var products = getAllProducts();
  products = $.grep(products, function(value, index) {
    return value.id != id;
  });
  setAllProducts(products);
}
var getTotalQuantity = function(){
  var total = 0;
  var products = getAllProducts();
  $.each(products, function(index, value){
    total += value.quantity * 1;
  });
  return total;
}
var getTotalPrice = function(){
  var products = getAllProducts();
  var total = 0;
  $.each(products, function(index, value){
    total += value.quantity * value.price;
    total = MathHelper.getRoundedNumber(total) * 1;
  });
  return total;
}

objToReturn.getAllProducts = getAllProducts;
objToReturn.updatePoduct = updatePoduct;
objToReturn.setProduct = setProduct;
objToReturn.clearProduct = clearProduct;
objToReturn.removeProduct = removeProduct;
objToReturn.getTotalQuantity = getTotalQuantity;
objToReturn.getTotalPrice = getTotalPrice;
return objToReturn;

} ());

var loadMyCartEvent = function () {

var options = OptionManager.getOptions();
var $cartIcon = $("." + options.classCartIcon);
var $cartBadge = $("." + options.classCartBadge);
var classProductQuantity = options.classProductQuantity;
var classProductRemove = options.classProductRemove;
var classCheckoutCart = options.classCheckoutCart;

var idCartModal = 'my-cart-modal';
var idCartTable = 'my-cart-table';
var idGrandTotal = 'my-cart-grand-total';
var idEmptyCartMessage = 'my-cart-empty-message';
var idDiscountPrice = 'my-cart-discount-price';
var classProductTotal = 'my-product-total';
var classAffixMyCartIcon = 'my-cart-icon-affix';


if(options.cartItems && options.cartItems.constructor === Array) {
  ProductManager.clearProduct();
  $.each(options.cartItems, function() {
    ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image);
  });
}

$cartBadge.text(ProductManager.getTotalQuantity());

if(!$("#" + idCartModal).length) {
  $('body').append(
    '<div class="modal fade" id="' + idCartModal + '" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">' +
    '<div class="modal-dialog" role="document">' +
    '<div class="modal-content">' +
    '<div class="modal-header">' +
    '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>' +
    '<h4 class="modal-title" id="myModalLabel"><i class="fa fa-shopping-cart"></i> Mi Carrito</h4>' +
    '</div>' +
    '<div class="modal-body">' +
    '<table class="table table-hover table-responsive" id="' + idCartTable + '"></table>' +
    '</div>' +
    '<div class="modal-footer">' +
    '<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>' +
    '<button type="button" class="btn btn-primary ' + classCheckoutCart + '">Comprar</button>' +
    '</div>' +
    '</div>' +
    '</div>' +
    '</div>'
  );
}

var drawTable = function(){
  var $cartTable = $("#" + idCartTable);
  $cartTable.empty();

  var products = ProductManager.getAllProducts();
  $.each(products, function(){
    var total = this.quantity * this.price;
    $cartTable.append(
      '<tr title="' + this.summary + '" data-id="' + this.id + '" data-price="' + this.price + '">' +
      '<td class="text-center" style="width: 40px;"><img width="40px" height="40px" src="' + this.image + '"/></td>' +
      '<td>' + this.name + '</td>' +
      '<td title="PrecioUnitario">' + options.currencySymbol + MathHelper.getRoundedNumber(this.price) + '</td>' +
      '<td title="Cantidad"><input type="number" min="1" style="width: 70px;" class="' + classProductQuantity + '" value="' + this.quantity + '"/></td>' +
      '<td title="Total" class="' + classProductTotal + '">' + options.currencySymbol  + MathHelper.getRoundedNumber(total) + '</td>' +
      '<td title="Eliminar del Carrito" class="text-center" style="width: 30px;"><a href="javascript:void(0);" class="btn btn-xs btn-danger ' + classProductRemove + '">X</a></td>' +
      '</tr>'
    );
  });

  $cartTable.append(products.length ?
    '<tr>' +
    '<td></td>' +
    '<td><strong>Total</strong></td>' +
    '<td></td>' +
    '<td></td>' +
    '<td><strong id="' + idGrandTotal + '"></strong></td>' +
    '<td></td>' +
    '</tr>'
    : '<div class="alert alert-danger" role="alert" id="' + idEmptyCartMessage + '">Tu Carro está Vacío</div>'
  );

  var discountPrice = options.getDiscountPrice(products, ProductManager.getTotalPrice(), ProductManager.getTotalQuantity());
  if(products.length && discountPrice !== null) {
    $cartTable.append(
      '<tr style="color: red">' +
      '<td></td>' +
      '<td><strong>Total (Incluyendo Descuentos)</strong></td>' +
      '<td></td>' +
      '<td></td>' +
      '<td><strong id="' + idDiscountPrice + '"></strong></td>' +
      '<td></td>' +
      '</tr>'
    );
  }

  showGrandTotal();
  showDiscountPrice();
}
var showModal = function(){
  drawTable();
  $("#" + idCartModal).modal('show');
}
var updateCart = function(){
  $.each($("." + classProductQuantity), function(){
    var id = $(this).closest("tr").data("id");
    ProductManager.updatePoduct(id, $(this).val());
  });
}
var showGrandTotal = function(){
  $("#" + idGrandTotal).text(options.currencySymbol + MathHelper.getRoundedNumber(ProductManager.getTotalPrice()));
}
var showDiscountPrice = function(){
  $("#" + idDiscountPrice).text(options.currencySymbol + MathHelper.getRoundedNumber(options.getDiscountPrice(ProductManager.getAllProducts(), ProductManager.getTotalPrice(), ProductManager.getTotalQuantity())));
}

/*
EVENT
*/
if(options.affixCartIcon) {
  var cartIconBottom = $cartIcon.offset().top * 1 + $cartIcon.css("height").match(/\d+/) * 1;
  var cartIconPosition = $cartIcon.css('position');
  $(window).scroll(function () {
    $(window).scrollTop() >= cartIconBottom ? $cartIcon.addClass(classAffixMyCartIcon) : $cartIcon.removeClass(classAffixMyCartIcon);
  });
}

$cartIcon.click(function(){
  options.showCheckoutModal ? showModal() : options.clickOnCartIcon($cartIcon, ProductManager.getAllProducts(), ProductManager.getTotalPrice(), ProductManager.getTotalQuantity());
});

$(document).on("input", "." + classProductQuantity, function () {
  var price = $(this).closest("tr").data("price");
  var id = $(this).closest("tr").data("id");
  var quantity = $(this).val();

  $(this).parent("td").next("." + classProductTotal).text(options.currencySymbol + MathHelper.getRoundedNumber(price * quantity));
  ProductManager.updatePoduct(id, quantity);

  $cartBadge.text(ProductManager.getTotalQuantity());
  showGrandTotal();
  showDiscountPrice();
});

$(document).on('keypress', "." + classProductQuantity, function(evt){
  if(evt.keyCode == 38 || evt.keyCode == 40){
    return ;
  }
  evt.preventDefault();
});

$(document).on('click', "." + classProductRemove, function(){
  var $tr = $(this).closest("tr");
  var id = $tr.data("id");
  $tr.hide(500, function(){
    ProductManager.removeProduct(id);
    drawTable();
    $cartBadge.text(ProductManager.getTotalQuantity());
  });
});

$("." + classCheckoutCart).click(function(){
  var products = ProductManager.getAllProducts();
  if(!products.length) {
    $("#" + idEmptyCartMessage).fadeTo('fast', 0.5).fadeTo('fast', 1.0);
    return ;
  }
  updateCart();
  options.checkoutCart(ProductManager.getAllProducts(), ProductManager.getTotalPrice(), ProductManager.getTotalQuantity());
  ProductManager.clearProduct();
  $cartBadge.text(ProductManager.getTotalQuantity());
  $("#" + idCartModal).modal("hide");
});

}

var MyCart = function (target) {     / *     PRIVATE     * /     var $ target = $ (target);     var options = OptionManager.getOptions ();     var $ cartIcon = $ ("." + options.classCartIcon);     var $ cartBadge = $ ("." + options.classCartBadge);

/*
EVENT
*/
$target.click(function(){
  options.clickOnAddToCart($target);

  var id = $target.data('id');
  var name = $target.data('name');
  var summary = $target.data('summary');
  var price = $target.data('price');
  var quantity = $target.data('quantity');
  var image = $target.data('image');

  ProductManager.setProduct(id, name, summary, price, quantity, image);
  $cartBadge.text(ProductManager.getTotalQuantity());

  options.afterAddOnCart(ProductManager.getAllProducts(), ProductManager.getTotalPrice(), ProductManager.getTotalQuantity());
});

}

$. fn.myCart = function (userOptions) {     OptionManager.loadOptions (userOptions);     loadMyCartEvent ();     return $ .each (this, function () {       new MyCart (this);     });   }

}) (jQuery);

    
asked by Nicoo1991 04.07.2017 в 02:07
source

1 answer

0

In the ajaxsaveAction you have $user = $this->getUser(); if($user) meaning that if anonymous is not going to execute the function

    
answered by 14.09.2017 в 00:06