context = adp_context(); $this->conditionsLoader = Factory::get("Core_Rule_CartCondition_ConditionsLoader"); $this->limitsLoader = Factory::get("Core_Rule_Limit_LimitsLoader"); $this->cartAdjLoader = Factory::get('Core_Rule_CartAdjustment_CartAdjustmentsLoader'); $this->optionsConverter = new OptionsConverter(); $this->wpmlCmp = new WpmlCmp(); if ( $this->wpmlCmp->isActiveSitepress() && $this->wpmlCmp->isActiveWcWpml() ) { $this->wpmlCmp->replaceVariationDataStore(); $this->wpmlCmp->addFilterPreloadedListLanguages(); $this->wpmlCmp->modifyContext($this->context); } else if ( $this->wpmlCmp->isActiveWcWpml()) { $this->wpmlCmp->setCurrency($this->context); } $this->priceBasedOnCountryCmp = new PriceBasedOnCountryCmp(); $this->polylangCmp = new PolylangCmp(); if ( $this->polylangCmp->isActive() ) { $this->polylangCmp->addFilterPreloadedListLanguages(); $this->polylangCmp->modifyContext($this->context); } } public function withContext(Context $context) { $this->context = $context; // $this->conditionsLoader->withContext($this->context); // $this->limitsLoader->withContext($this->context); // $this->cartAdjLoader->withContext($this->context); // $this->priceBasedOnCountryCmp->withContext($this->context); } /** * @param array $rows * * @return RulesCollection */ public function buildRules($rows): RulesCollection { $rules = array(); /** * @var Models\Rule $row */ foreach ($rows as $row) { $filters = isset($row->filters) ? $row->filters : array(); $filter = reset($filters); $filterFromIsSingle = $filter !== false && floatval($filter['qty']) === floatval(1); $filterToIsNotSingle = $filter !== false && $this->context->getOption("show_qty_range_in_product_filter") && isset($filter['qty_end']) && (floatval($filter['qty_end']) > floatval(1)); if (count($filters) === 1 && $filter !== false && $filterFromIsSingle && !$filterToIsNotSingle) { $rule = $this->buildSingleItemRule($row); } elseif (count($filters) > 1 || (count($filters) === 1 && $filter !== false && ( ! $filterFromIsSingle || $filterToIsNotSingle))) { $rule = $this->buildPackageRule($row); } elseif (( ! isset($row->productAdjustments['total']['value']) || $row->productAdjustments['total']['value'] === "") || ( ! isset($row->bulkAdjustments['ranges']) || count($row->bulkAdjustments['ranges']) == 0) || ( ! isset($row->roleDiscounts['rows']) || count($row->roleDiscounts['rows']) == 0) ) { $rule = $this->buildSingleItemRule($row); $filter = new Filter(); $filter->setType($filter::TYPE_ANY); $filter->setMethod($filter::METHOD_IN_LIST); $rule->addFilter($filter); } else { $rule = $this->buildNoItemRule($row); } $implodeRecursive = function ($item) use (&$implodeRecursive) { return is_array($item) ? implode("_", array_map($implodeRecursive, $item)) : serialize($item); }; $rule->setHash(md5($implodeRecursive($row))); if ($this->wpmlCmp->isActiveSitepress() && $this->wpmlCmp->shouldTranslate()) { if ($this->wpmlCmp->isActiveWcWpml()) { $rule = $this->wpmlCmp->changeRuleCurrency($rule); } if ( $this->wpmlCmp->getObjectInternationalization() && $this->context->isTranslateRules() ) { $rule = RuleTranslator::translate($rule, $this->wpmlCmp->getObjectInternationalization()); } } else if ($this->polylangCmp->isActive() && $this->polylangCmp->shouldTranslate()) { if ( $this->polylangCmp->getObjectInternationalization() && $this->context->isTranslateRules() ) { $rule = RuleTranslator::translate($rule, $this->polylangCmp->getObjectInternationalization()); } } if ( $this->priceBasedOnCountryCmp->isActive() ) { $rule = $this->priceBasedOnCountryCmp->changeRuleCurrency($rule); } $currencySwitcher = $this->context->currencyController; if ($currencySwitcher->isCurrencyChanged()) { $rule = RuleTranslator::setCurrency($rule, $this->context->currencyController->getRate()); } $rule->setCurrency($this->context->currencyController->getCurrentCurrency()); $rule->setBlocks($row->additional['blocks'] ?? []); $rules[$rule->getId()] = apply_filters('adp_rule_loaded', $rule, $row->getData()); } return new RulesCollection($rules); } /** * @param array $rows * * @return RulesCollection */ public function buildPersistentRules($rows): RulesCollection { $rules = array(); foreach ($rows as $row) { $rule = $this->buildPersistentRule($row); $implodeRecursive = function ($item) use (&$implodeRecursive) { return is_array($item) ? implode("_", array_map($implodeRecursive, $item)) : serialize($item); }; $rule->setHash(md5($implodeRecursive($row))); if ($this->wpmlCmp->isActiveSitepress() && $this->wpmlCmp->shouldTranslate()) { if ($this->wpmlCmp->isActiveWcWpml()) { $rule = $this->wpmlCmp->changeRuleCurrency($rule); } if ( $this->wpmlCmp->getObjectInternationalization() && $this->context->isTranslateRules() ) { $rule = RuleTranslator::translate($rule, $this->wpmlCmp->getObjectInternationalization()); } } else if ($this->polylangCmp->isActive() && $this->polylangCmp->shouldTranslate()) { if ( $this->polylangCmp->getObjectInternationalization() && $this->context->isTranslateRules() ) { $rule = RuleTranslator::translate($rule, $this->polylangCmp->getObjectInternationalization()); } } if ( $this->priceBasedOnCountryCmp->isActive() ) { $rule = $this->priceBasedOnCountryCmp->changeRuleCurrency($rule); } $currencySwitcher = $this->context->currencyController; if ($currencySwitcher->isCurrencyChanged()) { $rule = RuleTranslator::setCurrency($rule, $this->context->currencyController->getRate()); } $rule->setCurrency($this->context->currencyController->getCurrentCurrency()); $rules[] = apply_filters('adp_rule_loaded', $rule, $row); } return new RulesCollection($rules); } /** * @param Models\Rule $ruleData * * @return PersistentRule * @throws Exception */ protected function buildPersistentRule($ruleData) { $context = $this->context; /** @var PersistentRule $rule */ $rule = Factory::get("Core_Rule_PersistentRule"); if (isset($ruleData->id)) { $rule->setId($ruleData->id); } $rule->setTitle($ruleData->title); $rule->setEnabled($ruleData->enabled); if (isset($ruleData->additional['conditions_relationship'])) { $rule->setConditionsRelationship($ruleData->additional['conditions_relationship']); } if (isset($ruleData->additional['trigger_coupon_code'])) { $rule->setActivationCouponCode($ruleData->additional['trigger_coupon_code']); } if (isset($ruleData->additional['date_from'])) { $dateFrom = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_from'], new \DateTimeZone("UTC") ); if ( $dateFrom ) { $dateFrom->setTime(0, 0, 0); $rule->setDateFrom($dateFrom); } } if (isset($ruleData->additional['date_to'])) { $dateTo = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_to'], new \DateTimeZone("UTC") ); if ( $dateTo ) { $dateTo->setTime(23, 59, 59); $rule->setDateTo($dateTo); } } if (isset($ruleData->options['repeat'])) { $rule->setItemsCountLimit($ruleData->options['repeat']); } foreach ($ruleData->filters as $filterData) { $type = $filterData['type']; $method = $filterData['method'] ?? ""; $value = $filterData['value']; $filter = new Filter(); $filter->setType($type); $filter->setMethod($method); $filter->setValue($value); if(isset($filterData['excludes'])){ foreach ($filterData['excludes'] as $excludeFilterData) { if(isset($excludeFilterData['type']) && isset($excludeFilterData['value'])) { $excludeFilter = new SimpleFilter(); $excludeFilter->setType($excludeFilterData['type']) ->setValue($excludeFilterData['value']); $filter->addExcludeFilter($excludeFilter); } } } if (isset($filterData['product_exclude']['on_wc_sale'])) { $filter->setExcludeWcOnSale($filterData['product_exclude']['on_wc_sale'] === "1"); } if (isset($filterData['product_exclude']['already_affected'])) { $filter->setExcludeAlreadyAffected($filterData['product_exclude']['already_affected'] === "1"); } if (isset($filterData['product_exclude']['backorder'])) { $filter->setExcludeBackorder($filterData['product_exclude']['backorder'] === "1"); } $rule->addFilter($filter); } $this->installProductAdjustment($rule, $ruleData); $this->installRoleDiscounts($rule, $ruleData); $this->installFreeItems($rule, $ruleData); $this->installConditions($rule, $ruleData); $this->installLimits($rule, $ruleData); $this->installAdvertising($rule, $ruleData); $this->installConditionMessage($rule, $ruleData); return $rule; } /** * @param Models\Rule $ruleData * * @return NoItemRule */ protected function buildNoItemRule($ruleData) { /** @var NoItemRule $rule */ $rule = Factory::get("Core_Rule_NoItemRule"); if (isset($ruleData->id)) { $rule->setId($ruleData->id); } $rule->setTitle($ruleData->title); $rule->setEnabled($ruleData->enabled); $rule->setPriority($ruleData->priority); if (isset($ruleData->additional['conditions_relationship'])) { $rule->setConditionsRelationship($ruleData->additional['conditions_relationship']); } if (isset($ruleData->additional['trigger_coupon_code'])) { $rule->setActivationCouponCode($ruleData->additional['trigger_coupon_code']); } if (isset($ruleData->additional['date_from'])) { $dateFrom = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_from'], new \DateTimeZone("UTC") ); if ( $dateFrom ) { $dateFrom->setTime(0, 0, 0); $rule->setDateFrom($dateFrom); } } if (isset($ruleData->additional['date_to'])) { $dateTo = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_to'], new \DateTimeZone("UTC") ); if ( $dateTo ) { $dateTo->setTime(23, 59, 59); $rule->setDateTo($dateTo); } } $this->installCartAdjustments($rule, $ruleData); $this->installConditions($rule, $ruleData); $this->installLimits($rule, $ruleData); $this->installAdvertising($rule, $ruleData); return $rule; } /** * @param Models\Rule $ruleData * * @return PackageRule * @throws Exception */ protected function buildPackageRule($ruleData) { $context = $this->context; /** @var PackageRule $rule */ $rule = Factory::get("Core_Rule_PackageRule"); if (isset($ruleData->id)) { $rule->setId($ruleData->id); } $rule->setTitle($ruleData->title); $rule->setEnabled($ruleData->enabled); $rule->setPriority($ruleData->priority); if (isset($ruleData->additional['conditions_relationship'])) { $rule->setConditionsRelationship($ruleData->additional['conditions_relationship']); } if (isset($ruleData->additional['trigger_coupon_code'])) { $rule->setActivationCouponCode($ruleData->additional['trigger_coupon_code']); } if (isset($ruleData->additional['date_from'])) { $dateFrom = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_from'], new \DateTimeZone("UTC") ); if ( $dateFrom ) { $dateFrom->setTime(0, 0, 0); $rule->setDateFrom($dateFrom); } } if (isset($ruleData->additional['date_to'])) { $dateTo = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_to'], new \DateTimeZone("UTC") ); if ( $dateTo ) { $dateTo->setTime(23, 59, 59); $rule->setDateTo($dateTo); } } if (isset($ruleData->options['repeat'])) { $rule->setPackagesCountLimit($ruleData->options['repeat']); } if (isset($ruleData->options['apply_to'])) { $rule->setApplyFirstTo($ruleData->options['apply_to']); } foreach ($ruleData->filters as $filterData) { $item = $this->createRulePackage($filterData); $rule->addPackage($item); } $this->installProductAdjustment($rule, $ruleData); $this->installRoleDiscounts($rule, $ruleData); $this->installSortableProperties($rule, $ruleData); $this->installFreeItems($rule, $ruleData); $this->installCartAdjustments($rule, $ruleData); $this->installConditions($rule, $ruleData); $this->installLimits($rule, $ruleData); $this->installAdvertising($rule, $ruleData); $this->installConditionMessage($rule, $ruleData); return $rule; } /** * @param array $filterData * * @return PackageItem */ protected function createRulePackage($filterData) { $context = $this->context; $type = $filterData['type']; $method = $filterData['method'] ?? ""; $value = $filterData['value']; $qty = $filterData['qty']; $qtyEnd = isset($filterData['qty_end']) ? $filterData['qty_end'] : $qty; $item = new PackageItem(); $item->setQty($qty); $item->setQtyEnd($qtyEnd); $filter = new PackageItemFilter(); $filter->setType($type); $filter->setMethod($method); $filter->setValue($value); if(isset($filterData['excludes'])){ foreach ($filterData['excludes'] as $excludeFilterData) { if(isset($excludeFilterData['type']) && isset($excludeFilterData['value'])) { $excludeFilter = new SimpleFilter(); $excludeFilter->setType($excludeFilterData['type']) ->setValue($excludeFilterData['value']); $filter->addExcludeFilter($excludeFilter); } } } if (isset($filterData['product_exclude']['on_wc_sale'])) { $filter->setExcludeWcOnSale($filterData['product_exclude']['on_wc_sale'] === "1"); } if (isset($filterData['product_exclude']['already_affected'])) { $filter->setExcludeAlreadyAffected($filterData['product_exclude']['already_affected'] === "1"); } if (isset($filterData['product_exclude']['backorder'])) { $filter->setExcludeBackorder($filterData['product_exclude']['backorder'] === "1"); } if (isset($filterData['limitation'])) { $item->setLimitation($filterData['limitation']); } $item->addFilter($filter); return $item; } /** * @param Models\Rule $ruleData * * @return SingleItemRule * @throws Exception */ protected function buildSingleItemRule($ruleData) { $context = $this->context; /** @var SingleItemRule $rule */ $rule = Factory::get("Core_Rule_SingleItemRule"); if (isset($ruleData->id)) { $rule->setId($ruleData->id); } $rule->setTitle($ruleData->title); $rule->setEnabled($ruleData->enabled); $rule->setPriority($ruleData->priority); if (isset($ruleData->additional['conditions_relationship'])) { $rule->setConditionsRelationship($ruleData->additional['conditions_relationship']); } if (isset($ruleData->additional['trigger_coupon_code'])) { $rule->setActivationCouponCode($ruleData->additional['trigger_coupon_code']); } if (isset($ruleData->additional['date_from'])) { $dateFrom = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_from'], new \DateTimeZone("UTC") ); if ( $dateFrom ) { $dateFrom->setTime(0, 0, 0); $rule->setDateFrom($dateFrom); } } if (isset($ruleData->additional['date_to'])) { $dateTo = \DateTime::createFromFormat( "Y-m-d", $ruleData->additional['date_to'], new \DateTimeZone("UTC") ); if ( $dateTo ) { $dateTo->setTime(23, 59, 59); $rule->setDateTo($dateTo); } } if (isset($ruleData->options['repeat'])) { $rule->setItemsCountLimit($ruleData->options['repeat']); } if (isset($ruleData->options['apply_to'])) { $rule->setApplyFirstTo($ruleData->options['apply_to']); } foreach ($ruleData->filters as $filterData) { $type = $filterData['type']; $method = $filterData['method'] ?? 'in_list'; //for persistent rules where default method is in_list $value = $filterData['value']; $filter = new Filter(); $filter->setType($type); $filter->setMethod($method); $filter->setValue($value); if(isset($filterData['excludes'])){ foreach ($filterData['excludes'] as $excludeFilterData) { if(isset($excludeFilterData['type']) && isset($excludeFilterData['value'])) { $excludeFilter = new SimpleFilter(); $excludeFilter->setType($excludeFilterData['type']) ->setValue($excludeFilterData['value']); $filter->addExcludeFilter($excludeFilter); } } } if (isset($filterData['product_exclude']['on_wc_sale'])) { $filter->setExcludeWcOnSale($filterData['product_exclude']['on_wc_sale'] === "1"); } if (isset($filterData['product_exclude']['already_affected'])) { $filter->setExcludeAlreadyAffected($filterData['product_exclude']['already_affected'] === "1"); } if (isset($filterData['product_exclude']['backorder'])) { $filter->setExcludeBackorder($filterData['product_exclude']['backorder'] === "1"); } $rule->addFilter($filter); } $this->installProductAdjustment($rule, $ruleData); $this->installRoleDiscounts($rule, $ruleData); $this->installSortableProperties($rule, $ruleData); $this->installFreeItems($rule, $ruleData); $this->installCartAdjustments($rule, $ruleData); $this->installConditions($rule, $ruleData); $this->installLimits($rule, $ruleData); $this->installAdvertising($rule, $ruleData); $this->installConditionMessage($rule, $ruleData); return $rule; } /** * @param Rule $rule * @param Models\Rule $ruleData * * @throws Exception */ protected function installProductAdjustment(&$rule, $ruleData) { $replaceDiscount = isset($ruleData->additional['is_replace']) ? $ruleData->additional['is_replace'] === 'on' : false; $replaceDiscountName = isset($ruleData->additional['replace_name']) ? $ruleData->additional['replace_name'] : ""; if (isset($ruleData->bulkAdjustments['ranges'])) {//check rule for having bulk adj $bulkData = $ruleData->bulkAdjustments; $qty_based = $bulkData['qty_based']; $measurement = $bulkData['measurement'] ?? null; if ($rule instanceof SingleItemRule) { if ($qty_based === 'all') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_DEFAULT; } elseif ($qty_based === 'total_qty_in_cart') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_ALL_ITEMS_IN_CART; } elseif ($qty_based === 'product_categories') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_PRODUCT_CATEGORIES; } elseif ($qty_based === 'product_selected_categories') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_PRODUCT_SELECTED_CATEGORIES; } elseif ($qty_based === 'selected_products') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_PRODUCT_SELECTED_PRODUCTS; } elseif ($qty_based === 'sets') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_DEFAULT; } elseif ($qty_based === 'product') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_PRODUCT; } elseif ($qty_based === 'variation') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_VARIATION; } elseif ($qty_based === 'cart_position') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_CART_POSITIONS; } elseif ($qty_based === 'meta_data') { $qty_based = SingleItemRule\ProductsRangeAdjustments::GROUP_BY_META_DATA; } $productAdjustment = new SingleItemRule\ProductsRangeAdjustments( $this->context, $bulkData['type'], $qty_based, new BulkMeasurementEnum($measurement) ); } elseif ($rule instanceof PackageRule) { if ($qty_based === 'all') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_DEFAULT; } elseif ($qty_based === 'total_qty_in_cart') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_ALL_ITEMS_IN_CART; } elseif ($qty_based === 'product_categories') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_PRODUCT_CATEGORIES; } elseif ($qty_based === 'product_selected_categories') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_PRODUCT_SELECTED_CATEGORIES; } elseif ($qty_based === 'selected_products') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_PRODUCT_SELECTED_PRODUCTS; } elseif ($qty_based === 'sets') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_SETS; } elseif ($qty_based === 'product') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_PRODUCT; } elseif ($qty_based === 'variation') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_VARIATION; } elseif ($qty_based === 'cart_position') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_CART_POSITIONS; } elseif ($qty_based === 'meta_data') { $qty_based = PackageRule\PackageRangeAdjustments::GROUP_BY_META_DATA; } $productAdjustment = new PackageRule\PackageRangeAdjustments( $this->context, $bulkData['type'], $qty_based, new BulkMeasurementEnum($measurement) ); } else { return; } if (isset($bulkData['selected_products']) && is_array($bulkData['selected_products'])) { $productAdjustment->setSelectedProductIds($bulkData['selected_products']); } if (isset($bulkData['selected_categories']) && is_array($bulkData['selected_categories'])) { $productAdjustment->setSelectedCategoryIds($bulkData['selected_categories']); } $rangeDiscounts = array(); foreach ($bulkData['ranges'] as $range) { if ($productAdjustment instanceof SingleItemRule\ProductsRangeAdjustments) { $bulkData['discount_type'] = str_replace('set_', '', $bulkData['discount_type']); if (strpos($bulkData['discount_type'], 'range') === false) { if ($bulkData['discount_type'] === 'price__fixed') { if ($range['value'] === '') { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE, $range['value']); } } elseif ($bulkData['discount_type'] === 'discount__amount') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT, $range['value']); } elseif ($bulkData['discount_type'] === 'discount__expression_price') { $discount = new Discount($this->context, Discount::TYPE_EXPRESSION_PRICE, $range['value']); } else { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, $range['value']); } } else { if ($bulkData['discount_type'] === 'range_price__fixed') { if ( $range['value'] === '' ) { $discount = new DiscountForRange($this->context, DiscountForRange::TYPE_PERCENTAGE, 0); } else { $discount = new DiscountForRange($this->context, DiscountForRange::TYPE_FIXED_VALUE, $range['value']); } } elseif ($bulkData['discount_type'] === 'range_discount__amount') { $discount = new DiscountForRange($this->context, DiscountForRange::TYPE_AMOUNT, $range['value']); } else { $discount = new DiscountForRange($this->context, DiscountForRange::TYPE_PERCENTAGE, $range['value']); } } } elseif ($productAdjustment instanceof PackageRule\PackageRangeAdjustments) { if (strpos($bulkData['discount_type'], 'set') === false) { if ($bulkData['discount_type'] === 'price__fixed') { if ( $range['value'] === '' ) { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE, $range['value']); } } elseif ($bulkData['discount_type'] === 'discount__amount') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT, $range['value']); } else { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, $range['value']); } } else { if ($bulkData['discount_type'] === 'set_price__fixed') { if ( $range['value'] === '' ) { $discount = new SetDiscount($this->context, SetDiscount::TYPE_PERCENTAGE, 0); } else { $discount = new SetDiscount($this->context, SetDiscount::TYPE_FIXED_VALUE, $range['value']); } } elseif ($bulkData['discount_type'] === 'set_discount__amount') { $discount = new SetDiscount($this->context, SetDiscount::TYPE_AMOUNT, $range['value']); } else { $discount = new SetDiscount($this->context, SetDiscount::TYPE_PERCENTAGE, $range['value']); } } } else { return; } $rangeDiscounts[] = new RangeDiscount($range['from'], $range['to'], $discount); } /** * Fixed: range discount doesn't work if ending values are empty * e.g. * 1 - INF * 2 - INF * 3 - INF */ foreach ($rangeDiscounts as $index => &$rangeDiscount) { if ($rangeDiscount->getTo() === INF && isset($rangeDiscounts[$index + 1])) { $nextItem = $rangeDiscounts[$index + 1]; $rangeDiscount = new RangeDiscount( $rangeDiscount->getFrom(), $nextItem->getFrom() - 1, $rangeDiscount->getData() ); } } $productAdjustment->setRanges($rangeDiscounts); $productAdjustment->setReplaceAsCartAdjustment($replaceDiscount); $productAdjustment->setReplaceCartAdjustmentCode($replaceDiscountName); if (isset($bulkData['table_message'])) { $productAdjustment->setPromotionalMessage($bulkData['table_message']); } $rule->installProductRangeAdjustmentHandler($productAdjustment); } if (isset($ruleData->productAdjustments, $ruleData->productAdjustments['type'])) { $prodAdjData = $ruleData->productAdjustments; $type = $prodAdjData['type']; if ($type === 'total' and isset($prodAdjData['total']['type'])) {//check rule for having total adj $value = $prodAdjData['total']['value']; $discountType = $prodAdjData['total']['type']; if ($discountType === 'price__fixed') { if ( $value === '' ) { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE, $value); } } elseif ($discountType === 'price__fixed_per_item') { if ( $value === '' ) { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE_PER_ITEM, $value); } } elseif ($discountType === 'discount__percentage') { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, $value); } elseif ($discountType === 'discount__amount') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT, $value); } elseif ($discountType === 'discount__amount_per_item') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT_PER_ITEM, $value); }elseif ($discountType === 'discount__expression_price') { $discount = new Discount($this->context, Discount::TYPE_EXPRESSION_PRICE, $value); } else { return; } if ($rule instanceof SingleItemRule) { $productAdjustment = new SingleItemRule\ProductsAdjustment($discount); } elseif ($rule instanceof PackageRule) { $productAdjustment = new PackageRule\ProductsAdjustmentTotal($discount); } else { return; } $productAdjustment->setReplaceAsCartAdjustment($replaceDiscount); $productAdjustment->setReplaceCartAdjustmentCode($replaceDiscountName); if (isset($prodAdjData['max_discount_sum']) && is_numeric($prodAdjData['max_discount_sum'])) { $productAdjustment->setMaxAvailableAmount((float)$prodAdjData['max_discount_sum']); } if (isset($prodAdjData['split_discount_by'])) { if ($productAdjustment instanceof PackageRule\ProductsAdjustmentTotal) { try { $splitDiscount = new ProductAdjustmentSplitDiscount($prodAdjData['split_discount_by']); } catch (UnexpectedValueException $e) { $splitDiscount = ProductAdjustmentSplitDiscount::ITEM_COST(); } $productAdjustment->setSplitDiscount($splitDiscount); } } $rule->installProductAdjustmentHandler($productAdjustment); } elseif ($type === 'split' and isset($prodAdjData['split'][0]['type'])) {//check rule for having split adj if ($rule instanceof SingleItemRule) { return; } $discounts = array(); foreach ($prodAdjData[$type] as $split_discount) { $value = $split_discount['value']; $discountType = $split_discount['type']; if ($discountType === 'price__fixed') { if ( $value === '' ) { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE, $value); } } elseif ($discountType === 'price__fixed_per_item') { if ( $value === '' ) { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, 0); } else { $discount = new Discount($this->context, Discount::TYPE_FIXED_VALUE_PER_ITEM, $value); } } elseif ($discountType === 'discount__amount') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT, $value); } elseif ($discountType === 'discount__amount_per_item') { $discount = new Discount($this->context, Discount::TYPE_AMOUNT_PER_ITEM, $value); } else { $discount = new Discount($this->context, Discount::TYPE_PERCENTAGE, $value); } $discounts[] = $discount; } $productAdjustment = new PackageRule\ProductsAdjustmentSplit($discounts); $productAdjustment->setReplaceAsCartAdjustment($replaceDiscount); $productAdjustment->setReplaceCartAdjustmentCode($replaceDiscountName); if (isset($prodAdjData['max_discount_sum']) && is_numeric($prodAdjData['max_discount_sum'])) { $productAdjustment->setMaxAvailableAmount((float)$prodAdjData['max_discount_sum']); } if (isset($prodAdjData['split_discount_by'])) { try { $splitDiscount = new ProductAdjustmentSplitDiscount($prodAdjData['split_discount_by']); } catch (UnexpectedValueException $e) { $splitDiscount = ProductAdjustmentSplitDiscount::ITEM_COST(); } $productAdjustment->setSplitDiscount($splitDiscount); } $rule->installProductAdjustmentHandler($productAdjustment); } } } /** * @param SingleItemRule|PackageRule $rule * @param Models\Rule $ruleData */ protected function installRoleDiscounts(&$rule, $ruleData) { $replaceDiscount = isset($ruleData->additional['is_replace']) ? $ruleData->additional['is_replace'] === 'on' : false; $replaceDiscountName = isset($ruleData->additional['replace_name']) ? $ruleData->additional['replace_name'] : ""; if ( ! isset($ruleData->roleDiscounts['rows'])) { return; } $roleDiscounts = array(); foreach ($ruleData->roleDiscounts['rows'] as $row) { $type = isset($row['discount_type']) ? $row['discount_type'] : null; $value = isset($row['discount_value']) ? $row['discount_value'] : null; $roles = isset($row['roles']) ? $row['roles'] : array(); if ( ! isset($type, $value)) { continue; } if ($type === 'discount__percentage') { $type = Discount::TYPE_PERCENTAGE; } elseif ($type === 'discount__amount') { $type = Discount::TYPE_AMOUNT; } elseif ($type === 'discount__expression_price') { $type = Discount::TYPE_EXPRESSION_PRICE; }elseif ($type === 'price__fixed') { if ( $value === '' ) { $type = Discount::TYPE_PERCENTAGE; $value = 0; } else { $type = Discount::TYPE_FIXED_VALUE; } } $roleDiscount = new RoleDiscount(new Discount($this->context, $type, $value)); $roleDiscount->setReplaceAsCartAdjustment($replaceDiscount); $roleDiscount->setReplaceCartAdjustmentCode($replaceDiscountName); $roleDiscount->setRoles($roles); $roleDiscounts[] = $roleDiscount; } $rule->setRoleDiscounts($roleDiscounts); } /** * @param Rule $rule * @param Models\Rule $ruleData */ protected function installConditions(&$rule, $ruleData) { $conditionsLoader = $this->conditionsLoader; if ( ! empty($ruleData->conditions)) { foreach ($ruleData->conditions as $conditionData) { try { $rule->addCondition($conditionsLoader->build($conditionData)); } catch (Exception $exception) { $this->context->handleError($exception); } } } } /** * @param Rule $rule * @param Models\Rule $ruleData */ protected function installLimits(&$rule, $ruleData) { $converter = $this->optionsConverter; $limitsLoader = $this->limitsLoader; if ( ! empty($ruleData->limits)) { foreach ($ruleData->limits as $limitData) { try { $limitData = $converter::convertLimit($limitData); $rule->addLimit($limitsLoader->build($limitData)); } catch (Exception $exception) { $this->context->handleError($exception); } } } } /** * @param Rule $rule * @param Models\Rule $ruleData */ protected function installCartAdjustments(&$rule, $ruleData) { $converter = $this->optionsConverter; $cartAdjLoader = $this->cartAdjLoader; if ( ! empty($ruleData->cartAdjustments)) { foreach ($ruleData->cartAdjustments as $cartAdjData) { try { $cartAdjData = $converter::convertCartAdj($cartAdjData); $rule->addCartAdjustment($cartAdjLoader->build($cartAdjData)); } catch (Exception $exception) { $this->context->handleError($exception); } } } } /** * @param SingleItemRule|PackageRule|PersistentRule $rule * @param Models\Rule $ruleData */ protected function installFreeItems(&$rule, $ruleData) { $context = $this->context; // for Persistence rules if ( method_exists($rule, 'setReplaceItemGifts') && method_exists($rule, 'setReplaceItemGiftsCode')) { $replaceFreeProducts = isset($ruleData->additional['is_replace_free_products_with_discount']) ? $ruleData->additional['is_replace_free_products_with_discount'] === 'on' : false; $rule->setReplaceItemGifts($replaceFreeProducts); $replaceFreeProductsName = isset($ruleData->additional['free_products_replace_name']) ? $ruleData->additional['free_products_replace_name'] : ""; $rule->setReplaceItemGiftsCode($replaceFreeProductsName); } $rule = $this->setGiftItemStrategy($rule, $ruleData); $values = isset($ruleData->getProducts['value']) ? $ruleData->getProducts['value'] : array(); $gifts = array(); foreach ($values as $value) { $qty = floatval($value['qty']); $giftValues = isset($value['value']) ? array_map('intval', $value['value']) : array(); $giftMode = isset($value['gift_mode']) ? $value['gift_mode'] : "giftable_products"; $gift = new Gift(); if ($giftMode === "use_product_from_filter") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::CLONE_ADJUSTED)))); $gift->setMode(GiftModeEnum::USE_PRODUCT_FROM_FILTER()); } elseif ($giftMode === "use_only_first_product_from_filter") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::CLONE_ADJUSTED_FIRST)))); $gift->setMode(GiftModeEnum::USE_ONLY_FIRST_PRODUCT_FROM_FILTER()); } elseif ($giftMode === "giftable_products") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::PRODUCT))->setValues($giftValues))); $gift->setMode(GiftModeEnum::GIFTABLE_PRODUCTS()); } elseif ($giftMode === "giftable_products_in_rotation") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::PRODUCT))->setValues($giftValues))); $gift->setMode(GiftModeEnum::GIFTABLE_PRODUCTS_ROTATION()); } elseif ($giftMode === "giftable_products_in_random") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::PRODUCT))->setValues($giftValues))); $gift->setMode(GiftModeEnum::GIFTABLE_PRODUCTS_IN_RANDOM()); } elseif ($giftMode === "allow_to_choose") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::PRODUCT))->setValues($giftValues))); $gift->setMode(GiftModeEnum::ALLOW_TO_CHOOSE()); } elseif ($giftMode === "allow_to_choose_from_product_cat") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::CATEGORY))->setValues($giftValues))); $gift->setMode(GiftModeEnum::ALLOW_TO_CHOOSE_FROM_PRODUCT_CAT()); } elseif ($giftMode === "require_to_choose") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::PRODUCT))->setValues($giftValues))); $gift->setMode(GiftModeEnum::REQUIRE_TO_CHOOSE()); } elseif ($giftMode === "require_to_choose_from_product_cat") { $gift->setChoices(array((new GiftChoice())->setType(new GiftChoiceTypeEnum(GiftChoiceTypeEnum::CATEGORY))->setValues($giftValues))); $gift->setMode(GiftModeEnum::REQUIRE_TO_CHOOSE_FROM_PRODUCT_CAT()); } $gift->setQty($qty); $gifts[] = $gift; } $rule->setItemGifts($gifts); } /** * @param SingleItemRule|PackageRule $rule * @param Models\Rule $ruleData */ protected function installSortableProperties(&$rule, $ruleData) { if (isset($ruleData->sortableBlocksPriority)) { $rule->setSortableBlocksPriority($ruleData->sortableBlocksPriority); } if (isset($ruleData->additional['sortable_apply_mode'])) { $rule->setSortableApplyMode($ruleData->additional['sortable_apply_mode']); } if (isset($ruleData->roleDiscounts['dont_apply_bulk_if_roles_matched'])) { $rule->setDontApplyBulkIfRolesMatched($ruleData->roleDiscounts['dont_apply_bulk_if_roles_matched'] === "1"); } } /** * @param Rule $rule * @param Models\Rule $ruleData */ protected function installAdvertising(&$rule, $ruleData) { if (isset($ruleData->advertising['enabled_timer'])) { $rule->setEnabledTimer($ruleData->advertising['enabled_timer']); } if (isset($ruleData->advertising['timer_message'])) { $rule->setTimerMessage($ruleData->advertising['timer_message']); } if (isset($ruleData->advertising['discount_message'])) { $rule->setDiscountMessage($ruleData->advertising['discount_message']); } if (isset($ruleData->advertising['discount_message_cart_item'])) { $rule->setDiscountMessageCartItem($ruleData->advertising['discount_message_cart_item']); } if (isset($ruleData->advertising['long_discount_message'])) { $rule->setLongDiscountMessage($ruleData->advertising['long_discount_message']); } if (isset($ruleData->advertising['sale_badge'])) { $rule->setSaleBadge($ruleData->advertising['sale_badge']); } if (isset($ruleData->advertising['message_notice_discount'])) { $rule->setMessageNoticeDiscount($ruleData->advertising['message_notice_discount']); } if (isset($ruleData->advertising['message_notice_coupon_not_apply'])) { $rule->setMessageNoticeCouponNotApply($ruleData->advertising['message_notice_coupon_not_apply']); } } /** * @param SingleItemRule|PackageRule $rule * @param Models\Rule $ruleData * * @return SingleItemRule|PackageRule */ protected function setGiftItemStrategy(&$rule, $ruleData) { if ( ! isset($ruleData->getProducts['repeat'])) { return $rule; } $repeat = $ruleData->getProducts['repeat']; if ($repeat === 'based_on_subtotal') { $rule->setItemGiftStrategy($rule::BASED_ON_SUBTOTAL_EXCL_TAX_STRATEGY); if (isset($ruleData->getProducts['repeat_subtotal'])) { $rule->setItemGiftSubtotalDivider($ruleData->getProducts['repeat_subtotal']); } } elseif ($repeat === 'based_on_subtotal_inc') { $rule->setItemGiftStrategy($rule::BASED_ON_SUBTOTAL_INCL_TAX_STRATEGY); if (isset($ruleData->getProducts['repeat_subtotal'])) { $rule->setItemGiftSubtotalDivider($ruleData->getProducts['repeat_subtotal']); } } elseif (is_numeric($repeat)) { $rule->setItemGiftStrategy($rule::BASED_ON_LIMIT_STRATEGY); $attemptCount = (int)$ruleData->getProducts['repeat']; $attemptCount = $attemptCount !== -1 ? $attemptCount : INF; $rule->setItemGiftLimit($attemptCount); } return $rule; } protected function installConditionMessage(&$rule, $ruleData) { if (isset($ruleData->conditionMessage, $ruleData->conditionMessage['type'])) { $conditionMessageData = $ruleData->conditionMessage; $beginningMessage = $conditionMessageData['beginning_message']; $endMessage = $conditionMessageData['end_message']; $type = $conditionMessageData['type']; if ($type === 'total' and isset($conditionMessageData['total']['message'])) {//check rule for having total adj $message = $conditionMessageData['total']['message']; if ($rule instanceof SingleItemRule) { $conditionMessage = new SingleItemRule\ConditionMessage($beginningMessage, $message, $endMessage); } elseif ($rule instanceof PackageRule) { $conditionMessage = new PackageRule\ConditionMessageTotal($beginningMessage, $message, $endMessage); } else { return; } $rule->installConditionMessageHandler($conditionMessage); } elseif ($type === 'split' and isset($conditionMessageData['split'][0]['message'])) {//check rule for having split adj if ($rule instanceof SingleItemRule) { return; } $messages = $conditionMessageData['split']; $conditionMessage = new PackageRule\ConditionMessageSplit($beginningMessage, $messages, $endMessage); $rule->installConditionMessageHandler($conditionMessage); } } } }