299 lines
16 KiB
PHP
299 lines
16 KiB
PHP
<?php
|
|
class CartController extends CartControllerCore
|
|
{
|
|
protected $id_configurator;
|
|
|
|
protected function parseConfigurator()
|
|
{
|
|
$detectOptGroup = 'optgroup-';
|
|
$postValues = Tools::getAllValues();
|
|
|
|
if (count($postValues) > 0) {
|
|
$sqlValues = array();
|
|
foreach($postValues as $p => $v) {
|
|
if (!empty($v)) {
|
|
if (substr($p, 0, strlen($detectOptGroup)) === $detectOptGroup) {
|
|
$ids = explode('-', substr($p, strlen($detectOptGroup)));
|
|
$id_configurator_opt_group = $ids[0];
|
|
$id_configurator_opt = $v;
|
|
$optValue = '';
|
|
if (isset($ids[1])) {
|
|
$id_configurator_opt = $ids[1];
|
|
// Set value for text, date, file
|
|
$optValue = $v;
|
|
}
|
|
|
|
if (is_array($id_configurator_opt) && count($id_configurator_opt) > 0) {
|
|
foreach ($id_configurator_opt as $item) {
|
|
$price = Db::getInstance()->getValue('SELECT pcoi.`price` FROM `'._DB_PREFIX_.'configurator_opt` co,
|
|
`'._DB_PREFIX_.'product_configurator_opt_impact` pcoi
|
|
WHERE co.`id_configurator_opt` = pcoi.`id_configurator_opt` AND co.`id_configurator_opt` = '.(int)$item);
|
|
$sqlValues[] = '(@id_configurator, '.$this->id_product.', '.(int)$id_configurator_opt_group.', '.pSQL($item).', \''.pSQL($optValue).'\', '.$price.')';
|
|
}
|
|
} else {
|
|
$price = Db::getInstance()->getValue('SELECT pcoi.`price` FROM `'._DB_PREFIX_.'configurator_opt` co,
|
|
`'._DB_PREFIX_.'product_configurator_opt_impact` pcoi
|
|
WHERE co.`id_configurator_opt` = pcoi.`id_configurator_opt` AND co.`id_configurator_opt` = '.(int)$id_configurator_opt);
|
|
$sqlValues[] = '(@id_configurator, '.$this->id_product.', '.(int)$id_configurator_opt_group.', '.(int)$id_configurator_opt.', \''.pSQL($optValue).'\', '.$price.')';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count($sqlValues) > 0) {
|
|
if ($this->id_configurator === null) {
|
|
$this->id_configurator = 0;
|
|
}
|
|
|
|
if ($this->id_configurator == 0) {
|
|
// Get id_configurator max
|
|
$cmaxSql = 'SELECT IF(MAX(cp.id_configurator) IS NULL, 0, MAX(cp.id_configurator)) AS maxCp,
|
|
IF(MAX(cs.id_configurator) IS NULL, 0, MAX(cs.id_configurator)) AS maxCs
|
|
FROM ps_configurator_storage cs, ps_cart_product cp';
|
|
$max = Db::getInstance()->getRow($cmaxSql);
|
|
$this->id_configurator = ($max['maxCp'] > $max['maxCs'] ? $max['maxCp'] : $max['maxCs']) + 1;
|
|
|
|
// Assign id on cart_product
|
|
Db::getInstance()->update('cart_product', array(
|
|
'id_configurator' => (int)$this->id_configurator),
|
|
'id_cart='.(int)$this->context->cart->id.
|
|
' AND id_product='.(int)$this->id_product.
|
|
' AND id_address_delivery='.(int)$this->id_address_delivery.
|
|
' AND id_shop='.(int)$this->context->cart->id_shop.
|
|
' AND id_product_attribute='.(int)$this->id_product_attribute.
|
|
' AND quantity='.(int)$this->qty
|
|
.' AND id_configurator = 0');
|
|
}
|
|
// Delete
|
|
else {
|
|
Db::getInstance()->delete('configurator_storage', 'id_configurator = '.(int)$this->id_configurator);
|
|
}
|
|
|
|
// Insert configuration
|
|
Db::getInstance()->execute('SET @id_configurator = '.$this->id_configurator.';
|
|
INSERT INTO `'._DB_PREFIX_.'configurator_storage`
|
|
(`id_configurator`, `id_product`, `id_configurator_opt_group`, `id_configurator_opt`, `opt_value`, `price`)
|
|
VALUES '.implode(',', $sqlValues)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function processDeleteProductInCart()
|
|
{
|
|
$customization_product = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'customization`
|
|
WHERE `id_cart` = '.(int)$this->context->cart->id.' AND `id_product` = '.(int)$this->id_product.
|
|
' AND `id_customization` != '.(int)$this->customization_id);
|
|
|
|
if (count($customization_product)) {
|
|
$product = new Product((int)$this->id_product);
|
|
if ($this->id_product_attribute > 0) {
|
|
$minimal_quantity = (int)Attribute::getAttributeMinimalQty($this->id_product_attribute);
|
|
} else {
|
|
$minimal_quantity = (int)$product->minimal_quantity;
|
|
}
|
|
|
|
$total_quantity = 0;
|
|
foreach ($customization_product as $custom) {
|
|
$total_quantity += $custom['quantity'];
|
|
}
|
|
|
|
if ($total_quantity < $minimal_quantity) {
|
|
$this->ajaxDie(Tools::jsonEncode(array(
|
|
'hasError' => true,
|
|
'errors' => array(sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity)),
|
|
)));
|
|
}
|
|
}
|
|
|
|
// Get id_configurator
|
|
$id_configurator = Tools::getValue('id_configurator', 0);
|
|
|
|
if ($this->context->cart->deleteProduct($this->id_product, $this->id_product_attribute, $this->customization_id, $this->id_address_delivery, true, $id_configurator)) {
|
|
Hook::exec('actionAfterDeleteProductInCart', array(
|
|
'id_cart' => (int)$this->context->cart->id,
|
|
'id_product' => (int)$this->id_product,
|
|
'id_product_attribute' => (int)$this->id_product_attribute,
|
|
'customization_id' => (int)$this->customization_id,
|
|
'id_address_delivery' => (int)$this->id_address_delivery
|
|
));
|
|
|
|
if (!Cart::getNbProducts((int)$this->context->cart->id)) {
|
|
$this->context->cart->setDeliveryOption(null);
|
|
$this->context->cart->gift = 0;
|
|
$this->context->cart->gift_message = '';
|
|
$this->context->cart->update();
|
|
}
|
|
}
|
|
$removed = CartRule::autoRemoveFromCart();
|
|
CartRule::autoAddToCart();
|
|
if (count($removed) && (int)Tools::getValue('allow_refresh')) {
|
|
$this->ajax_refresh = true;
|
|
}
|
|
}
|
|
|
|
protected function processChangeProductInCart()
|
|
{
|
|
$mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';
|
|
|
|
if ($this->qty == 0) {
|
|
$this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
|
|
} elseif (!$this->id_product) {
|
|
$this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
|
|
}
|
|
|
|
$product = new Product($this->id_product, true, $this->context->language->id);
|
|
if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
|
|
$this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
|
|
return;
|
|
}
|
|
|
|
$qty_to_check = $this->qty;
|
|
$cart_products = $this->context->cart->getProducts();
|
|
|
|
$this->id_configurator = Tools::getValue('id_configurator', null);
|
|
|
|
if (is_array($cart_products)) {
|
|
foreach ($cart_products as $cart_product) {
|
|
// Configurator
|
|
if (isset($cart_product['id_configurator']) && $cart_product['id_configurator'] > 0) {
|
|
if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
|
|
(isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
|
|
|
|
$qty_to_check = $cart_product['cart_quantity'];
|
|
|
|
// Define configurator
|
|
$this->id_configurator = $cart_product['id_configurator'];
|
|
|
|
if (Tools::getValue('op', 'up') == 'down') {
|
|
$qty_to_check -= $this->qty;
|
|
} else {
|
|
$qty_to_check += $this->qty;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
// Default
|
|
elseif ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
|
|
(isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
|
|
$qty_to_check = $cart_product['cart_quantity'];
|
|
|
|
if (Tools::getValue('op', 'up') == 'down') {
|
|
$qty_to_check -= $this->qty;
|
|
} else {
|
|
$qty_to_check += $this->qty;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check product quantity availability
|
|
if ($this->id_product_attribute) {
|
|
if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
|
|
$this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
|
|
}
|
|
} elseif ($product->hasAttributes()) {
|
|
$minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
|
|
$this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
|
|
// @todo do something better than a redirect admin !!
|
|
if (!$this->id_product_attribute) {
|
|
Tools::redirectAdmin($this->context->link->getProductLink($product));
|
|
} elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
|
|
$this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
|
|
}
|
|
} elseif (!$product->checkQty($qty_to_check)) {
|
|
$this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
|
|
}
|
|
|
|
// If no errors, process product addition
|
|
if (!$this->errors && $mode == 'add') {
|
|
// Add cart if no cart found
|
|
if (!$this->context->cart->id) {
|
|
if (Context::getContext()->cookie->id_guest) {
|
|
$guest = new Guest(Context::getContext()->cookie->id_guest);
|
|
$this->context->cart->mobile_theme = $guest->mobile_theme;
|
|
}
|
|
$this->context->cart->add();
|
|
if ($this->context->cart->id) {
|
|
$this->context->cookie->id_cart = (int)$this->context->cart->id;
|
|
}
|
|
}
|
|
|
|
// Check customizable fields
|
|
if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
|
|
$this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
|
|
}
|
|
|
|
if (!$this->errors) {
|
|
$cart_rules = $this->context->cart->getCartRules();
|
|
$available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
|
|
|
|
// Configurator options
|
|
$this->parseConfigurator();
|
|
|
|
// Send configurator id
|
|
$update_quantity = $this->context->cart->updateQty(
|
|
$this->qty,
|
|
$this->id_product,
|
|
$this->id_product_attribute,
|
|
$this->customization_id,
|
|
Tools::getValue('op', 'up'),
|
|
$this->id_address_delivery,
|
|
null,
|
|
true,
|
|
$this->id_configurator
|
|
);
|
|
|
|
if ($update_quantity < 0) {
|
|
// If product has attribute, minimal quantity is set with minimal quantity of attribute
|
|
$minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
|
|
$this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
|
|
} elseif (!$update_quantity) {
|
|
$this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
|
|
} elseif ((int)Tools::getValue('allow_refresh')) {
|
|
// If the cart rules has changed, we need to refresh the whole cart
|
|
$cart_rules2 = $this->context->cart->getCartRules();
|
|
if (count($cart_rules2) != count($cart_rules)) {
|
|
$this->ajax_refresh = true;
|
|
} elseif (count($cart_rules2)) {
|
|
$rule_list = array();
|
|
foreach ($cart_rules2 as $rule) {
|
|
$rule_list[] = $rule['id_cart_rule'];
|
|
}
|
|
foreach ($cart_rules as $rule) {
|
|
if (!in_array($rule['id_cart_rule'], $rule_list)) {
|
|
$this->ajax_refresh = true;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
|
|
if (count($available_cart_rules2) != count($available_cart_rules)) {
|
|
$this->ajax_refresh = true;
|
|
} elseif (count($available_cart_rules2)) {
|
|
$rule_list = array();
|
|
foreach ($available_cart_rules2 as $rule) {
|
|
$rule_list[] = $rule['id_cart_rule'];
|
|
}
|
|
foreach ($cart_rules2 as $rule) {
|
|
if (!in_array($rule['id_cart_rule'], $rule_list)) {
|
|
$this->ajax_refresh = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$removed = CartRule::autoRemoveFromCart();
|
|
CartRule::autoAddToCart();
|
|
if (count($removed) && (int)Tools::getValue('allow_refresh')) {
|
|
$this->ajax_refresh = true;
|
|
}
|
|
}
|
|
} |