Skip to content

Instantly share code, notes, and snippets.

@jdembowski
Last active July 13, 2021 23:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jdembowski/54e4fe6ba763c9935c458bd8d74a3d69 to your computer and use it in GitHub Desktop.
Save jdembowski/54e4fe6ba763c9935c458bd8d74a3d69 to your computer and use it in GitHub Desktop.
Use Gravatar images in WordPress but don't reveal the Gravatar img src URL. Display the Gravatar inline instead.
<?php
/*
Plugin Name: Tin Foil Hat Gravatars
Description: Use Gravatars but don't use Gravatars. What? Shut up.
Author: Jan Dembowski
Author URI: https://blog.dembowski.net/
Version: 0.7
License: GPL2
*/
add_filter( 'get_avatar', 'tinfoilhat_get_avatar', 10, 6 );
function tinfoilhat_get_avatar( $avatar, $id_or_email, $size, $default, $alt, $args ) {
// Are we in the WordPress dashboard? If so stop, don't
// bother with any Gravatar substitutions.
if ( is_admin() ) return $avatar;
// Save the orginal hash of the unmodified $avatar
$mh_avatar_hash = md5( $avatar );
// Is the result already in a transient? If so get and return that.
$mh_transient_avatar = get_transient( 'mh_notgravatar_' . $mh_avatar_hash );
if( $mh_transient_avatar ) {
$avatar = '<!-- Transient Gravatar -->' . $mh_transient_avatar;
return $avatar;
}
// If there's no Gravatar to hide then just return $avatar after
// the email hash is munged.
if( !(mh_validate_gravatar( $id_or_email ))) {
// Get md5 for example+number@example.com
$mh_email_hash = md5( strtolower( trim( 'example+' . rand(1,2000) . '@example.com' )));
// Replace the current md5 with the new one
$avatar = preg_replace( '/gravatar.com\/avatar\/.{32}/', 'gravatar.com/avatar/' . $mh_email_hash, $avatar );
// Save the new $avatar in a transient for the next time
set_transient( 'mh_notgravatar_' . $mh_avatar_hash, $avatar, 30 * MINUTE_IN_SECONDS );
return $avatar;
}
// If there is a valid Gravatar then remove the URL and inline the image.
// Regex and preg_match_all to put all urls from $avatar into an array.
$mh_src_regex = "/'(http|https)\:(.*?)[' ]/";
preg_match_all( $mh_src_regex , $avatar, $mh_urls );
// Go through that array and replace src='url' with src='data:...'
foreach( $mh_urls[0] as $match ) {
// Remove the first and last characters in the string. The regex
// is close enough for government work but has 1 extra character
// at the start and end.
$mh_old_url = substr( $match , 1, -1 );
// Download the image into an array.
$mh_image = wp_remote_get( $mh_old_url );
// base64 encode the image from the body part of that download.
$mh_inline_gravatar = base64_encode( $mh_image['body'] );
// I need the content type from the headers for JPEG/PNG or
// whatever was retrieved.
$mh_content_type = $mh_image['headers']['content-type'];
// Put it together and make the inline substitution for the avatar
$mh_inline_src = 'data:' . $mh_content_type . ';base64,' . $mh_inline_gravatar;
$avatar = str_replace( $mh_old_url, $mh_inline_src, $avatar );
}
// Save the new $avatar in a transient for the next time
set_transient( 'mh_notgravatar_' . $mh_avatar_hash, $avatar, 30 * MINUTE_IN_SECONDS );
return $avatar;
}
// I copied this whole from https://gist.github.com/justinph/5197810
// Justin Heideman (https://github.com/justinph) wrote validate_gravatar
// and it's very complete. The wp_cache part is neat.
//
// I prefixed the function name in case a validate_gravatar() exists
// in future WordPress versions.
function mh_validate_gravatar($id_or_email) {
//id or email code borrowed from wp-includes/pluggable.php
$email = '';
if ( is_numeric($id_or_email) ) {
$id = (int) $id_or_email;
$user = get_userdata($id);
if ( $user )
$email = $user->user_email;
} elseif ( is_object($id_or_email) ) {
// No avatar for pingbacks or trackbacks
$allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) );
if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) )
return false;
if ( !empty($id_or_email->user_id) ) {
$id = (int) $id_or_email->user_id;
$user = get_userdata($id);
if ( $user)
$email = $user->user_email;
} elseif ( !empty($id_or_email->comment_author_email) ) {
$email = $id_or_email->comment_author_email;
}
} else {
$email = $id_or_email;
}
$hashkey = md5(strtolower(trim($email)));
$uri = 'http://www.gravatar.com/avatar/' . $hashkey . '?d=404';
$data = wp_cache_get($hashkey);
if (false === $data) {
$response = wp_remote_head($uri);
if( is_wp_error($response) ) {
$data = 'not200';
} else {
$data = $response['response']['code'];
}
wp_cache_set($hashkey, $data, $group = '', $expire = 60*5);
}
if ($data == '200'){
return true;
} else {
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment