How to edit a user profile on the front end?

  • How can I edit a user profile in the front end with a form?
    first name, last name, username, email address and password

  • Bainternet

    Bainternet Correct answer

    10 years ago

    You can do that by copy your theme's page.php to a new file named something like user-profile.php and add to the very top of it this code:

    <?php
    /**
     * Template Name: User Profile
     *
     * Allow users to update their profiles from Frontend.
     *
     */
    
    /* Get user info. */
    global $current_user, $wp_roles;
    //get_currentuserinfo(); //deprecated since 3.1
    
    /* Load the registration file. */
    //require_once( ABSPATH . WPINC . '/registration.php' ); //deprecated since 3.1
    $error = array();    
    /* If profile was saved, update profile. */
    if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {
    
        /* Update user password. */
        if ( !empty($_POST['pass1'] ) && !empty( $_POST['pass2'] ) ) {
            if ( $_POST['pass1'] == $_POST['pass2'] )
                wp_update_user( array( 'ID' => $current_user->ID, 'user_pass' => esc_attr( $_POST['pass1'] ) ) );
            else
                $error[] = __('The passwords you entered do not match.  Your password was not updated.', 'profile');
        }
    
        /* Update user information. */
        if ( !empty( $_POST['url'] ) )
            wp_update_user( array( 'ID' => $current_user->ID, 'user_url' => esc_url( $_POST['url'] ) ) );
        if ( !empty( $_POST['email'] ) ){
            if (!is_email(esc_attr( $_POST['email'] )))
                $error[] = __('The Email you entered is not valid.  please try again.', 'profile');
            elseif(email_exists(esc_attr( $_POST['email'] )) != $current_user->id )
                $error[] = __('This email is already used by another user.  try a different one.', 'profile');
            else{
                wp_update_user( array ('ID' => $current_user->ID, 'user_email' => esc_attr( $_POST['email'] )));
            }
        }
    
        if ( !empty( $_POST['first-name'] ) )
            update_user_meta( $current_user->ID, 'first_name', esc_attr( $_POST['first-name'] ) );
        if ( !empty( $_POST['last-name'] ) )
            update_user_meta($current_user->ID, 'last_name', esc_attr( $_POST['last-name'] ) );
        if ( !empty( $_POST['description'] ) )
            update_user_meta( $current_user->ID, 'description', esc_attr( $_POST['description'] ) );
    
        /* Redirect so the page will show updated info.*/
      /*I am not Author of this Code- i dont know why but it worked for me after changing below line to if ( count($error) == 0 ){ */
        if ( count($error) == 0 ) {
            //action hook for plugins and extra fields saving
            do_action('edit_user_profile_update', $current_user->ID);
            wp_redirect( get_permalink() );
            exit;
        }
    }
    ?>
    

    then replace the loop of that page with this one:

    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
        <div id="post-<?php the_ID(); ?>">
            <div class="entry-content entry">
                <?php the_content(); ?>
                <?php if ( !is_user_logged_in() ) : ?>
                        <p class="warning">
                            <?php _e('You must be logged in to edit your profile.', 'profile'); ?>
                        </p><!-- .warning -->
                <?php else : ?>
                    <?php if ( count($error) > 0 ) echo '<p class="error">' . implode("<br />", $error) . '</p>'; ?>
                    <form method="post" id="adduser" action="<?php the_permalink(); ?>">
                        <p class="form-username">
                            <label for="first-name"><?php _e('First Name', 'profile'); ?></label>
                            <input class="text-input" name="first-name" type="text" id="first-name" value="<?php the_author_meta( 'first_name', $current_user->ID ); ?>" />
                        </p><!-- .form-username -->
                        <p class="form-username">
                            <label for="last-name"><?php _e('Last Name', 'profile'); ?></label>
                            <input class="text-input" name="last-name" type="text" id="last-name" value="<?php the_author_meta( 'last_name', $current_user->ID ); ?>" />
                        </p><!-- .form-username -->
                        <p class="form-email">
                            <label for="email"><?php _e('E-mail *', 'profile'); ?></label>
                            <input class="text-input" name="email" type="text" id="email" value="<?php the_author_meta( 'user_email', $current_user->ID ); ?>" />
                        </p><!-- .form-email -->
                        <p class="form-url">
                            <label for="url"><?php _e('Website', 'profile'); ?></label>
                            <input class="text-input" name="url" type="text" id="url" value="<?php the_author_meta( 'user_url', $current_user->ID ); ?>" />
                        </p><!-- .form-url -->
                        <p class="form-password">
                            <label for="pass1"><?php _e('Password *', 'profile'); ?> </label>
                            <input class="text-input" name="pass1" type="password" id="pass1" />
                        </p><!-- .form-password -->
                        <p class="form-password">
                            <label for="pass2"><?php _e('Repeat Password *', 'profile'); ?></label>
                            <input class="text-input" name="pass2" type="password" id="pass2" />
                        </p><!-- .form-password -->
                        <p class="form-textarea">
                            <label for="description"><?php _e('Biographical Information', 'profile') ?></label>
                            <textarea name="description" id="description" rows="3" cols="50"><?php the_author_meta( 'description', $current_user->ID ); ?></textarea>
                        </p><!-- .form-textarea -->
    
                        <?php 
                            //action hook for plugin and extra fields
                            do_action('edit_user_profile',$current_user); 
                        ?>
                        <p class="form-submit">
                            <?php echo $referer; ?>
                            <input name="updateuser" type="submit" id="updateuser" class="submit button" value="<?php _e('Update', 'profile'); ?>" />
                            <?php wp_nonce_field( 'update-user' ) ?>
                            <input name="action" type="hidden" id="action" value="update-user" />
                        </p><!-- .form-submit -->
                    </form><!-- #adduser -->
                <?php endif; ?>
            </div><!-- .entry-content -->
        </div><!-- .hentry .post -->
        <?php endwhile; ?>
    <?php else: ?>
        <p class="no-data">
            <?php _e('Sorry, no page matched your criteria.', 'profile'); ?>
        </p><!-- .no-data -->
    <?php endif; ?>
    

    and all that is left for you to do is create a new page and select the "user profile" as the page template.

    now if all of this is too much you can use some plugins that do the hard work for you like:

    You answer worked so well for me! Could I use a similar method to edit an existing post? See my question here: http://wordpress.stackexchange.com/questions/9912/front-end-post-editing-using-a-form

    does this method works with custom fields in register form too?

    Thanks for this, works great. How could I add a message that appears after the profile has been successfully updated? At the moment it does nothing.

    Actually, I think I got it working, is it acceptable? I modified your code to be: `if ( !$error ) { wp_redirect( get_permalink() .'?updated=true' ); exit; }` and then added

    Your profile has been updated

    Thanks for this, however, email doesn't update and neither does website. The other fields do update though. Can you think of a reason why this might be? Thanks.

    @Nicola, I had the same problem. it's because the email and website URL are not user meta; they are stored in the `wp_users` table (vs. the `wp_usermeta` table). To update the email and URL, you need to use `wp_update_user()`, rather than `update_usermeta()`.

    It seems this is not checking for duplicate email addresses which can cause problems like in my case where I allow users to login via email.

    Its an example which you can edit and add your checks to it

    @BandonRandon I updated the code with a simple email validation, duplication check and added some action hooks that WordPress Uses to allow plugin integration. thanks

    Awesome, I've already started to modify this and it works quite well. Just to point out what others have noted email uses `wp_update_user` not `update_usermeta` but that's an easy fix

    Please reading this @Bainternet. Wasn't surprised when I got to the end and so your avatar

    @raam86 - Wan't surprised to see you on SO network.

    Error: registration.php is deprecated since version 3.1 with no alternative available. This file no longer needs to be included.

    Is it fine if there is no `wp_verify_nonce()`?

    its not recommended, you should always validate the request with as many methods as you can, and this is just one of them.

    @Bainternet thank you for the nice piece of code. Edited some fixes and commented out some deprecated lines.

    We use the PRO version of ProfilePress (https://profilepress.net) for our front-end edit profile and couldn't be more happy with it.

    this $referer is forever alone on the code. I guess that is why im not being redirected after the update.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM