Last active
July 13, 2021 23:04
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 [email protected] | |
$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