回答这个问题需要分为四个步骤来完成。
1. 在woocommerce结账页面上添加4个自定义字段。你现在的做法并不是最佳实践,应该通过使用actions/filters来完成。
2. 当向后端发送请求时,验证数据,以确保用户选择和输入了必要的内容。
3. 将数据保存到订单中作为文章元素,以便以后可以访问。
4. 实现javascript切换功能,以便根据用户对第一个问题的选择,显示相关字段。
在woocommerce结账中添加自定义字段
您需要找到适当的操作,以添加字段。我建议使用操作
woocommerce_after_checkout_billing_form
,因为它会在所有个人/帐单信息之后显示字段。
if( !function_exists( 'custom_checkout_question_field' ) ) {
function custom_checkout_question_field( $checkout ) {
echo "<div class='custom-question-field-wrapper custom-question-1'>";
echo sprintf( '<p>%s</p>', __( "Sei un privato cittadino, un'azienda o un libero professionista?" ) );
woocommerce_form_field( 'custom_question_field', array(
'type' => 'radio',
'required' => true,
'class' => array('custom-question-field', 'form-row-wide'),
'options' => array(
'privato_cittadino' => 'Privato cittadino',
'azienda_professionista' => 'Azienda o libero professionista',
),
), $checkout->get_value( 'custom_question_field' ) );
woocommerce_form_field( 'custom_question_text_codice_fiscale', array(
'type' => 'text',
'label' => 'Codice Fiscale',
'required' => true,
'class' => array('custom-question-codice-fiscale-field', 'form-row-wide'),
), $checkout->get_value( 'custom_question_text_codice_fiscale' ) );
woocommerce_form_field( 'custom_question_text_p_iva', array(
'type' => 'text',
'label' => 'P.Iva',
'required' => true,
'class' => array('custom-question-p-iva-field', 'form-row-wide'),
), $checkout->get_value( 'custom_question_text_p_iva' ) );
woocommerce_form_field( 'custom_question_text_ragione_sociale', array(
'type' => 'text',
'label' => 'Ragione sociale',
'required' => true,
'class' => array('custom-question-ragione-sociale-field', 'form-row-wide'),
), $checkout->get_value( 'custom_question_text_ragione_sociale' ) );
echo "</div>";
}
add_action( 'woocommerce_after_checkout_billing_form', 'custom_checkout_question_field' );
}
Javascript前端切换
您需要添加自定义JavaScript代码,以便根据问题切换3个附加字段。我已创建一个PHP函数,它将输出一个带有一些JavaScript的HTML script
标签。然后将其附加到wp_footer
操作上。
这不是推荐的方法,您应该将其分成一个新的js文件,并在需要时将文件加入队列中。
请参见:https://codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts
if( !function_exists( 'custom_question_conditional_javascript' ) ) {
function custom_question_conditional_javascript() {
?>
<script type="text/javascript">
(function() {
if(!window.jQuery) {
return;
};
var $ = window.jQuery;
$(document).ready(function() {
var questionField = $('.custom-question-field'),
codiceFiscaleField = $('.custom-question-codice-fiscale-field'),
pIvaField = $('.custom-question-p-iva-field'),
ragioneSocialeField = $('.custom-question-ragione-sociale-field ');
if(
!questionField.length ||
!codiceFiscaleField.length ||
!pIvaField.length ||
!ragioneSocialeField.length
) {
return;
}
function toggleVisibleFields() {
var selectedAnswer = questionField.find('input:checked').val();
if(selectedAnswer === 'privato_cittadino') {
codiceFiscaleField.show();
pIvaField.hide();
ragioneSocialeField.hide();
} else if(selectedAnswer === 'azienda_professionista') {
codiceFiscaleField.hide();
pIvaField.show();
ragioneSocialeField.show();
} else {
codiceFiscaleField.hide();
pIvaField.hide();
ragioneSocialeField.hide();
}
}
$(document).on('change', 'input[name=custom_question_field]', toggleVisibleFields);
$(document).on('updated_checkout', toggleVisibleFields);
toggleVisibleFields();
});
})();
</script>
<?php
}
add_action( 'wp_footer', 'custom_question_conditional_javascript', 1000 );
}
从提交的POST请求中获取字段
您需要从php的$_POST
数组中获取数据,并对其进行净化以防止SQL注入或其他恶意代码。我创建了一个帮助函数,它将通过提供的键在数组中获取所有字段,并使用WordPress的sanitize_text_field
帮助函数进行净化。
在验证和添加文章元数据时,可以使用此帮助程序。
if( !function_exists( 'custom_checkout_question_get_field_values' ) ) {
function custom_checkout_question_get_field_values() {
$fields = [
'custom_question_field' => '',
'custom_question_text_codice_fiscale' => '',
'custom_question_text_p_iva' => '',
'custom_question_text_ragione_sociale' => '',
];
foreach( $fields as $field_name => $value ) {
if( !empty( $_POST[ $field_name ] ) ) {
$fields[ $field_name ] = sanitize_text_field( $_POST[ $field_name ] );
} else {
unset( $fields[ $field_name ] );
}
}
return $fields;
}
}
后端验证字段
验证很重要,因为前端不可信,用户很容易在前端修改必填字段。您可以使用Woocommerce的woocommerce_checkout_process
操作来验证字段,并在不符合要求时添加错误消息。
if( !function_exists( 'custom_checkout_question_field_validate' ) ) {
function custom_checkout_question_field_validate() {
$field_values = custom_checkout_question_get_field_values();
if ( empty( $field_values['custom_question_field'] ) ) {
wc_add_notice( 'Please select an answer for the question.', 'error' );
}
if (
$field_values['custom_question_field'] === 'privato_cittadino' &&
empty( $field_values['custom_question_text_codice_fiscale'] )
) {
wc_add_notice( 'Please enter codice fiscale.', 'error' );
}
if (
$field_values['custom_question_field'] === 'azienda_professionista' &&
empty( $field_values['custom_question_text_p_iva'] )
) {
wc_add_notice( 'Please enter p iva.', 'error' );
}
if (
$field_values['custom_question_field'] === 'azienda_professionista' &&
empty( $field_values['custom_question_text_ragione_sociale'] )
) {
wc_add_notice( 'Please enter ragione sociale.', 'error' );
}
}
add_action( 'woocommerce_checkout_process', 'custom_checkout_question_field_validate' );
}
保存自定义文章元数据到订单
您可以使用woocommerce woocommerce_checkout_update_order_meta
操作来将附加的文章元数据保存到订单文章类型中。在这里,我们将使用上面创建的helper函数 custom_checkout_question_get_field_values
从php $ _POST
数组中获取所有字段,并在保存每个字段到文章元数据之前对其进行清理。
if( !function_exists( 'custom_checkout_question_field_save' ) ) {
function custom_checkout_question_field_save( $order_id ) {
$field_values = custom_checkout_question_get_field_values();
foreach( $field_values as $field_name => $value ) {
if( !empty( $field_values[ $field_name ] ) ) {
update_post_meta( $order_id, $field_name, $value );
}
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_question_field_save' );
}