phpwordpressadvanced-custom-fieldsadminusermetadata

Fill the ACF field who modified the user profile


I'd like to record the user_id or display_name of the user (admin, moderator) who modified the members profile ACF field. Because this field will be use to identify who is the responsible user updated the member profile via email notification plugin. So generally, I need the display_name to be there right away before the user hit the "Update Profile" button.

My current code:

add_action( 'edit_user_profile', 'member_profile', 20, 2 );
add_action( 'show_user_profile', 'member_profile', 20, 2 );
function member_profile( $member_id, $user_id ) {

  update_field( 'field_673bbd254e89a', $user_id->display_name, 'user_'.$member_id );

};

However, I noticed that the user_id->display_name & 'user_'.$member_id don't seem to work in the admin.


Solution

  • First, note that there is only one available argument, which is the WP_User object for your hooked function.

    Also, note that edit_user_profile and show_user_profile, are hooks made for displaying input fields on the viewed user profile, but not saving the data when submitted.

    So you can try the following slight different, instead:

    add_action( 'edit_user_profile', 'keep_last_edit_user_dname', 20, 1 );
    add_action( 'show_user_profile', 'keep_last_edit_user_dname', 20, 1 );
    function keep_last_edit_user_dname( $user ) {
        global $current_user;
    
        // If the current user role matches with admin or moderator
        if ( array_intersect( $current_user->roles, ['administrator', 'moderator'] ) ) { 
            // Update the ACF field
            update_field( 'field_673bbd254e89a', $current_user->display_name, $user->ID );
        }
    };
    

    But it should grab the current user display name (when it's an administrator or a moderator), each time they visit a user profile, even if they don't make any changes.


    A better way

    Maybe a better way should be to display a hidden input field with that admin or moderator display name, so the field is updated only when the data is submitted, like:

    // Display a hidden input field  with admin/moderator user display name
    add_action( 'edit_user_profile', 'add_last_edit_user_dname', 20, 1 );
    add_action( 'show_user_profile', 'add_last_edit_user_dname', 20, 1 );
    function add_last_edit_user_dname( $user ) {
        global $current_user;
    
        // If the current user role matches with admin or moderator
        if ( array_intersect( $current_user->roles, ['administrator', 'moderator'] ) ) { 
            // Display a hidden input field with the admin display name
            printf('<input type="hidden" name="modified_by" value="%s" />', $current_user->display_name );
        }
    };
    

    Then when user data is edited via submit, we use the following to update the ACF field:

    // Save the ACF field with admin/moderator user display name
    add_action( 'personal_options_update', 'save_last_edit_user_dname', 20 );
    add_action( 'edit_user_profile_update', 'save_last_edit_user_dname', 20 );
    function save_last_edit_user_dname( $user_id )
    {
        if( isset($_POST['modified_by']) && ! empty($_POST['modified_by']) ) {
            // Update the ACF field
            update_field( 'field_673bbd254e89a', esc_attr($_POST['modified_by']), $user_id );
        }
    }
    

    This could work in a better way.