context = adp_context(); $rule = $contextOrRule instanceof NoItemRule ? $contextOrRule : $deprecated; if ( ! ($rule instanceof NoItemRule)) { $this->context->handleError(new Exception("Wrong rule type")); } $this->rule = clone $rule; $this->originalRule = $rule; $this->conditionsCheckStrategy = new ConditionsCheckStrategy($rule); $this->limitsCheckStrategy = new LimitsCheckStrategy($rule); $this->cartAdjustmentsApplyStrategy = new CartAdjustmentsApplyStrategy($rule); $this->ruleTimer = new RuleTimer($rule); $this->ruleUsedStock = new ProductStockController(); $this->giftStrategy = Factory::get('Core_RuleProcessor_GiftStrategy', $rule, $this->ruleUsedStock); $this->autoAddStrategy = Factory::get('Core_RuleProcessor_AutoAddStrategy', $rule, $this->ruleUsedStock); $this->activationTriggerStrategy = new ActivationTriggerStrategy($rule); } public function withContext(Context $context) { $this->context = $context; } public function getStatus() { return $this->status; } /** * @return NoItemRule */ public function getRule() { return $this->originalRule; } public function applyToCart($cart) { $this->ruleTimer->start(); global $wp_filter; $current_wp_filter = $wp_filter; try { $this->process($cart); } catch (RuleExecutionTimeout $e) { $this->status = self::STATUS_OUT_OF_TIME; $this->ruleTimer->handleOutOfTime(); } $wp_filter = $current_wp_filter; $this->ruleTimer->finish(); return true; } /** * @param Cart $cart * * @throws RuleExecutionTimeout */ protected function process($cart) { $this->status = self::STATUS_STARTED; $this->rule = apply_filters('adp_before_apply_rule', $this->rule, $this, $cart); if ( ! apply_filters('adp_is_apply_rule', true, $this->rule, $this, $cart)) { $this->status = self::STATUS_DISABLED_WITH_FORCE; return; } if ( ! $this->activationTriggerStrategy->canBeAppliedByDate($cart)) { $this->status = self::STATUS_DISABLED_BY_DATE; return; } if ( ! $this->activationTriggerStrategy->canBeAppliedUsingCouponCode($cart)) { $this->status = self::STATUS_DISABLED_BY_COUPON_CODE_TRIGGER; return; } if ( ! $this->isRuleMatchedCart($cart)) { return; } $this->ruleTimer->checkExecutionTime(); $this->addGifts($cart); $this->ruleTimer->checkExecutionTime(); $this->addAutoAdds($cart); $this->ruleTimer->checkExecutionTime(); $this->applyCartAdjustments($cart); $this->status = self::STATUS_SUCCESSFULLY_COMPLETED; } /** * @param Cart $cart * * @return bool */ public function isRuleMatchedCart($cart) { if ( ! $this->checkLimits($cart)) { $this->status = $this::STATUS_LIMITS_NOT_PASSED; return false; } if ( ! $this->checkConditions($cart)) { $this->status = $this::STATUS_CONDITIONS_NOT_PASSED; return false; } return true; } /** * @param Cart $cart * * @return bool */ protected function checkLimits($cart) { return $this->limitsCheckStrategy->check($cart); } /** * @param Cart $cart * * @return bool */ protected function checkConditions($cart) { return $this->conditionsCheckStrategy->check($cart); } /** * @param Cart $cart */ protected function applyCartAdjustments($cart) { $this->cartAdjustmentsApplyStrategy->applyToCart($cart); } /** * @param Cart $cart */ protected function addGifts($cart) { if ( ! $this->giftStrategy->canGift()) { return; } $this->giftStrategy->addGifts($cart); } /** * @param Cart $cart */ protected function addAutoAdds($cart) { if ( ! $this->autoAddStrategy->canAutoAdd()) { return; } $this->autoAddStrategy->addAutoAdds($cart); } /** * @return float */ public function getLastExecTime() { return $this->ruleTimer->getLastExecTime(); } /** * @param Cart $cart * @param WC_Product $product * @param bool $checkConditions * * @return bool */ public function isProductMatched($cart, $product, $checkConditions = false) { if ( ! ($product instanceof WC_Product)) { return false; } if ( ! $this->checkLimits($cart)) { return false; } if ($checkConditions && ! $this->checkConditions($cart)) { return false; } return true; } }