How to Save Different Usermeta Fields According to User Role?

I have created some custom roles using a plugin and I have also created custom user meta fields that are show in the Profile pages of each user (/wp-admin/profile.php)

I have a problem with saving the custom fields, I can save the fields ok if I don’t change the users’ role. So, to give an example:

  • User 1 has fields a, b, and c and they have a user role of Pending.
  • If I change their user role to Owner, the fields they have are a and
    b
  • If I then change their user role to Pending the details that were in field C disappear

It seems that WP is removing it from the database. I want to be able to change the roles and fields without losing the data that is stored in the usermeta database table.

I think my problem is with the update_usermeta function.

//saving the user fields
add_action( 'personal_options_update', 'save_user_fields' );
add_action( 'edit_user_profile_update', 'save_user_fields' );

function save_user_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) )
    return false;
update_usermeta( $user_id, 'unit_type', $_POST['unit_type'] );
update_usermeta( $user_id, 'registered_as', $_POST['registered_as'] );
update_usermeta( $user_id, 'date_registered', $_POST['date_registered'] );
update_usermeta( $user_id, 'unit_number', $_POST['unit_number'] );
update_usermeta( $user_id, 'first_name', $_POST['first_name'] );
update_usermeta( $user_id, 'last_name', $_POST['last_name'] );
update_usermeta( $user_id, 'owner1_address', $_POST['owner1_address'] );
update_usermeta( $user_id, 'owner1_tel_day', $_POST['owner1_tel_day'] );
update_usermeta( $user_id, 'owner1_tel_night', $_POST['owner1_tel_night'] );
update_usermeta( $user_id, 'emergency_contact_name', $_POST['emergency_contact_name'] );
update_usermeta( $user_id, 'emergency_contact_tel_day',     $_POST['emergency_contact_tel_day'] );
update_usermeta( $user_id, 'emergency_contact_tel_night',     $_POST['emergency_contact_tel_night'] );
}

1 Answer
1

Observation: following the guidelines suggested in this article, I’m trying to improve the quality both of the Q and the A. It’s a learning process…

In your original code, you were displaying different input fields according to the user role and other conditionals.

add_action( 'show_user_profile', 'user_fields_for_admin', 10);
add_action( 'edit_user_profile', 'user_fields_for_admin', 10);
function user_fields_for_admin( $user ){ 
    switch ($user->roles[0]) {
        case 'pending':
            if ($selected_register == "Owner"){
                // Display some fields;
            } elseif ($selected_register == "Board") {
                // Display other fields
            }
            break;

        case 'owner':
            // Display yet another fields
            break;
    }
}

But when saving the fields using update_usermeta (as per the code in your edited question), all the fields were being saved, regardless if they were being displayed or not.

You have to check if the field value is being passed, so the usermeta will not be overridden with non-existent values at each and every update.

function save_user_fields($user_id) {
    if (!current_user_can('edit_user', $user_id))
        return false;
    if( isset($_POST['unit_type']) )     update_usermeta($user_id, 'unit_type', $_POST['unit_type']);
    if( isset($_POST['registered_as']) ) update_usermeta($user_id, 'registered_as', $_POST['registered_as']);
    // ETC
}

Suggestions for debug and printing Html

For your reference, you can check the contents of a PHP object using this code:

echo '<pre>'.print_r($user, true).'</pre>';

And instead of echoing one line at the time, you can use the Heredoc sintax for easy reading/printing Html. PHP variables goes inside curly brackets. Example:

echo <<<HTML
    <h3>Owner Details</h3>
    <table class="form-table"><tbody><tr>
    <tr><th>First Name</th>
    <td><input type="text" name="first_name" id="first_name1" value="{$first_name}" class="regular-text" /></td>
    </tr>
    <tr><th>Last Name</th>
    <td><input type="text" name="last_name" id="last_name1" value="{$last_name}" class="regular-text" /></td>
    </tr>
HTML;

Leave a Comment