You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce自定义尺码变体与Addify报价插件数据获取异常

问题:WooCommerce + Addify报价插件无法获取尺码数量数据

我基于WooCommerce和Addify的Request a Quote插件开发项目,已实现用户按尺码提交多数量的自定义变体功能,但在提交报价请求或添加至报价购物车时,AJAX或会话无法获取到服饰尺码(Apparel Sizes)的数据。以下是我在子主题variable.php中编写的代码:

<?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
    <p class="stock out-of-stock"><?php echo esc_html( apply_filters( 'woocommerce_out_of_stock_message', __( 'This product is currently out of stock and unavailable.', 'woocommerce' ) ) ); ?></p>
<?php else : ?>
    <table class="variations" cellspacing="0" role="presentation">
        <tbody>
            <?php foreach ( $attributes as $attribute_name => $options ) : ?>
                <?php if ( 'pa_apparel-size' === sanitize_title( $attribute_name ) ) : ?>
                    <?php
                        // 获取排序后的尺码属性术语
                        $terms = get_terms( array(
                            'taxonomy'   => 'pa_apparel-size',
                            'hide_empty' => false,
                            'orderby'    => 'menu_order',
                        ) );

                        // 过滤当前产品使用的尺码
                        $sorted_options = array_filter(
                            wp_list_pluck( $terms, 'slug' ),
                            function( $slug ) use ( $options ) {
                                return in_array( $slug, $options );
                            }
                        );
                    ?>
                    <tr>
                        <th class="label"><?php echo wc_attribute_label( $attribute_name ); ?></th>
                        <td class="value">
                            <div class="size-qty-horizontal">
                                <?php foreach ( $sorted_options as $option ) :
                                    $term = get_term_by( 'slug', $option, $attribute_name );
                                    $label = $term && ! is_wp_error( $term ) ? $term->name : strtoupper( str_replace( '-', ' ', $option ) ); ?>
                                    <div class="size-block">
                                        <div class="size-label"><?php echo esc_html( $label ); ?></div>
                                        <input type="number" name="variation_qty[<?php echo esc_attr( $option ); ?>]" min="0" value="0" />
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </td>
                    </tr>
                <?php else : ?>
                    <tr>
                        <th class="label"><label for="<?php echo esc_attr( sanitize_title( $attribute_name ) ); ?>"><?php echo wc_attribute_label( $attribute_name ); ?></label></th>
                        <td class="value">
                            <?php
                                wc_dropdown_variation_attribute_options(
                                    array(
                                        'options'   => $options,
                                        'attribute' => $attribute_name,
                                        'product'   => $product,
                                    )
                                );
                                echo end( $attribute_keys ) === $attribute_name ? wp_kses_post( apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . esc_html__( 'Clear', 'woocommerce' ) . '</a>' ) ) : '';
                            ?>
                        </td>
                    </tr>
                <?php endif; ?>
            <?php endforeach; ?>
        </tbody>
    </table>
    <?php do_action( 'woocommerce_after_variations_table' ); ?>

    <div class="single_variation_wrap">
        <?php
            do_action( 'woocommerce_before_single_variation' );
            do_action( 'woocommerce_single_variation' );
            do_action( 'woocommerce_after_single_variation' );
        ?>
    </div>
<?php endif; ?>

<?php do_action( 'woocommerce_after_variations_form' ); ?>

解决方案

问题根源在于自定义的variation_qty字段未被Addify插件的AJAX处理逻辑识别,需要通过钩子将尺码数量数据注入会话和报价项。

1. 拦截AJAX请求,保存尺码数量到会话

将以下代码添加到子主题functions.php:

add_action('wp_ajax_addify_add_to_quote', 'save_size_qty_to_session', 1);
add_action('wp_ajax_nopriv_addify_add_to_quote', 'save_size_qty_to_session', 1);

function save_size_qty_to_session() {
    if (isset($_POST['variation_qty']) && is_array($_POST['variation_qty'])) {
        // 过滤掉数量为0的尺码
        $valid_qty = array_filter($_POST['variation_qty'], function($qty) {
            return (int)$qty > 0;
        });
        
        if (!empty($valid_qty)) {
            $product_id = isset($_POST['product_id']) ? (int)$_POST['product_id'] : 0;
            if ($product_id) {
                WC()->session->set('addify_size_qty_' . $product_id, $valid_qty);
            }
        }
    }
}

2. 将尺码数据注入报价项

继续在functions.php中添加:

add_filter('addify_raq_item_data', 'inject_size_qty_to_quote_item', 10, 2);

function inject_size_qty_to_quote_item($item_data, $item) {
    $product_id = $item['product_id'];
    $size_qty = WC()->session->get('addify_size_qty_' . $product_id);
    
    if ($size_qty && is_array($size_qty)) {
        foreach ($size_qty as $size_slug => $qty) {
            $term = get_term_by('slug', $size_slug, 'pa_apparel-size');
            $size_name = $term ? $term->name : ucwords(str_replace('-', ' ', $size_slug));
            
            $item_data[] = array(
                'key' => $size_name,
                'value' => $qty . ' 件'
            );
        }
        // 清除会话数据,避免重复添加
        WC()->session->__unset('addify_size_qty_' . $product_id);
    }
    
    return $item_data;
}

3. 确保前端AJAX携带尺码数据

如果Addify默认未抓取variation_qty字段,添加以下JS代码(可放入子主题自定义JS文件或通过wp_enqueue_script加载):

jQuery(document).on('click', '.addify-add-to-quote-button', function(e) {
    e.preventDefault();
    
    var $form = jQuery(this).closest('form.variations_form');
    var variationQty = {};
    
    // 收集尺码数量
    $form.find('input[name^="variation_qty"]').each(function() {
        var sizeSlug = jQuery(this).attr('name').match(/variation_qty\[(.*?)\]/)[1];
        variationQty[sizeSlug] = jQuery(this).val();
    });
    
    // 发送AJAX请求
    jQuery.ajax({
        url: addify_raq_params.ajax_url,
        type: 'POST',
        data: {
            action: 'addify_add_to_quote',
            product_id: $form.find('input[name="product_id"]').val(),
            variation_qty: variationQty
        },
        success: function(response) {
            if (response.success) {
                // 更新报价计数
                jQuery('.addify-raq-count').text(response.data.count);
                // 可选:显示成功提示
                alert('已添加到报价请求');
            }
        }
    });
});

注意事项

  • 确保WooCommerce会话功能已启用(默认启用)
  • 若使用缓存插件,需排除报价相关页面的缓存
  • 测试时清空浏览器缓存,避免旧JS代码干扰

内容的提问来源于stack exchange,提问作者Jeric Yambot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:32:03