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 / CatalogPriceManager.php

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

286 lines 7.7 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 TierPricingTable\Admin\ProductManagers\AdvanceOptionsForVariableProduct;
4 use TierPricingTable\Cache;
5 use TierPricingTable\Core\ServiceContainerTrait;
6 use TierPricingTable\PriceManager;
7 use TierPricingTable\PricingRule;
8 use TierPricingTable\Settings\Sections\GeneralSection\Subsections\ProductPagePriceSubsection;
9 use WC_Product;
10 use WC_Product_Variable;
11
12 /**
13 * Class CatalogPriceManager
14 *
15 * @package TierPricingTable
16 */
17 class CatalogPriceManager {
18
19 use ServiceContainerTrait;
20
21 /**
22 * Price hash
23 *
24 * @var string
25 */
26 private $variablePriceHash;
27
28 /**
29 * CatalogPriceManager constructor.
30 */
31 public function __construct() {
32
33 if ( $this->isEnabled() && ! is_admin() ) {
34 add_filter( 'woocommerce_get_price_html', array( $this, 'formatPrice' ), 99, 2 );
35
36 // Store variable products price hash
37 add_filter( 'woocommerce_get_variation_prices_hash', function ( $hash, WC_Product_Variable $product ) {
38
39 $hash[] = $product->get_date_modified();
40
41 $this->variablePriceHash[ $product->get_id() ] = md5( wp_json_encode( $hash ) . $this->getDisplayType() );
42
43 return $hash;
44 }, 10, 2 );
45 }
46 }
47
48 /**
49 * Change logic showing prince at catalog for product with tiered price rules
50 *
51 * @param string $priceHtml
52 * @param WC_Product $product
53 *
54 * @return string
55 */
56 public function formatPrice( $priceHtml, $product ) {
57
58 // Some themes uses ->get_price_html() to show cart item price. Do not modify such prices
59 if ( is_cart() ) {
60 return $priceHtml;
61 }
62
63 $currentProductPageProductId = get_queried_object_id();
64 $parentProductId = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
65
66 if ( AdvanceOptionsForVariableProduct::productHasNoRules( $parentProductId ) ) {
67 return $priceHtml;
68 }
69
70 $isAdjustPriceOnProductPage = 'same_as_catalog' === ProductPagePriceSubsection::getFormatPriceType();
71
72 if ( $currentProductPageProductId === $parentProductId ) {
73
74 // Do not modify prices for variations on product page
75 if ( ! apply_filters( 'tiered_pricing_table/catalog_pricing/format_variation_price', false, $priceHtml, $product ) && $product->is_type( 'variation' ) ) {
76 return $priceHtml;
77 }
78
79 if ( $isAdjustPriceOnProductPage ) {
80 if ( $product instanceof WC_Product_Variable ) {
81 $newPriceHTML = $this->getFormattedPriceForVariableProduct( $product );
82 } else {
83 $newPriceHTML = $this->getFormattedPriceForSimpleProducts( $product );
84 }
85 } else {
86 $newPriceHTML = false;
87 }
88
89 } else {
90
91 if ( $product instanceof WC_Product_Variable && 'yes' === $this->useForVariable() ) {
92 $newPriceHTML = $this->getFormattedPriceForVariableProduct( $product );
93 } else {
94 $newPriceHTML = $this->getFormattedPriceForSimpleProducts( $product );
95 }
96 }
97
98 $newPriceHtml = $newPriceHTML ? $newPriceHTML . ' ' . $product->get_price_suffix() : $priceHtml;
99
100 return apply_filters( 'tiered_pricing_table/catalog_pricing/price_html', $newPriceHtml, $priceHtml, $product );
101 }
102
103 /**
104 * Format price for simple/variation products.
105 *
106 * @param WC_Product $product
107 *
108 * @return bool|string
109 */
110 protected function getFormattedPriceForSimpleProducts( WC_Product $product ) {
111
112 $priceHtml = false;
113
114 if ( in_array( $product->get_type(), array( 'simple', 'variation' ) ) ) {
115
116 $displayPriceType = $this->getDisplayType();
117 $pricingRule = PriceManager::getPricingRule( $product->get_id() );
118
119 if ( ! empty( $pricingRule->getRules() ) ) {
120 if ( 'range' === $displayPriceType ) {
121 $priceHtml = $this->getRange( $pricingRule, $product );
122 } else {
123 $priceHtml = $this->getLowestPrice( $pricingRule, $product );
124 }
125 }
126 }
127
128 return $priceHtml;
129 }
130
131 /**
132 * Format price for variable product. Range uses lowest and high prices from all variations
133 *
134 * @param WC_Product_Variable $product
135 * @param bool $force
136 *
137 * @return bool|string
138 */
139 protected function getFormattedPriceForVariableProduct( WC_Product_Variable $product, $force = false ) {
140
141 $price = Cache::getCachedDataForVariableProduct( $product->get_id(), 'price_html' );
142
143 // For product that has no tiered pricing
144 if ( $price === 'default' ) {
145 return false;
146 }
147
148 if ( ! $price ) {
149 $price = $this->formatPriceForVariableProduct( $product );
150
151 Cache::setCachedDataForVariableProduct( $product->get_id(), 'price_html', $price );
152
153 return $price;
154 }
155
156 return $price;
157 }
158
159 /**
160 * Format price for variable product. Range uses lowest and high prices from all variations
161 *
162 * @param WC_Product_Variable $product
163 *
164 * @return bool|string
165 */
166 protected function formatPriceForVariableProduct( WC_Product_Variable $product ) {
167
168 // With taxes
169 $maxPrice = (float) $product->get_variation_price( 'max', true );
170 $minPrices = array( (float) $product->get_variation_price( 'min', true ) );
171
172 foreach ( $product->get_available_variations() as $variation ) {
173 $pricingRule = PriceManager::getPricingRule( $variation['variation_id'] );
174
175 if ( ! empty( $pricingRule->getRules() ) ) {
176 $minPrices[] = $this->getLowestPrice( $pricingRule, wc_get_product( $variation['variation_id'] ), false );
177 }
178 }
179
180 if ( ! empty( $minPrices ) && count( $minPrices ) > 1 ) {
181
182 if ( 'range' === $this->getDisplayType() ) {
183
184 if ( min( $minPrices ) === $maxPrice ) {
185 return false;
186 }
187
188 return wc_price( min( $minPrices ) ) . ' - ' . wc_price( $maxPrice );
189 } else {
190 return $this->getLowestPrefix() . ' ' . wc_price( min( $minPrices ) );
191 }
192 }
193
194 return false;
195 }
196
197 /**
198 * Get range from lowest to highest price from price rules
199 *
200 * @param PricingRule $pricingRule
201 * @param WC_Product $product
202 *
203 * @return string
204 */
205 protected function getRange( PricingRule $pricingRule, $product ) {
206 $pricingRules = $pricingRule->getRules();
207 $lowest = array_pop( $pricingRules );
208
209 $highest_html = wc_price( wc_get_price_to_display( $product, array(
210 'price' => $product->get_price(),
211 ) ) );
212
213 if ( $pricingRule->isPercentage() ) {
214
215 $lowest_html = wc_price(
216 wc_get_price_to_display( $product, array(
217 'price' => PriceManager::getPriceByPercentDiscount( $product->get_price(), $lowest ),
218 ) )
219 );
220
221 $range = $lowest_html . ' - ' . $highest_html;
222 } else {
223 $lowest_html = wc_price(
224 wc_get_price_to_display( $product, array(
225 'price' => $lowest,
226 ) )
227 );
228
229 $range = $lowest_html . ' - ' . $highest_html;
230 }
231
232 if ( $lowest_html !== $highest_html ) {
233 return $range;
234 }
235
236 return $lowest_html;
237 }
238
239 /**
240 * Get lowest price from price rules
241 *
242 * @param PricingRule $pricingRule
243 * @param WC_Product $product
244 *
245 * @param bool $html
246 *
247 * @return string|float
248 */
249 protected function getLowestPrice( $pricingRule, $product, $html = true ) {
250 $pricingRules = $pricingRule->getRules();
251
252 if ( $pricingRule->isPercentage() ) {
253 $lowest = PriceManager::getPriceByPercentDiscount( $product->get_price(),
254 array_pop( $pricingRules ) );
255 } else {
256 $lowest = array_pop( $pricingRules );
257 }
258
259 if ( ! $html ) {
260 return wc_get_price_to_display( $product, array(
261 'price' => $lowest
262 ) );
263 }
264
265 return $this->getLowestPrefix() . ' ' . wc_price( wc_get_price_to_display( $product, array(
266 'price' => $lowest
267 ) ) );
268 }
269
270 public function getLowestPrefix() {
271 return $this->getContainer()->getSettings()->get( 'lowest_prefix', __( 'From', 'tier-pricing-table' ) );
272 }
273
274 public function isEnabled() {
275 return 'yes' === $this->getContainer()->getSettings()->get( 'tiered_price_at_catalog', 'yes' );
276 }
277
278 public function getDisplayType() {
279 return $this->getContainer()->getSettings()->get( 'tiered_price_at_catalog_type', 'range' );
280 }
281
282 public function useForVariable() {
283 return $this->getContainer()->getSettings()->get( 'tiered_price_at_catalog_for_variable', 'yes' );
284 }
285 }
286