I like to have avatars shown for people who comment on my blog. WordPress supports the gravatar service natively so enabling this is very easy. However it comes with a cost — accessing external files from another domain adds lots of extra load time in the form of new DNS lookups, new SSL connections to make, etc. Wouldn’t it be nice to have gravatars stored locally and served from your own server. Well that’s what I’ve been doing for some time now, if you’d like to know how, read on…
In case you’re still wondering just why you’d want to do this, let me offer a few more benefits — images served locally can be compressed before serving them, for example ‑all my images are converted into webp versions, and any browser which supports webp gets the webp version. This is in addition to the reduction from not having to connect to an external server. The local resources can also have a caching header set on them so that browsers will cache them. Gravatar doesn’t provide for a very long cache time.
I have created 3 custom functions, which I simply place in my theme’s functions.php. The first is a custom filter for the native wordpress get_avatar(). The second grabs avatars from gravatar and google when called upon, and the third creates a daily cronjob which refreshes the gravatars — in case they’ve been changed, or a previously unavailable one is now available.
You will need to do a little bit of tinkering to make it compatible with your theme — I use the “bones” framework as you’ll notice in the 3rd function I’ve reused some code that it provided. You will also need to create, or customise the path to store the gravatars, which in my case are stored in the theme folder in the subpath “/library/images/gravatars/”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | /*********************************************\ * Filter get_avatar to use local avatars only * \*********************************************/ function bones_gravatar($avatar, $id_or_email, $size, $default, $alt) { $root_path= get_template_directory_uri() . ‘/library/images/gravatars/’; $root_path_local= get_template_directory() . ‘/library/images/gravatars/’; $gravatar_path= $root_path . ‘default_avatar’; $gravatar_path_hidpi= ‘data-gravatar-hidpi=“ ‘.$root_path . ‘default_avatar-hidpi.png“ ‘; //shamelessly reuse original code to get the e‑mail address $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; } if ( !empty($email) ) { $email_hash = md5( strtolower( trim( $email ) ) ); if(file_exists($root_path_local . $email_hash . ‘.png’)) { //if we have a local cache then use it $gravatar_path= $root_path . $email_hash ; $gravatar_path_hidpi= ‘data-gravatar-hidpi=“ ‘.$root_path . $email_hash . ‘-hidpi.png“ ‘; } } if($size >= 47) $avatar= ‘<img class=“load-gravatar avatar avatar-’.$size.’ photo” width=“ ‘.$size.’ ” height=“ ‘.$size.’ ” src=“ ‘ . $gravatar_path . ‘-hidpi.png” alt=“gravatar” />’; else $avatar= ‘<img class=“load-gravatar avatar avatar-’.$size.’ photo” width=“ ‘.$size.’ ” height=“ ‘.$size.’ ” src=“ ‘ . $gravatar_path . ‘.png” alt=“gravatar” ’ . $gravatar_path_hidpi . ’ />’; return $avatar; } add_filter(‘get_avatar’, ‘bones_gravatar’, 10, 5); /***********************\ * Create gravatar cache * \***********************/ function grab_avatar($comment_id,$comment,$refresh=false,$email=”) { usleep(20); $root_path= get_template_directory_uri() . ‘/library/images/gravatars/’; $root_path_local= get_template_directory() . ‘/library/images/gravatars/’; if($refresh==false) $img_name= md5( get_comment_author_email($comment_id) ); else $img_name= md5( $email ); if(!file_exists($root_path_local . $img_name . ‘.png’) || $refresh==true) { if($refresh==false) $bgauthemail = get_comment_author_email(); else $bgauthemail= $email; //try google first $domain= explode(“@”,$bgauthemail); if($domain[1]==“gmail.com”) { $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, “http://picasaweb.google.com/data/entry/api/user/” . $bgauthemail . “?alt=json”); $result = curl_exec($ch); curl_close($ch); $obj = json_decode($result,true); $avatar_from_gmail= $obj[‘entry’][‘gphoto$thumbnail’][‘$t’]; $extension= strrchr($avatar_from_gmail, ‘.’); $ch = curl_init($avatar_from_gmail); curl_setopt( $ch, CURLOPT_NOBODY, true ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false ); curl_setopt( $ch, CURLOPT_HEADER, false ); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $ch, CURLOPT_MAXREDIRS, 3 ); curl_exec( $ch ); $headers = curl_getinfo( $ch ); curl_close( $ch ); if($headers[‘http_code’] === 200) { $ch = curl_init($avatar_from_gmail); $fp = fopen($root_path_local . $img_name . ‘-hidpi’ . $extension, ‘wb’); curl_setopt($ch,CURLOPT_USERAGENT,‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.62 Safari/537.36’); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); $usegravatar=false; $small_image= wp_get_image_editor($root_path_local . $img_name . ‘-hidpi’ . $extension); if ( ! is_wp_error( $small_image ) ) { //check it isn’t a blank man image, if so, delete it if (md5_file($root_path_local . $img_name . ‘-hidpi.jpg’) == strtolower(“686E5C46776BA0E5C488853C1C0B492C”)) { //delete unlink($root_path_local . $img_name . ‘-hidpi.jpg’); //try gravatar $usegravatar=true; } else if (md5_file($root_path_local . $img_name . ‘-hidpi.jpg’) == strtolower(“6D4083BE95FB32358A5110F5A83B9979”)) { //delete unlink($root_path_local . $img_name . ‘-hidpi.jpg’); //try gravatar $usegravatar=true; } else { //always convert to png because some plugins expect all gravatars to be pngs $small_image->save($root_path_local . $img_name . ‘-hidpi.png’,‘image/png’); $small_image->resize(40, 40, true); $small_image->set_quality( 10 ); $small_image->save($root_path_local . $img_name . ‘.png’,‘image/png’); if($extension==”.jpg”) unlink($root_path_local . $img_name . ‘-hidpi.jpg’); } } } } //check e‑mail isnt a blank generic one else if($bgauthemail!==“noemail@intensedebate.com” || $usegravatar==true) { $avatar_from_gravatar= “https://www.gravatar.com/avatar/” . $img_name . “?s=80&d=404”; $ch = curl_init($avatar_from_gravatar); curl_setopt( $ch, CURLOPT_NOBODY, true ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false ); curl_setopt( $ch, CURLOPT_HEADER, false ); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $ch, CURLOPT_MAXREDIRS, 3 ); curl_exec( $ch ); $headers = curl_getinfo( $ch ); curl_close( $ch ); if($headers[‘http_code’] === 200) { $ch = curl_init($avatar_from_gravatar); $fp = fopen($root_path_local . $img_name . ‘-hidpi.png’, ‘wb’); curl_setopt($ch,CURLOPT_USERAGENT,‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.62 Safari/537.36’); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); $small_image= wp_get_image_editor($root_path_local . $img_name . ‘-hidpi.png’); if ( ! is_wp_error( $small_image ) ) { $small_image->resize(40, 40, true); $small_image->save($root_path_local . $img_name . ‘.png’); } } } } } add_action(‘wp_insert_comment’, ‘grab_avatar’); /********************************************\ * Refresh gravatar cache in background daily * \********************************************/ add_action( ‘wp’, ‘bones_setup_schedule’ ); function bones_setup_schedule() { if ( ! wp_next_scheduled( ‘bones_daily_event’ ) ) { wp_schedule_event( time(), ‘daily’, ‘bones_daily_event’); } } add_action( ‘bones_daily_event’, ‘bones_refresh_gravatars’ ); function bones_refresh_gravatars() { //get list of gravatars somehow global $wpdb; $comment_author_emails= $wpdb->get_results( “SELECT DISTINCT(comment_author_email) FROM ” . $wpdb->prefix . “comments” ); foreach($comment_author_emails as $key => $val) { foreach($val as $a => $b) { grab_avatar(”,”,true,$b); } } } |
Think we've missed something? Let us know by commenting below. If you would like to subscribe please use the subscribe link on the menu at the top right. You can also share this with your friends by using the social links below. Cheers.
Leave a Reply