PluginProbe
Tiered Pricing Table for WooCommerce / 7.1.7
Tiered Pricing Table for WooCommerce v7.1.7
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 / Addons / CartUpsells / CartUpsellsService.php

CartUpsellsService.php in Tiered Pricing Table for WooCommerce 7.1.7, at src/Addons/CartUpsells/CartUpsellsService.php

184 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TierPricingTable\Addons\CartUpsells;
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\Addons\CartUpsells
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 public function showUpsellInBlock( $itemData, $cartItem ) {
46 if ( !$this->isCartUpsellEnabled() ) {
47 return $itemData;
48 }
49 $isStoreApi = false;
50 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
51 $requestUri = ( isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' );
52 if ( strpos( $requestUri, '/wc/store/' ) !== false ) {
53 $isStoreApi = true;
54 }
55 }
56 $isBlockPage = function_exists( 'has_block' ) && (has_block( 'woocommerce/cart' ) || has_block( 'woocommerce/checkout' ));
57 // If it's NOT the Store API and NOT a block page, it's the classic cart. Bail out.
58 if ( !$isStoreApi && !$isBlockPage ) {
59 return $itemData;
60 }
61 $upsellString = $this->formatUpsellString( $cartItem );
62 if ( !$upsellString ) {
63 return $itemData;
64 }
65 $itemData[] = array(
66 'key' => '',
67 'value' => wp_strip_all_tags( $upsellString ),
68 );
69 return $itemData;
70 }
71
72 protected function formatUpsellString( $cartItem ) {
73 $nextPriceData = $this->getNextPriceData( $cartItem );
74 if ( empty( $nextPriceData ) ) {
75 return false;
76 }
77 $template = $this->getTemplate();
78 return strtr( $template, array(
79 '{tp_required_quantity}' => $nextPriceData['next_quantity'],
80 '{tp_next_price}' => wc_price( $nextPriceData['next_price'] ),
81 '{tp_next_discount}' => number_format(
82 $nextPriceData['next_discount'],
83 wc_get_price_decimals(),
84 wc_get_price_decimal_separator(),
85 wc_get_price_thousand_separator()
86 ),
87 '{tp_actual_discount}' => number_format(
88 $nextPriceData['actual_discount'],
89 wc_get_price_decimals(),
90 wc_get_price_decimal_separator(),
91 wc_get_price_thousand_separator()
92 ),
93 ) );
94 }
95
96 protected function getNextPriceData( $cartItem ) {
97 $pricingRule = $this->getPricingRule( $cartItem );
98 if ( !empty( $pricingRule->getRules() ) ) {
99 $iterator = new ArrayIterator(array_reverse( $pricingRule->getRules(), true ));
100 $currentQuantity = $this->getTotalProductCountInCart( $cartItem );
101 while ( $iterator->valid() ) {
102 if ( $currentQuantity < $iterator->key() ) {
103 $prevQuantity = $iterator->key();
104 $prevPrice = $iterator->current();
105 $iterator->next();
106 if ( $iterator->valid() && $currentQuantity >= $iterator->key() ) {
107 $product = wc_get_product( $this->getProductId( $cartItem ) );
108 if ( $pricingRule->isFixed() ) {
109 $nextPrice = $prevPrice;
110 $currentPrice = $iterator->current();
111 } else {
112 $nextPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $prevPrice );
113 $currentPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $iterator->current() );
114 }
115 $currentPrice = PriceManager::getPriceToDisplay( $currentPrice, $product, 'cart' );
116 $nextPrice = PriceManager::getPriceToDisplay( $nextPrice, $product, 'cart' );
117 return array(
118 'next_price' => $nextPrice,
119 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
120 'actual_discount' => ( $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $product->get_price( 'edit' ), $currentPrice ) ),
121 'next_quantity' => $prevQuantity - $currentQuantity,
122 );
123 } elseif ( !$iterator->valid() ) {
124 $product = wc_get_product( $this->getProductId( $cartItem ) );
125 if ( $pricingRule->isFixed() ) {
126 $nextPrice = $prevPrice;
127 $currentPrice = $product->get_price();
128 } else {
129 $nextPrice = PriceManager::getProductPriceWithPercentageDiscount( $product, $prevPrice );
130 $currentPrice = $product->get_price();
131 }
132 $nextPrice = PriceManager::getPriceToDisplay( $nextPrice, $product, 'cart' );
133 return array(
134 'next_price' => $nextPrice,
135 'next_discount' => PriceManager::calculateDiscount( $currentPrice, $nextPrice ),
136 'actual_discount' => ( $pricingRule->isPercentage() ? $prevPrice : PriceManager::calculateDiscount( $currentPrice, $product->get_price( 'edit' ) ) ),
137 'next_quantity' => $prevQuantity - $currentQuantity,
138 );
139 }
140 } else {
141 $iterator->next();
142 }
143 }
144 }
145 return array();
146 }
147
148 public function getTotalProductCountInCart( $cartItem ) {
149 return ( !empty( $cartItem['tiered_pricing_data']['total_item_quantity'] ) ? $cartItem['tiered_pricing_data']['total_item_quantity'] : $cartItem['quantity'] );
150 }
151
152 /**
153 * Get pricing rules from cart item
154 *
155 * @param array $cartItem
156 *
157 * @return PricingRule|false
158 */
159 protected function getPricingRule( $cartItem ) {
160 $productId = $this->getProductId( $cartItem );
161 if ( $productId ) {
162 return PriceManager::getPricingRule( $productId );
163 }
164 return false;
165 }
166
167 protected function getProductId( $cartItem ) {
168 return ( !empty( $cartItem['variation_id'] ) ? $cartItem['variation_id'] : $cartItem['product_id'] );
169 }
170
171 protected function getTemplate() {
172 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' ) );
173 }
174
175 protected function getUpsellColor() {
176 return $this->getContainer()->getSettings()->get( 'cart_upsell_color', '#3858e9' );
177 }
178
179 protected function isCartUpsellEnabled() {
180 return $this->getContainer()->getSettings()->get( 'cart_upsell_enabled', 'no' ) === 'yes';
181 }
182
183 }
184