PluginProbe
Tiered Pricing Table for WooCommerce / 8.1.0
Tiered Pricing Table for WooCommerce v8.1.0
8.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 All 92 releases
← All changes | src/Addons/YouSave/YouSaveService.php +122 -23 7.1.7 → 8.1.0 View file →
@@ -19,9 +19,15 @@
19 19 * CatalogPriceManager constructor.
20 20 */
21 21 public function __construct() {
22 22
23 - add_action( 'woocommerce_get_price_html', array( $this, 'addYouSave' ), 150, 2 );
23 + if ( 'price' === $this->getPosition() ) {
24 + add_action( 'woocommerce_get_price_html', array( $this, 'addYouSave' ), 150, 2 );
25 + } elseif ( 'before_add_to_cart' === $this->getPosition() ) {
26 + add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'renderBeforeAddToCart' ), 20 );
27 + } else {
28 + add_action( 'tiered_pricing_table/after_rendering_tiered_pricing', array( $this, 'renderAfterTable' ), 10, 3 );
29 + }
24 30
25 31 add_shortcode( 'tiered_price_you_save', function ( $tag, $args ) {
26 32
27 33 $args = wp_parse_args( $args, array(
@@ -28,29 +34,36 @@
28 34 'product_id' => null,
29 35 'color' => $this->getTextColor(),
30 36 'template' => $this->getTemplate(),
31 37 'consider_sale_price' => $this->considerSalePrice(),
38 + 'style' => $this->getStyle(),
32 39 ) );
33 40
34 41 $product = wc_get_product( $args['product_id'] );
35 42
36 - if ( ! $product ) {
43 + if ( ! $product || ! $this->isEnabledFor( $product ) ) {
37 44 return '';
38 45 }
39 46
40 - $hasRules = \TierPricingTable\PricingTable::getInstance()->productHasPricingRules( $product );
41 - $isEnabled = $hasRules
42 - ? 'yes' === $this->getContainer()->getSettings()->get( 'you_save_enabled', 'yes' )
43 - : 'yes' === $this->getContainer()->getSettings()->get( 'you_save_non_tiered', 'no' ) && 'yes' === $this->getContainer()->getSettings()->get( 'you_save_consider_sale_price', 'yes' );
47 + return $this->getYouSaveHTML( $args['color'], $args['template'], $args['consider_sale_price'], $product, $args['style'] );
48 + } );
49 + }
44 50
45 - if ( ! $isEnabled ) {
46 - return '';
47 - }
51 + /**
52 + * Whether the badge is switched on for this product: the badge switch for products with tiers,
53 + * the "products without tiered pricing" switch (with the sale discount counted) for the rest.
54 + */
55 + public function isEnabledFor( WC_Product $product ): bool {
56 + $hasRules = \TierPricingTable\PricingTable::getInstance()->productHasPricingRules( $product );
48 57
49 - return $this->getYouSaveHTML( $args['color'], $args['template'], $args['consider_sale_price'], $product );
50 - } );
58 + return $hasRules
59 + ? 'yes' === $this->getContainer()->getSettings()->get( 'you_save_enabled', 'yes' )
60 + : 'yes' === $this->getContainer()->getSettings()->get( 'you_save_non_tiered', 'no' ) && 'yes' === $this->getContainer()->getSettings()->get( 'you_save_consider_sale_price', 'yes' );
51 61 }
52 62
63 + /**
64 + * Position "under the price": appended to the price line while that line follows the quantity.
65 + */
53 66 public function addYouSave( $priceHTML, WC_Product $product ) {
54 67
55 68 if ( false === strpos( $priceHTML, 'tiered-pricing-dynamic-price-wrapper' ) ) {
56 69 return $priceHTML;
@@ -55,14 +68,9 @@
55 68 if ( false === strpos( $priceHTML, 'tiered-pricing-dynamic-price-wrapper' ) ) {
56 69 return $priceHTML;
57 70 }
58 71
59 - $hasRules = \TierPricingTable\PricingTable::getInstance()->productHasPricingRules( $product );
60 - $isEnabled = $hasRules
61 - ? 'yes' === $this->getContainer()->getSettings()->get( 'you_save_enabled', 'yes' )
62 - : 'yes' === $this->getContainer()->getSettings()->get( 'you_save_non_tiered', 'no' ) && 'yes' === $this->getContainer()->getSettings()->get( 'you_save_consider_sale_price', 'yes' );
63 -
64 - if ( ! $isEnabled ) {
72 + if ( ! $this->isEnabledFor( $product ) ) {
65 73 return $priceHTML;
66 74 }
67 75
68 76 $priceHTML .= '<br>' . $this->getYouSaveHTML( $this->getTextColor(), $this->getTemplate(),
@@ -70,30 +78,121 @@
70 78
71 79 return $priceHTML;
72 80 }
73 81
74 - public function getYouSaveHTML( $color, $template, $considerSalePrice, $product = null ): string {
82 + /**
83 + * Position "above the add-to-cart button".
84 + */
85 + public function renderBeforeAddToCart() {
86 + global $product;
87 +
88 + if ( ! is_product() || ! $product instanceof WC_Product ) {
89 + return;
90 + }
91 +
92 + $this->renderBlock( $product );
93 + }
94 +
95 + /**
96 + * Position "after the pricing table": follows the table wherever it is placed.
97 + *
98 + * @param WC_Product $parentProduct
99 + * @param int|null $variationID
100 + * @param array $settings
101 + */
102 + public function renderAfterTable( $parentProduct, $variationID, $settings ) {
103 +
104 + if ( ! $parentProduct instanceof WC_Product || 'product-page' !== ( $settings['display_context'] ?? 'product-page' ) || ! is_product() ) {
105 + return;
106 + }
107 +
108 + $this->renderBlock( $parentProduct );
109 + }
110 +
111 + protected function renderBlock( WC_Product $product ) {
112 +
113 + if ( ! $this->isEnabledFor( $product ) ) {
114 + return;
115 + }
116 +
117 + echo '<div class="tiered-pricing-you-save-wrapper tiered-pricing-you-save-wrapper--' . esc_attr( $this->getPosition() ) . '">'
118 + . $this->getYouSaveHTML( $this->getTextColor(), $this->getTemplate(), $this->considerSalePrice(), $product ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
119 + . '</div>';
120 + }
121 +
122 + public function getYouSaveHTML( $color, $template, $considerSalePrice, $product = null, $style = null ): string {
75 123 $template = $this->parseTemplate( $template );
124 + $style = in_array( $style, self::getStyles(), true ) ? $style : $this->getStyle();
125 + $color = $color ? $color : $this->getActiveTierColor();
76 126
127 + switch ( $style ) {
128 + case 'pill':
129 + $css = 'background-color: ' . $color . '; color: #ffffff;';
130 + break;
131 + case 'outline':
132 + $css = 'color: ' . $color . '; border-color: ' . $color . ';';
133 + break;
134 + default:
135 + $css = 'color: ' . $color . ';';
136 + }
137 +
77 138 ob_start();
78 139 ?>
79 140 <small data-consider-sale-price="<?php echo esc_attr( wc_bool_to_string( $considerSalePrice ) ); ?>"
80 141 data-product-id="<?php echo esc_attr( $product->get_id() ); ?>"
81 142 data-parent-id="<?php echo esc_attr( $product->get_parent_id() ? $product->get_parent_id() : $product->get_id() ); ?>"
82 - class="tiered-pricing-you-save tiered-pricing-you-save--hidden"
83 - style="color: <?php echo esc_attr( $color ); ?>"><?php echo wp_kses_post( $template ); ?>
143 + class="tiered-pricing-you-save tiered-pricing-you-save--hidden tiered-pricing-you-save--<?php echo esc_attr( $style ); ?>"
144 + style="<?php echo esc_attr( $css ); ?>"><?php echo wp_kses_post( $template ); ?>
84 145 </small>
85 146 <?php
86 147 return ob_get_clean();
87 148 }
88 149
150 + /**
151 + * Badge styles: coloured text, a filled pill, or an outlined label.
152 + */
153 + public static function getStyles(): array {
154 + return array( 'text', 'pill', 'outline' );
155 + }
156 +
157 + /**
158 + * Badge positions on the product page.
159 + */
160 + public static function getPositions(): array {
161 + return array( 'price', 'before_add_to_cart', 'after_table' );
162 + }
163 +
164 + public function getStyle(): string {
165 + $style = (string) get_option( Settings::SETTINGS_PREFIX . 'you_save_style', 'text' );
166 +
167 + return in_array( $style, self::getStyles(), true ) ? $style : 'text';
168 + }
169 +
170 + public function getPosition(): string {
171 + $position = (string) get_option( Settings::SETTINGS_PREFIX . 'you_save_position', 'price' );
172 +
173 + return in_array( $position, self::getPositions(), true ) ? $position : 'price';
174 + }
175 +
89 176 public function getTemplate() {
90 177 return get_option( Settings::SETTINGS_PREFIX . 'you_save_template',
91 - 'You save {tp_ys_total_price} ({tp_ys_percentage_discount}%)' );
178 + 'You save {tp_ys_total_price}' );
92 179 }
93 180
94 - public function getTextColor() {
95 - return get_option( Settings::SETTINGS_PREFIX . 'you_save_text_color', '#FF0000' );
181 + /**
182 + * The badge colour; empty means "Auto": the active tier colour.
183 + */
184 + public function getTextColor(): string {
185 + return (string) get_option( Settings::SETTINGS_PREFIX . 'you_save_text_color', '' );
186 + }
187 +
188 + /**
189 + * The active tier colour of the pricing layout, which the badge follows unless it has its own colour.
190 + */
191 + public function getActiveTierColor(): string {
192 + $color = (string) get_option( Settings::SETTINGS_PREFIX . 'selected_quantity_color', '#3858e9' );
193 +
194 + return '' !== $color ? $color : '#3858e9';
96 195 }
97 196
98 197 public function considerSalePrice(): bool {
99 198 return get_option( Settings::SETTINGS_PREFIX . 'you_save_consider_sale_price', 'yes' ) === 'yes';