Maybe a silly question, but how do I set a Form so that the email field is displayed but not required?
Hello, it depends on what kind of Form this is, and whether the email field is a custom field, a generic field, or a standard user email field.
- Is this a User form or a post form?
- Is the email field a standard User email field, a custom field created with Types, or a generic email field created in the Form builder?
- If it's a custom field created with Types, is it set to be "required" or not in the custom field settings?
It's a User form, with the standard email field.
The email field is required by default, but you can use the CRED API cred_filter_field_before_add_to_form to remove that requirement for all forms:
// make the email field in a User form not required
add_filter('cred_filter_field_before_add_to_form', 'tssupp_not_required_email_func', 10, 1);
function tssupp_not_required_email_func($field){
if(isset($field['id']) && in_array($field['id'], array('user_email'))){
// in some cases $fields['data'] is an empty string, so you'll need to first set it's expected format for PHP 7.1 compatibility
if (!is_array($field['data'])) {
$field['data'] = array();
}
unset($field['data']['validate']['required']);
}
return $field;
}
I get "No new user can be created if the login name is empty."
The form it's already set to create automatically pass, user and nickname.
Maybe this custom function I'm using can cause this problem?
// Change the customer role from Customer to Seller and update user fields
add_action('cred_save_data', 'cred_update_customer_fields',10,2);
function cred_update_customer_fields($user_id, $form_data) {
$username = strtolower($_REQUEST['first_name'] . $_REQUEST['last_name']) . $userid ;
$customer_id = "MTI-" . $userid;
if ( isset ($_REQUEST['customer_select_role'])){
$role = $_REQUEST['customer_select_role'];
}else{
$role = 'customer';
}
$userdata = array (
'ID' => $user_id,
'nickname' => $username,
'user_nicename' => $username,
'user_login' => $username,
'user_role' => $role
);
// if is a new created user
if ($form_data['id'] == 5466 || $form_data['id'] == 1574)
{
wp_update_user($userdata);
}
// if is a edited user
if ($form_data['id'] == 9077)
{
wp_update_user($userdata);
// modify the user role to match the selected option
$user_meta = get_userdata($user_id);
$user_role = $user_meta->roles;
$role = $_REQUEST['customer_select_role'];
$u = new WP_User( $user_id );
$u->remove_role( $user_role ); //cred form roles field
$u->set_role( $role );
}
}
I have turned on debug, and this line
if(in_array($field['id'], array('user_email'))){
generate this error
Notice: Trying to access array offset on value of type null
Okay since there are multiple custom code snippets involved here, it might be best for me to work with a clone of your site so I can monitor the code execution and see the form itself. I can create a clone using the All in One WP Migration plugin if you provide login credentials in the private reply fields here. Please let me know where I can find this Form on the frontend of the site so I can run some tests.
I have added an admin link to a staging site where I add all snippets to test before I apply them to the live site.
Sorry, I don't understand what you mean. Where can I access the staging site? I don't see an obvious link anywhere in the wp-admin area or the top bar. I'm attaching a screenshot of my wp-admin screen.
The screenshot you sent me IS the staging site 😉
You are already logged in and can edit anything you want.
Okay but I don't see the custom code snippet you already referred to anywhere, i.e.
add_action('cred_save_data', 'cred_update_customer_fields',10,2);
I was expecting to see a staging environment as close to production as possible where I could go ahead and test everything out. If you're saying I need to add both code snippets that's fine, I can do that, but I want to confirm that's the only difference between staging and production. Also, please let me know where to find the User Form on the front-end of the staging site so I can test.
This site is very close to the live site. I get the same error in both.
Even better because on this one almost all unnecessary plugins are disabled.
The snippet is added to my custom plugin
hidden link
Here you can try to add a user without email and see the debug error:
hidden link
The user form is this one
hidden link
Okay I've updated the custom code snippet to prevent this debug notice. The issue occurs when certain fields like generic fields are added to the form. The following update resolves the debug notice:
add_filter('cred_filter_field_before_add_to_form', 'tssupp_not_required_email_func', 10, 1);
function tssupp_not_required_email_func($field){
if(isset($field['id']) && in_array($field['id'], array('user_email'))){
// in some cases $fields['data'] is an empty string, so you'll need to first set it's expected format for PHP 7.1 compatibility
if (!is_array($field['data'])) {
$field['data'] = array();
}
unset($field['data']['validate']['required']);
}
return $field;
}
I was able to submit the form successfully, but I'll need you to verify the other custom code worked as expected.
Still not working.
I get these errors
hidden link
Here a small screencast to show my registration procedure
hidden link
Okay thanks for the additional information. I understand the problem better now, but I do not think there is a simple solution. When a User Form is set to automatically generate the username, Forms is designed to generate a unique username using part of the email address (the text before "@") in the template. Since our custom code has removed the requirement for an email address, the email field may be empty, and the error you see is generated during array/string manipulation because the system expects an email address to be provided. Without the email, the username is not generated, and without a username the User is not created.
Unfortunately I do not think you will be able to use cred_save_data or cred_submit_complete to generate a username without an email address provided in the standard email field because neither hook will be triggered. User creation will fail, so cred_save_data and cred_submit_complete will not fire.
You could work around this by using the cred_before_save_data hook to generate the username programmatically using your own custom algorithm. However, since the cred_before_save_data hook is triggered before the User is actually created, there is no User ID available yet when the callback is executed. Example that sets username to somethingunique:
add_action('cred_before_save_data', 'tssupp_autogen_username',10,1);
function tssupp_autogen_username($form_data)
{
// if a specific form
$forms = array( 123, 456 );
if ( in_array( $form_data['id'], $forms ) )
{
$_POST['user_login'] = 'somethingunique'; // generate unique username here based on your own algorithm
}
}
By setting the user_login information here in the $_POST superglobal, the autogeneration process in Forms is bypassed, and the empty email address is no longer a problem for User creation.
I though I could execute the 'cred_before_save_data' function, with a temporary unique number, and then use a 'cred_save_data' function to set the proper username.
Something like this
// Create temporary username
add_action('cred_before_save_data', 'temp_username',10,1);
function temp_username($form_data)
{
// if a specific form
$forms = array( 5466, 1574 );
if ( in_array( $form_data['id'], $forms ) )
{
$_POST['user_login'] = date('YmdHms'); // generate almost unique username based on timestamp
}
}
// Set proper username
add_action('cred_save_data','func_proper_username',12,2);
function func_proper_username'($user_id,$form_data) {
$username = strtolower($_REQUEST['first_name'] . $_REQUEST['last_name']) . $userid ;
$userdata = array (
'ID' => $user_id,
'user_login' => $username
);
$forms = array( 5466, 1574 );
if ( in_array( $form_data['id'], $forms ) ) {
wp_update_user($userdata);
}
}
Sadly, the second function doesn't change the username.
I have tested also with 'cred_submit_complete' but didn't help.
Do I miss something?