Ejemplo n.º 1
0
    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;
    }