context = adp_context(); $this->priceFunctions = new PriceFunctions(); $this->subscriptionCmp = new WcSubscriptionsCmp(); } public function withContext(Context $context) { $this->context = $context; } public function register() { // 10000 for WPC bundles add_filter('woocommerce_cart_item_price', array($this, 'wcCartItemPrice'), 10000, 3); add_filter('woocommerce_cart_item_subtotal', array($this, 'wcCartItemSubtotal'), 10000, 3); } /** * @param string $price formatted price after wc_price() * @param array $cartItem * @param string $cartItemKey * * @return string */ public function wcCartItemPrice($price, $cartItem, $cartItemKey) { if (!is_array($cartItem)) { return $price; } if ($this->context->getOption('show_striked_prices')) { $price = $this->wcMainCartItemPrice($price, $cartItem, $cartItemKey); } return $price; } /** * @param string $price formatted price after wc_price() * @param array $cartItem * @param string $cartItemKey * * @return string */ public function wcCartItemSubtotal($price, $cartItem, $cartItemKey) { if (!is_array($cartItem)) { return $price; } if ($this->context->getOption('show_striked_prices')) { $price = $this->wcMainCartItemSubtotal($price, $cartItem, $cartItemKey); } return $price; } /** * @param string $price formatted price after wc_price() * @param array $cartItem * @param string $cartItemKey * * @return string */ protected function wcMainCartItemPrice($price, $cartItem, $cartItemKey) { if ($this->subscriptionCmp->isSetFreeTrial($cartItem)) { return $price; } $context = $this->context; $facade = new WcCartItemFacade($context, $cartItem, $cartItemKey); $subsCmp = new WcSubscriptionsCmp($context); $newPriceHtml = $price; $displayPricesIncludingTax = 'incl' === $context->getTaxDisplayCartMode(); $oldPrice = $this->getOriginalPriceToDisplayForCartItem($facade, $displayPricesIncludingTax); $newPrice = $this->getCalculatedPriceToDisplayForCartItem($facade, $displayPricesIncludingTax); $signUpFee = $subsCmp->isSubscriptionProduct($facade->getProduct()) ? (float)$subsCmp->maybeGetSignUpFee($facade->getProduct()) : null; if (!is_null($signUpFee) && $signUpFee > 0) { $oldPrice -= $signUpFee; $newPrice -= $signUpFee; } if ($oldPrice === null || $newPrice === null) { return $price; } $newPrice = apply_filters('wdp_cart_item_new_price', $newPrice, $cartItem, $cartItemKey); $oldPrice = apply_filters('wdp_cart_item_initial_price', $oldPrice, $cartItem, $cartItemKey); if (is_numeric($newPrice) && is_numeric($oldPrice)) { $oldPriceRounded = round($oldPrice, $this->context->priceSettings->getDecimals()); $newPriceRounded = round($newPrice, $this->context->priceSettings->getDecimals()); if ($newPriceRounded < $oldPriceRounded) { $priceHtml = $this->priceFunctions->formatSalePrice($oldPrice, $newPrice); if ($subsCmp->isSubscriptionProduct($facade->getProduct())) { $priceHtml = $subsCmp->maybeAddSubsTail($facade->getProduct(), $priceHtml); } } elseif ($newPriceRounded === $oldPriceRounded) { $priceHtml = $this->priceFunctions->format($oldPrice); if ($subsCmp->isSubscriptionProduct($facade->getProduct())) { $priceHtml = $subsCmp->maybeAddSubsTail($facade->getProduct(), $priceHtml); } } else { $priceHtml = $newPriceHtml; } } else { $priceHtml = $newPriceHtml; } return apply_filters("adp_cart_item_price_html",$priceHtml, $newPrice, $oldPrice); } /** * @param string $price formatted price after wc_price() * @param array $cartItem * @param string $cartItemKey * * @return string */ protected function wcMainCartItemSubtotal($price, $cartItem, $cartItemKey) { if ($this->subscriptionCmp->isSetFreeTrial($cartItem)) { return $price; } $context = $this->context; $facade = new WcCartItemFacade($context, $cartItem, $cartItemKey); $containerCmp = $this->context->getContainerCompatibilityManager()->getCompatibilityFromPartOfContainerFacade($facade); if ($containerCmp && ! $containerCmp->adaptContainerPartCartItem($facade)->isPricedIndividually()) { return $price; } $subsCmp = new WcSubscriptionsCmp($context); $newPriceHtml = $price; $displayPricesIncludingTax = 'incl' === $context->getTaxDisplayCartMode(); $oldPrice = $this->getOriginalPriceToDisplayForCartItem($facade, $displayPricesIncludingTax); $newPrice = $this->getCalculatedPriceToDisplayForCartItem($facade, $displayPricesIncludingTax); $signUpFee = $subsCmp->isSubscriptionProduct($facade->getProduct()) ? (float)$subsCmp->maybeGetSignUpFee($facade->getProduct()) : null; if (!is_null($signUpFee) && $signUpFee > 0) { $oldPrice -= $signUpFee; $newPrice -= $signUpFee; } $newPrice *= $facade->getQty(); $oldPrice *= $facade->getQty(); $newPrice = apply_filters('wdp_cart_item_subtotal', $newPrice, $cartItem, $cartItemKey); $oldPrice = apply_filters('wdp_cart_item_initial_subtotal', $oldPrice, $cartItem, $cartItemKey); if (is_numeric($newPrice) && is_numeric($oldPrice)) { $oldPriceRounded = round($oldPrice, $this->context->priceSettings->getDecimals()); $newPriceRounded = round($newPrice, $this->context->priceSettings->getDecimals()); if ($newPriceRounded < $oldPriceRounded) { $priceHtml = $this->priceFunctions->formatSalePrice($oldPrice, $newPrice); if ($displayPricesIncludingTax) { if (!$context->getIsPricesIncludeTax() && $facade->getExactSubtotalTax() > 0) { $priceHtml .= ' ' . WC()->countries->inc_tax_or_vat() . ''; } } else { if ($context->getIsPricesIncludeTax() && $facade->getExactSubtotalTax() > 0) { $priceHtml .= ' ' . WC()->countries->ex_tax_or_vat() . ''; } } if ($subsCmp->isSubscriptionProduct($facade->getProduct())) { $priceHtml = $subsCmp->maybeAddSubsTail($facade->getProduct(), $priceHtml); } } elseif ($newPriceRounded === $oldPriceRounded) { $priceHtml = $this->priceFunctions->format($oldPrice); if ($subsCmp->isSubscriptionProduct($facade->getProduct())) { $priceHtml = $subsCmp->maybeAddSubsTail($facade->getProduct(), $priceHtml); } } else { $priceHtml = $newPriceHtml; } } else { $priceHtml = $newPriceHtml; } return apply_filters("adp_cart_item_subtotal_html",$priceHtml, $newPrice, $oldPrice); } protected function getOriginalPriceToDisplayForCartItem(WcCartItemFacade $facade, bool $inclTax): ?float { $context = $this->context; $useRegularPriceForOriginalPrice = $context->getOption('regular_price_for_striked_price'); if ($facade->isContainerType()) { $parentPriceType = $facade->getContainerPriceType(); if ($parentPriceType === null) { return null; } if ($parentPriceType->equals(ContainerPriceTypeEnum::FIXED())) { if ($inclTax) { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax() + $facade->getRegularPriceTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax() + $facade->getOriginalPriceTax(); } } else { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax(); } } } elseif ($parentPriceType->equals(ContainerPriceTypeEnum::BASE_PLUS_SUM_OF_SUB_ITEMS())) { $children = array_map(function ($key) { return new WcCartItemFacade(WC()->cart->cart_contents[$key], $key); }, $facade->getContainerChildrenHashes()); if ($inclTax) { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax() + $facade->getRegularPriceTax(); if(!apply_filters('adp_true_bundle_individ_price', false)) { $originalPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return ($child->getRegularPriceWithoutTax() + $child->getRegularPriceTax()) * $child->getQty() / $facade->getQty(); } else { return 0.0; } }, $children) ); } } else { $originalPrice = $facade->getOriginalPriceWithoutTax() + $facade->getOriginalPriceTax(); if(!apply_filters('adp_true_bundle_individ_price', false)) { $originalPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return ($child->getOriginalPriceWithoutTax() + $child->getOriginalPriceTax()) * $child->getQty() / $facade->getQty(); } else { return 0.0; } }, $children) ); } } } else { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax(); if(!apply_filters('adp_true_bundle_individ_price', false)) { $originalPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return $child->getRegularPriceWithoutTax() * $child->getQty() / $facade->getQty(); } else { return 0.0; } }, $children) ); } } else { $originalPrice = $facade->getOriginalPriceWithoutTax(); if(!apply_filters('adp_true_bundle_individ_price', false)) { $originalPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return $child->getOriginalPriceWithoutTax() * $child->getQty() / $facade->getQty(); } else { return 0.0; } }, $children) ); } } } } else { return null; } } elseif ($facade->isContaineredType()) { $parentPriceType = $facade->getParentContainerPriceType(); if ($parentPriceType === null) { return null; } if ($parentPriceType->equals(ContainerPriceTypeEnum::FIXED())) { return null; // do nothing } elseif ($parentPriceType->equals(ContainerPriceTypeEnum::BASE_PLUS_SUM_OF_SUB_ITEMS())) { if ($inclTax) { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax() + $facade->getRegularPriceTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax() + $facade->getOriginalPriceTax(); } } else { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax(); } } } else { return null; } } else { if ($inclTax) { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax() + $facade->getRegularPriceTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax() + $facade->getOriginalPriceTax(); } } else { if ($useRegularPriceForOriginalPrice) { $originalPrice = $facade->getRegularPriceWithoutTax(); } else { $originalPrice = $facade->getOriginalPriceWithoutTax(); } } } return $originalPrice; } protected function getCalculatedPriceToDisplayForCartItem(WcCartItemFacade $facade, bool $inclTax): ?float { $context = $this->context; if ($facade->isContainerType()) { $parentPriceType = $facade->getContainerPriceType(); if ($parentPriceType === null) { return null; } if ($parentPriceType->equals(ContainerPriceTypeEnum::FIXED())) { if ($inclTax) { $calculatedPrice = ($facade->getSubtotal() + $facade->getExactSubtotalTax()) / $facade->getQty(); } else { $calculatedPrice = $facade->getSubtotal() / $facade->getQty(); } } elseif ($parentPriceType->equals(ContainerPriceTypeEnum::BASE_PLUS_SUM_OF_SUB_ITEMS())) { $children = array_map(function ($key) { return new WcCartItemFacade(WC()->cart->cart_contents[$key], $key); }, $facade->getContainerChildrenHashes()); if ($inclTax) { $calculatedPrice = ($facade->getSubtotal() + $facade->getExactSubtotalTax()) / $facade->getQty(); $calculatedPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return ($child->getSubtotal() + $child->getExactSubtotalTax()) / $facade->getQty(); } else { return 0.0; } }, $children) ); } else { $calculatedPrice = $facade->getSubtotal() / $facade->getQty(); $calculatedPrice += array_sum( array_map(function ($child) use ($facade) { if ($child->isContaineredPricedIndividually()) { return $child->getSubtotal() / $facade->getQty(); } else { return 0.0; } }, $children) ); } } else { return null; } } elseif ($facade->isContaineredType()) { $parentPriceType = $facade->getParentContainerPriceType(); if ($parentPriceType === null) { return null; } if ($parentPriceType->equals(ContainerPriceTypeEnum::FIXED())) { return null; // do nothing } elseif ($parentPriceType->equals(ContainerPriceTypeEnum::BASE_PLUS_SUM_OF_SUB_ITEMS())) { if ($inclTax) { $calculatedPrice = ($facade->getSubtotal() + $facade->getExactSubtotalTax()) / $facade->getQty(); } else { $calculatedPrice = $facade->getSubtotal() / $facade->getQty(); } } else { return null; } } else { if ($inclTax) { $calculatedPrice = ($facade->getSubtotal() + $facade->getExactSubtotalTax()) / $facade->getQty(); } else { $calculatedPrice = $facade->getSubtotal() / $facade->getQty(); } } return $calculatedPrice; } }