Skip to content

Feature: Save google profile picture of the user during first login for both the new and existing users#250

Open
mi5t4n wants to merge 46 commits into
developfrom
feature/save-google-profile-picture-during-account-creation
Open

Feature: Save google profile picture of the user during first login for both the new and existing users#250
mi5t4n wants to merge 46 commits into
developfrom
feature/save-google-profile-picture-during-account-creation

Conversation

@mi5t4n
Copy link
Copy Markdown
Member

@mi5t4n mi5t4n commented May 5, 2025

Description

This PR implements saving the user’s Google profile picture for both new and existing users, with slightly different handling for each case.

User Settings

Two new user options have been introduced:

  • Profile Picture Source
  • Google Profile Picture Thumbnail
2025-12-10_17-04

New User

  1. Retrieve and process the Google profile picture.
  2. Download and save it as a WordPress attachment.
  3. Update user meta with the saved attachment ID.
  4. Set the Profile Picture Source to Google.
Kazam_screencast_00004.mp4

Existing User

  1. Check if a Google profile picture has already been downloaded and associated with the user.
  2. If not already downloaded, retrieve and download the Google profile picture.
  3. Save the downloaded image as an attachment.
  4. Update the user meta with the new attachment ID.
Kazam_screencast_00003.mp4

Notice

If a Google profile picture already exists for a user but the Profile Picture Source is not set to Google, an admin notice is displayed:
2025-12-10_17-07

New Filters Added

  1. Bypass profile picture saving

    /**
    * Filter to bypass the profile picture saving process.
    *
    * @since n.e.x.t
    *
    * @param boolean $save Whether to save profile picture or not.
    * @param int $user_id WP User ID.
    * @param \stdClass $user User object returned by Google.
    */
    $save_profile_picture = apply_filters( 'rtcamp.google_should_save_user_profile_picture', true, $user_id, $user );

  2. Enables re-downloading the Google profile picture regardless of existing attachments.

    /**
    * Filter to download profile picture even if it is not already downloaded.
    *
    * @since n.e.x.t
    *
    * @param boolean $download_profile_picture Whether to download profile picture.
    * @param int $user_id WP User ID.
    * @param \stdClass $user User object returned by Google.
    */
    $download_profile_picture = apply_filters(
    'rtcamp.google_download_profile_picture',
    ! $user_has_google_profile_picture,
    $user_id,
    $user
    );

Note

The rtcamp.google_download_profile_picture filter can be used to sync a user’s latest Google profile picture.

Closes - #249

@mi5t4n mi5t4n self-assigned this May 5, 2025
@mi5t4n mi5t4n requested a review from SH4LIN May 5, 2025 13:26
rtBot
rtBot previously requested changes May 5, 2025
Copy link
Copy Markdown
Contributor

@rtBot rtBot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code analysis identified issues

action-phpcs-code-review has identified potential problems in this pull request during automated scanning. We recommend reviewing the issues noted and that they are resolved.

phpcs scanning turned up:

🚫 1 error


Powered by rtCamp's GitHub Actions Library

Comment thread src/Utils/Authenticator.php Outdated
@rtBot rtBot dismissed their stale review May 5, 2025 13:30

Dismissing review as all inline comments are obsolete by now

@mi5t4n mi5t4n requested a review from rtBot May 5, 2025 13:32
Copy link
Copy Markdown
Contributor

@SH4LIN SH4LIN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

"You can change your profile picture on Gravatar."

Wouldn't this be confusing? Currently, the feature only updates the image during registration. We should either periodically check for updates, add a button to re-sync the image, or enhance the feature to also check the profile image during login.

I'm testing the .tmp case for download_url() and will submit feedback after some time.

Comment thread src/Utils/Authenticator.php Outdated
// Using larger image size. By default, profile picture has 96 width size with cropped.
$profile_picture_url = str_replace( '=s96-c', '', $user->picture );

$profile_picture_filename = download_url( $profile_picture_url );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a check for WPVIP? and if the site is hosted on WPVIP we directly use wpcom_vip_download_image() this function.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SH4LIN Yes, it can be a bit unclear—I’ll look into it further to make it more straightforward. As for re-syncing the image at each login, should we also extend this to include the First Name and Last Name, since those fields can also be updated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SH4LIN Regarding vip check, that is a good catch. I will promptly implement this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also extend this to include the First Name and Last Name, since those fields can also be updated?

In WordPress, we have the option to update the first name and last name. So, if they want to customize it, they can do so from the settings. However, there is no option in the WordPress dashboard to change the image.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a check for WPVIP? and if the site is hosted on WPVIP we directly use wpcom_vip_download_image() this function.

I tried to use this function, it seems it won't work in our scenario. I got the following error while trying to use it .
2025-05-15_15-38

The function was expecting a POST request, but Google calls the redirect URL using the GET method instead. We could try to change the global variables to make it work, but that would be a hacky solution. So, I decided to remove the function for now.

Copy link
Copy Markdown
Contributor

@SH4LIN SH4LIN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mi5t4n,

From what I can see in the implementation of media_handle_sideload(), it appears to handle the .tmp file case as well. Is there a specific reason we’ve added this case explicitly?

Also, I noticed that wpcom_vip_download_image() doesn’t seem to account for this scenario—just wanted to highlight that for consistency.

Thanks!

@mi5t4n
Copy link
Copy Markdown
Member Author

mi5t4n commented May 7, 2025

@SH4LIN In my test cases, media_handle_sideload() wasn't handling the temporary files correctly. Even though the MIME types were valid, it rejected the files because they had a .tmp extension, resulting in the error: "You are not allowed to upload the given file type." When the correct extension was set to the file according it's mime type, it worked.

@SH4LIN
Copy link
Copy Markdown
Contributor

SH4LIN commented May 7, 2025

@SH4LIN In my test cases, media_handle_sideload() wasn't handling the temporary files correctly. Even though the MIME types were valid, it rejected the files because they had a .tmp extension, resulting in the error: "You are not allowed to upload the given file type." When the correct extension was set to the file according it's mime type, it worked.

If that's the case then another option is this, we identify mime, and ext from our end pass it to the file array with key type and ext. Can we check whether this solution works or not.

Copy link
Copy Markdown
Contributor

@SH4LIN SH4LIN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mi5t4n We will also need to update the docs with the newly added hooks.

@mi5t4n
Copy link
Copy Markdown
Member Author

mi5t4n commented May 15, 2025

image

"You can change your profile picture on Gravatar."

Wouldn't this be confusing? Currently, the feature only updates the image during registration. We should either periodically check for updates, add a button to re-sync the image, or enhance the feature to also check the profile image during login.

At the moment, I can think of two ways to make it better.

  1. Override the defaule Profile Picture section to handle the removal and upload of the picture.

Before:
2025-05-15_20-58_1

After:
2025-05-15_20-58

  1. Create a new section called Google Profile Picture and a global setting to override the default avatar.

2025-05-15_21-11

LMK your thoughts on this.

cc @SH4LIN @joelabreo227

@mi5t4n
Copy link
Copy Markdown
Member Author

mi5t4n commented May 16, 2025

@SH4LIN In my test cases, media_handle_sideload() wasn't handling the temporary files correctly. Even though the MIME types were valid, it rejected the files because they had a .tmp extension, resulting in the error: "You are not allowed to upload the given file type." When the correct extension was set to the file according it's mime type, it worked.

If that's the case then another option is this, we identify mime, and ext from our end pass it to the file array with key type and ext. Can we check whether this solution works or not.

I'm not sure why, but during my second test, the .tmp files were no longer created. Now, every profile picture is saved with the correct file extension. Also, we can provide the MIME type, but not the file extension directly — the extension comes from the filename itself. The media_handle_sideload() function throws an error if the file extension doesn’t match the MIME type.

Copilot AI review requested due to automatic review settings November 6, 2025 07:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds functionality to save and use Google profile pictures for user avatars. When users register via Google login, their profile picture is downloaded and stored as a WordPress media attachment, then used as their avatar throughout the site.

  • Adds profile picture saving during user registration with a filter to bypass the process
  • Implements avatar URL override to use stored Google profile pictures instead of Gravatar
  • Extracts profile picture saving logic into a reusable private method

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
src/Utils/Authenticator.php Adds save_user_profile_picture() method to download and store Google profile pictures during registration, with filter hook to bypass
src/Plugin.php Adds return_avatar_url() method hooked to get_avatar_url filter to replace Gravatar with stored profile pictures

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php
Comment thread src/Utils/Authenticator.php
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Plugin.php Outdated
Comment thread src/Plugin.php Outdated
Comment thread src/Utils/Authenticator.php
mi5t4n and others added 6 commits December 3, 2025 14:44
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.

Comments suppressed due to low confidence (1)

src/Utils/Authenticator.php:224

  • Security concern: The profile picture URL from Google is used directly without validation. While Google is a trusted source, it's a best practice to validate that the URL is actually from Google's domain before downloading to prevent potential SSRF (Server-Side Request Forgery) attacks if the $user->picture field is somehow manipulated.

Consider adding URL validation:

if ( ! isset( $user->picture ) || empty( $user->picture ) ) {
    return;
}

// Validate it's a Google URL
$parsed_url = wp_parse_url( $user->picture );
if ( ! $parsed_url || ! isset( $parsed_url['host'] ) || 
     ! preg_match( '/^([a-z0-9-]+\.)*googleusercontent\.com$/i', $parsed_url['host'] ) ) {
    return;
}
		if ( ! isset( $user->picture ) || empty( $user->picture ) ) {
			return;
		}

		// Using larger image size. By default, profile picture has 96 width size with cropped.
		$profile_picture_url = str_replace( '=s96-c', '', $user->picture );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Utils/Authenticator.php
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php Outdated
Comment thread src/Utils/Authenticator.php
Comment thread src/Plugin.php Outdated
Comment thread src/Plugin.php Outdated
Comment thread src/Utils/Authenticator.php
@mi5t4n mi5t4n changed the title Feature: Save google profile picture of the user during account creation Feature: Save google profile picture of the user during first login Dec 10, 2025
@mi5t4n mi5t4n changed the title Feature: Save google profile picture of the user during first login Feature: Save google profile picture of the user during first login for both the new and existing users Dec 10, 2025
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 18 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Modules/UserProfile.php Outdated
Comment thread src/Modules/UserProfile.php Outdated
Comment thread src/Utils/UserProfileHelper.php Outdated
Comment thread src/Utils/Authenticator.php Outdated
Comment thread templates/user-profile-edit.php Outdated
Comment thread src/Utils/Authenticator.php
Comment thread templates/user-profile-edit.php Outdated
* @return integer|null
*/
public static function get_saved_google_profile_picture_id( int $user_id ): ?int {
$profile_picture_id = get_user_meta( $user_id, 'rtlwg_profile_picture_id', true );
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same inconsistency in the meta key prefix. Uses rtlwg_profile_picture_id while other meta keys use rtlg_ prefix.

Copilot uses AI. Check for mistakes.
Comment thread src/Modules/UserProfile.php Outdated
Comment thread src/Modules/UserProfile.php Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@rtBot rtBot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code analysis identified issues

action-phpcs-code-review has identified potential problems in this pull request during automated scanning. We recommend reviewing the issues noted and that they are resolved.

phpcs scanning turned up:

🚫 1 error


Powered by rtCamp's GitHub Actions Library

Comment thread src/Utils/UserProfileHelper.php
mi5t4n and others added 2 commits December 10, 2025 17:42
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@rtBot rtBot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code analysis identified issues

action-phpcs-code-review has identified potential problems in this pull request during automated scanning. We recommend reviewing the issues noted and that they are resolved.

phpcs scanning turned up:

🚫 1 error


Powered by rtCamp's GitHub Actions Library

Comment thread src/Modules/UserProfile.php
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Modules/UserProfile.php Outdated
Comment thread src/Modules/UserProfile.php Outdated
Comment thread src/Container.php
Comment thread src/Utils/Authenticator.php
Comment thread src/Modules/UserProfile.php
Comment thread src/Utils/Authenticator.php
Comment thread src/Utils/Authenticator.php Outdated
mi5t4n and others added 4 commits December 10, 2025 17:57
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@mi5t4n mi5t4n requested a review from mchirag2002 December 10, 2025 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants