protected function checkProductRestrictions(Context $context, $return_products = false, $display_error = true, $alreadyInCart = false) { $selectedProducts = array(); // Check if the products chosen by the customer are usable with the cart rule if ($this->product_restriction) { $productRuleGroups = $this->getProductRuleGroups(); foreach ($productRuleGroups as $id_product_rule_group => $productRuleGroup) { $eligibleProductsList = array(); foreach ($context->cart->getProducts() as $product) { $eligibleProductsList[] = (int) $product['id_product'] . '-' . (int) $product['id_product_attribute']; } if (!count($eligibleProductsList)) { return !$display_error ? false : Tools::displayError('You cannot use this voucher in an empty cart'); } $productRules = $this->getProductRules($id_product_rule_group); foreach ($productRules as $productRule) { switch ($productRule['type']) { case 'attributes': $cartAttributes = Db::getInstance()->executeS(' SELECT cp.quantity, cp.`id_product`, pac.`id_attribute`, cp.`id_product_attribute` FROM `' . _DB_PREFIX_ . 'cart_product` cp LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON cp.id_product_attribute = pac.id_product_attribute WHERE cp.`id_cart` = ' . (int) $context->cart->id . ' AND cp.`id_product` IN (' . implode(array_map('intval', $eligibleProductsList), ',') . ') AND cp.id_product_attribute > 0'); $countMatchingProducts = 0; $matchingProductsList = array(); foreach ($cartAttributes as $cartAttribute) { if (in_array($cartAttribute['id_attribute'], $productRule['values'])) { $countMatchingProducts += $cartAttribute['quantity']; if ($alreadyInCart && $this->gift_product == $cartProduct['id_product'] && $this->gift_product_attribute == $cartProduct['id_product_attribute']) { --$countMatchingProducts; } $matchingProductsList[] = $cartAttribute['id_product'] . '-' . $cartAttribute['id_product_attribute']; } } if ($countMatchingProducts < $productRuleGroup['quantity']) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } $eligibleProductsList = CartRule::array_uintersect($eligibleProductsList, $matchingProductsList); break; case 'products': $cartProducts = Db::getInstance()->executeS(' SELECT cp.quantity, cp.`id_product` FROM `' . _DB_PREFIX_ . 'cart_product` cp WHERE cp.`id_cart` = ' . (int) $context->cart->id . ' AND cp.`id_product` IN (' . implode(array_map('intval', $eligibleProductsList), ',') . ')'); $countMatchingProducts = 0; $matchingProductsList = array(); foreach ($cartProducts as $cartProduct) { if (in_array($cartProduct['id_product'], $productRule['values'])) { $countMatchingProducts += $cartProduct['quantity']; if ($alreadyInCart && $this->gift_product == $cartProduct['id_product']) { --$countMatchingProducts; } $matchingProductsList[] = $cartProduct['id_product'] . '-0'; } } if ($countMatchingProducts < $productRuleGroup['quantity']) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } $eligibleProductsList = CartRule::array_uintersect($eligibleProductsList, $matchingProductsList); break; case 'categories': $cartCategories = Db::getInstance()->executeS(' SELECT cp.quantity, cp.`id_product`, cp.`id_product_attribute`, catp.`id_category` FROM `' . _DB_PREFIX_ . 'cart_product` cp LEFT JOIN `' . _DB_PREFIX_ . 'category_product` catp ON cp.id_product = catp.id_product WHERE cp.`id_cart` = ' . (int) $context->cart->id . ' AND cp.`id_product` IN (' . implode(array_map('intval', $eligibleProductsList), ',') . ') AND cp.`id_product` <> ' . (int) $this->gift_product); $countMatchingProducts = 0; $matchingProductsList = array(); foreach ($cartCategories as $cartCategory) { if (in_array($cartCategory['id_category'], $productRule['values']) && !in_array($cartCategory['id_product'] . '-' . $cartCategory['id_product_attribute'], $matchingProductsList)) { $countMatchingProducts += $cartCategory['quantity']; $matchingProductsList[] = $cartCategory['id_product'] . '-' . $cartCategory['id_product_attribute']; } } if ($countMatchingProducts < $productRuleGroup['quantity']) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } // Attribute id is not important for this filter in the global list, so the ids are replaced by 0 foreach ($matchingProductsList as &$matchingProduct) { $matchingProduct = preg_replace('/^([0-9]+)-[0-9]+$/', '$1-0', $matchingProduct); } $eligibleProductsList = CartRule::array_uintersect($eligibleProductsList, $matchingProductsList); break; case 'manufacturers': $cartManufacturers = Db::getInstance()->executeS(' SELECT cp.quantity, cp.`id_product`, p.`id_manufacturer` FROM `' . _DB_PREFIX_ . 'cart_product` cp LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON cp.id_product = p.id_product WHERE cp.`id_cart` = ' . (int) $context->cart->id . ' AND cp.`id_product` IN (' . implode(array_map('intval', $eligibleProductsList), ',') . ')'); $countMatchingProducts = 0; $matchingProductsList = array(); foreach ($cartManufacturers as $cartManufacturer) { if (in_array($cartManufacturer['id_manufacturer'], $productRule['values'])) { $countMatchingProducts += $cartManufacturer['quantity']; $matchingProductsList[] = $cartManufacturer['id_product'] . '-0'; } } if ($countMatchingProducts < $productRuleGroup['quantity']) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } $eligibleProductsList = CartRule::array_uintersect($eligibleProductsList, $matchingProductsList); break; case 'suppliers': $cartSuppliers = Db::getInstance()->executeS(' SELECT cp.quantity, cp.`id_product`, p.`id_supplier` FROM `' . _DB_PREFIX_ . 'cart_product` cp LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON cp.id_product = p.id_product WHERE cp.`id_cart` = ' . (int) $context->cart->id . ' AND cp.`id_product` IN (' . implode(array_map('intval', $eligibleProductsList), ',') . ')'); $countMatchingProducts = 0; $matchingProductsList = array(); foreach ($cartSuppliers as $cartSupplier) { if (in_array($cartSupplier['id_supplier'], $productRule['values'])) { $countMatchingProducts += $cartSupplier['quantity']; $matchingProductsList[] = $cartSupplier['id_product'] . '-0'; } } if ($countMatchingProducts < $productRuleGroup['quantity']) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } $eligibleProductsList = CartRule::array_uintersect($eligibleProductsList, $matchingProductsList); break; } if (!count($eligibleProductsList)) { return !$display_error ? false : Tools::displayError('You cannot use this voucher with these products'); } } $selectedProducts = array_merge($selectedProducts, $eligibleProductsList); } } if ($return_products) { return $selectedProducts; } return !$display_error ? true : false; }