Assigning Role On WordPress Registration & Profile Page

Phew. I didn’t expect that the previous article, Assigning Role On WordPress Registration Page gained so much attention. This might be a little late for a follow up, but better late than never eh?

For this post, we’ll try to assign role on WordPress registration page, and then allow user to change their own role through their profile page. This might sound a bit risky as we’re giving the user rights to change their own role, but we’ll limit the role choices to our custom roles only.

The changes should satisfy one of the scenarios mentioned by Devexus. Oh, and we’ll do all this without depending on any plugins.

Create the custom roles

I’m sure by now, you should already familiarized yourself with functions.php, so let’s open it and include the snippets below:

<?php
// Add two new role.
// Full list of capabilities can be found at http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table
 add_role('writer', 'Writer', array( 
   'delete_posts' => true,
   'delete_published_posts' => true,
   'edit_posts' => true,
   'edit_published_posts' => true,
   'publish_posts' => true,
   'read' => true,
   'upload_files' => true,
   'edit_users' => true
));
 add_role('designer', 'Designer', array(
   'edit_files' => true,
   'edit_plugins' => true,
   'edit_theme_options' => true,
   'edit_themes' => true,
   'install_plugins' => true,
   'install_themes' => true,
   'switch_themes' => true,
   'update_plugins' => true,
   'update_themes' => true,
   'read' => true,
   'edit_users' => true
));

Remember that the roles will allow certain capabilities to your user. If you’re using your roles as a way for the user to subscribe to a newsletter (or other uses) like Devexus, you might want to set the roles to be similar to the capabilities of Subscriber.

Modifying WordPress Registration Page

Now that we have our roles added, we’ll need to include these new roles to the registration page. Simply include the code snippets below:

add_action('register_form','role_registration_form');
function role_registration_form(){
   $wp_roles = new WP_Roles();
   $wp_roles->use_db = true;
   $role_names = $wp_roles->get_names();
  
   foreach( $role_names as $role_name ) {
      // Ensure that the options exclude default Wordpress roles
      if ( ($role_name !== 'Administrator') and ($role_name !== 'Editor') and ($role_name !== 'Author') and ($role_name !== 'Contributor' ) and ($role_name !== 'Subscriber') ) {
         //  Role value below needs to be in lowercase only
         $role_option .= "<option value='".strtolower($role_name)."'>";
         $role_option .= $role_name;
         $role_option .= "</option>";
      }
   }
   $html = '
      <style type="text/css">
         #role {
            background:#fbfbfb;
            border:1px solid #e5e5e5;
            font-size:24px;
            margin-bottom:16px;
            margin-right:6px;
            margin-top:2px;
            padding:3px;
            width:97%;
         }
      </style>

      <div width="100%">
         <p>
            <label style="display: block; margin-bottom: 5px;">' . __('Role', 'Role') . '
               <select id="role" name="role" class="input">
                  ' . $role_option . '
               </select>
            </label>
         </p>
      </div>
   ';
   echo $html;
}

Save the file, and take a peek at your WordPress registration page. You should see a screen similar to the one below:

Screenshot showing the modified WordPress registration page.
Screenshot showing the modified WordPress registration page.

Feel free to modify the markup, or even the CSS to suit your theme.

Now that we’ve managed to output the new role, next we’ll need to make sure that the role is saved when a user actually clicks on the Register page. The code below should do the trick:

add_action('user_register', 'register_role');
function register_role($user_id, $password="", $meta=array()) {

   $userdata = array();
   $userdata['ID'] = $user_id;
   $userdata['role'] = $_POST['role'];

   // allow if a role is selected
   if ( $userdata['role'] ){
      wp_update_user($userdata);
   }
}

Modifying WordPress Profile Page

If you’ve read the last post, this is where we stopped. Previously, as you might have noticed, updating the role on the profile will take no effect as WordPress will revert it back to the default state.

This time, we’ll still output the same field on the profile page, plus updating WordPress role field for that user based on the selection.

add_action( 'show_user_profile', 'role_selection_field' );
add_action( 'edit_user_profile', 'role_selection_field' );
function role_selection_field( $user ) {
   $wp_roles = new WP_Roles();
   $wp_roles->use_db = true;
   $role_names = $wp_roles->get_names();
  
   foreach( $role_names as $role_name ) {
      if ( ($role_name !== 'Administrator') and ($role_name !== 'Editor') and ($role_name !== 'Author') and ($role_name !== 'Contributor' ) and ($role_name !== 'Subscriber') ) {
         if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
            foreach ( $user->roles as $role ) {			
               if ( strtolower($role_name) == $role ) {
                  $role_option .= "<option value='".strtolower($role_name)."' selected='selected'>";
                  $currentrole = strtolower($role_name);
               } else {
                  $role_option .= "<option value='".strtolower($role_name)."'>";
               }
   
               $role_option .= $role_name;
               $role_option .= "</option>";
            }
         }
      }
   }
   ?>

What we’re doing above is including our custom user meta to the Profile page. First, we get the list of names for each role on WordPress. For each of the roles available, we’ll check if the role is one of the default roles provided by WordPress. If it’s not, we’ll include the role’s name and value as one of the options for the select element.

Next, we’ll need to output the actual markup that the user will see on the Profile page.

<h3><?php _e("Extra profile information", "blank"); ?></h3>
<style type="text/css">
   #role { width: 15em; }
</style>
   <table class="form-table">
      <tr>
         <th><label for="role"><?php _e("Role"); ?></label></th>
         <td>
            <select id="role" name="role" class="input">
            <?php 
               echo $role_option;
            ?>
            </select>
            <span class="description"><?php _e("Select your role if you feel like going to the other side"); ?></span>
         </td>
      </tr>
   </table>
<?php }

I guess the code above is pretty much explains themselves. We output the label, the list of roles we generated earlier into the select element, and a brief explaination for the users to explain the purpose of that field.

Save your functions.php file one more time, and checkout the Profile page. You should be able to see an extra user meta field like the screenshot below:

Screenshot showing the role field.
Screenshot showing the role field.

Next, we’ll include the code that will actually update the role when the user make the changes.

add_action( 'personal_options_update', 'save_role_selection_field' );
add_action( 'edit_user_profile_update', 'save_role_selection_field' );
function save_role_selection_field( $user_id ) {
   update_usermeta( $user_id, 'role', $_POST['role'] );
   $user = new WP_User( $user_id );

   // Remove role
   $current_user_role = get_current_user_role();
   $user->remove_role( $current_user_role );

   // Add role
   $user->add_role( $_POST['role'] );
}
// Function that will return the current user role whenever we need it.
function get_current_user_role () {
   global $current_user;
   get_currentuserinfo();
   $user_roles = $current_user->roles;
   $user_role = array_shift($user_roles);
   return $user_role;
};

?>

That’s it! You could try and create a test account and update the role through the profile page. If you have different capabilities for each role, you should be able to see your sidebar changes based on your selected role. Feel free to check out the complete code on Gist.

Now dance baby, dance 🙂


Comments

5 responses to “Assigning Role On WordPress Registration & Profile Page”

  1. […] Update! There’s a newer post has been published as a follow-up to this post. Read Assigning Role On WordPress Registration & Profile Page […]

  2. Great design! Simple and neat 🙂 Greetings!

  3. I have a question if I want to modified another field on the cimy user at the same time how would i accomplish that on the fuctions.php. Sample one my user select the role and i will like another field to have a value based on the role selection.

    Sample Role = Manager then Position = manager or Role=Director then position=director.

    Any help will be appreciated thank you.

  4. I am using a plugin which inputs a custom role. What i have notice is i cant also remove this from the forum. I only want my 2 cutom rolesto show not the role created by a plugin. I tried adding the role to the section like so…

    if ( ($role_name !== 'Administrator') and ($role_name !== 'Editor') and ($role_name !== 'Author') and ($role_name !== 'Contributor' ) and ($role_name !== 'Unverified') ) {

    But nothing happens and its still showing.

  5. I was looking for something like this as my site has many many sections that needs to handled by multiple section editors. This would be great for assigning roles at http://www.espenvogel.com.

    Sid