Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.