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数据中,校验函数因无法获取字段值,导致逻辑失效。
解决方案
- 调整钩子优先级:将
wk_add_text_field挂载到woocommerce_single_product_summary时设置优先级为25(默认Add to Cart按钮优先级为30),确保字段渲染在表单内部。 - 优化校验逻辑:增加
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
相关产品推荐
相关产品推荐

