Jurist Posted May 6, 2020 Share Posted May 6, 2020 Hello, I am trying to create a small module that adds another products to the shopping cart through ajax call to module's controller. It works, however I get fatal error: Fatal error: Uncaught PrestaShopException: Fatal error in /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Tools.php:1175 Stack trace: #0 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Product.php(3170): ToolsCore::displayError() #1 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Product.php(4780): ProductCore::getPriceStatic(786, false, 0, 6, NULL, false, true, 2) #2 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Cart.php(790): ProductCore::getProductProperties(1, Array) #3 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Cart.php(1467): CartCore->getProducts(true) #4 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/modules/productAsCombination/productAsCombination.php(242): CartCore->updateQty(2, 786, 0, false) #5 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/modules/productAsCombination/controllers/front/ProductAsCombinationController.php(9): ProductAsCombination->addProductToCart(786, 2, NULL) #6 /home/xxxxyyyy/dev.xxxxyyyy.co.uk/modules/productAsCombination/controllers/front/Pro in /home/xxxxyyyy/dev.xxxxyyyy.co.uk/classes/Tools.php on line 1175 I found that if I comment out: if (!is_object($cur_cart) || (Validate::isUnsignedInt($id_cart) && $id_cart && $cur_cart->id != $id_cart)) { /* * When a user (e.g., guest, customer, Google...) is on PrestaShop, he has already its cart as the global (see /init.php) * When a non-user calls directly this method (e.g., payment module...) is on PrestaShop, he does not have already it BUT knows the cart ID * When called from the back office, cart ID can be inexistant */ if (!$id_cart && !isset($context->employee)) { //die(Tools::displayError()); } $cur_cart = new Cart($id_cart); // Store cart in context to avoid multiple instantiations in BO if (!Validate::isLoadedObject($context->cart)) { $context->cart = $cur_cart; } } Line die(Tools::displayError()); the error is no more. My controller: public function addToCart($id_product, $quantity, $attribute) { $productsAsCombination = new productAsCombination(); if(!$productsAsCombination->addProductToCart($id_product, $quantity, $attribute)) return false; $price = Product::getPriceStatic($id_product); // $price = 69; return $price; } } if(isset($_GET['function'])) { if($_GET['function'] == 'addToCart' && $_GET['id_product'] && $_GET['quantity']) { $ProductAsCombinationController = new ProductAsCombinationController(); $id_product = (int)$_GET['id_product']; $quantity = (int)$_GET['quantity']; $attribute = null; $data = $ProductAsCombinationController->addToCart($id_product, $quantity, $attribute); echo json_encode($data); } } and module's class: public function addProductToCart($id_product, $quantity, $attribute = null) { $context=Context::getContext(); if ($this->context->cookie->id_cart) { $cart = new Cart($this->context->cookie->id_cart); } // create new cart if needed if (!isset($cart) OR !$cart->id) { $cart = new Cart($this->context->cookie->id_cart); $cart->id_customer = (int)($this->context->cookie->id_customer); $cart->id_address_delivery = (int) (Address::getFirstCustomerAddressId($cart->id_customer)); $cart->id_address_invoice = $cart->id_address_delivery; $cart->id_lang = (int)($this->context->cookie->id_lang); $cart->id_currency = (int)($this->context->cookie->id_currency); $cart->id_carrier = 1; $cart->recyclable = 0; $cart->gift = 0; $cart->add(); $this->context->cookie->id_cart = (int)($cart->id); } $cart->update(); $cart->updateQty((int)$quantity, (int)$id_product, $attribute, false); $cart->update(); } Anybody could tip where there's a problem? Apparently $id_cart is not defined when Product::getPriceStatic is called by CartCore. My module is working, however Internal server error from ajax call gives me anxiety. Any help, will be much appreciated. Link to comment Share on other sites More sharing options...
Jurist Posted May 8, 2020 Author Share Posted May 8, 2020 Hi ndiaga, Thank you very much for your answer, much appreciated. You quoted Cart.php core, which I have not edited in any way. $cart->updateQty((int)$quantity, (int)$id_product, $attribute, false); called in my class causes the problem. Not sure why but for some reason, Cart.php, called from my module's class 'doesn't see' $id_cart. Link to comment Share on other sites More sharing options...
Jurist Posted May 12, 2020 Author Share Posted May 12, 2020 Hi @ndiaga, I have created it other way, without using custom controller and using cartController instead. The problem I have is that sometimes on add to cart button click, the store adds products from my function first, which are then overwritten by the product that the add to cart button is clicked on. There's code: function addProduct(id_product, quantity, totalQty) { const token = prestashop.static_token; const url = prestashop.urls.pages.cart; const query = 'controller=cart&add=1&action=update&ajax=true&token=' + token + '&id_product=' + id_product + '&id_customization=0&qty=' + totalQty; var controllerUrl = url.concat(query); var functionName = "addToCart"; // var delay = 10; $.ajax({ // url: controllerUrl, headers: { "cache-control": "no-cache" }, cache: false, async: false, data: query, beforeSend: function () { // setTimeout(delay); }, success: function(resp) { // console.log(resp); prestashop.emit('updateCart', { reason: {}, resp: resp }); }, error: function(resp) { // console.log(resp); prestashop.emit('handleError', {eventType: 'addProductToCart', resp: resp}); } }); } Do you have an idea how to fire the event after the original product was added to the shopping cart? So the products added by the function are added after, to an existing cart. I would be very grateful for your help. Kind regards Link to comment Share on other sites More sharing options...
Jurist Posted May 14, 2020 Author Share Posted May 14, 2020 Hi @ndiaga, Do you mean _dev/cart.js? File is hard to read and understand, which part is responsible for adding product to shopping cart? Basically the only problem I have with my function is that it add the product I want to shopping cart, but sometimes adds a new shopping cart which leaves 'original' product behind. Is there a way to make sure that the event is fired only after previous add to cart action is done? Maybe I should change query somehow? Link to comment Share on other sites More sharing options...
Jurist Posted May 14, 2020 Author Share Posted May 14, 2020 4 minutes ago, ndiaga said: Hi, You don't need to read any js code, just call it as the default classic calls it in the file : themes/classic/templates/catalog/_partials/product-add-to-cart.tpl I checked that file contents but I think its called elsewhere, it's just template file that generates html content, which may then be used to fire JS event that adds product to shopping cart. I need to add another product that is not shown on this product page (as accessory), that's why I use JS: if checkbox is selected, then add product id 786 to shopping cart as well. It works but the problem is, new cart with product id 786 overwrites old cart with original product which means only product id 786 is now in cart. I need to make sure cart is not empty and add it only after original product is added (which creates appropriate cart as well). I am thinking about setting interval and checking cart quantity... Link to comment Share on other sites More sharing options...
Jurist Posted May 14, 2020 Author Share Posted May 14, 2020 Where specifically in the file you see it called? Link to comment Share on other sites More sharing options...
Jurist Posted May 15, 2020 Author Share Posted May 15, 2020 On 5/14/2020 at 12:01 PM, ndiaga said: The function that is called here : themes/classic/templates/catalog/_partials/product-add-to-cart.tpl can be called anywhere in the website. hi ndiaga, Could you please show me sample how to call it? I tried reading documentation but couldn't find such info anywhere. I've spent few days on that and cannot solve the problem I have... Link to comment Share on other sites More sharing options...
Jurist Posted May 15, 2020 Author Share Posted May 15, 2020 Man, I really appreciate your time and help. However I have no possibility of adding extra button / changes to .tpl files. Please have a look here: https://dev.wetroomsdesign.co.uk/wet-room-kit-800-x-800-line-ponente Add to cart button is meant to add another products to the shopping cart if appropriate select options are chosen. I am trying to do that with: function addProduct(id_product, quantity, totalQty, delay) { const token = prestashop.static_token; const url = prestashop.urls.pages.cart; const query = 'controller=cart&add=1&action=add&ajax=true&token=' + token + '&id_product=' + id_product + '&id_customization=0&qty=' + totalQty; var controllerUrl = url.concat(query); var functionName = "addToCart"; $.ajax({ cache: false, data: query, beforeSend: function () { setTimeout(delay); }, success: function(resp) { // console.log(resp); prestashop.emit('updateCart', { reason: {}, resp: resp }); }, error: function(resp) { // console.log(resp); prestashop.emit('handleError', {eventType: 'addProductToCart', resp: resp}); } }); } and it works but only if someone has cart created before. If user adds to cart for the first time, the original product is overwritten. I need to fire it from javascript. Any ideas? Link to comment Share on other sites More sharing options...
AnthonyJane Posted May 6, 2021 Share Posted May 6, 2021 Hi Jurist Did you ever resolve this? I am having exactly the same issue and need to fire from JS via ajax also. Thanks AJ Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now