Contact Form 7 is a popular form plugin for WordPress. You can use it to create a user registration form on the front-end of your web site. Normally Contact Form 7 will email the form submission to the site administrator, who then has to create the user manually in the Users section of the site admin. However, this process can be automated by hooking into the ‘wpcf7_before_send_mail’ action and creating a user from the submitted form fields.
Contact Form 7 version 3.9 introduced a new API to retrieve the form data and I have not found this documented anywhere, so the code below may help users of 3.9 who are scratching their heads.
The code below is placed in your theme’s functions.php file. You will need to adjust it to reflect your own user registration form title and form field names.
function create_user_from_registration($cfdata) { if (!isset($cfdata->posted_data) && class_exists('WPCF7_Submission')) { // Contact Form 7 version 3.9 removed $cfdata->posted_data and now // we have to retrieve it from an API $submission = WPCF7_Submission::get_instance(); if ($submission) { $formdata = $submission->get_posted_data(); } } elseif (isset($cfdata->posted_data)) { // For pre-3.9 versions of Contact Form 7 $formdata = $cfdata->posted_data; } else { // We can't retrieve the form data return $cfdata; } // Check this is the user registration form if ( $cfdata->title() == 'Your Registration Form Title') { $password = wp_generate_password( 12, false ); $email = $formdata['form-email-field']; $name = $formdata['form-name-field']; // Construct a username from the user's name $username = strtolower(str_replace(' ', '', $name)); $name_parts = explode(' ',$name); if ( !email_exists( $email ) ) { // Find an unused username $username_tocheck = $username; $i = 1; while ( username_exists( $username_tocheck ) ) { $username_tocheck = $username . $i++; } $username = $username_tocheck; // Create the user $userdata = array( 'user_login' => $username, 'user_pass' => $password, 'user_email' => $email, 'nickname' => reset($name_parts), 'display_name' => $name, 'first_name' => reset($name_parts), 'last_name' => end($name_parts), 'role' => 'subscriber' ); $user_id = wp_insert_user( $userdata ); if ( !is_wp_error($user_id) ) { // Email login details to user $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); $message = "Welcome! Your login details are as follows:" . "\r\n"; $message .= sprintf(__('Username: %s'), $username) . "\r\n"; $message .= sprintf(__('Password: %s'), $password) . "\r\n"; $message .= wp_login_url() . "\r\n"; wp_mail($email, sprintf(__('[%s] Your username and password'), $blogname), $message); } } } return $cfdata; } add_action('wpcf7_before_send_mail', 'create_user_from_registration', 1);
Notes:
- If the email address is already associated with an existing user, a new one will not be created.
- You can pass additional fields such as website URL to wp_insert_user – see the documentation.
- If you need to manually approve the user before giving them access, you can create a ‘pending’ role with limited capabilities, and set the script to allocate that role to the new user. You will then have to manually allocate the user to their full role in the site admin once approved.
- Justin Tadlock’s Members plugin is useful for managing WordPress Roles from the admin.
Hello Robin,
First I want to thank you for sharing this snippet,
I am having issues and mine is not working:
function create_user_from_registration($cfdata) {
if (!isset($cfdata->posted_data) && class_exists(‘WPCF7_Submission’)) {
// Contact Form 7 version 3.9 removed $cfdata->posted_data and now
// we have to retrieve it from an API
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$formdata = $submission->get_posted_data();
}
} elseif (isset($cfdata->posted_data)) {
// For pre-3.9 versions of Contact Form 7
$formdata = $cfdata->posted_data;
} else {
// We can’t retrieve the form data
return $cfdata;
}
// Check this is the user registration form
if ( $cfdata->title() == ‘Contact form 1’) {
$password = wp_generate_password( 12, false );
$email = $formdata[‘your-email’];
$name = $formdata[‘your-name’];
// Construct a username from the user’s name
$username = strtolower(str_replace(‘ ‘, ”, $name));
$name_parts = explode(‘ ‘,$name);
if ( !email_exists( $email ) ) {
// Find an unused username
$username_tocheck = $username;
$i = 1;
while ( username_exists( $username_tocheck ) ) {
$username_tocheck = $username . $i++;
}
$username = $username_tocheck;
// Create the user
$userdata = array(
‘user_login’ => $username,
‘user_pass’ => $password,
‘user_email’ => $email,
‘nickname’ => reset($name_parts),
‘display_name’ => $name,
‘first_name’ => reset($name_parts),
‘last_name’ => end($name_parts),
‘role’ => ‘subscriber’
);
$user_id = wp_insert_user( $userdata );
if ( !is_wp_error($user_id) ) {
// Email login details to user
$blogname = wp_specialchars_decode(get_option(‘blogname’), ENT_QUOTES);
$message = “Welcome! Your login details are as follows:” . “\r\n”;
$message .= sprintf(__(‘Username: %s’), $username) . “\r\n”;
$message .= sprintf(__(‘Password: %s’), $password) . “\r\n”;
$message .= wp_login_url() . “\r\n”;
wp_mail($email, sprintf(__(‘[%s] Your username and password’), $blogname), $message);
}
}
}
return $cfdata;
}
add_action(‘wpcf7_before_send_mail’, ‘create_user_from_registration’, 1);
Hello
I posted the code in my php functions but the contact form 7 is now showing on my WordPress registration form.
Is there a new page for registration i have to create and use the contact form as a short-code or what?
Do you have any video
Hi Robin,
I want to thank you first for taking time to share your code with the world.
I have some issue and i want to ask you, can this be user to change profile image?
I know WP using Gravatar and possible it’s not possible to do it like this, that is why i added ACF, and what i need is to upload that image from input file type field and do update_meta_field of that ACF field.
Are you familiar with ACF?
Here is the code https://gist.github.com/Soullighter/06f84a960cfdb40ea838fdf3f0d292b5
Hi Stefan. If you’re using ACF, you should use ACF functions to store the data on the user. For example:
instead of
Images are trickier to handle than text fields – you’ll have to construct an image array with values from the uploaded file, and then use update_field with this array.
Updating ACF fields is doing just fine with update_user_meta 🙂 but true, its better to use ACF functionality
About images, i was digging deeper in CF7 functionality and found something but it’s not enough
$uploaded_files = $submission->uploaded_files();
foreach ( (array) $uploaded_files as $name => $path ) {
$attachments[] = $path;
}
Yes, update_user_meta will work but I don’t think it stores the ACF field_key in the database so might cause some problems with other ACF functions.
WRT images, it kind of depends how you’re implementing it. Is your avatar ACF field storing the object array, the URL or the ID? See https://www.advancedcustomfields.com/resources/image/ for more. And how are you displaying it on the site?
Hi Robin…
Looking this code I think this a very great job and very useful for the newbies like me 🙂
I was wondering if your code still works for current CF7 v.5.1.1 ?
Many thanks in advance!
I haven’t tested it – maybe try it?
Thank you Robin, its working ok, BUT… the role update not working, always set ‘susbscriber’ despite I change for ‘author’ or anything else.
¿Some idea what’s wrong?
Thanks again
same problem 🙁
Have you solve it?
Hi Robin,
Thank you for this code! I have no problem registering users with this code however I was wondering if you could help me. My client wants to redirect users that register with this specific form to a quiz that’s only viewable to logged in users. I’m trying to implement an auto login code, which does actually log the user in. However during this process the form doesn’t “complete”, as in it stays spinning and doesn’t redirect like it’s supposed to. I’m using CF7 Redirection for that function.
Here’s the relevant code from my functions file (ignore line 66, was testing the redirect function but that doesn’t work either): https://pastebin.com/6Bt9y9gg
I would appreciate any help possible!
Hi Peter. Maybe try and move this code:
into the create_user_from_registration function at the end.
I tried that and it didn’t seem to work correctly. If I had it before the “return $cfdata;” then the form doesn’t complete. If I put it after then it doesn’t execute any code after that. I also tried manually adding a redirect code both before and after “return $cfdata;” but that didn’t fire either for some reason.
Hi Robin, I tried implementing your code on a website and it just isn’t working. Would you mind having a look at the code and telling me where I’m going wrong?
https://pastebin.com/zU7LVTPF
Thanks a lot!
Charlie
Hi Charlie. You were checking the value of the checkbox-register form value before the $formdata object had been created, so $checkbox was always false. Try this:
Thanks Robin! I’ll give it a try.
That all works now, but I’m having difficulty geting the fname and lname to concatenate into a name and be passed as a username.
// Check this is the user registration form
if ( $cfdata->title() == ‘Quick Register’) {
$checkbox = isset( $formdata[‘checkbox-register’] );
if ( $checkbox ) {
$password = wp_generate_password( 12, false );
$email = $formdata[’email’];
$name = $formdata[‘first-name’] . [‘last-name’];
// Construct a username from the user’s name
$username = strtolower(str_replace(‘ ‘, ”, $name));
if ( !email_exists( $email ) ) {
// Find an unused username
$username_tocheck = $username;
$i = 1;
while ( username_exists( $username_tocheck ) ) {
$username_tocheck = $username . $i++;
}
$username = $username_tocheck;
// Create the user
$userdata = array(
‘user_login’ => $username,
‘user_pass’ => $password,
‘user_email’ => $email,
‘nickname’ => $username,
‘display_name’ => $name,
‘first_name’ => $formdata[‘first-name’],
‘last_name’ => $formdata[‘last-name’],
‘role’ => ‘candidate’
);
This line:
should be:
Hi Robin,
need some help here, I’m trying to add a checkbox in cf7, only when user tick off the checkbox then enable this user registration function, but nothing happen
$checkbox = isset($formdata[‘checkbox-register’]);
if ( $cfdata->title() == ‘user’ && $checkbox == ‘2’) {
//enable registration
}
else {
//disable registration
}
any idea ?
Sorry for my broken english
Hi Mike. I think you need to move the checkbox check inside the check for the right form (‘user’). Also, your test for the checkbox field is wrong. Try this:
Hi Robin,
I did it ! Thanks a lot!
I thought I’d tried that before, but clearly I hadn’t as it worked. Thanks very much Robin!
Hi Robin, I’m trying get a message when email already exists with:
if ( ! email_exists($email)) {
…
} else {
$result->invalidate( $email, ‘Email address already exists, please choose another.’ );
return $result;
}
But the form neither shows an error message nor submit.
$result->invalidate won’t work in the wpcf7_before_send_mail hook since the $result object doesn’t exist. I think you’d need to set up a separate custom validation filter to return the error message.
Hi Robin.,
Is there any way to display an error from here?
Hi Robin,
Never mind! I did it! You were right, I had to create a custom validate filter to display the error.
Thanks a lot!
Great, glad to hear you cracked it.
Hello Hugo,
I also trying to get an email validation and error message going. Very new to php do you mind sharing your snippet that got this to work? … thanks!
Hi Edmund,
Here it is:
add_filter( ‘wpcf7_validate_email*’, ‘custom_email_confirmation_validation_filter’, 20, 2 );
function custom_email_confirmation_validation_filter( $result, $tag )
{
$email = isset( $_POST[‘your-email’] ) ? trim( $_POST[‘your-email’] ) : ”;
if (email_exists( $email ))
{
$result->invalidate( $tag, “The email already exists, please try another one.” );
}
return $result;
}
Thanks a million Hugo … let me try it out.
Hi Hugo,
Can you please show me where i should insert your code for email validation to the code for user registration? I have tried but not success, always get this error “The site is experiencing technical difficulties.” Thank you very much.
Hi Quang,
In your theme functions.php, but I’m not sure if this error is related.
Hi Robin,
Just wondering if is it possible to add a background image to the email notification that is sent to the user with the username and password on the body of the email.
Thank you!
Hi Romulo. You’d have to send the email as HTML, and set the background image there. See example #5 in the PHP Mail documentation for how to send email as HTML.
Hello,
Is there anyway to change this link?-> $message .= wp_login_url() . “\r\n”;
HI Robin,
Thanks for reply me but i cant find useful any other but your registration process, but it was useful too. I am given link here for user activation by admin side after user creation. This gives email and password and notify by mail to new user also. It helps other who want to activate/deny/delete user from admin side. It is the link https://github.com/picklewagon/new-user-approve
Thanks for posting everything. Cheers….
Hi Robin, great post!
I was wondering if you have a simple solution for a problem that’s been bothering me for some time now.. I need to find a permanent way of sending the username of the person using the contact form (user_login) in a way so as that it won’t be overwritten with every new update of the plugin. Do you have any ideas?
Thanks for everything 🙂
According to the CF7 docs, you can set a text field with default values from the logged in user. So create a text field like this:
Robin, do you think it’s also possible to set custom fields this way? I haven’t found anything related to it. I mean fields like description or even my own fields.
I was thinking to write my own function to load existing values from existing user profile into form fields but not sure which hook to use. From the list available here http://hookr.io/plugins/contact-form-7 I would say wpcf7_init but not sure. Do you have any experience with this?
Many thanks.
Sorry, I don’t , and this is getting pretty far from the topic of the post. Have you tried contacting the CF7 developer?
Thanks for reply Robin. I figured it out, it’s so easy. Takayuki did absolutely incredible job here.
As described on the link you provided earlier http://contactform7.com/setting-default-values-to-the-logged-in-user, you can set default value to your fields. I thought that this is restricted only to those options described in documentations but that’s not the case.
If you want to set description field, simply use default:user_description. Even better, if you want to set you own custom field (I am using Pods), simply use default:.
Hopefully this will help someone.
Sorry, the second value should be default:”name-of-your-custom-field”
Hi robin,
I am a newbie in wordpress. I have a custom theme and i want to register new user signup with cf7 with email verification. After signup the verification link go to that user and after click, i want some mechanism which gives me notification that user mail verified. And than i will activate them by admin site. How it can be possible with cf7. Is there any plugin or code is require. I am also a web developer but in learning phase. Please help me to doing this.Any help will be appreciate.
Thanks in advance.
Have a look at my reply to Jahanzeb Khan below to see how to send out a welcome email on activating a user by changing their role in admin.
A standard WordPress installation doesn’t confirm email addresses on registration – what plugin are you using for this?
Hi robin! thanks to quick reply. I am not use any plugin for this. Can you provide the link for this type of plugin(it should not be premium). Please give me code with steps if you can on my mail. I will be very thankful to you.
I appreciate for your help.
I don’t have any recommendations for an email confirmation plugin I’m afraid. You’d have to do some research and try some out.
There are code examples in the comment I mentioned which, together with an email confirmation plugin, should give you what you need.
Once you have a plugin working, the last thing you’d need to find will be a hook to send a notification to you once the email in verified.
how great! By combining various code snippets that I see on the comments, it seems perfect for my purpose of creating a simple member area for my site.
Thankyou very much Robin!
You’re very welcome, I’m happy it’s been useful.
Robin, thank you so much for this amazing code. I know you coded it almost 2 years ago but I have one small problem and I am not able to figure it out.
When I click submit button, the form always times out and no message from Contact Form 7 is displayed (be default it’s displayed below the form). Everything else works – user is created and notification email is sent so there’s definitely no error in the code. It just looks like this function prevents Contact Form 7 from continuing. Even the JS commands which I defined on ‘Additional Settings’ tab in Contact Form 7 are completely ignored.
Do you have any experience with this issue?
Hi Igor. This sounds like a Javascript error is preventing the confirmation script from running. Are there any errors in the browser console? (View > Developer > Javascript Console in Mac Chrome; Tools > Web Developer > Browser Console in Mac Firefox).
Robin, thank you very much for reply. That’s the funny thing, there are absolutely no errors. I first thought it was caused by reCaptcha module but the situation is exactly the same with or without it. I also have other contact forms on the same page and they work without any issues. So it must be something within this one.
Just to confirm, this function shouldn’t prevent Contact Form 7 from further processing, right?
So, another clue Robin. It’s not caused by the main function create_user_from_registration. I also use your second function notify_approved_user_login as every user must be approved by administrator. When I comment this function out everything works perfectly. Not sure why but I will figure it out 🙂
All right, Robin, got it. The function notify_approved_user_login( $user_id, $new_role, $old_roles ) should have only 2 parameters, like this: notify_approved_user_login( $user_id, $new_role ). I removed the $old_roles parameter and everything is working now. Hope this helps and thank you again for your amazing help.
Good detective work Igor! But I’m mystified why you need to remove the $old_roles parameter – according to the documentation for the set_user_role hook, the parameter should be fine. Unless you are using an old version of WordPress (before 3.6)?
Thank you for reply Robin. Yes, you’re right, the $old_roles parameter can stay there, it was the issue only in my function. However, what’s strange is the behaviour of this hook. There are mainly 2 issues:
1. the parameter $new_role is always empty. I tried to print it out and there’s nothing. So the ‘if’ statement is useless right now. I have no idea why is this.
2. it works only when you assign a role to user who doesn’t have any role yet. If you change existing role, this hook is not triggered. Again, very strange.
All right Robin, hopefully the last post about this issue but it might help someone else with the same problem 🙂
The whole problem was caused by Members plugin. It’s an awesome plugin but somehow it breaks the functionality of set_user_role hook. I already wrote to its author. Without it everything works perfectly.
That does make sense, although I’m surprised… Let me know what Justin says. Thanks for sharing the solution.
Robin, great answer and explanation from Justin. Everything’s described here and it makes even more sense now: https://wordpress.org/support/topic/changing-role-no-longer-fires-the-set_user_role-hook?replies=4
Thanks for the link, it does clarify what’s happening. For anyone else, the issue is this: The set_user_role hook only fires when user is assigned to a single role, which is what normally happens when the Role is changed in core WordPress. The Members plugin allows multiple roles to be assigned to a user in the admin, which means the hook sometimes won’t fire. Basically, if you’re using the Members plugin, hook on add_user_role instead.
Hi Robin,
Thank you so much for the great script, it is exactly what I need as a requirement for my site. I am having problems getting this to work however. I saw you requested Pastebin’s in the past of the function.php so here is mine: http://pastebin.com/udqKqesr
My CF7 form is:
[contact-form-7 id=”1076″ title=”blog_registration”]
Email (required)
[email* your-email]
Password (required)
[submit “Send”]
Any help would be great appreciated. Thank you very much.
James
I think you may have placed the code in the wrong functions.php – it should go into /wp-content/themes/YOUR-THEME-NAME/functions.php.
This is currently located in my Child Theme where other functionality is working from the functions.php file.
Try moving the code to below the // END ENQUEUE PARENT ACTION line.
That didn’t seem to work. I receive my email from CF7 but the user is not registering.
Ah, I see the problem. You don’t have a name field in your form, so the code can’t construct a username from it (it concatenates the first and last names in lower case).
So you either have to reinstate the name field in your form and the code, or construct it in some other way – perhaps from the email address?
Your most recent suggestion worked, thank you! I removed the name field to simplify registration didn’t realize it would ruin the whole script. I am trying to use your script in conjunction with this widget: https://wordpress.org/plugins/email-before-download/.
Doesn’t seem to play nicely together at present moment but thanks again as your script is now working as advertised.
Hi Robin, I have another question if you don’t mind: Do you know how to add a “weigh” to CF7 dropdown fields (think Quiz)? And then create a separate field where the total is calculated?
For example:
Education
1. High-School (weight: 5)
2. Some college (weight: 10)
3. Undergraduate (weight: 15)
4. Grad school (weight: 20)
Are you a homeowner?
1. Yes (weight: 10)
2. No (weight: 5)
So if the user selects “Undergraduate” in the education field and “Yes” for Homeowner, the total would be 25.
I’ve been scratching my head over this for a while but cant really come up with a solution so I was hoping maybe you do….
Thanks again!
This is off the topic of this post, and not really possible with CF7 without a lot of customisation. I’ll email you.
Is it possible to use CF7 to update current (logged-in) user field, including meta-data?
Hi Brian. Yes, you need to use wp_get_current_user to get the current user ID, then wp_update_user to update the user data. Something like this:
Thank you Robin!!!
Is it possible to combine this with the original code? Logged in users will update information and new users will create the new account.
//Update Current User
function update_current_user($cfdata) {
if (!isset($cfdata->posted_data) && class_exists(‘WPCF7_Submission’)) {
// Contact Form 7 version 3.9 removed $cfdata->posted_data and now
// we have to retrieve it from an API
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$formdata = $submission->get_posted_data();
}
} elseif (isset($cfdata->posted_data)) {
// For pre-3.9 versions of Contact Form 7
$formdata = $cfdata->posted_data;
} else {
// We can’t retrieve the form data
return $cfdata;
}
// Check this is the user update form
if ( $cfdata->title() == ‘Sample Request New’) {
$email = $formdata[‘your-email’];
$name = $formdata[‘first-name’];
$firstname = $formdata[‘first-name’];
$lastname = $formdata[‘last-name’];
$jobtitle = $formdata[‘job-title’];
$company = $formdata[‘your-company’];
$phone = $formdata[‘phone-num’];
$address = $formdata[‘shipping-address’];
$city = $formdata[‘your-city’];
$state = $formdata[‘state-province’];
$postcode = $formdata[‘zip-code’];
$country = $formdata[‘country’];
$business = $formdata[‘business-type’];
$publications = $formdata[‘publications’];
$distributors = $formdata[‘distributors’];
$additional = $formdata[‘additional-info’];
// Check the user is logged in
if ( is_user_logged_in() ) {
$current_user = wp_get_current_user();
// Update the user data
$userdata = array(
‘ID’ => $current_user->id,
‘user_email’ => $email,
‘display_name’ => $name,
);
$user_id = wp_update_user( $userdata );
if ( !is_wp_error($user_id) ) {
// Update the custom user field
update_user_meta( $user_id, ‘user_first_name’, $firstname );
update_user_meta( $user_id, ‘job_title’, $jobtitle );
update_user_meta( $user_id, ‘billing_company’, $company );
update_user_meta( $user_id, ‘billing_phone’, $phone );
update_user_meta( $user_id, ‘billing_address_1’, $address );
update_user_meta( $user_id, ‘billing_city’, $city );
update_user_meta( $user_id, ‘billing_state’, $state );
update_user_meta( $user_id, ‘billing_postcode’, $postcode );
update_user_meta( $user_id, ‘billing_country’, $country );
update_user_meta( $user_id, ‘business_type’, $business );
update_user_meta( $user_id, ‘trade_publications’, $publications );
update_user_meta( $user_id, ‘distributors’, $distributors );
update_user_meta( $user_id, ‘additional_info’, $additional );
}
}
}
return $cfdata;
}
add_action(‘wpcf7_before_send_mail’, ‘update_current_user’, 1);
*/
//Create New User From CF7
function create_user_from_registration($cfdata) {
if (!isset($cfdata->posted_data) && class_exists(‘WPCF7_Submission’)) {
// Contact Form 7 version 3.9 removed $cfdata->posted_data and now
// we have to retrieve it from an API
$submission = WPCF7_Submission::get_instance();
if ($submission) {
$formdata = $submission->get_posted_data();
}
} elseif (isset($cfdata->posted_data)) {
// For pre-3.9 versions of Contact Form 7
$formdata = $cfdata->posted_data;
} else {
// We can’t retrieve the form data
return $cfdata;
}
// Check this is the user registration form
if ( $cfdata->title() == ‘Sample Request New’) {
$password = wp_generate_password( 12, false );
$email = $formdata[‘your-email’];
$name = $formdata[‘first-name’];
$firstname = $formdata[‘first-name’];
$lastname = $formdata[‘last-name’];
$jobtitle = $formdata[‘job-title’];
$company = $formdata[‘your-company’];
$phone = $formdata[‘phone-num’];
$address = $formdata[‘shipping-address’];
$city = $formdata[‘your-city’];
$state = $formdata[‘state-province’];
$postcode = $formdata[‘zip-code’];
$country = $formdata[‘country’];
$business = $formdata[‘business-type’];
$publications = $formdata[‘publications’];
$distributors = $formdata[‘distributors’];
$additional = $formdata[‘additional-info’];
// Construct a username from the user’s name
$username = strtolower(str_replace(‘ ‘, ”, $name));
$name_parts = explode(‘ ‘,$name);
if ( !email_exists( $email ) ) {
// Find an unused username
$username_tocheck = $username;
$i = 1;
while ( username_exists( $username_tocheck ) ) {
$username_tocheck = $username . $i++;
}
$username = $username_tocheck;
// Create the user
$userdata = array(
‘user_login’ => $username,
‘user_pass’ => $password,
‘user_email’ => $email,
‘nickname’ => reset($name_parts),
‘display_name’ => $name,
‘first_name’ => $firstname,
‘last_name’ => $lastname,
‘role’ => ‘subscriber’
);
$user_id = wp_insert_user( $userdata );
if ( !is_wp_error($user_id) ) {
update_user_meta( $user_id, ‘user_first_name’, $firstname );
update_user_meta( $user_id, ‘job_title’, $jobtitle );
update_user_meta( $user_id, ‘billing_company’, $company );
update_user_meta( $user_id, ‘billing_phone’, $phone );
update_user_meta( $user_id, ‘billing_address_1’, $address );
update_user_meta( $user_id, ‘billing_city’, $city );
update_user_meta( $user_id, ‘billing_state’, $state );
update_user_meta( $user_id, ‘billing_postcode’, $postcode );
update_user_meta( $user_id, ‘billing_country’, $country );
update_user_meta( $user_id, ‘business_type’, $business );
update_user_meta( $user_id, ‘trade_publications’, $publications );
update_user_meta( $user_id, ‘distributors’, $distributors );
update_user_meta( $user_id, ‘additional_info’, $additional );
// Email login details to user
$blogname = wp_specialchars_decode(get_option(‘blogname’), ENT_QUOTES);
$message = “Welcome! Your login details are as follows:” . “\r\n”;
$message .= sprintf(__(‘Username: %s’), $username) . “\r\n”;
$message .= sprintf(__(‘Password: %s’), $password) . “\r\n”;
$message .= wp_login_url() . “\r\n”;
wp_mail($email, sprintf(__(‘[%s] Your username and password’), $blogname), $message);
}
}
}
return $cfdata;
}
add_action(‘wpcf7_before_send_mail’, ‘create_user_from_registration’, 1);
You’re on the right track. However, you appear to be using one form (Sample Request New) to create and update the user – you will need separate forms. Also, you should use a single function (e.g. create_or_update_user) to create and update the user. In this function, check which form has been submitted, and carry out either the register or update process accordingly.
Hello
Sorry I know this is quite an old post but it describes exactly what I am trying to do, I’ve copied the code into my functions.php and I get no errors but it does not work. I have altered the fields and title correctly (I think) but it just doesn’t do anything – if your still monitoring this I would greatly appreciate some help!!
Hi Dan. Upload your functions.php to Pastebin (or similar) and post the link. I’ll have a look.
Hello, sorry I didn’t expect such a quick reply and I’ve been away for the weekend. I’ve put my code on pastebin – http://pastebin.com/iS7dxDxx
Thanks for taking a look and your quick response!
Dan
I think you may need to install it into a child theme for your Vantage theme – you can download one here. Unzip it, and upload to /wp-content/themes. Now add the Contact Form 7 hook code to /wp-content/themes/vantage-child-starter/functions.php, and remove it from /wp-content/themes/vantage/functions.php. Lastly, activate the child theme in Appearance > Themes. Child themes are useful because they allow you to customise your theme and your changes won’t be overwritten by any updates to the base theme (Vantage).
All the comments have magically appeared now. I only realised the purpose of child themes after i’d already edited the base theme so I didnt bother with it but I will try this out, thank you!
Hello
I uploaded the child theme and activated it, moved the function and its still not working 🙁 Anything else you can recommend trying?
Thanks!
Dan
Is there a way to test if its not picking up the hook or if its failing on creating user – I’ve done coding before but not much on website creation, so I always want to break down the code and test parts of it but while I can recognise what the code is doing I don’t really know what I am doing :-/
Ok after altering code for a few hours (a little bit of trial and error to be honest!), I stripped away bits of code that I figured were not needed in the sense of just testing it out i.e. checking if the user already exists and I got it working! In the end I believe (although I am not sure why) it didn’t like the nested if statement starting with:
if (!isset($cfdata->posted_data) && class_exists(‘WPCF7_Submission’))
I removed the full nested if statement and just left:
$submission = WPCF7_Submission::get_instance();
$formdata = $submission->get_posted_data();
and it now works. Thank you very much for the code, maybe this will help other people if they have problems or help you identify why the odd person has issues? I saw a few other people were having problems, not sure if its related to the same thing. Anyway I really appreciate you posting the code up and for your prompt reply in helping out!!
Take it easy.
cheers
Dan
Good detective work! I’m glad you got to the bottom of it. That section of the code was written just as CF7 changed the structure of its data objects for version 3.9 to allow it to handle both the old and new, and is now pretty redundant. When I get the chance, I’ll have a look at the latest version and update my script.
Hi Robin
Sorry just checking you got my last message, I posted the code on pastebin for you but my comment seems to have disappeared?
Thanks
Dan
Hi Robin, great article.
I am using similar to register users on a site but want to pass error messages to CF7 if the email already exists. I am having difficulty working out the correct json format for the response to make the form fail – not much documentation for cf7 developers I guess.
Do you have any thoughts?
Hi Steve. I don’t think you need to use JSON, but rather look at the wpcf7_validate_email hook. Try something like:
Hi Robin thanks for the quick response. And the code!
However, I tried that and it works… partially, any email that exists now reports this error,
Validation errors occurred. Please confirm the fields and submit it again.
But not the one specified in the $result array
Strange, the plugin author himself does it this way in a post here… Have a look at the wpcf7_text_validation_filter function in modules/text.php to see if you can get any clues as to why this is.
Hi, I found the problem…
Looks like since version changed we need to treat $result as an object. This works….
Yes, that makes sense. Glad you found the solution, and thanks for sharing it.
Great article. Just trying a few things from the comments. Seems this method isn’t working again – both of them, that is. Both return the ‘validation error’ print. Any thoughts?
A second question if I can, Robin: I’m looking to display such a message but still send the e-mail and process the form/create the account. The idea being that if they’ve already got an account that they’re still able to proceed. Any idea on how to do that but still display a message to let them know that they already have an account?
Thanks!
I’ve just tested this on the latest version of CF7 (4.3.1) using the
result->invalidate
method and it works fine for me. Note that the ‘Email address already exists, please choose another’ message appears right next to the field being validated. The ‘Validation errors occurred’ message appears below the submitted form i.e. both messages will appear if a user with that email address already exists.Re: your second question, do you mean to just skip the account creation process if a registration form is submitted for an existing user, while still emailing the form contents? If so, then you can’t use the wpcf7_validate filter, since this will prevent the form from submitting if the validation fails. You could leave it out, and then my create_user_from_registration function will simply skip the user creation process if the email exists, leaving the form to be emailed as normal. But I’m not sure how to display a message to the user…
Hello Thank you for sharing this useful information.
I want to know if this can be implemented for woocommerce.
for user registration…
Hi Chidi. I think you’ll need to look at the woocommerce_api_create_customer and woocommerce_api_update_customer_data actions in class-wc-api-customers.php. Unfortunately, the WooCommerce documentation of these actions is non-existent… Good luck!
Hi Robin!
First of all thank you for this great tutorial, it’s much appreciated!
I have a question about user registration with CF7 with custom fields. I already set up a few fields that are working fine on the user profile. However, putting these custom fields in the code you provided just doesnt populate it in the user profile.
e.g. I used the following code:
=======
“fav-game” is the custom field I’d like populated in the user profile. However, I cant seem to get it to work. Can you help please?
Thanks in advance!
Hi Brian. You need to use the update_user_meta function to set the custom field value after you’ve created the user:
…
There’s good post on updating user meta on registration here.
Thanks for the help Robin!!
Hi Robin,
Need your help!
I can pass the two fields (Name & Email).
I want your help in the below thing, I would be really helpful to you if you can help.
I am working on creating a Registration form for Vendors. The details include shop name, contact details, bank account details (acc no, bank name, branch). I need to save these details. Also create a new user role as ‘Vendor’ and tag them in it. Am not a pro in WordPress, neither am a techie, am just a business guy. What I understand that these details needs to be saved in a database in wordpress, which includes more details than that a wordpress db on user data has. Please help!
Hi Roy. You’d need to extend the user with some custom fields, perhaps using the Pods module. You can use the Members plugin to create the vendor Role. Also, in the UK there are strict compliance regulations when you’re storing sensitive customer data like bank accounts in your site database, likewise in most countries. This is a bit out of scope for a blog post – drop me an email if you’d like me to quote for the work.
This time I really need to say THANK YOU MAN, you saved my ass!
My pleasure.
Hi Robin,
Thank you for this tip. could you share with us a possible option to use contact form 7 to actually create posts from front end?
Thanks
Hi Toure. You can use the wp_insert_post function to create a post using values from your submitted form. You could use something like:
Check the documentation for wp_insert_post for more details.
Thank you.
I guess I can add in the array:
‘post_type’ => ‘my_cpt’ // my custom post type name
right?
Yes, I would think so. Try it!
Hi Robin, thanks for this post. I use CF7 quite a lot for basic forms, buit now i’m having a project where i need to create a for, where people register in the site as subscriber and also can create a post with several fields of information. All in one form.
I’m a little bit limited in php, so i’m trying to figure out how to achieve this. Any help would be highly appreciate.
Thanks!
Hi Ivan. You could use the user registration code from this post, but also include the create post code in the reply to Toure above. You would need to add post title and post content fields to your CF7 form. You may want to set the post status to ‘draft’ so that you could moderate the posts, and then publish those you approve.
Hi again Robin, i inserted the code with the proper fields in the functions file of my child theme, but when i update the site, this one goes blank.
I believe i’m placing the ‘createpost’ code in the wrong place?
Hope you can help me…
Thanks a lot!
Try inserting the following code at line 55 (just before the return cfdata; line):
Also check that you’ve got the correct category IDs in the ‘post_category’ line – you can get these by going to Posts > Categories in admin. Hover over the Edit link and you will tag_id=XX in the URL, where XX is the category ID.
Hi Robin, i tried your advised with no succes. Again, when i update my code in my functions.php of my child theme,the site goes blank
Here’s the code i’m trying to insert following your advise:
I have no clue what to do. Hope you can help me.
Thanks a lot!
You seem to be missing the first couple of lines of the function…
Hi,
What about to change the default from email address?
This is out of the scope of this post. You can find out how to set the from address in the wp_mail documentation.
Thank you so much for the relevant information. I will try it myself
Hi Robin,
This is brilliant, and unusually for me achieved almost exactly what I needed at the first attempt! Just one thing I’d like it to do slightly differently, and that is to email the username and password to me instead of to the user. I will then forward them on later.
Can this be done?
Many thanks
I wouldn’t recommend this, as it is a bit of a security risk because you’ll have all your user’s login details sitting around in your inbox unencrypted. It would be more secure to follow the approach detailed in the post below to Jahanzeb.
However, if you want to go ahead, it’s a simple change: substitute your email address in single quotes for $email in line 51. For example:
Thanks Robin, much appreciated.
Hi Robin
how can i add a functionality in your code to verify the account before sending the email of username and pass to subscriber. Admin approves the user and then user gets the email of username and pass. Can you please help me with that i am stuck on it for two days
Thanks.
This is tricky because WordPress stores passwords with a one-way hashing algorithm, which means it is impossible to retrieve the unencrypted password from the database at a later date (once you have verified the account). The solution is in 2 parts:
Now the user will automatically be sent their login when you approve them by changing their role in Admin > Users.
Again Robin Bundle of thanks for getting me out of this situation and for coming up with this solution it works awesome.
You’re welcome.
If you’re using the Members plugin, and want to use this code, you’ll need to hook on the new add_user_role instead.
I want to pass html tags like
<b></b>
eg,$message .= sprintf(__('<b>Phone:</b> %s'), $phone) . "\r\n";
can you help me make this possible because i am a beginner and stuck here for a while.
Hi Jahanzeb. The wp_mail function sends plaintext emails by default. To send HTML emails, you need to set the content-type to HTML in the headers. Replace line 51 with:
Alternatively, you can use the wp_mail_content_type filter to set the content-type to HTML before sending the email, but it’s a bit more long-winded and you have to remember to reset the content-type back to plaintext afterwards. The documentation for sending HTML emails is here.
Thanks Robin it worked fine.
People like you motivate beginners like me.
Hi,
Its working fine for me. great job
This isn’t working for me. I created a functions.php file in my child theme folder and this just places all the code above as text at the top of the page…I don’t get what I’m missing, but I’m very novice with coding….I did change the form name to match my form name and the field names to match my field names and that’ s all the modification I did..if there’s something else then can you explain that too for those of use who aren’t experts in this stuff?
Hi Nicole. It sounds like you didn’t include the opening PHP tag when you created your functions.php file, like this:
I didn't mention it because most themes already have a functions.php, and you just have to insert the function above into it. You can read more about functions.php here.
Hi!
I think I did everything right, but it does not work. and I do not know why. I do not mark any mistakes but I registered users
can you help me?
Hi Fabrizio. So the script is not creating the user when you register? Check:
– line 24 should be
– line 17 must have the title of your Contact 7 form.
– lines 19 and 20 must have the right field names from your Contact 7 form.
Nothing …. It does not work 🙁 I do not understand
Post your theme’s functions.php to pastebin so I can have a look.
Hello , Thanks for the script but it doesn’t seem to work on my website.
I can send you my functions.php file & it would be great if you can help me
Is your site for real? 😉 WooCommerce has its own method of registering users, so I’m not sure if you need this script. Put your functions.php up on pastebin and I’ll have a look at it.
Yes i know i just need to test something that i am thinking to modify later.
Patebin doesn’t seem to be working , here’s the chop link http://chopapp.com/#yof59p31. Thanks for helping me.
Are you sure this is the theme functions.php at /wp-content/themes/your-theme-name/functions.php? If so, it doesn’t include my CF7 script…
Yes it is, I removed it because it was showing errors. It would be great if you integrate it and send me. I maybe doing something wrong
Ah, I see the script was missing a closing bracket on line 24. I’ve corrected it now. Let me know how you get on.
Hi Robin,
What if the username that was generated already exists? How can you modify it so that the username will always be a unique one?
Best Regards.
Hi Kris. You could do something like adding a digit to the username until an unused one is found. I’ve updated the code above to do this – see lines 25-31.
Thanks Robin, that works great.
Hi Robin.
Is it possible to create a form with CF7 for login users and that these depending on your role be directed to one or another page ?
Regards.
Hi Jose. You wouldn’t use CF7 for this purpose – this post is about using CF7 to register users, rather than logging in. To redirect users after login based on role, check this tutorial.
Could the user have an option of entering their own password? Or do they need to go with a random generated password? Also, how would they know what their password is?
The script emails the user their login details in lines 45-51. You could add a password field to the form if you wished the user to choose their own.
This is just what I’ve been looking for, as I’m trying to run all site functions through Contact Form 7. Once you have this set up, do you have to redirect users to the page with the form or can it be integrated into the WordPress registration page?
Well, there isn’t really a WordPress user registration page (unless you count the Add User page in admin). So you need to create a CF7 user registration form with at the minimum fields for email and name, and direct users wanting to register to this form via the navigation.
Thanks, works great. My bad.
This would really help me, thanks for posting this. I’m a newbie at this I might be missing something. I’m getting the following error:
Fatal error: Call to undefined function add_action() in /home/teamfas/public_html/wp-includes/functions.php on line 92
I might be misunderstanding your statement “However, this process can be automated by hooking into the ‘wpcf7_before_send_mail’ action and creating a user from the submitted form fields.”
Do I need to do something more with the ‘wpcf7_before_send_mail’ to make this work?
It looks like you’ve added the code to the wrong functions.php file. It should be added to your theme functions.php, which is located at /wp-content/themes/your-theme-name/functions.php. You can also edit the file from the WP admin by going to Appearance > Editor and opening Theme Functions.
Thanks for the snippet, very helpful and it’s working great!
A minor typo on line 9:
(isset($cfdata->posted_data)
should be:
(isset($cfdata->posted_data))
Well spotted John. I’ve updated the code.
This sounds really useful as I use CF7 constantly, but my knowledge of php is limited and I´m not sure where to start with this so I am going to have to bother you with some questions:
Do I need to create a separate form for this to work?
If not, what shortcode do I need to use to add the form to a page?
Is it compatible with having other CF7 forms on the same site?
Can I edit the fields from the form itself or do I need do modify everything from this snippet?.
Thanks a ton.
Hey Alvaro, to answer your questions:
– you do need to create a CF7 registration form with at least 2 fields: name and email.
– either set the field names to form-email-field and form-name-field, or change the snippet to match your own field names in lines 19, 20 and 22.
– make sure the title in line 17 matches the title of your registration form.
– insert your form on a page or post with the CF7 shortcode. The shortcode of your registration form will be shown in the backend at Contact > Contact Forms.
– the hook will only run for submissions from your registration form, so it won’t interfere with any other CF7 forms.
Hope this helps.
I entered the code in the file fuctions.php of my theme but it doesn’t work. Where in the file do I have to enter it? Before closing the last brace or after?
Questo è il codice : https://pastebin.com/vLFKCMn3
And like can i do it : – either set the field names to form-email-field and form-name-field, or change the snippet to match your own field names in lines 19, 20 and 22.