[wp-trac] [WordPress Trac] #16020: Upload custom avatar for user in Dashboard

WordPress Trac noreply at wordpress.org
Fri Sep 9 09:27:02 UTC 2022


#16020: Upload custom avatar for user in Dashboard
-------------------------------------+-------------------------------------
 Reporter:  computerwiz908           |       Owner:  whyisjake
     Type:  feature request          |      Status:  accepted
 Priority:  normal                   |   Milestone:  Future Release
Component:  Users                    |     Version:
 Severity:  minor                    |  Resolution:
 Keywords:  has-patch needs-refresh  |     Focuses:  ui, administration,
  has-screenshots                    |  privacy
-------------------------------------+-------------------------------------

Comment (by domainsupport):

 Hi,

 I've been looking at the following issues with gravatar being used on a
 WordPress site and have commented on the closed ticket
 [https://core.trac.wordpress.org/ticket/55062 #55062] ...

 - The use of gravatar poses an issue with GDPR because it exposes
 visitor's IP addresses to a third party server without their prior consent
 - The use of gravatar exposes the md5 hash of a user's email address which
 is insecure and poses an issue because an email address is considered to
 be PII, or personally identifiable information
 - Users' hashed emails are exposed whether they have signed up to gravatar
 or not
 - Visitors' browsers request a gravatar whether the gravatar exists or not

 I have put together a rough solution in the form of a filter which I think
 solves all of these issues. The code below caches the gravatars at a
 server level on request and names them by user ID. Images are re-requested
 when they are a week old.

 As far a I can see, this code only has two issues ...

 1) The initial (and subsequent) caching requests are made at the time of
 page load which will slow down the page. This could be resolved by moving
 this into a CRON schedule.
 2) The code requires that the users have an account. This won't work for
 gravatars for comments that don't have user accounts.

 I'd be interested to hear what you think.

 Thanks,

 Oliver

 {{{#!php
 <?php
         add_filter('get_avatar_url', 'gravatar_cache_get_avatar_url', 10,
 3);

         function gravatar_cache_get_avatar_url($url, $id_or_email, $args)
 {

             $user = false;
             $mystery = false;

             if (is_object($id_or_email) &&
 isset($id_or_email->comment_ID)) {

                 $id_or_email = get_comment($id_or_email);

             }

                 if (is_numeric($id_or_email)) {

                         $user = get_user_by('id', absint($id_or_email));

                 } elseif (is_string($id_or_email)) {

                         $user = get_user_by('email', $id_or_email);

                 } elseif ($id_or_email instanceof WP_User) {

                         $user = $id_or_email;

                 } elseif ($id_or_email instanceof WP_Post) {

                         $user = get_user_by('id', (int)
 $id_or_email->post_author);

                 } elseif ($id_or_email instanceof WP_Comment) {

                         if (!empty($id_or_email->user_id)) {

                                 $user = get_user_by('id', (int)
 $id_or_email->user_id);

                         }

                         if ((!$user || is_wp_error($user)) &&
 !empty($id_or_email->comment_author_email)) {

                             $user = get_user_by('email',
 $id_or_email->comment_author_email);

                         }

                 }

             $upload_dir = wp_upload_dir();
             $filepath = $upload_dir['basedir'] . '/gravatar/';

             if (!is_dir($filepath)) {

                 mkdir($filepath);

             }

             if (isset($user->ID) && $user->ID && isset($user->user_email)
 && sanitize_email($user->user_email)) {

                 $last_checked = absint(get_user_meta($user->ID,
 'gravatar_updated', true));
                 $current_timestamp = time();
                 $avatar_filename = $user->ID . '-' . $args['size'] .
 '.jpeg';
                 $avatar_filename_png = $user->ID . '-' . $args['size'] .
 '.png';

                 if ($last_checked < ($current_timestamp - 604800)) {

                     if (file_exists($filepath . $avatar_filename)) {

                         unlink($filepath . $avatar_filename);

                     }

                     if (file_exists($filepath . $avatar_filename_png)) {

                         unlink($filepath . $avatar_filename_png);

                     }

                     delete_user_meta($user->ID, 'gravatar_mystery');
                     update_user_meta($user->ID, 'gravatar_updated',
 $current_timestamp);

                 }

                 if (get_user_meta($user->ID, 'gravatar_mystery', true)) {

                     $avatar_filename = 'mystery-' . $args['size'] .
 '.jpeg';
                     $avatar_filename_png = 'mystery-' . $args['size'] .
 '.png';

                 }

                 if (file_exists($filepath . $avatar_filename)) {

                     return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename;

                 }

                 if (file_exists($filepath . $avatar_filename_png)) {

                     return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename_png;

                 }

                 $headers = @get_headers('https://www.gravatar.com/avatar/'
 . md5(strtolower(trim($user->user_email))) . '?d=404');

                 if (!$headers || ($headers && !preg_match("|200|",
 $headers[0]))) {

                     update_user_meta($user->ID, 'gravatar_mystery', true);
                     $avatar_filename = 'mystery-' . $args['size'] .
 '.jpeg';
                     $avatar_filename_png = 'mystery-' . $args['size'] .
 '.png';

                     if (file_exists($filepath . $avatar_filename)) {

                         return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename;

                     }

                     if (file_exists($filepath . $avatar_filename_png)) {

                         return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename_png;

                     }

                 }

             } else {

                 $avatar_filename = 'mystery-' . $args['size'] . '.jpeg';
                 $avatar_filename_png = 'mystery-' . $args['size'] .
 '.png';

                 if (file_exists($filepath . $avatar_filename)) {

                     return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename;

                 }

                 if (file_exists($filepath . $avatar_filename_png)) {

                     return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename_png;

                 }

             }

             $gravatar = wp_safe_remote_get($url);

             if (
                 isset($gravatar['body'])
             ) {

                 if ('.png"' === substr($gravatar['headers']->offsetGet
 ('content-disposition'), -5)) {

                     $avatar_filename = $avatar_filename_png;

                 }

                 global $wp_filesystem;

                 if (empty($wp_filesystem)) {

                     require_once (ABSPATH . '/wp-
 admin/includes/file.php');
                     WP_Filesystem();

                 }

                 $wp_filesystem->put_contents($filepath . $avatar_filename,
 $gravatar['body']);

             } else {

                 $avatar_filename = 'mystery-' . $args['size'] . '.jpeg';

             }

             return $upload_dir['baseurl'] . '/gravatar/' .
 $avatar_filename;

         }
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/16020#comment:136>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list