Padrox Posted June 30, 2023 Share Posted June 30, 2023 Hey there, I'm first would like to apologize for this thread because it is possible the answer already exist somewhere else. I'm making a Custom Module for Prestashop 8, what I'm trying to achieve is a button that adds a Product with a Custom Parameter which I'll handle myself in the backend of my module. What I've done yet is a button on my template linked to my module php file through an ajax function. I have the product I want to add as a variable and right now I'm using the cart->updateQty() method but it doesn't seem to be the proper way of doing it nowadays. I'm really confused and the more I read the more I feel lost about this whole Prestashop 8 update. Here is my ajax method: public function _ajax_add_plinths($quantity) { $context = Context::getContext(); $id_cart = $context->cookie->__get('id_cart'); if (!$id_cart) { $cart = new Cart(); $cart->id_customer = (int)($context->cookie->__get('id_customer')); $cart->id_address_delivery = (int)(Address::getFirstCustomerAddressId($cart->id_customer)); $cart->id_address_invoice = $cart->id_address_delivery; $cart->id_lang = (int)($context->cookie->__get('id_lang')); $cart->id_currency = (int)($context->cookie->__get('id_currency')); $cart->id_carrier = 1; $cart->recyclable = 0; $cart->gift = 0; $cart->add(); $context->cookie->__set('id_cart', (int)($cart->id)); $context->cart = $cart; } else { $cart = new Cart($id_cart); } $cart->id_currency = 1; $cart->id_lang = 1; $product = $this->getProductByProductName('Plinthes associées'); if ($product) { $cart->updateQty($quantity, $product['id_product'], false, null, 'up', 0, null, true); $context->smarty->assign(array( 'confirmation' => 1 )); } else { $context->smarty->assign(array( 'confirmation' => 0 )); } } Am I on the good path or should I refactor my whole module because what I've made is deprecated ? Don't hesitate to ask if you need me to provide more information, Any help would be appreciated, Padrox Link to comment Share on other sites More sharing options...
Padrox Posted July 4, 2023 Author Share Posted July 4, 2023 Hey, I'm back with more information, here is my updated add to cart Ajax method in my Custom Module main class. public function _ajax_add_plinths($currentProductName, $quantity) { $returnMap = array("Initialization" => "Success"); $cart = $this->context->cart; // Retrieve the plinths Product $plinths = $this->GetProductByProductId(3); $plinthsId = $plinths['id_product']; $plinthsAttributeId = $plinths['product_attribute_id']; $plinthsProduct = new Product($plinthsId); //Get the customization field ID for "Carrelage associé" $customizationFields = $plinthsProduct->getCustomizationFields(); $returnMap["CustomizationFields"] = $customizationFields; $carrelageAssociéFound = false; $fieldId = null; foreach ($customizationFields as $field) { $returnMap[$field["3"]["1"]['name']] = "Field Name"; if ($field["3"]["1"]['name'] === 'Carrelage associé') { $carrelageAssociéFound = true; $fieldId = $field["3"]["1"]['id_customization_field']; break; } } $returnMap['Carrelage Associé Found'] = $carrelageAssociéFound; $returnMap["FieldId"] = $fieldId; // Set the customization value for the field "Carrelage associé" if ($fieldId) { $customizationValue = $currentProductName; $returnMap['customizationValue'] = $customizationValue; $cart->update(); $cart->updateQty($quantity, $plinthsId, null, false); $returnMap['updateQty'] = "Called"; $cart->_addCustomization($plinthsId, $plinthsAttributeId, $fieldId, $plinthsProduct::CUSTOMIZE_TEXTFIELD, $customizationValue, $quantity, false); $returnMap['_addCustomization'] = "Called"; } // Save the cart $cart->update(); $returnMap['Cart Status'] = "Updated!"; echo json_encode($returnMap); } My product is successfully added to the cart but there is not notification. To display the update of the cart I have to reload the page. One more thing the Customization isn't applied on my newly added product. Please help Link to comment Share on other sites More sharing options...
ps8modules.com Posted July 5, 2023 Share Posted July 5, 2023 It won't work for you that way 😉 I'll give you an example for javascript and ajax.php. javascript: // customize product in your module function addToCartInMyModule() { // call ajax function $.ajax({ type: "POST", url: your_ajax_url, // /modules/mymodule/ajax.php data:'action=addTocart', async: false, cache: false, dataType: 'json', success: function(data){ if (data !== ''){ if (data['id_product'] !== '' && data['id_product_attribute'] !== '' && data['quantity'] !== '' && data['operand'] !== '') { // OK, data myAjaxAddToCart(data['id_product'], data['id_product_attribute'], data['quantity'], data['operand']) ; } } } }); } // add to cart and refresh page function myAjaxAddToCart(id_product, id_product_attribute, quantity, operand) { // operand up / down const token = prestashop.static_token; const actionURL = prestashop.urls.pages.cart; var query= 'controller=cart&add=1&action=update&ajax=true&qty='+quantity+'&op='+operand+'&token='+token+'&id_product='+id_product+'&ipa='+id_product_attribute; $.post(actionURL, query, null, 'json').then((resp) => { prestashop.emit('updateCart', { reason: {}, resp: resp }); console.log(resp); }).fail((resp) => { prestashop.emit('handleError', {eventType: 'addProductToCart', resp: resp}); }); } ajax.php: <?php include('../../config/config.inc.php'); include('../../init.php'); $module_name = 'mymodule'; $module = Module::getInstanceByName($module_name); if (!Module::isInstalled($module->name) || !$module->active) { echo($module->l('Ajax Error')); return; } if (Tools::getValue('action') == 'addTocart') { $response = array(); $myLog = ''; // call your module function or add here $response['id_product'] = $id_product; $response['id_product_attribute'] = $id_product_attribute; $response['quantity'] = $quantity; $response['operand'] = 'up' // or down; $response['log'] = $myLog; echo json_encode($response); } Link to comment Share on other sites More sharing options...
Padrox Posted July 10, 2023 Author Share Posted July 10, 2023 Hey, Thank you so much for your answer. I'm starting to feel completely lost and depressed about my progression curve on Prestashop because I feel like I'm doing a total non-sense... I really appreciate your help. First, I've made a lot of changes recently so I wouldn't know how to adapt my newly pseudo fonctionnal code to the example you've provided me with. If you want to take a look, here is what I came up with recently public function getProductByProductId($search, $id_shop = 1, $id_lang = 1) { return Db::getInstance()->getValue(' SELECT id_product FROM '._DB_PREFIX_.'product_lang WHERE id_product LIKE "%'.(string)$search.'%" AND id_shop = '.$id_shop.' AND id_lang = '.$id_lang.' '); } public function getProductByProductName($search, $id_shop = 1, $id_lang = 1) { return Db::getInstance()->getValue(' SELECT id_product FROM '._DB_PREFIX_.'product_lang WHERE name LIKE "%'.(string)$search.'%" AND id_shop = '.$id_shop.' AND id_lang = '.$id_lang.' '); } public function getProductVariantIdFromDimension($product, $index) { $productAttributesIds = Product::getProductAttributesIds($product['id_product']); return (int)$productAttributesIds[$index]['id_product_attribute']; } public function _ajax_add_plinths($currentProductName, $quantity) { $returnMap = []; // Accessors $context = $this->context; $cookie = $context->cookie; // Get cart if already exist or create one if ($cookie->id_cart) { $cart = new Cart($cookie->id_cart); } if (!isset($cart) OR !$cart->id) { $cart = new Cart($cookie->id_cart); $cart->id_customer = (int)$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)$cookie->id_lang; $cart->id_currency = (int)$cookie->id_currency; $cart->id_carrier = 1; $cart->recyclable = 0; $cart->gift = 0; $cart->add(); $cookie->id_cart = (int)$cart->id; } // Retrive the current Product $currentProduct = $this->getProductByProductName($currentProductName); $currentId = $currentProduct['id_product']; // Retrieve the plinths Product $plinths = $this->getProductByProductId(3); $plinthsId = $plinths['id_product']; $plinthsProduct = new Product($plinthsId); // This is the ID of the feature that determines what will be the dimension of the newly added plinths $featureId = 2; $features = Product::getFeaturesStatic($currentId); $dimensionFeature = null; foreach($features as $feature) { if($feature['id_feature'] == $featureId) { $dimensionFeature = $feature; break; } } if($dimensionFeature == null) { $returnMap['ERROR'] = "No dimension feature found on this product. Cannot add the associated plinths to the cart!"; echo json_encode($returnMap); return; } $attributeId = 0; switch($feature['id_feature_value']) { case 7: // Manches longues $attributeId = $this->getProductVariantIdFromDimension($plinths, 0); break; case 8: // Manches courtes $attributeId = $this->getProductVariantIdFromDimension($plinths, 1); break; case 9: // Housse amovible $attributeId = $this->getProductVariantIdFromDimension($plinths, 2); break; case 10: // 120 pages $attributeId = $this->getProductVariantIdFromDimension($plinths, 2); break; default: $returnMap['ERROR'] = 'id_feature_value cannot be used! ID = ' . $feature['id_feature_value']; echo json_encode($returnMap); return; } //Get the customization field ID for "Carrelage associé" $customizationFields = $plinthsProduct->getCustomizationFields(); $fieldId = null; foreach ($customizationFields as $field) { if ($field["3"]["1"]['name'] === 'Carrelage associé') { $fieldId = $field["3"]["1"]['id_customization_field']; break; } } // Set the customization value for the field "Carrelage associé" if ($fieldId) { $cart->update(); $cart = $context->cart; $customizationValue = $currentProductName; $id_customization = $cart->_addCustomization((int)$plinthsId, (int)$attributeId, (int)$fieldId, $plinthsProduct::CUSTOMIZE_TEXTFIELD, $customizationValue, (int)$quantity, true); $cart->updateQty((int)$quantity, (int)$plinthsId, (int)$attributeId, (int)$id_customization); } $cart->update(); echo json_encode($returnMap); Now, I can call my ajax and the product is properly added to the cart with the correct customization (which is defined by myself based on a ProductFeature). I have one major issue that is the cart isn't updated until I refresh manually. I'd like to have the default popup saying "new product added to cart". How should I adapt my new code with the example you provided me with ? Sorry for the confusion .. Link to comment Share on other sites More sharing options...
Padrox Posted July 11, 2023 Author Share Posted July 11, 2023 (edited) Hey So i've tried to implement what you suggested on my own. These are the updated correspondiong ajax.php and .tpl I don't know how and why but the Ajax method seems to be called because I don't have a 404 error when clicking the button but there is absolutely no return no error. I'm completely lost. Any suggestion ? Edited July 11, 2023 by Padrox (see edit history) Link to comment Share on other sites More sharing options...
Padrox Posted July 11, 2023 Author Share Posted July 11, 2023 The PHP: <?php include('../../config/config.inc.php'); include('../../init.php'); $aled = array(); $module_name = 'mymodule'; $module = Module::getInstanceByName($module_name); $aled['Please work'] = true; if (Module::isInstalled($module->name) || $module->active) { echo($module->l('Ajax Error')); return; } if (Tools::getValue('action') == 'addTocart') { $response = array(); $myLog = ''; // call your module function or add here $response['HERE'] = "Not working ..."; // $response['id_product'] = $id_product; // $response['id_product_attribute'] = $id_product_attribute; // $response['quantity'] = $quantity; // $response['operand'] = 'up'; // or down // $response['log'] = $myLog; echo json_encode($response); } echo json_encode($aled); Link to comment Share on other sites More sharing options...
Padrox Posted July 11, 2023 Author Share Posted July 11, 2023 function addPlinths() { // call ajax function $.ajax({ type: "POST", url: '../../modules/plinthshandler/ajax/ajax.php', // /modules/mymodule/ajax.php data:'action=addTocart', async: false, cache: false, dataType: 'json', success: function(data){ console.log("Returned in the success"); console.log(JSON.parse(data)); // if (data !== ''){ // if (data['id_product'] !== '' && data['id_product_attribute'] !== '' && data['quantity'] !== '' && data['operand'] !== '') { // // OK, data // myAjaxAddToCart(data['id_product'], data['id_product_attribute'], data['quantity'], data['operand']) ; // } // } } }); } Link to comment Share on other sites More sharing options...
ps8modules.com Posted July 12, 2023 Share Posted July 12, 2023 Hi. I wrote you a sample of how it should work. I wrote her off the top of my head and didn't test. Test module: ps8mod_ajaxcart.zip Link to comment Share on other sites More sharing options...
Padrox Posted July 12, 2023 Author Share Posted July 12, 2023 Hey, I checked your module example and it really looks like what I have indeed. In my module, I successfully add the product with the proper customization in the cart. The only thing is that the product and the cart are not automatically visually updated. I'd love to add the "A new product has been added to the cart" from the default template. I feel like it must be something easy to add but it seems way more complicated than what I've expected. If you could please enlighten for me where the code responsible for this feature is located. To be honest, I'm reaching my deadlines, so if I can add this feature as quick as possible, it would be great. Though, if I have to refactor everything I'll do it... Link to comment Share on other sites More sharing options...
ps8modules.com Posted July 12, 2023 Share Posted July 12, 2023 (edited) JS function myAjaxAddToCart ajax=true .... You can find the sample directly in the ps_shopingcart module and the ps_shopingcart.js folder. Look at line 49 > prestashop.on( 'updateCart', More info: https://devdocs.prestashop-project.org/8/themes/reference/javascript-events/ Edited July 12, 2023 by ps8moduly.cz (see edit history) 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