10
votes

I'm trying to achieve the following and I don't know from where to start.

I'm trying to create a sign up/registration form with two steps.

First step: is to have 2 input fields(Name, Email) and when the user submits, an Email is sent with a link to step two.

Step two: a user enters the link sent to his email, enters a page with a second form. that has a value of the email and name he used, + 2 other fields( Username, Password) in which he will have access to certain pages with.

I could not find where to start and no plugins meet the following.

Regards,

Mostafa.

7
Please have a look my answer stackoverflow.com/a/40959220/1960558. it's really long but I hope you can easily understand code on gist: gist.github.com/avastamin/b49481968fd5f984c1e9bd51f91779b4 - Ruhul Amin

7 Answers

6
votes

STEP 1

First you should create two separate templates ( one for each step ). In first template you should create a form that will send user email to the second page. The link should have GET attributes so you can get his email and First name. Here is an example ( note that it can be improved ):

<?php 
/*
** Template Name: Step 1
*/

get_header();

if ( !empty( $_POST['firstname'] ) && !empty( $_POST['email'] ) ) {
    $link = 'http://my-site/step-2';
    $link = add_query_arg(
        array(
            'firstname' => $_POST['firstname'],
            'email'     => $_POST['email'],
        ),
        $link
    );

    $subject = 'New user registration';
    $message = 'Please click on the following link to complete your registration: ' . $link;
    $headers = array('Content-Type: text/html; charset=UTF-8');

    $result = wp_mail( $_POST['email'], $subject, $message, $headers );

    if ( $result ) {
        $message = 'Please check your email address to complete the registration';
    } else {
        $message = 'Something went wrong. Please contact the administrator';
    }

    echo $message;
} else {
?>
    <form method="POST" action="">
        <input type="text" name="firstname" placeholder="First Name">
        <input type="email" name="email" placeholder="Email address">
        <input type="submit" value="Submit">
    </form>
<?php
}
get_footer();

We create a simple check if the form is submitted and all the fields are filled. If so we can send an email to step 2.


STEP 2

We will create a separate template where we will fill the data from first one using $_GET, and we will add two new fields ( username and password ) that will be empty.

<?php 
/*
** Template Name: Step 2
*/

get_header();

if ( !empty( $_POST['firstname'] ) && !empty( $_POST['email'] ) && !empty( $_POST['password'] ) ) {
    $user_id = username_exists( $_POST['username'] );

    if ( !$user_id and email_exists($_POST['email']) == false ) {

        $user_id = wp_create_user( $_POST['username'], $_POST['password'], $_POST['email'] );

        if ( $user_id ) {
            update_user_meta($user_id, 'first_name', $_POST['firstname']);
            $message = 'User has been created';
        }
    } else {
        $message = 'User already exists!';
    }

    echo $message;
} else {
?>
    <form method="POST" action="">
        <input type="text" name="firstname" value="<?php echo ( !empty( $_GET['firstname'] ) ) ? $_GET['firstname'] : '' ; ?>" placeholder="First Name">
        <input type="email" name="email" value="<?php echo ( !empty( $_GET['email'] ) ) ? $_GET['email'] : '' ; ?>" placeholder="Email Address">
        <input type="text" name="username" placeholder="Username">
        <input type="password" name="password" placeholder="Password">
        <input type="submit" value="Submit">
    </form>
<?php
}
get_footer();

If the second form is submitted and everything is ok we can create the user. Once created we can update its first name.

You can make unlimited modifications to my code, but this is the base. For example, we can make the fields required, we can check the password strength, the name length etc.

3
votes

Here's a short brief of the steps you can take.

Make sure the user is unique and store the credentials for the confirmation.

if(!email_exists( $email )){

    /*
       Store credentials in a custom table 
       with a unique identifier, 
       hashed password and email. 

       Email user with the confirmation link ex.
       site.com/confirmation/<unique-identifier>
    */

}

In the confirmation page create the user simply by:

// Confirm <unique-identifier>

// Create user
$user_id = wp_create_user( $email, $password, $email );

// Set user role
$user = new WP_User( $user_id );
$user->set_role( 'contributor' ); // or a custom role
1
votes

I think for now you can try this Contact form 7 Multi-Step Form plugin down here :

Contact Form 7 Multi-Step Forms

Try demo here

Later you can get to know how to develop such registration form by your talent

1
votes
1
votes
  1. Try o create a custom plugin and create a 2 shortcodes.

  2. Create 2 pages and insert the 2 shortcodes respectively.

  3. In the first shortcode write the code for a form to let the user enter their email address and name.

  4. Then enter the details (name and email address) to database with wp_insert_user and then send an email to the email address generating a link to second page and appending the encrypted user ID in the link.

  5. When User clicks on the link redirect them to second page where name and email address will be auto filled using select query.

  6. Insert all the remaining details in this page.

-1
votes

I prefer to use shortcode. Here is the step. Complete code: Gist

  1. Create a page(signup). For example [request_form action="/thanks"]

Note: inside thanks_func you need to user correct url $confirmation_body_text = "/signup/?hid='.$hash.'";

  1. Create thanks page and add this shortcode:

    [thanks] Thank you page [/thanks]

  2. Create new table into user database:

    CREATE TABLEwp_new_user( idint(11) NOT NULL, namevarchar(40) NOT NULL, emailvarchar(80) NOT NULL, usernamevarchar(30) DEFAULT NULL, passwordvarchar(30) DEFAULT NULL, hashvarchar(40) DEFAULT NULL, created_attimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_attimestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

In first step email will be sent with link like signup?hid=1679091c5a880faf6fb5e6087eb1b2dc

So in 2nd step we will get existing user record from this unique email hash and pre-populate name and email fields.

  1. On 2nd step, we will just update existing user record.

    function request_form_func($atts, $content = null){ extract(shortcode_atts(array( 'id' => false, 'class' => false, 'title' => false, 'subtitle' => false, 'action' => "/thanks", 'key' => false, 'button_text' => "Submit" ), $atts));

    if( $class ) {  $class = ' ' . $class; }
    else { $class = ''; }
    
    if( empty($_GET) ){
        $next_step = false;
        $db_name = '';
        $db_email = '';
    }
    if(isset($_GET['hid'])){
        $email_hash = trim($_GET['hid']);
    
        $table = "wp_new_user";
        $project_data = new wpdb('root','root','wordpress','localhost');  // Testserver
        $rows = $project_data->get_results( $project_data->prepare(
            "
                SELECT id,name, email, hash FROM " . $table . "
                WHERE hash = %d
            ",
            $email_hash
        ) );
    
        $db_hash = $rows[0]->hash;
        if( $db_hash == $email_hash ) {
            $field_id = $rows[0]->id;
            $db_name = $rows[0]->name;
            $db_email = $rows[0]->email;
            $next_step = true;
        }
    }
    
    $out = '';
    
    if($id) { $id = '-'.$id; }
    
    $out .= '<div class="request_form'.$class.'">';
    $out .= '<div class="form-wrap">';
    if($title) {
        $out .= '<span class="title">' . $title . '</span>';
    }
    $out .= '<form id="step-form" class="cf" method="post" action="'.$action.'">';
    $out .= '<div class="field-wrap"><label for="fullname'.$id.'"><span class="desc">Name</span>';
    $out .= '<input type="text" id="fullname'.$id.'" name="fullname" data-required="true" placeholder="Jon Doe" value="'.$db_name.'"></label></div>';
    
    $out .= '<div class="field-wrap"><label for="email'.$id.'"><span class="desc">E-Mail</span>';
    $out .= '<input type="email" id="email'.$id.'" name="email" data-required="true" placeholder="[email protected]" value="'.$db_email.'"></label></div>';
    
    if($next_step){
        $out .= '<div class="field-wrap"><label for="username'.$id.'"><span class="desc">Username</span>';
        $out .= '<input type="text" id="username'.$id.'" name="username" data-required="true" placeholder="username"></label></div>';
    
        $out .= '<div class="field-wrap"><label for="password'.$id.'"><span class="desc">Password</span>';
        $out .= '<input type="password" id="password'.$id.'" name="password" data-required="true" placeholder="password"></label></div>';
    

    $out .= ''; } $out .= '';

    $out .= wp_nonce_field('step_form', 'step_form_nonce'.$id, true, false);
    $out .= '</form>';
    $out .= '</div>';
    $out .= '</div>';
    return $out;
    

    } add_shortcode('request_form', 'request_form_func');

  2. Then I create thanks shortcode thanks which will take care your form data. Basically, in first step you need to save your data, Also you need generate unique id to send through email and save to database. The link will look like 'signup?hid=1679091c5a880faf6fb5e6087eb1b2dc'

    function thanks_func($atts, $content = null){ $out = '';

    if(!empty($_POST) || wp_verify_nonce($_POST['step_form_nonce'],'step_form')){
    }
    else {
        $out .= '<div class="content-area">';
        $out .= '<h2 class="h1 page-title">Something went wrong</h2>';
        $out .= '<p class="block">Please Re-Submit your form again</p>';
        $out .= '</div>';
    
        return $out;
    }
    
    if(isset($_POST['fullname'])){ $fullname = trim($_POST['fullname']); }
    if(isset($_POST['email'])){ $email = trim($_POST['email']); }
    
    if(isset($_POST['username'])){ $username = trim($_POST['username']); }
    if(isset($_POST['password'])){ $password = trim($_POST['password']); }
    if(isset($_POST['hash'])){ $db_hash = trim($_POST['hash']); }
    $hash = md5( rand(0,1000) ); // Generate random 32 character hash and assign it to a local variable.
    
    $header .= "MIME-Version: 1.0\n";
    $header .= "Content-Type: text/html; charset=utf-8\n";
    $header .= "From:" . "[email protected]";
    
    $confirmation_text = "Thanks for Submitting your first form";
    $confirmation_body_text = "/registration/?hid='.$hash.'";
    
    $subject = "Please click the link below";
    $message = "Name: $fullname\n";
    $message .= "Email Address: $email\n";
    $message .= "Click the link: $confirmation_body_text\n";
    
    if (!empty($username) && !empty($password) && !empty($field_id)){
        update_custom_user($username, $password, $$db_hash);
    } else if (create_custom_user($fullname, $email, $hash) && wp_mail($email, $subject, $message, $header)){
    
    }
    
    $out .= '<div class="content-area">';
    $content = do_shortcode($content);
    $out .= $content;
    $out .= '</div>';
    
    return $out;
    

    }

    add_shortcode('thanks', 'thanks_func');

I also wrote 2 function create_custom_user and update_custom_user which will save data data from first step and update username and password in 2nd step.

function create_custom_user($fullname, $email, $hash){
    global $wpdb;
    $table_name = $wpdb->prefix . "new_user";

    $cur_date = new DateTime();
    $cur_date->setTimezone(new DateTimeZone('Europe/Berlin'));
    $cur_date = $cur_date->format('d.m.Y').', '.$cur_date->format('G:i');


    $wpdb->insert( $table_name, array(
        'name' => $fullname,
        'email' => $email,
        'hash' => $hash,
        'created_at' => $cur_date

    ) );

    return true;
}


function update_custom_user($username, $password, $field_id){
    global $wpdb;
    $table_name = $wpdb->prefix . "new_user";

    $cur_date = new DateTime();
    $cur_date->setTimezone(new DateTimeZone('Europe/Berlin'));
    $cur_date = $cur_date->format('d.m.Y').', '.$cur_date->format('G:i');


    $wpdb->update( $table_name, array(
        'username' => $username,
        'password' => $password,
        'updated_at' => $cur_date
    ),
        array(
            "id" => $field_id
        ) );

    return true;
}