Support

Account

Home Forums Front-end Issues Front-end user registration

Solved

Front-end user registration

  • Trying to create a front-end form for user registration. I saw this post and decided that it would be a good template.

    My question is specific to this set of code:

    
    // set ACF pre-save stuff
    add_filter('acf/pre_save_post' , 'acf_create_new_user' );
    
    function acf_create_new_user( $post_id ) {
    
        error_log( $post_id );
    
        if ( $post_id != 'new' ) {
            return $post_id;
        }
    
        //prepare basic user info
        $password = wp_generate_password( 10, true, false );
        $username = $_POST['fields']['field_59364c779d819'];
        $email = $_POST['fields']['field_59364c779d819'];
    
        //register user
        $user_id = wp_create_user( $username, $password, $email );
    
        //update other user info
        wp_update_user( array(
            'ID'            => $user_id,
            'first_name'    => $_POST['fields']['field_593642087f8f5'],
            'last_name'     => $_POST['fields']['field_593642267f8f6'],
            'display_name'  => $_POST['fields']['field_593642087f8f5'] . ' ' . $_POST['fields']['field_593642267f8f6']
        ) );
    
        return $user_id;
    
    }
    

    Basically, it doesn’t work for me. I’ve put it in the page template and in functions.php (as suggested in documentation), doesn’t work in either spot.

    The documentation for acf_form mentions that I might need to use acf_form_head(). I’m not sure if this is necessary, as there’s nothing here that creates a post. But I went for it anyway, putting acf_create_new_user() right above acf_form_head() at the end of functions.php – it breaks the form right after submission. Error log suggests that WP doesn’t know what the $_POST fields refer to.

    For reference, this is my ACF form (included in page template, right before content loads):

    
    // front-end form
    if ( is_user_logged_in() == true ) : 
    
        global $current_user;
        $user_id = 'user_' . $current_user->ID;
    
    else : $user_id = 'new';
    
    endif;
    
    $args = array(
        'post_id'               => $user_id,
        'field_groups'          => array( 475 ),
    );
    
    acf_form( $args );
    
  • calling acf_form_head() is required before get_header() or before any output is created in header.php. Nothing will be created if you don’t because this function, or functions called by this function is where the apply_filters('acf/pre_save_post'... is called. Basically, nothing will be saved if this acf_form_head() is not called.

    The only error I see in your filter is

    
    
        //register user
        $user_id = wp_create_user( $username, $password, $email );
    
        //update other user info
        wp_update_user( array(
            'ID'            => $user_id,
            'first_name'    => $_POST['fields']['field_593642087f8f5'],
            'last_name'     => $_POST['fields']['field_593642267f8f6'],
            'display_name'  => $_POST['fields']['field_593642087f8f5'] . ' ' . $_POST['fields']['field_593642267f8f6']
        ) );
    
       // if you don't want the above fields also saved as custom fields for the user
      unset(
        $_POST['fields']['field_593642087f8f5'],
        $_POST['fields']['field_593642267f8f6'],
        $_POST['fields']['field_593642087f8f5'],
        $_POST['fields']['field_593642267f8f6']
      )
        
        // for ACF, you need to return
        return 'user_'.$user_id;
    
  • Thanks! Got it working, mostly.

    calling acf_form_head() is required before get_header() or before any output is created in header.php

    Noted. I’ve moved this bit to the page template, called it in at right place.

    // if you don’t want the above fields also saved as custom fields for the user

    Regarding unset(), good call. I wish I had done this sooner, now I have hundreds of instances of orphaned post data I have to delete…

    I’ve simplified the code (and also complicated it a bit). It’s solved most issues, created others.

    
    <?php
    
    // set ACF pre-save stuff
    add_filter('acf/pre_save_post' , 'acf_create_new_user' );
    
    function acf_create_new_user( $post_id ) {
    
        error_log( 'post id: ' . $post_id);
    
        // // exit if user already logged in, front-end form sent his ID
        // if ( $post_id != 'new' ) {
    
        //     error_log( 'post not new: ' . $post_id);
        //     // wp_redirect( home_url() );
        //     return $post_id;
    
        // }
    
        $field_group = acf_get_fields_by_id('302');
    
        //prepare basic user info
        foreach ( $field_group as $key => $value ) {
    
            $$value['name'] = $_POST['acf'][$value['key']];
    
        }
    
        $password           = wp_generate_password( 10, true, false );
        $username           = $candidate_email;
        $display_name       = $candidate_given_name_romaji . ' ' . $candidate_family_name_romaji;
    
        // check if user exists, exit if so
        if ( email_exists( $candidate_email ) ) {
    
            error_log( 'email exists: ' . $candidate_email );
            wp_redirect( home_url() . '/sign-up/?email_exists&user_email=' . $candidate_email );
            return $candidate_email;
    
        }
    
        // register user
        $user_id = wp_create_user( $username, $password, $candidate_email );
        error_log( 'guy just created: ' . $user_id );
    
        // update other user info
        wp_update_user( array(
    
            'ID'            => $user_id,
            'first_name'    => $candidate_given_name_romaji,
            'last_name'     => $candidate_family_name_romaji,
            'display_name'  => $display_name
    
        ) );
    
        // update other user meta, prevent creation of post data
        foreach ( $field_group as $key => $value ) {
    
            update_user_meta( $user_id, $value['name'], $_POST['acf'][$value['key']] );
            unset( $_POST['acf'][$value['key']] );
    
        }
    
        // redirect to login page after finish
        wp_redirect( home_url() . '/sign-in/?new_user=true&user_email=' . $candidate_email );
        return 'user_' . $user_id;
    
    }
    
    ?>
    

    (1) // exit if user already logged in bit has been commented out because it just grabs the ID of the page, not the post data. I can’t remember if this was working before.

    (2) wp_redirect() bits are not working. I know I can add redirects to acf_form() but they’re conditional: a successful registration will go to one place and an unsuccessful one will go elsewhere.

    Please note, the way I use acf_form() code has changed. I ran into some issues with calling in an entire field group and had to call in the fields one-by-one. It looks like this:

    
    <?php
    
    // ensures that user is not logged in
    if ( is_user_logged_in() == true ) : 
        global $current_user;
        $user_id = 'user_' . $current_user->ID;
    else : $user_id = 'new';
    endif;
    
    acf_form( array(
        'post_id' => $user_id,
        'form' => false,
    ) );
    
    ?>
    

    Then further down the page I have a bunch of these:

    
    <?php
    acf_form( array(
        'fields' => array('some_acf_field'),
        'form' => false,
    ) );
    ?>
    
  • You should probably keep the exit code if the user is already logged in.

    I think you can dynamically alter the return value, but I can’t say exactly how. I think it has to do with setting

    
    $_POST['return'] = $url;
    

    but you’d need to test that to be sure

  • I think I got it: if I move the is_user_logged_in() part to the bottom of the form, just before the submit button, it correctly passes the user ID to acf_create_new_user(). I suppose that all those instances of acf_form() reset the post ID?

    Do you have any thoughts on my other question, why wp_redirect() isn’t working after form submission? To reiterate, I don’t want to use acf_form( 'return' => 'some-url' ) because the redirects are conditional (e.g. user already exists, user was registered, etc.).

  • If you want to redirect in another way than using return. First of all you need to make sure you take care of all of the saving of everything in your pre_save_post filter. If there are additional values that ACF needs to update, this will not happen if you do not return from your function. The reason I say this is that you need to exit completely after performing the redirect

    
    wp_redirect( home_url() . '/sign-in/?new_user=true&user_email=' . $candidate_email );
    exit;
    

    Would it be possible to generate the return value for acf_form() before calling it and set the ‘return’ value based on whether or not it’s a new user?

  • Right, exit! That did the trick.

    I can’t generate a value for return in acf_form() prior to calling it, as part of the process is a check to see if the user is already registered (even if he’s not logged in). This might get changed later, and if it is I’d definitely prefer go this route instead of wp_redirect() -> exit.

Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.