REGISTER_SETTING和ADD_SETTINGS_ERROR多个字段的验证问题

时间:2021-01-22 作者:Jon

我一直在尝试使用Settings API 这是第一次。我设法拼凑出一个可行的示例,但我一直在研究如何使多个输入字段成为必需的。现在我有一个管理通知显示,但它为每个字段显示,所以如果我有3个字段,它会显示3次。如何使其适用于多个字段?

Register the fields...

function my_settings_init() {
    
    add_settings_section(
        \'my_custom_setting_section\',
        \'Text for the page\',
        \'my_custom_setting_section_callback\',
        \'my-settings\'
    );

        add_settings_field(
            \'field-1\',
            \'Field 1\',
            \'my_settings_step1_markup\',
            \'my-settings\',
            \'my_custom_setting_section\'
        );

        register_setting(\'my-settings\', \'field-1\', \'my_settings_settings_validation\');
    
        add_settings_field(
            \'field-2\',
            \'<span class="my-settings-step">Step 2</span>\',
            \'my_settings_step2_markup\',
            \'my-settings\',
            \'my_custom_setting_section\'
        );

        register_setting(\'my-settings\', \'field-2\', \'my_settings_settings_validation\');
    
        ... More fields below
}

add_action(\'admin_init\', \'my_settings_init\');

My validation callback so far...

function my_settings_settings_validation($input){
    
    $message = null;
    $type = null;
    
    if (null != $input) {
        if (false === get_option(\'my-settings\')) {
            add_option(\'my-settings\', $input);
            $message = __(\'Option added!\');
            $type = \'updated\';
        } else {
            update_option(\'my-settings\', $input);
            $message = __(\'Option updated!\');
            $type = \'updated\';
        }
    }else{
        $message = __(\'There was a problem.\');
        $type = \'error\';
    }
    
    add_settings_error(\'my_option_notice\', \'my_option_notice\', $message, $type);
    
    return $input;
}
任何帮助都将是伟大的,因为我显然错过了一些东西!

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

如果希望清理回调仅应用于特定的设置字段(即使用register_setting()), 然后,您希望对每个设置字段使用不同的回调。例如。

// Sample field HTML:
//<input name="field-1" value="<?php esc_attr( get_option( \'field-1\' ) ); ?>">

function my_settings_field_1_validation( $value ) {
    if ( empty( $value ) ) {
        $value = get_option( \'field-1\' ); // ignore the user\'s changes and use the old database value
        add_settings_error( \'my_option_notice\', \'invalid_field_1\', \'Field 1 is required.\' );
    }

    return $value;
}

function my_settings_field_2_validation( $value ) {
    if ( empty( $value ) ) {
        $value = get_option( \'field-2\' ); // ignore the user\'s changes and use the old database value
        add_settings_error( \'my_option_notice\', \'invalid_field_2\', \'Field 2 is required.\' );
    }

    return $value;
}

// Then in your my_settings_init():
register_setting( \'my-settings\', \'field-1\', \'my_settings_field_1_validation\' );
register_setting( \'my-settings\', \'field-2\', \'my_settings_field_2_validation\' );
或者可以使用闭包register_setting():

function my_settings_field_validation( $value, $field, $name ) {
    if ( empty( $value ) ) {
        $value = get_option( $field ); // ignore the user\'s changes and use the old database value
        add_settings_error( \'my_option_notice\', "invalid_$field", "$name is required." );
    }

    return $value;
}

// Then in your my_settings_init():

register_setting( \'my-settings\', \'field-1\', function ( $value ) {
    return my_settings_field_validation( $value, \'field-1\', \'Field 1\' );
} );

register_setting( \'my-settings\', \'field-2\', function ( $value ) {
    return my_settings_field_validation( $value, \'field-2\', \'Field 2\' );
} );
你为什么打电话add_option()update_option() 在您的回拨中(my_settings_settings_validation())? 我是说,register_setting() 用于注册一个选项,该选项将在通过设置窗体更改值时自动添加/更新,因此您不需要手动更新值。

如果您真的想让这些设置成为名为my-settings, 然后将选项保存为数组,然后调用register_setting() 只需使用一次my-settings[<field>] 在您的输入中name 属性例如。

// Sample field HTML:
//<input name="my-settings[field-1]" value="<?php echo esc_attr( $options[\'field-1\'] ); ?>">
// whereby $options is:
//$options = (array) get_option( \'my-settings\' );

function my_settings_field_validation( $value ) {
    $value = (array) $value;
    $valid = true;

    if ( empty( $value[\'field-1\'] ) ) {
        $valid = false;
        add_settings_error( \'my_option_notice\', \'invalid_field-1\', \'Field 1 is required.\' );
    }

    if ( empty( $value[\'field-2\'] ) ) {
        $valid = false;
        add_settings_error( \'my_option_notice\', \'invalid_field-2\', \'Field 2 is required.\' );
    }

    // Ignore the user\'s changes and use the old database value.
    if ( ! $valid ) {
        $value = get_option( \'my-settings\' );
    }

    return $value;
}

// Then in your my_settings_init():
register_setting( \'my-settings\', \'my-settings\', \'my_settings_field_validation\' );
顺便说一句,你可以简单地添加required 但最好在客户端(浏览器)和服务器端都进行验证。

此外,如果我是你,我可能会使用复数形式;“通知”;如中所示my_option_notices.. 但这只是我自己的喜好。=)