← All changes
|
src/Addons/RequestAQuote/Frontend/QuoteFormDisplay.php
+59
-6
7.1.1
→
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" |