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/GlobalTieredPricing/CPT/Columns/Pricing.php +156 -120 7.1.1 → 8.1.0 View file →
@@ -1,140 +1,176 @@
1 1 <?php namespace TierPricingTable\Addons\GlobalTieredPricing\CPT\Columns;
2 2
3 -use ArrayIterator;
4 3 use Exception;
5 4 use TierPricingTable\Addons\GlobalTieredPricing\GlobalPricingRule;
6 5 use TierPricingTable\Core\ServiceContainerTrait;
7 6
7 +/**
8 + * What the rule changes, only when set: base price, the tiers as a small table, quantity limits.
9 + */
8 10 class Pricing {
9 -
11 +
10 12 use ServiceContainerTrait;
11 -
13 +
12 14 public function getName(): string {
13 15 return __( 'Pricing', 'tier-pricing-table' );
14 16 }
15 -
17 +
16 18 public function render( GlobalPricingRule $rule ) {
17 19 try {
18 20 $rule->validatePricing();
19 -
20 - $pricingType = $rule->getTieredPricingType();
21 - $rules = 'percentage' === $pricingType ? $rule->getPercentageTieredPricingRules() : $rule->getFixedTieredPricingRules();
22 - $minimum = $rule->getMinimum() ? intval( $rule->getMinimum() ) : 1;
23 -
24 - $regularProductPriceString = __( 'Regular price', 'tier-pricing-table' );
25 -
26 - if ( $rule->getPricingType() === 'flat' ) {
27 - if ( $rule->getSalePrice() ) {
28 - $regularProductPriceString = wc_price( $rule->getSalePrice() );
29 - } elseif ( $rule->getRegularPrice() ) {
30 - $regularProductPriceString = wc_price( $rule->getRegularPrice() );
31 - }
32 - } elseif ( $rule->getDiscount() ) {
33 - $regularProductPriceString = $rule->getDiscount() . '% off';
34 - }
35 -
21 + } catch ( Exception $e ) {
36 22 ?>
37 -
38 - <?php
39 - $applyingType = $rule->getApplyingType() === 'individual' ? __( '(Individual)', 'tier-pricing-table' ) : __( '(Mix and match)', 'tier-pricing-table' );
40 - ?>
41 - <div style="margin-bottom: 12px;">
42 - <?php
43 - $hasBasePricing = ( $rule->getPricingType() === 'flat' && ( $rule->getRegularPrice() || $rule->getSalePrice() ) ) || ( $rule->getPricingType() !== 'flat' && $rule->getDiscount() );
44 - if ( $hasBasePricing ) : ?>
45 - <div style="margin-bottom: 8px;">
46 - <strong style="display: block; margin-bottom: 4px;"><?php esc_html_e( 'Base Pricing:', 'tier-pricing-table' ); ?></strong>
47 - <div style="display: flex; flex-wrap: wrap; gap: 4px;">
48 - <?php if ( $rule->getPricingType() === 'flat' ) : ?>
49 - <?php if ( $rule->getRegularPrice() ) : ?>
50 - <span style="display: inline-block; padding: 2px 8px; background: #f0f0f1; border-radius: 3px; font-size: 12px; color: #3c434a; border: 1px solid #dcdcdc;">
51 - <?php echo wp_kses_post( __( 'Regular:', 'tier-pricing-table' ) . ' <b>' . wc_price( $rule->getRegularPrice() ) . '</b>' ); ?>
52 - </span>
53 - <?php endif; ?>
54 - <?php if ( $rule->getSalePrice() ) : ?>
55 - <span style="display: inline-block; padding: 2px 8px; background: #f0f0f1; border-radius: 3px; font-size: 12px; color: #3c434a; border: 1px solid #dcdcdc;">
56 - <?php echo wp_kses_post( __( 'Sale:', 'tier-pricing-table' ) . ' <b>' . wc_price( $rule->getSalePrice() ) . '</b>' ); ?>
57 - </span>
58 - <?php endif; ?>
59 - <?php else : ?>
60 - <?php if ( $rule->getDiscount() ) : ?>
61 - <span style="display: inline-block; padding: 2px 8px; background: #f0f0f1; border-radius: 3px; font-size: 12px; color: #3c434a; border: 1px solid #dcdcdc;">
62 - <?php esc_html_e( 'Discount:', 'tier-pricing-table' ); ?> <b><?php echo esc_html( $rule->getDiscount() ); ?>%</b>
63 - (<?php echo $rule->getDiscountType() === 'sale_price' ? esc_html__( 'Sale price', 'tier-pricing-table' ) : esc_html__( 'Regular price', 'tier-pricing-table' ); ?>)
64 - </span>
65 - <?php endif; ?>
66 - <?php endif; ?>
67 - </div>
68 - </div>
69 - <?php endif; ?>
70 -
71 - <?php if ( ! empty( $rules ) ) : ?>
72 - <div>
73 - <div style="display: flex; align-items: center; margin-bottom: 8px;">
74 - <strong style="display: block; color: #1d2327; margin-right: 6px;"><?php esc_html_e( 'Tiered Rules:', 'tier-pricing-table' ); ?></strong>
75 - <span style="color: #50575e; font-size: 13px;">
76 - <?php echo esc_html( $applyingType ); ?>
77 - </span>
78 - </div>
79 - <table style="width: 100%; border-collapse: collapse; font-size: 13px; text-align: left; margin-bottom: 8px; border: 1px solid #c3c4c7; border-radius: 4px; overflow: hidden; background: #fff;">
80 - <thead style="background: #f0f0f1; border-bottom: 2px solid #c3c4c7;">
81 - <tr>
82 - <th style="padding: 8px 10px; font-weight: 600; color: #1d2327;"><?php esc_html_e( 'Quantity', 'tier-pricing-table' ); ?></th>
83 - <th style="padding: 8px 10px; font-weight: 600; color: #1d2327;"><?php echo 'percentage' === $pricingType ? esc_html__( 'Discount', 'tier-pricing-table' ) : esc_html__( 'Price', 'tier-pricing-table' ); ?></th>
84 - </tr>
85 - </thead>
86 - <tbody>
87 - <?php
88 - // Base quantity row
89 - $baseQtyStr = '';
90 - if ( 1 >= array_keys( $rules )[0] - $minimum ) {
91 - $baseQtyStr = number_format_i18n( $minimum );
92 - } else {
93 - $baseQtyStr = number_format_i18n( $minimum ) . ' - ' . number_format_i18n( array_keys( $rules )[0] - 1 );
94 - }
95 - ?>
96 - <tr style="border-bottom: 1px solid #c3c4c7;">
97 - <td style="padding: 6px 10px; color: #1d2327; border-right: 1px solid #e2e4e7;"><?php echo esc_html( $baseQtyStr ); ?></td>
98 - <td style="padding: 6px 10px; color: #1d2327;"><?php echo wp_kses_post( $regularProductPriceString ); ?></td>
99 - </tr>
100 -
101 - <?php
102 - $iterator = new ArrayIterator( $rules );
103 - while ( $iterator->valid() ) {
104 - $currentPrice = $iterator->current();
105 - $currentQuantity = $iterator->key();
106 - $iterator->next();
107 -
108 - if ( $iterator->valid() ) {
109 - $quantity = $currentQuantity;
110 - if ( intval( $iterator->key() - 1 != $currentQuantity ) ) {
111 - $quantity = number_format_i18n( $quantity );
112 - if ( $this->getContainer()->getSettings()->get( 'quantity_type', 'range' ) === 'range' ) {
113 - $quantity .= ' - ' . number_format_i18n( intval( $iterator->key() - 1 ) );
114 - }
115 - }
116 - } else {
117 - $quantity = number_format_i18n( $currentQuantity ) . '+';
118 - }
119 -
120 - $priceStr = 'percentage' === $pricingType ? esc_html( $currentPrice . '%' ) : wp_kses_post( wc_price( $currentPrice ) );
121 - ?>
122 - <tr style="border-bottom: 1px solid #c3c4c7;">
123 - <td style="padding: 6px 10px; color: #1d2327; font-weight: 600; border-right: 1px solid #e2e4e7;"><?php echo esc_html( $quantity ); ?></td>
124 - <td style="padding: 6px 10px; color: #0070bc; font-weight: 600;"><?php echo $priceStr; ?></td>
125 - </tr>
126 - <?php
127 - }
128 - ?>
129 - </tbody>
130 - </table>
131 - </div>
132 - <?php endif; ?>
23 + <div class="tpt-rules-list__line tpt-rules-list__warn">
24 + <span class="dashicons dashicons-warning"></span>
25 + <span><?php echo esc_html( $e->getMessage() ); ?></span>
133 26 </div>
134 27 <?php
135 -
136 - } catch ( Exception $e ) {
137 - echo wp_kses_post( '<div class="help_tip tpt-rule-status tpt-rule-status--invalid" data-tip="' . $e->getMessage() . '">!</div>' );
138 28 }
29 +
30 + $this->renderBasePrice( $rule );
31 + $this->renderTiers( $rule );
32 + $this->renderQuantityLimits( $rule );
33 + }
34 +
35 + protected function renderBasePrice( GlobalPricingRule $rule ) {
36 + $chips = array();
37 +
38 + if ( 'flat' === $rule->getPricingType() ) {
39 + if ( $rule->getRegularPrice() ) {
40 + $chips[] = __( 'Regular', 'tier-pricing-table' ) . ' <b>' . wc_price( $rule->getRegularPrice() ) . '</b>';
41 + }
42 + if ( $rule->getSalePrice() ) {
43 + $chips[] = __( 'Sale', 'tier-pricing-table' ) . ' <b>' . wc_price( $rule->getSalePrice() ) . '</b>';
44 + }
45 + } elseif ( $rule->getDiscount() ) {
46 + $chips[] = sprintf(
47 + /* translators: 1: percentage, 2: "sale price" or "regular price" */
48 + __( 'Discount <b>%1$s%%</b> off the %2$s', 'tier-pricing-table' ),
49 + esc_html( $rule->getDiscount() ),
50 + 'sale_price' === $rule->getDiscountType() ? __( 'sale price', 'tier-pricing-table' ) : __( 'regular price', 'tier-pricing-table' )
51 + );
52 + }
53 +
54 + if ( $chips ) {
55 + $this->renderLine( __( 'Base price', 'tier-pricing-table' ), $chips );
56 + }
57 + }
58 +
59 + /**
60 + * The tiers as a small table: quantity ranges (or thresholds, per the plugin's quantity type
61 + * setting) and the price or discount, with a base row for the quantities below the first tier.
62 + */
63 + protected function renderTiers( GlobalPricingRule $rule ) {
64 + $percentage = 'percentage' === $rule->getTieredPricingType();
65 + $tiers = $percentage ? $rule->getPercentageTieredPricingRules() : $rule->getFixedTieredPricingRules();
66 +
67 + if ( empty( $tiers ) ) {
68 + return;
69 + }
70 +
71 + ksort( $tiers );
72 + $quantities = array_map( 'intval', array_keys( $tiers ) );
73 + $values = array_values( $tiers );
74 + $minimum = $rule->getMinimum() ? (int) $rule->getMinimum() : 1;
75 + $ranges = 'range' === $this->getContainer()->getSettings()->get( 'quantity_type', 'range' );
76 +
77 + // what the customer pays below the first tier
78 + $base = __( 'Regular price', 'tier-pricing-table' );
79 + if ( 'flat' === $rule->getPricingType() ) {
80 + if ( $rule->getSalePrice() ) {
81 + $base = wc_price( $rule->getSalePrice() );
82 + } elseif ( $rule->getRegularPrice() ) {
83 + $base = wc_price( $rule->getRegularPrice() );
84 + }
85 + } elseif ( $rule->getDiscount() ) {
86 + /* translators: %s: percentage */
87 + $base = esc_html( sprintf( __( '%s%% off', 'tier-pricing-table' ), $rule->getDiscount() ) );
88 + }
89 +
90 + $rows = array();
91 + if ( $quantities[0] > $minimum ) {
92 + $rows[] = array( $this->quantityLabel( $minimum, $quantities[0] - 1, $ranges ), $base, false );
93 + }
94 +
95 + foreach ( $quantities as $index => $quantity ) {
96 + $next = $quantities[ $index + 1 ] ?? null;
97 + $label = null === $next ? number_format_i18n( $quantity ) . '+' : $this->quantityLabel( $quantity, $next - 1, $ranges );
98 + $value = $percentage ? esc_html( $values[ $index ] . '%' ) : wc_price( $values[ $index ] );
99 + $rows[] = array( $label, $value, true );
100 + }
101 +
102 + $label = sprintf(
103 + /* translators: 1: "fixed" or "percentage", 2: "individual" or "mix & match" */
104 + __( 'Tiers (%1$s, %2$s)', 'tier-pricing-table' ),
105 + $percentage ? __( 'percentage', 'tier-pricing-table' ) : __( 'fixed', 'tier-pricing-table' ),
106 + 'individual' === $rule->getApplyingType() ? __( 'individual', 'tier-pricing-table' ) : __( 'mix & match', 'tier-pricing-table' )
107 + );
108 + ?>
109 + <div class="tpt-rules-list__line tpt-rules-list__line--chips">
110 + <span class="tpt-rules-list__muted"><?php echo esc_html( $label ); ?></span>
111 + </div>
112 + <table class="tpt-rules-list__tiers">
113 + <thead>
114 + <tr>
115 + <th><?php esc_html_e( 'Quantity', 'tier-pricing-table' ); ?></th>
116 + <th><?php echo $percentage ? esc_html__( 'Discount', 'tier-pricing-table' ) : esc_html__( 'Price', 'tier-pricing-table' ); ?></th>
117 + </tr>
118 + </thead>
119 + <tbody>
120 + <?php foreach ( $rows as list( $quantityLabel, $value, $isTier ) ) : ?>
121 + <tr>
122 + <td><?php echo esc_html( $quantityLabel ); ?></td>
123 + <td class="<?php echo $isTier ? 'is-tier' : ''; ?>"><?php echo wp_kses_post( $value ); ?></td>
124 + </tr>
125 + <?php endforeach; ?>
126 + </tbody>
127 + </table>
128 + <?php
129 + }
130 +
131 + /**
132 + * "10 - 29" with ranges on, "10" otherwise (or when the range is a single quantity).
133 + */
134 + protected function quantityLabel( int $from, int $to, bool $ranges ): string {
135 + if ( $to <= $from || ! $ranges ) {
136 + return number_format_i18n( $from );
137 + }
138 +
139 + return number_format_i18n( $from ) . ' - ' . number_format_i18n( $to );
140 + }
141 +
142 + protected function renderQuantityLimits( GlobalPricingRule $rule ) {
143 + $chips = array();
144 +
145 + if ( $rule->getMinimum() ) {
146 + /* translators: %s: quantity */
147 + $chips[] = sprintf( __( 'Min <b>%s</b>', 'tier-pricing-table' ), esc_html( number_format_i18n( $rule->getMinimum() ) ) );
148 + }
149 + if ( ! empty( $rule->data['maximum_quantity'] ) ) {
150 + /* translators: %s: quantity */
151 + $chips[] = sprintf( __( 'Max <b>%s</b>', 'tier-pricing-table' ), esc_html( number_format_i18n( (int) $rule->data['maximum_quantity'] ) ) );
152 + }
153 + if ( ! empty( $rule->data['group_of_quantity'] ) ) {
154 + /* translators: %s: quantity */
155 + $chips[] = sprintf( __( 'Step <b>%s</b>', 'tier-pricing-table' ), esc_html( number_format_i18n( (int) $rule->data['group_of_quantity'] ) ) );
156 + }
157 +
158 + if ( $chips ) {
159 + $this->renderLine( __( 'Quantity', 'tier-pricing-table' ), $chips );
160 + }
161 + }
162 +
163 + /**
164 + * @param string[] $chips Escaped HTML.
165 + */
166 + protected function renderLine( string $label, array $chips ) {
167 + ?>
168 + <div class="tpt-rules-list__line tpt-rules-list__line--chips">
169 + <span class="tpt-rules-list__muted"><?php echo esc_html( $label ); ?></span>
170 + <?php foreach ( $chips as $chip ) : ?>
171 + <span class="tpt-rules-list__chip"><?php echo wp_kses_post( $chip ); ?></span>
172 + <?php endforeach; ?>
173 + </div>
174 + <?php
139 175 }
140 176 }