php - 在 WooCommerce 中启用自定义条件注册字段验证

标签 php wordpress woocommerce registration account

根据 This Guideprevious question 的建议,我在 WooCommerce 中创建了一个注册表单,其中的字段是否可见取决于下拉/选择字段的值。在下拉列表中选择关联选项后变得可见的字段应该是必需的,但我在获取此功能时遇到问题。

我相信我的问题来自这样一个事实:我的插件中调用“get_custom_fields”函数的任何函数都会获取手动输入的字段数组的初始值。在此声明中,我将最初隐藏的字段分配为“off”类,这允许在隐藏时跳过它。

如何根据当前是否具有“off”类而不是是否使用“off”类初始化来要求这些字段?我将在下面发布我的插件代码。

<?php
/*
Plugin Name: Education - Custom Account Fields
Plugin Author: Case Silva
*/

//Create Custom Fields
if(!function_exists('get_custom_fields')){
    function get_custom_fields(){
        return apply_filters('custom_fields', array(
            'verified_education_acct' => array(
                'type' => 'checkbox',
                'label' => __('Verified?'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_registration' => true,
                'hide_in_checkout' => true
            ),
            'customer_id_num' => array(
                'type' => 'text',
                'label' => __('Customer ID# (Acumatica)'),
                'placeholder' => __('e.g. 1234567890'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => true,
                'hide_in_registration' => true
            ),
            'account_type' => array(
                'type' => 'select',
                'label' => __('What type of account will this be?'),
                'options' => array(
                    '' => __('Select an option...'),
                    1 => __('Education'),
                    2 => __('Standard')
                ),
                'required' => true,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_trigger' => true
            ),
            'school_name' => array(
                'type' => 'text',
                'label' => __('School Name'),
                'class' => array('form-row-wide off'),
                'placeholder' => __('e.g. North Middle School'),
                'required' => true,
                'hide_in_account' => false,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_triggered_by' => 'account_type',
                'js_show_val' => '1'
            ),
            'school_address' => array(
                'type' => 'text',
                'label' => __('School Address'),
                'class' => array('form-row-wide off'),
                'placeholder'=> __('e.g. 123 Main St.'),
                'required' => true,
                'hide_in_account' => false,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_triggered_by' => 'account_type',
                'js_show_val' => '1'
            ),
            'school_city' => array(
                'type' => 'text',
                'label' => __('School City'),
                'class' => array('form-row-wide off'),
                'placeholder' => __('e.g. Chicago'),
                'required' => true,
                'hide_in_account' => false,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_triggered_by' => 'account_type',
                'js_show_val' => '1'
            ),

        ));
    }
}

//Add them to User Area
if(!function_exists('print_user_frontend_fields')){
    function print_user_frontend_fields(){
        $fields = get_custom_fields();
        $user_logged_in = is_user_logged_in();
        $enable_js = false;
        $data_js = [];

        //Hide conditional form field (with "off" class)
        echo '<style>p.form-row.off{display:none;}</style>';

        foreach ($fields as $key => $field_args) {
            $value = null;

            if($user_logged_in && !empty($field_args['hide_in_account'])){
                continue;
            }
            if(! $user_logged_in && ! empty($field_args['hide_in_registration'])){
                continue;
            }
            if($is_user_logged_in){
                $user_id = get_edit_user_id();
                $value = get_userdata($user_id, $key);
            }

            $value = isset($field_args['value']) ? $field_args['value'] : $value;
            if(isset($field_args['js_trigger']) && $field_args['js_trigger']){
                $enable_js = true;
            }
            if(isset($field_args['js_triggered_by']) && $field_args['js_show_val']){
                $data_js[$key] = [$field_args['js_triggered_by'] => $field_args['js_show_val']];
            }

            woocommerce_form_field($key, $field_args, $value);
        }
        if($user_logged_id || ! $enable_js) return;

        //jQuery for conditional visibility
        ?>
        <script type = 'text/javascript'>
            jQuery(function($){
                var a = <?php echo json_encode($data_js)?>;
                $.each(a, function(b,o){
                    $.each(o, function(k,v){
                        $('#'+k).on('change', function(){
                            var cf = '#'+b+'_field';
                            if($(this).val()==v && $(cf).hasClass('off')){
                                $(cf).find("input").addClass('required_field');
                                $(cf).removeClass('off');
                            } else if($(this).val() != v && ! $(cf).hasClass('off')){
                                $(cf).find("input").removeClass('required_field');
                                $(cf).addClass('off');
                            }
                        });
                    });
                });
            });
        </script>
        <?php
    }
}

//Add them to Admin Area
if(!function_exists('print_user_admin_fields')){
    function print_user_admin_fields(){
        $fields = get_custom_fields();

        ?>
        <h2><?php _e('Education/School Information'); ?></h2>
        <table class = "form-table" id = "additional-information">
            <tbody>
                <?php foreach ($fields as $key => $field_args) { ?>
                    <?php
                    if(! empty($field_args['hide_in_admin'])){
                        continue;
                    }

                    $user_id = get_edit_user_id();
                    $value = st_get_userdata($user_id, $key);
                    ?>
                    <tr>
                        <th>
                            <label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
                        </th>
                        <td>
                            <?php $field_args['label'] = false; ?>
                            <?php woocommerce_form_field($key, $field_args, $value); ?>
                        </td>
                    </tr>
                <?php } ?>
            </tbody>
        </table>
        <?php
    }
}

//Save them to the database
if(!function_exists('save_acct_fields')){
    function save_acct_fields($customer_id){
        $fields = get_custom_fields();
        $sanitized_data = array();

        foreach ($fields as $key => $field_args) {
            if(! is_field_visible($field_args)){
                continue;
            }

            $sanitize = isset($field_args['sanitize']) ? $field_args['sanitize'] : 'wc_clean';
            $value = isset($_POST[$key]) ? call_user_func($sanitize, $_POST[$key]) : '';

            if(is_userdata($key)){
                $sanitized_data[$key] = $value;
                continue;
            }

            update_user_meta($customer_id, $key, $value);
        }

        if(! empty($sanitized_data)){
            $sanitized_data['ID'] = $customer_id;
            wp_update_user($sanitized_data);
        }
    }
}

//Check if field is visible on page
if(!function_exists('is_field_visible')){
    function is_field_visible($field_args){
        $visible = true;
        $action = filter_input(INPUT_POST, action);

        if(is_admin() && ! empty($field_args['hide_in_admin'])){
            $visible = false;
        } elseif((is_account_page() || $action === 'save_account_details') && is_user_logged_in() && ! empty($field_args['hide_in_account'])){
            $visible = false;
        } elseif((is_account_page() || $action === 'save_account_details') && ! is_user_logged_in() && ! empty($field_args['hide_in_registration'])){
            $visible = false;
        } elseif(is_checkout() && ! empty($field_args['hide_in_checkout'])){
            $visible = false;
        }
        return $visible;
    }
}

//Check if field is predefined
if(!function_exists('is_userdata')){
    function is_userdata($key){
        $userdata = array(
            'user_pass',
            'user_login',
            'user_nicename',
            'user_url',
            'user_email',
            'display_name',
            'nickname',
            'first_name',
            'last_name',
            'description',
            'rich_editing',
            'user_registered',
            'role',
            'jabber',
            'aim',
            'yim',
            'show_admin_bar_front'
        );
        return in_array($key, $userdata);
    }
}

//Verify required fields have value
if(!function_exists('validate_frontend_fields')){
    function validate_frontend_fields($errors){
        $fields = get_custom_fields();

        foreach ($fields as $key => $field_args) {
            //Skip if nothing in 'required' field
            if(empty($field_args['required'])){
                continue;
            }
            //Skip if set to be hidden in account
            if(!isset($_POST['register']) && ! empty($field_args['hide_in_account'])){
                continue;
            }
            //Skip if set to be hidden in registration
            if(isset($_POST['register']) && ! empty($field_args['hide_in_registration'])){
                continue;
            }
            if(empty($_POST[$key])){
                $message = sprintf(__('%s is a required field.'), '<strong>' . $field_args['label'] . '</strong>');
                $errors -> add($key, $message);
            }
        }
        return $errors;
    }
}

//Populate form with submitted data
if(!function_exists('get_edit_user_id')){
    function get_edit_user_id(){
        return isset($_GET['user_id']) ? (int) $_GET['user_id'] : get_current_user_id();
    }
}

//Re-fill entries on Registration error
if(!function_exists('add_post_data_to_account_fields')){
    function add_post_data_to_account_fields($fields){
        if(empty($_POST)){
            return $fields;
        }
        foreach($fields as $key => $field_args){
            if(empty($_POST[$key])){
                $fields[$key]['value'] = '';
                continue;
            }
            $fields[$key]['value'] = $_POST[$key];
        }
        return $fields;
    }
}

//Access saved data
if(!function_exists('st_get_userdata')){
    function st_get_userdata($user_id, $key){
        if(!is_userdata($key)){
            return get_user_meta($user_id, $key, true);         
        }

        $userdata = get_userdata($user_id);

        if(!$userdata || ! isset($userdata->{$key})){
            return '';
        }

        return $userdata->{$key};
    }
}

add_action('woocommerce_register_form', 'print_user_frontend_fields', 10);
add_action('woocommerce_edit_account_form', 'print_user_frontend_fields', 10);

add_action('show_user_profile', 'print_user_admin_fields', 30);
add_action('edit_user_profile', 'print_user_admin_fields', 30);

add_action('woocommerce_created_customer', 'save_acct_fields');
add_action('personal_options_update', 'save_acct_fields');
add_action('edit_user_profile_update', 'save_acct_fields');
add_action('woocommerce_save_account_details', 'save_acct_fields');

add_filter('woocommerce_registration_errors', 'validate_frontend_fields', 10);
add_filter('woocommerce_save_account_details_errors', 'validate_frontend_fields', 10);

add_filter('custom_fields', 'add_post_data_to_account_fields', 10, 1);
?>

最佳答案

对于自定义注册字段验证,您将使用以下代码:

// Conditional Field validation
add_action( 'woocommerce_register_post', 'conditional_fields_validation', 10, 3 );
function conditional_fields_validation( $username, $email, $validation_errors ) {
    if ( isset( $_POST['account_type'] ) && empty($_POST['account_type']) )
        $validation_errors->add( 'account_type', __( 'Please choose an account type', 'woocommerce' ) );

    if( isset( $_POST['account_type'] ) && $_POST['account_type'] === '1' ) {
        if( isset( $_POST['school_name'] ) && empty($_POST['school_name']) )
            $validation_errors->add( 'account_type', __( '"School name" is a required field', 'woocommerce' ) );

        if( isset( $_POST['school_address'] ) && empty($_POST['school_address']) )
            $validation_errors->add( 'account_type', __( '"School address" is a required field', 'woocommerce' ) );

        if( isset( $_POST['school_city'] ) && empty($_POST['school_city']) )
            $validation_errors->add( 'account_type', __( '"School city" is a required field', 'woocommerce' ) );
    }
    return $validation_errors;
}

代码位于事件子主题(或事件主题)的 function.php 文件中。经过测试并有效。

关于php - 在 WooCommerce 中启用自定义条件注册字段验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53620885/

相关文章:

php - 无法在循环中选择表单选项

php - WordPress - 允许在作者页面上发表评论

php - 将隐藏元数据添加到产品 Woocommerce

php - 删除 woocommerce 店面主页标题 php

php - 苹果推送通知反馈服务

php - vagrant homestead无法访问主机(laravel 5.2)

php - CakePHP HABTM 查找具有或不具有关联记录的所有行

Facebook 分享按钮内部服务器错误

php - 将 body 类添加到类别及其所有子类别 |吴商务

javascript - 使用 Gutenberg getEntityRecords 获取 woocommerce 产品类别