PluginProbe
Tiered Pricing Table for WooCommerce / 6.1.0
Tiered Pricing Table for WooCommerce v6.1.0
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
tier-pricing-table / src / Services / CartUpsellsService.php

CartUpsellsService.php in Tiered Pricing Table for WooCommerce 6.1.0, at src/Services/CartUpsellsService.php

157 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TierPricingTable\Services;
4
5 use ArrayIterator;
6 use TierPricingTable\Core\ServiceContainerTrait;
7 use TierPricingTable\PriceManager;
8 use TierPricingTable\PricingRule;
9 /**
10 * Class CartUpsellsService
11 *
12 * Service shows upsells for each cart item that has tiered pricing
13 *
14 * @package TierPricingTable\Services
15 */
16 class CartUpsellsService {
17 use ServiceContainerTrait;
18 /**
19 * CatalogPriceManager constructor.
20 */
21 public function __construct() {
22 }
23
24 public function showUpsell( $cartItem ) {
25 if ( !$this->isCartUpsellEnabled() ) {
26 return;
27 }
28 $upsellString = $this->formatUpsellString( $cartItem );
29 if ( !$upsellString ) {
30 return;
31 }
32 ?>
33 <div>
34 <small style="color: <?php
35 echo esc_attr( $this->getUpsellColor() );
36 ?>">
37 <?php
38 echo wp_kses_post( $upsellString );
39 ?>
40 </small>
41 </div>
42 <?php
43 }
44
45 protected function formatUpsellString( $cartItem ) {
46 $nextPriceData = $this->getNextPriceData( $cartItem );
47 if ( empty( $nextPriceData ) ) {
48 return false;
49 }
50 $template = $this->getTemplate();
51 return strtr( $template, array(
52 '{tp_required_quantity}' => $nextPriceData['next_quantity'],
53 '{tp_next_price}' => wc_price( $nextPriceData['next_price'] ),
54 '{tp_next_discount}' => number_format(
55 $nextPriceData['next_discount'],
56 wc_get_price_decimals(),
57 wc_get_price_decimal_separator(),
58 wc_get_price_thousand_separator()
59 ),
60 '{tp_actual_discount}' => number_format(
61 $nextPriceData['actual_discount'],
62 wc_get_price_decimals(),
63 wc_get_price_decimal_separator(),
64 wc_get_price_thousand_separator()
65 ),
66 ) );
67 }
68
69 protected function getNextPriceData( $cartItem ) {
70 $pricingRule = $this->getPricingRule( $cartItem );
71 if ( !empty( $pricingRule->getRules() ) ) {
72 $iterator = new ArrayIterator(array_reverse( $pricingRule->getRules(), true ));
73 $currentQuantity = $this->getTotalProductCountInCart( $cartItem );
74 while ( $iterator->valid() ) {
75 if ( $currentQuantity < $iterator->key() ) {
76 $prevQuantity = $iterator->key();
77 $prevPrice = $iterator->current();
78 $iterator->next();
79 if ( $iterator->valid() && $currentQuantity >= $iterator->key() ) {
80 $product = wc_get_product( $this->getProductId( $cartItem ) );
81 if ( $pricingRule->isFixed() ) {
82 $nextPrice = $prevPrice;
83 $currentPrice = $iterator->current();
84 } else {
85 $nextPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $prevPrice );
86 $currentPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $iterator->current() );
87 }
88 $currentPrice = PriceManager::getPriceToDisplay( $currentPrice, $product, 'cart' );
89 $nextPrice = PriceManager::getPriceToDisplay( $nextPrice, $product, 'cart' );
90 return array(
91 'next_price' => $nextPrice,
92 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
93 'actual_discount' => ( $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $product->get_price( 'edit' ), $currentPrice ) ),
94 'next_quantity' => $prevQuantity - $currentQuantity,
95 );
96 } elseif ( !$iterator->valid() ) {
97 $product = wc_get_product( $this->getProductId( $cartItem ) );
98 if ( $pricingRule->isFixed() ) {
99 $nextPrice = $prevPrice;
100 $currentPrice = $product->get_price();
101 } else {
102 $nextPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $prevPrice );
103 $currentPrice = $product->get_price();
104 }
105 $nextPrice = PriceManager::getPriceToDisplay( $nextPrice, $product, 'cart' );
106 return array(
107 'next_price' => $nextPrice,
108 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
109 'actual_discount' => ( $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $currentPrice, $product->get_price( 'edit' ) ) ),
110 'next_quantity' => $prevQuantity - $currentQuantity,
111 );
112 }
113 } else {
114 $iterator->next();
115 }
116 }
117 }
118 return array();
119 }
120
121 public function getTotalProductCountInCart( $cartItem ) {
122 return ( !empty( $cartItem['tiered_pricing_data']['total_item_quantity'] ) ? $cartItem['tiered_pricing_data']['total_item_quantity'] : $cartItem['quantity'] );
123 }
124
125 /**
126 * Get pricing rules from cart item
127 *
128 * @param array $cartItem
129 *
130 * @return PricingRule|false
131 */
132 protected function getPricingRule( $cartItem ) {
133 $productId = $this->getProductId( $cartItem );
134 if ( $productId ) {
135 return PriceManager::getPricingRule( $productId );
136 }
137 return false;
138 }
139
140 protected function getProductId( $cartItem ) {
141 return ( !empty( $cartItem['variation_id'] ) ? $cartItem['variation_id'] : $cartItem['product_id'] );
142 }
143
144 protected function getTemplate() {
145 return $this->getContainer()->getSettings()->get( 'cart_upsell_template', __( 'Buy <b>{tp_required_quantity}</b> more to get <b>{tp_next_price}</b> each', 'tier-pricing-table' ) );
146 }
147
148 protected function getUpsellColor() {
149 return $this->getContainer()->getSettings()->get( 'cart_upsell_color', '#96598A' );
150 }
151
152 protected function isCartUpsellEnabled() {
153 return $this->getContainer()->getSettings()->get( 'cart_upsell_enabled', 'no' ) === 'yes';
154 }
155
156 }
157