I'm adding a custom profile field to users of a specific role, like this :

function add_custom_profile_fields( $fields ) {

    // get current user ID
    $user = new WP_User( $_GET['user_id'] );

    // get current user role
    if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
        foreach ( $user->roles as $role ) {

            // filter roles
            if ($role == "paying_member"){
               $fields['paypal_account'] = 'Paypal account';        

    return $fields;

The problem is, the field's value doesn't get saved. When I login as admin an I edit a user's profile. It somehow has to do with the fact that I'm filtering by user role, because when I remove that part, the values get saved perfectly.

EDIT : I think maybe the whole method is wrong, I'm going to try this instead.

  • Would love to see how error objects feed into this design pattern.
    – editor
    Aug 1 '11 at 19:40

Ok, I was doing it wrong, here's a working solution, based on Justin Tadlock's tutorial.

/* Add custom profile fields (call in theme : echo $curauth->fieldname;) */ 

add_action( 'show_user_profile', 'my_show_extra_profile_fields' );
add_action( 'edit_user_profile', 'my_show_extra_profile_fields' );

function my_show_extra_profile_fields( $user ) { ?>

    <?php if(user_can($user->ID, "paying_member")) : ?>

        <h3>Extra profile information</h3>

        <table class="form-table">

                <th><label for="paypal_account">Paypal</label></th>

                    <input type="text" name="paypal_account" id="paypal_account" value="<?php echo esc_attr( get_the_author_meta( 'paypal_account', $user->ID ) ); ?>" class="regular-text" /><br />
                    <span class="description">Please enter your Paypal account.</span>


    <?php endif; ?>

<?php }

add_action( 'personal_options_update', 'my_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'my_save_extra_profile_fields' );

function my_save_extra_profile_fields( $user_id ) {

    if ( !current_user_can( 'edit_user', $user_id ) )
        return false;

    /* Copy and paste this line for additional fields. Make sure to change 'paypal_account' to the field ID. */
    update_usermeta( $user_id, 'paypal_account', $_POST['paypal_account'] );


The main addition to his code, is this line of code:

<?php if(user_can($user->ID, "paying_member")) : ?>

Which displays the custom fields only for users with the role of "paying_member" and admins.


You can skip the looping over roles and use user_can

The function takes either a capability or a role as param.

if (user_can($user->ID, "paying_member")) { 
    $fields['paypal_account'] = 'Paypal account';

Might also be worth checking into current_user_can to skip the user lookup.

  • thanks that works too, but unfortunately saving the profile still doesn't save the values of the custom fields.
    – mike23
    May 17 '11 at 13:39

The problem is that $_GET['user_id'] is not populated. You want to pull in the current user variable. Try this out:

function add_custom_profile_fields( $fields ) {
  global $current_user;
  if user_can($current_user, "paying_member") { 
    $fields['paypal_account'] = 'Paypal account';
  return $fields;
  • $_GET['user_id'] is populated. When I go (as an admin) to the Users section of WP and click on any user name to edit his profile, there is a "user_id" variable in the URL.
    – mike23
    May 17 '11 at 16:51
  • I quickly tested it out by doing var_dump( $_GET ); inside the function attached to user_contactmethods. I got NULL back. It's not a good idea to rely on user input anyway like that for security purposes. Loading the global current user will get you the user as verified by WordPress. May 17 '11 at 17:28
  • Ok let me re-explain. Let's say there is a user named "bob", who's role is "paying_member". Me, i'm user "admin". If I log in as "admin" and I go to "Users" in the WP backend, and I click on "bob" to edit his profile, on this profile page, the URL has a GET variable named "user_id". It is not user generated, it is generated by the WP core functions. Now, if I use "$current_user", that would return my own ID (because I'm logged as "admin") instead of "bob"'s ID (the one I'm really interested in). Do you see what I mean ?
    – mike23
    May 18 '11 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.