How to change a user profile picture in WordPress without a plugin?

I have a WordPress website, and I want to change my user’s profile pictures without using any plugins. By default, WordPress uses Gravatar, which I am unable to replace with a custom image uploaded in WordPress. I don’t want to allow the users to upload the images but as an admin, I should be able to upload the image and set it as their profile picture using the built-in WordPress upload functionality. Can you guide me on how to achieve this?

To build the custom user profile picture option you need to know a little bit of PHP and jQuery. This is OK if you don’t know, I’ll try to explain the steps properly, you can follow these steps:

1. In your WordPress theme’s functions.php file, add the following code:


function avatar_upload_btn( $description, $user ) {
    
    if( !current_user_can('upload_files') ) {
        return $description;
    }

    $attachment_id = get_user_meta($user->ID, '_custom_avatar', true);
    
    return '
        <input type="hidden" name="_custom_avatar" id="_custom_avatar" value="' . $attachment_id . '" />
        <input type="button" class="button" id="custom-avatar-btn" value="Upload Picture" />
    ';

}
add_action( 'user_profile_picture_description', 'avatar_upload_btn', 10, 2 );


function avatar_admin_scripts(){ 
    wp_enqueue_media();
    wp_enqueue_script('avatar-uploader', get_stylesheet_directory_uri().'/js/uploader.js', array('jquery'), false, true );
}
add_action('admin_enqueue_scripts', 'avatar_admin_scripts');


function save_custom_avatar($user_id){
    
    if( current_user_can('upload_files') && !empty($_POST['_custom_avatar']) ){
        update_user_meta($user_id, '_custom_avatar', $_POST['_custom_avatar']);
        
    }
    
}
add_action('profile_update', 'save_custom_avatar');


// Apply filter
function custom_avatar( $avatar, $id_or_email, $size, $default, $alt ) {
    $user = false;

    if ( is_numeric( $id_or_email ) ) {
        $id = (int) $id_or_email;
        $user = get_user_by( 'id' , $id );
    } 
    elseif ( is_object( $id_or_email ) ) {
        if ( ! empty( $id_or_email->user_id ) ) {
            $id = (int) $id_or_email->user_id;
            $user = get_user_by( 'id' , $id );
        }
    } 
    else {
        $user = get_user_by( 'email', $id_or_email );	
    }

    if ( $user && is_object( $user ) ) {
        
        $attachment_id = get_user_meta($user->ID, '_custom_avatar', true);

        if ( !empty($attachment_id) ) {
            $avatar = wp_get_attachment_image_src( $attachment_id );
            $avatar = "<img alt='{$alt}' src='{$avatar[0]}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
        }

    }

    return $avatar;
}
add_filter( 'get_avatar' , 'custom_avatar' , 1 , 5 );

2. Now create an uploader.js file inside your theme’s js folder, and add the following code:

(function($){
    
    
    $( '#custom-avatar-btn' ).click(function() {

        let button = $(this);

        wp.media.editor.send.attachment = function( props, attachment ) {
            console.log( attachment );
            if ( attachment.type === 'image' ) {
                $('#_custom_avatar').val( attachment.id );
                button.closest('td').find('img').attr( 'src', attachment.url );
            } 
            else {
                alert( 'Please select a valid image file' );
                return false;
            }
        }

        wp.media.editor.open();
        return false;
    } );
    
    
})(jQuery);