even if I put in the schema 'type' => array('string','null')
I can’t
POST a request with this field left empty, because WP always respond
with rest_invalid_param
and rest_invalid_email
Actually, adding the 'null'
there does not mean that any empty-ish values like ''
and 0
will be allowed. It just means that an actual null
value is allowed, apart from string. E.g. (these are JSON-encoded data)
{"my_email_field":"[email protected]"}
✅
{"my_email_field":null}
✅
{"my_email_field":""}
❌ (value is empty, but it's not a null)
{"my_email_field":"null"}
❌ (invalid email address..)
So if you had sent a null
, you would have not received those errors.
But then, a null
will unfortunately not pass the isset( $request[ $field_name ] )
validation in WP_REST_Controller::update_additional_fields_for_object()
, hence the update callback will never be called. (See source on GitHub)
- So maybe the WordPress core team should do something about that.. e.g. use
array_key_exists()
instead..
But as stated in @birgire's answer, you can use the anyOf
or oneOf
property to achieve what you were trying to do. (See source on GitHub)
Here's an example which requires the value to be an empty string where the length is exactly 0, or a non-empty string which must be a properly-formatted email address:
'schema' => array(
'type' => 'string',
'oneOf' => array(
// Requires an empty string.
array(
'type' => 'string',
'maxLength' => 0,
),
// Or if it's not empty, then it must be a valid email address.
array(
'type' => 'string',
'format' => 'email',
),
),
'description' => 'Email address to use for contact',
// Your other args.
),
Another one that you might want to try is, a custom validate callback which can be passed via arg_options.validate_callback
like so:
Supplying the custom validate callback:
'schema' => array(
'type' => 'string',
'arg_options' => array(
'validate_callback' => 'myemail_custom_validate_callback',
),
'description' => 'Email address to use for contact',
// Your other args.
),
Sample callback:
function myemail_custom_validate_callback( $value, $request, $param ) {
// Requires an empty string or a valid email address.
if ( 0 === strlen( $value ) || is_email( $value ) ) {
return true;
}
return new WP_Error(
'rest_invalid_param',
sprintf( '%s is not a valid email address', $param )
);
}
Note: Specifying a custom validate callback means the default/core ones (e.g. rest_validate_value_from_schema()
) would no longer be used, unless explicitly called from within your callback.