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

WooCommerce单品页自定义字段移至summary钩子后验证失效

问题:WooCommerce自定义字段更换钩子后校验失效

问题描述

将自定义字段的渲染钩子从woocommerce_before_add_to_cart_button替换为woocommerce_single_product_summary后,wk_add_to_cart_validation函数的所有校验规则完全失效,无法检查必填字段。

原因分析

woocommerce_before_add_to_cart_button钩子本身位于Add to Cart表单内部,字段会被自动纳入表单提交范围。而woocommerce_single_product_summary钩子的渲染位置如果优先级设置不当,会导致字段被渲染到表单标签外部,提交表单时自定义字段的数值不会被包含进$_POST数据中,校验函数因无法获取字段值,导致逻辑失效。

解决方案

  1. 调整钩子优先级:将wk_add_text_field挂载到woocommerce_single_product_summary时设置优先级为25(默认Add to Cart按钮优先级为30),确保字段渲染在表单内部。
  2. 优化校验逻辑:增加isset判断,避免因$_POST字段不存在引发的报错,同时保证校验逻辑严谨性。

修改后的完整代码

/**
 * Add a custom input field to the product page.
 */
function wk_add_text_field() { ?>
<div class="custom-field-1-wrap">
            <label for="vuoiMontare">Vuoi montare gli attacchi?</label>
            <select id="vuoiMontare" name="vuoiMontare">
                <option value="no"><?php esc_html_e( 'No', 'theme-domain' ); ?></option>
                <option value="si"><?php esc_html_e( 'Sì', 'theme-domain' ); ?></option>
            </select>

            <br>
            <div class="opzioni-attacchi">
                <label for="altezza">
                    <?php esc_html_e( 'Altezza (cm):', 'theme-domain' ); ?>
                </label>
                <input type="text" name='altezza' id='altezza' value=''>
                <br>

                <label for="peso">
                    <?php esc_html_e( 'Peso (kg):', 'theme-domain' ); ?>
                </label>
                <input type="text" name='peso' id='peso' value=''>
                <br>

                <label for="lunghezzaScarpone">
                    <?php esc_html_e( 'Lung. Scarpone (mm):', 'theme-domain' ); ?>
                </label>
                <input type="text" name='lunghezzaScarpone' id='lunghezzaScarpone' value=''>
                <br>

                <label for="eta">
                    <?php esc_html_e( 'Età:', 'webkul' ); ?>
                </label>
                <input type="text" name='eta' id='eta' value=''>
            </div>
        </div>
    <?php
}
// 设置优先级25,确保字段在Add to Cart表单内部渲染
add_action( 'woocommerce_single_product_summary', 'wk_add_text_field', 25 );


/**
 * Validate custom input field value
 */
function wk_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null ) {
    // 先检查字段是否存在
    if ( isset( $_POST['vuoiMontare'] ) && $_POST['vuoiMontare'] === 'si' ) {
        $custom_fields = array( 'altezza', 'peso', 'lunghezzaScarpone', 'eta' );

        foreach ( $custom_fields as $field ) {
            if ( !isset( $_POST[ $field ] ) || empty( $_POST[ $field ] ) ) {
                $passed = false;
                wc_add_notice( sprintf( __( '%s is a required field.', 'theme-domain' ), ucfirst( $field ) ), 'error' );
            }
        }
    }

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'wk_add_to_cart_validation', 10, 4 );

/**
 * Add custom cart item data
 */
function wk_add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
    
    // 检查字段存在性后再获取数据
    $vuoiMontare = isset( $_POST['vuoiMontare'] ) ? sanitize_text_field($_POST['vuoiMontare']) : 'no';
    $altezza = isset( $_POST['altezza'] ) ? sanitize_text_field($_POST['altezza']) : '';
    $peso = isset( $_POST['peso'] ) ? sanitize_text_field($_POST['peso']) : '';
    $lunghezzaScarpone = isset( $_POST['lunghezzaScarpone'] ) ? sanitize_text_field($_POST['lunghezzaScarpone']) : '';
    $eta = isset( $_POST['eta'] ) ? sanitize_text_field($_POST['eta']) : '';
    
    $cart_item_data['pr_field'] = array(
        'vuoiMontare' => $vuoiMontare,
        'altezza' => $altezza,
        'peso' => $peso,
        'lunghezzaScarpone' => $lunghezzaScarpone,
        'eta' => $eta,
    );
    
    return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'wk_add_cart_item_data', 10, 3 );

/**
 * Display custom item data in the cart
 */
function wk_get_item_data( $item_data, $cart_item_data ) {
    if ( isset( $cart_item_data['pr_field'] ) ) {
        $item_data[] = array(
            'key'   => __( 'Montare attacchi?', 'theme-domain' ),
            'value' => wc_clean( $cart_item_data['pr_field']['vuoiMontare'] ),
        );
        $item_data[] = array(
            'key'   => __( 'Altezza', 'theme-domain' ),
            'value' => wc_clean( $cart_item_data['pr_field']['altezza'] ) . 'cm',
        );
        $item_data[] = array(
            'key'   => __( 'Peso', 'theme-domain' ),
            'value' => wc_clean( $cart_item_data['pr_field']['peso'] ) . 'Kg',
        );
        $item_data[] = array(
            'key'   => __( 'Lunghezza scarpone', 'theme-domain' ),
            'value' => wc_clean( $cart_item_data['pr_field']['lunghezzaScarpone'] ) . 'mm',
        );
        $item_data[] = array(
            'key'   => __( 'Età', 'theme-domain' ),
            'value' => wc_clean( $cart_item_data['pr_field']['eta'] ),
        );
    }
    return $item_data;
}
add_filter( 'woocommerce_get_item_data', 'wk_get_item_data', 10, 2 );

关键修改点

  • 替换钩子并设置优先级25,确保字段在Add to Cart表单内部渲染。
  • 校验函数中增加isset判断,避免字段不存在时的逻辑错误。
  • 所有$_POST数据获取环节增加isset判断,防止Undefined index警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:14:55