If you want your sanitization callback to apply only to a specific settings field (i.e. a database option registered using register_setting()
), then you would want to use a different callback for each of your settings fields. E.g.
// 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' );
Or you can use a closure with 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' );
} );
And why do you call add_option()
and update_option()
in your callback (my_settings_settings_validation()
)? I mean, register_setting()
is intended for registering an option that will be automatically added/updated whenever the value is changed via your settings form, so you shouldn’t need to update the value manually.
And if you actually wanted those settings be part of a single database option named my-settings
, then you would want to save the option an array, then call register_setting()
just once and use my-settings[<field>]
in your input’s name
attribute. E.g.
// 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' );
BTW, you could simply add required
to your field HTML, but it’s always a good idea to validate both on the client-side (browser) and server-side.
Also, if I were you, I’d probably use the plural “notices” as in my_option_notices
.. but that’s just my own preference. =)