PluginProbe
Tiered Pricing Table for WooCommerce / 8.0.2
Tiered Pricing Table for WooCommerce v8.0.2
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
← All changes | src/Addons/RequestAQuote/Frontend/QuoteFormDisplay.php +59 -6 7.1.4 → 8.0.2 View file →
@@ -12,8 +12,61 @@
12 12 public static function addModalToRender( $form, $productId ) {
13 13 self::$renderedModals[ $productId ] = $form;
14 14 }
15 15
16 + /**
17 + * The product a modal is keyed by: variations share their parent's modal.
18 + *
19 + * @param int $productId
20 + *
21 + * @return int
22 + */
23 + public static function getModalProductId( $productId ): int {
24 + $product = wc_get_product( $productId );
25 +
26 + if ( $product && $product->get_parent_id() ) {
27 + return (int) $product->get_parent_id();
28 + }
29 +
30 + return (int) $productId;
31 + }
32 +
33 + /**
34 + * Make sure a variable product's modal is printed in wp_footer even if no quote button rendered
35 + * during the page request: with more variations than the AJAX threshold, every variation's
36 + * pricing table (and its button) is fetched by AJAX later, and no default variation may be
37 + * selected at all. Fires only in the main page render, never in the AJAX handler.
38 + *
39 + * @param \WC_Product|mixed $parentProduct
40 + * @param mixed $variationId
41 + * @param array $settings
42 + */
43 + public function registerVariableProductModal( $parentProduct, $variationId = null, $settings = array() ) {
44 +
45 + if ( ! ( $parentProduct instanceof \WC_Product ) || ! TierPricingTablePlugin::isVariableProductSupported( $parentProduct ) ) {
46 + return;
47 + }
48 +
49 + // Only the product page switches variations (and loads their tables by AJAX). Tables in shop
50 + // loops, related products etc. never do, so they don't need a modal registered up front.
51 + if ( ( $settings['display_context'] ?? 'product-page' ) !== 'product-page' ) {
52 + return;
53 + }
54 +
55 + $parentId = $parentProduct->get_id();
56 +
57 + if ( isset( self::$renderedModals[ $parentId ] ) ) {
58 + return;
59 + }
60 +
61 + $formId = PriceManager::getPricingRule( $parentId )->data['tier_pricing_table_quote_form_id'] ?? null;
62 + $form = $formId ? RequestQuoteForm::get( (string) $formId ) : null;
63 +
64 + if ( $form ) {
65 + self::addModalToRender( $form, $parentId );
66 + }
67 + }
68 +
16 69 public function __construct() {
17 70 // Initialize and register hooks for Layout Adapters
18 71 ( new Adapters\TableAdapter() )->registerHooks();
19 72 ( new Adapters\HorizontalTableAdapter() )->registerHooks();
@@ -22,8 +75,9 @@
22 75 ( new Adapters\DropdownAdapter() )->registerHooks();
23 76 ( new Adapters\PlainTextAdapter() )->registerHooks();
24 77 ( new Adapters\AddToCartAdapter() )->registerHooks();
25 78
79 + add_action( 'tiered_pricing_table/before_rendering_tiered_pricing', array( $this, 'registerVariableProductModal' ), 10, 3 );
26 80 add_action( 'wp_footer', array( $this, 'renderFormModal' ) );
27 81 add_action( 'wp_enqueue_scripts', array( $this, 'enqueueAssets' ) );
28 82 add_action( 'template_redirect', array( $this, 'handleSuccessNotice' ) );
29 83 }
@@ -175,16 +229,15 @@
175 229 str_replace( ' ', '', $field['allowedTypes'] ) ) ) : '';
176 230 ?>
177 231 <input type="file" id="tpt_field_<?php echo esc_attr( $name ); ?>"
178 232 name="<?php echo esc_attr( $name ); ?>"
179 - <?php echo $allowedTypes ? 'accept="' . $allowedTypes . '"' : ''; ?>
233 + <?php if ( $allowedTypes ) : ?>accept="<?php echo esc_attr( $allowedTypes ); ?>"<?php endif; ?>
180 234 <?php echo $required ? 'required' : ''; ?>>
181 235
182 236 <?php else : ?>
183 237 <?php
184 238 $syncClass = ( $type === 'number' && ! empty( $field['syncWithQuantity'] ) ) ? 'tpt-quote-sync-quantity' : '';
185 - $maxLengthAttr = in_array( $type,
186 - array( 'text', 'email', 'tel', 'url' ) ) ? 'maxlength="255"' : '';
239 + $maxLength = in_array( $type, array( 'text', 'email', 'tel', 'url' ), true ) ? 255 : 0;
187 240
188 241 $min = 1;
189 242 if ( $type === 'number' && ! empty( $field['syncWithQuantity'] ) && $productId ) {
190 243 $pricingRule = PriceManager::getPricingRule( $productId );
@@ -193,18 +246,18 @@
193 246 $min = $ruleMin;
194 247 }
195 248 }
196 249
197 - $minAttr = ( $type === 'number' ) ? 'min="' . esc_attr( $min ) . '"' : '';
250 + $minValue = ( $type === 'number' ) ? (string) $min : '';
198 251
199 252 if ( $type === 'date' && ! empty( $field['disablePastDates'] ) ) {
200 - $minAttr = 'min="' . esc_attr( wp_date( 'Y-m-d' ) ) . '"';
253 + $minValue = wp_date( 'Y-m-d' );
201 254 }
202 255 ?>
203 256 <input type="<?php echo esc_attr( $type ); ?>" id="tpt_field_<?php echo esc_attr( $name ); ?>"
204 257 name="<?php echo esc_attr( $name ); ?>"
205 258 class="<?php echo esc_attr( $syncClass ); ?>"
206 - value="<?php echo esc_attr( $value ); ?>" <?php echo $maxLengthAttr; ?> <?php echo $minAttr; ?> <?php echo $required ? 'required' : ''; ?> <?php echo ( ! empty( $field['hasPlaceholder'] ) && $placeholder ) ? 'placeholder="' . esc_attr( $placeholder ) . '"' : ''; ?>>
259 + value="<?php echo esc_attr( $value ); ?>" <?php if ( $maxLength ) : ?>maxlength="<?php echo esc_attr( $maxLength ); ?>"<?php endif; ?> <?php if ( '' !== $minValue ) : ?>min="<?php echo esc_attr( $minValue ); ?>"<?php endif; ?> <?php echo $required ? 'required' : ''; ?> <?php echo ( ! empty( $field['hasPlaceholder'] ) && $placeholder ) ? 'placeholder="' . esc_attr( $placeholder ) . '"' : ''; ?>>
207 260 <?php endif; ?>
208 261
209 262 <?php if ( ! empty( $field['hasDescription'] ) && $description ) : ?>
210 263 <p class="tpt-field-description"