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 / Frontend / CartUpsellManager.php

CartUpsellManager.php in Tiered Pricing Table for WooCommerce 6.1.0, at src/Frontend/CartUpsellManager.php

191 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Frontend;
2
3 use ArrayIterator;
4 use TierPricingTable\Core\ServiceContainerTrait;
5 use TierPricingTable\PriceManager;
6 use TierPricingTable\PricingRule;
7
8 /**
9 * Class CartUpsellManager
10 *
11 * @package TierPricingTable
12 */
13 class CartUpsellManager {
14
15 use ServiceContainerTrait;
16
17 /**
18 * CatalogPriceManager constructor.
19 */
20 public function __construct() {
21 add_action( 'woocommerce_after_cart_item_name', array( $this, 'showUpsell' ), 1, 3 );
22 }
23
24 public function showUpsell( $cartItem ) {
25 if ( ! $this->isCartUpsellEnabled() ) {
26 return;
27 }
28
29 $upsellString = $this->formatUpsellString( $cartItem );
30
31 if ( ! $upsellString ) {
32 return;
33 }
34
35 ?>
36 <div>
37 <small style="color: <?php echo esc_attr( $this->getUpsellColor() ); ?>"><?php echo wp_kses_post( $upsellString ); ?></small>
38 </div>
39 <?php
40 }
41
42 protected function formatUpsellString( $cartItem ) {
43
44 $nextPriceData = $this->getNextPriceData( $cartItem );
45
46 if ( empty( $nextPriceData ) ) {
47 return false;
48 }
49
50 $template = $this->getTemplate();
51
52 return strtr( $template, array(
53 '{tp_required_quantity}' => $nextPriceData['next_quantity'],
54 '{tp_next_price}' => wc_price( $nextPriceData['next_price'] ),
55 '{tp_next_discount}' => number_format( $nextPriceData['next_discount'], wc_get_price_decimals(), wc_get_price_decimal_separator(), wc_get_price_thousand_separator() ),
56 '{tp_actual_discount}' => number_format( $nextPriceData['actual_discount'], wc_get_price_decimals(), wc_get_price_decimal_separator(), wc_get_price_thousand_separator() ),
57 ) );
58 }
59
60 protected function getNextPriceData( $cartItem ) {
61 $pricingRule = $this->getPricingRule( $cartItem );
62
63 if ( ! empty( $pricingRule->getRules() ) ) {
64
65 $iterator = new ArrayIterator( array_reverse( $pricingRule->getRules(), true ) );
66 $currentQuantity = $this->getTotalProductCountInCart( $cartItem );
67
68 while ( $iterator->valid() ) {
69 if ( $currentQuantity < $iterator->key() ) {
70
71 $prevQuantity = $iterator->key();
72 $prevPrice = $iterator->current();
73
74 $iterator->next();
75
76 if ( $iterator->valid() && $currentQuantity >= $iterator->key() ) {
77
78 $product = wc_get_product( $this->getProductId( $cartItem ) );
79
80 if ( $pricingRule->isFixed() ) {
81 $nextPrice = $prevPrice;
82 $currentPrice = $iterator->current();
83 } else {
84 $nextPrice = PriceManager::getPriceByPercentDiscount( $product->get_price(), $prevPrice );
85 $currentPrice = PriceManager::getPriceByPercentDiscount( $product->get_price(), $iterator->current() );
86 }
87
88 $currentPrice = PriceManager::getPriceWithTaxes( $currentPrice, $product, 'cart' );
89 $nextPrice = PriceManager::getPriceWithTaxes( $nextPrice, $product, 'cart' );
90
91 return array(
92 'next_price' => $nextPrice,
93 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
94 'actual_discount' => $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $product->get_price( 'edit' ), $currentPrice ),
95 'next_quantity' => $prevQuantity - $currentQuantity,
96 );
97 } else if ( ! $iterator->valid() ) {
98 $product = wc_get_product( $this->getProductId( $cartItem ) );
99
100 if ( $pricingRule->isFixed() ) {
101 $nextPrice = $prevPrice;
102 $currentPrice = $product->get_price();
103 } else {
104 $nextPrice = PriceManager::getPriceByPercentDiscount( $product->get_price(), $prevPrice );
105 $currentPrice = $product->get_price();
106 }
107
108 $nextPrice = PriceManager::getPriceWithTaxes( $nextPrice, $product, 'cart' );
109
110 return array(
111 'next_price' => $nextPrice,
112 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
113 'actual_discount' => $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $currentPrice, $product->get_price( 'edit' ) ),
114 'next_quantity' => $prevQuantity - $currentQuantity,
115 );
116 }
117 } else {
118 $iterator->next();
119 }
120 }
121 }
122
123 return array();
124 }
125
126 public function getTotalProductCountInCart( $cartItem ) {
127
128 if ( isset( $cartItem['tpt_pricing_rule_id'] ) ) {
129 $samePricingRuleCartItems = [];
130
131 foreach ( wc()->cart->cart_contents as $cartContent ) {
132 if ( isset( $cartContent['tpt_pricing_rule_id'] ) && $cartContent['tpt_pricing_rule_id'] === $cartItem['tpt_pricing_rule_id'] ) {
133 $samePricingRuleCartItems[] = $cartContent;
134 }
135 }
136 } else {
137 $samePricingRuleCartItems[] = $cartItem;
138 }
139
140 $quantity = 0;
141
142 foreach ( $samePricingRuleCartItems as $cartItem ) {
143 if ( $this->getContainer()->getSettings()->get( 'summarize_variations', 'no' ) !== 'yes' ) {
144 $quantity += $cartItem['quantity'];
145 } else {
146 foreach ( wc()->cart->cart_contents as $cart_content ) {
147 if ( $cart_content['product_id'] == $cartItem['product_id'] ) {
148 $quantity += $cart_content['quantity'];
149 }
150 }
151 }
152 }
153
154 return $quantity;
155 }
156
157 /**
158 * Get pricing rules from cart item
159 *
160 * @param array $cartItem
161 *
162 * @return PricingRule|false
163 */
164 protected function getPricingRule( $cartItem ) {
165
166 $productId = $this->getProductId( $cartItem );
167
168 if ( $productId ) {
169 return PriceManager::getPricingRule( $productId );
170 }
171
172 return false;
173 }
174
175 protected function getProductId( $cartItem ) {
176 return ! empty( $cartItem['variation_id'] ) ? $cartItem['variation_id'] : $cartItem['product_id'];
177 }
178
179 protected function getTemplate() {
180 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' ) );
181 }
182
183 protected function getUpsellColor() {
184 return $this->getContainer()->getSettings()->get( 'cart_upsell_color', '#96598A' );
185 }
186
187 protected function isCartUpsellEnabled() {
188 return $this->getContainer()->getSettings()->get( 'cart_upsell_enabled', 'no' ) === 'yes';
189 }
190 }
191