1/** 2 * @author Doofinder 3 * @copyright Doofinder 4 * @license MIT 5 * @see https://opensource.org/licenses/MIT 6 */ 7 8class DoofinderAddToCartError extends Error { 9 constructor(reason, status = "") { 10 const message = "Error adding an item to the cart. Reason: " + reason + ". Status code: " + status; 11 super(message); 12 this.name = "DoofinderAddToCartError"; 13 } 14} 15 16//implementation of "add to cart" functionality for prestashop 1.7.x 17 18let dfAddToCart = (cartOptions) => { 19 20 let IdProductCart; 21 let IdCustomization; 22 if (cartOptions.productID.includes('VAR-')) { 23 IdProductCart = cartOptions.group_id; 24 IdCustomization = cartOptions.productID.replace('VAR-', ''); 25 } else { 26 IdProductCart = cartOptions.productID; 27 IdCustomization = cartOptions.customizationID; 28 } 29 30 /** 31 * 1º create the necessary form to add to cart with the required inputs. 32 * (the "name" attribute of the inputs is necessary to trigger the event that prestashop uses natively 33 * for "add to cart"). 34 */ 35 let form = document.createElement("form"); 36 Object.assign(form, { 37 method: "post", 38 action: cartOptions.cartURL, 39 style: "display: none;" 40 }); 41 42 let quantityInput = document.createElement("input"); 43 Object.assign(quantityInput, { 44 type : "number", 45 name : "qty", 46 value : cartOptions.quantity, 47 min : 1 48 }); 49 50 let productAttributeInput = document.createElement("input"); 51 Object.assign(productAttributeInput, { 52 type : "hidden", 53 name : "id_product_attribute", 54 value : IdCustomization 55 }); 56 57 let productInput = document.createElement("input"); 58 Object.assign(productInput, { 59 type : "hidden", 60 name : "id_product", 61 value : IdProductCart 62 }); 63 64 let tokenInput = document.createElement("input"); 65 Object.assign(tokenInput, { 66 type : "hidden", 67 name : "token", 68 value : cartOptions.cartToken 69 }); 70 71 let submit = document.createElement("input"); 72 submit.setAttribute("type", "submit"); 73 submit.setAttribute("data-button-action", "add-to-cart"); 74 75 form.appendChild(quantityInput); 76 form.appendChild(productAttributeInput); 77 form.appendChild(productInput); 78 form.appendChild(tokenInput); 79 form.appendChild(submit); 80 81 /** 82 * 2º Add to DOM the form. 83 */ 84 document.body.appendChild(form); 85 86 if (typeof prestashop !== 'undefined' && typeof cartOptions.statusPromise !== 'undefined') { 87 88 // It's triggered everytime the cart is updated. 89 prestashop.on('updateCart', function (event) { 90 // This should be trigger only if the cart has been updated from the layer. Otherwise, the statusPromise will be undefined. 91 if (typeof cartOptions.statusPromise === 'undefined' || 92 !event || 93 !event.reason || 94 !event.resp) { 95 return; 96 } 97 98 if (event.resp.success) { 99 cartOptions.statusPromise.resolve("The item has been successfully added to the cart."); 100 } else { 101 // The event.resp.errors can be "" or an array 102 errorList = Array.isArray(event.resp.errors) ? event.resp.errors.join(", ") : event.resp.errors; 103 console.warn("Error adding to the cart: " + errorList); 104 cartOptions.statusPromise.reject(new DoofinderAddToCartError(errorList)); 105 /* Special case: the product cannot be added because is customizable. 106 I don't know if it's the best way to detect it, but at least it's better than 107 detecting it from the error message. In this case, the user should be redirected 108 to the product detail page */ 109 if (0 === event.resp.quantity && 'undefined' === typeof event.reason.cart) { 110 window.location.href = cartOptions.itemLink; 111 } 112 } 113 }); 114 115 prestashop.on('handleError', function (event) { 116 // This should be trigger only if the cart has been updated from the layer. Otherwise, the statusPromise will be undefined. 117 if (typeof cartOptions.statusPromise === 'undefined') { 118 return; 119 } 120 121 // Possible errors variations coming from Add to Cart 122 if (event && event.eventType && ('updateProductInCart' === event.eventType || 123 'updateShoppingCart' === event.eventType || 124 'updateCart' === event.eventType || 125 'updateProductInCart' === event.eventType || 126 'updateProductQuantityInCart' === event.eventType || 127 'addProductToCart' === event.eventType)) { 128 129 console.group(`Error of type '${event.eventType}' adding item to the cart.`); 130 131 // If the event is addProductToCart, redirect to the item link. 132 // This will prevent silent errors from both customizable products and products with minimal quantity. 133 if (event.eventType === 'addProductToCart') { 134 console.error("Redirecting user to the item page."); 135 window.location.href = item_link; 136 } 137 138 /* Empirically I've have reproduced this error after loading another page in a specific moment */ 139 if (0 === event.resp.readyState) { 140 console.error("The connection was interrupted
140while adding to the cart"); 141 } 142 143 console.groupEnd(); 144 cartOptions.statusPromise.reject(new DoofinderAddToCartError(message)); 145 } 146 }); 147 } 148 149 /** 150 * 3º clicks on the submit (does not work if you invoke the submit event) 151 * and removes the form from the DOM 152 */ 153 submit.click(); 154 form.remove(); 155} 156 157let doofinderManageCart = (cartOptions) => { 158 dfAddToCart(cartOptions); 159}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.