1
votes

I have a ACF select field with a field name of "sales_rep". It is populated with:

John Doe Bart Simpson Eric Cartman

The field is set to show on the "User Form" and only show when the "Current User Role" is an admin.

The field shows on each user page and I can manually change it to the sales rep I want and save it.

The issue is that I want to be able to programmatically update it whenever the user profile is saved. I will eventually add more code to determine the sales rep but I simplified the issue for this post.

Below is my code in functions.php:

Attempt 1: No error and no change to value

// Update sales rep
add_action( 'edit_user_profile_update', 'update_rep' );
add_action( 'personal_options_update', 'update_rep' );


function update_rep( $user_id )
{
    update_user_meta( $user_id, 'sales_rep', 'Eric Cartman' );
}

Attempt 2: No error and no change to value

// Update sales rep
add_action( 'edit_user_profile_update', 'update_rep' );
add_action( 'personal_options_update', 'update_rep' );


function update_rep( $user_id )
{
    $field_key = "sales_rep";
    $value = array("Eric Cartman");
    update_field( $field_key, $value, $user_id );
}
2

2 Answers

1
votes

Seems like user_ prefix could fix the issue.

Try to get/update fields with user_ prefix. F.e:

update_field( $field_key, $value, "user_$user_id" );

And for update_user_meta,

Calling delete_user_meta before could solve the problem.

User meta could have duplicate keys.

Try this one

delete_user_meta( $user_id, $field_key );
add_user_meta( $user_id, $field_key, $value );  
1
votes

I think @Andrii Kovalenko is right, user_ prefix could be your issue.

Also noticed you are saving acf field data as an array("Eric Cartman").

I am assuming your ACF select field predefined select options look like this...

John Doe
Bart Simpson
Eric Cartman

This should work for your acf option...

// is run when you edit YOUR profile, and save it
add_action('personal_options_update', 'handle_user_profile_update' );

// is run when you edit ANY OTHER profile and save it
add_action('edit_user_profile_update', 'handle_user_profile_update' );

// on user profile update function handler
function handle_user_profile_update($user_id) {

    // update sales rep
    update_sales_rep_field($user_id);

    // add anymore on user update profile functions here...

}

// update sales rep field
function update_sales_rep_field($user_id) {

    // our values
    $value = 'Eric Cartman';

    // update acf user field by user id
    update_field('sales_rep', $value, 'user_' . $user_id);

}



Out of curiosity, are these sales reps actually users in your wordpress site?

If so you can dynamically populate the select sales_rep user field with sales rep users on your site like this...

function render_sales_rep_select_field($field) {
    
    // reset sales_rep select field choices
    $field['choices'] = [];

    // get users with user role sales
    $args = array(
        'role'    => 'sales', // your sales reps user role
        'orderby' => 'user_nicename',
        'order'   => 'ASC'
    );

    // get user with args from above
    $users = get_users( $args );

    // for each sales rep user
    foreach ( $users as $user ) {
        
        // build our sales rep select field choices by user_id > full name
        $field['choices'][$user->id] = $user->first_name . ' ' . $user->last_name
    
    }

    // return the select field
    return $field;
    
}

// load user field with our custom select drop of sales rep users
add_filter('acf/load_field/name=sales_rep', 'render_sales_rep_select_field');

With this method you won't need to update the field when the user saves changes to their profile.

For example if you get_field like this...

// get user field sales rep array
get_field('sales_rep', 'user_' . $user_id ); // random user id

it will return an array of user_id and full name...

Array
    (
        [5] => Eric Cartman
    )

In your acf user select field settings you will need select return both value and label.