[Typecho] Gravatar & Qlogo 评论头像缓存
当前页面是本站的「Baidu MIP」版。查看和发表评论请点击:完整版 »
√> 支持 Handsome 4.2.0
修改主题获取头像的函数,使得评论头像能够缓存在本地并加载,而不用每次都由来访者从 Gravator 和 Qlogo 加载,节省加载时间。
Head Pic: 「ウォーロックジータちゃん」/「konomi★きのこのみ」のイラスト [pixiv]
评论头像缓存
2017-12-05:随 Handsome 4.1.1 主题同步更新
2017-12-11:增加一个检测头像下载失败重新下载的功能
说明
这次魔改是针对 handsome主题 的,即本站所使用的主题。实际上是从“Gravatar 头像缓存插件”获得的启发,也参考了其代码。如果这个插件(Github项目地址在最后)不支持你所使用的主题,比如 handsome主题,那么你也可以试试仿照着魔改一下。
2017-10-21 修复一个 Qlogo 默认头像不能识别的 bug
思路
- 以一个每个邮箱独有的标志命名每个缓存文件,例如 Gravator 就是邮箱的 md5,Qlogo 就是QQ号。
- 如果不存在已经缓存的头像,或者超出设定的缓存时限,则将头像下载到服务器本地。
- 下载成功,则返回本地缓存图片路径。
- 下载失败,或者得到的为 Gravator 或者 Qlogo 的默认头像,则返回自己设定的默认头像。
- 如果存在已经缓存的头像,那么直接返回缓存的图片路径。
魔改代码
如果是 handsome 主题则直接修改/(网站根目录)/usr/themes/handsome/libs/Utils.php
在此文件的类的末端(即最后一个右大括号}
之前)加上如下4个函数:
//缓存Qlogo头像
public static function getQlogoCache($avatar,$nk){
//setting-start
$options = mget();
$default = '';
if (strlen($options->defaultAvator) > 0){
$default = $options->defaultAvator;
}
//缓存时间,单位秒,1209600秒=14天
$timeCache = 1209600;
//头像缓存目录
$tempDir = "/usr/uploads/qlogoCache/";
//setting-end
$host = "https://q.qlogo.cn";
$imgName = $nk . ".jpg";
$localImgFile = __TYPECHO_ROOT_DIR__ . $tempDir . $imgName;
if(!self::mkdirs(dirname($localImgFile))){
throw new exception('GravatarCache 缓存目录创建失败,请检查指定的目录是否可写' );
}
if(!file_exists($localImgFile) || (time() - filemtime($localImgFile)) > $timeCache){
if(!self::download($avatar, $host, $localImgFile)) return $default;
}
$fileSize = filesize($localImgFile);
if($fileSize < 1){
if(!self::download($avatar, $host, $localImgFile)) return $default;
}
if($fileSize == 1512 || $fileSize == 971) return $default;
return $tempDir . $imgName;
}
//缓存Gravator头像
public static function getGravatorCache($email,$host){
//setting-start
$options = mget();
$default = '';
if (strlen($options->defaultAvator) > 0){
$default = $options->defaultAvator;
}
//缓存时间,单位秒,1209600秒=14天
$timeCache = 1209600;
//头像缓存目录
$tempDir = "/usr/uploads/avatarCache/";
//setting-end
$url = '/';//自定义头像目录,一般保持默认即可
$size = '40';//自定义头像大小
$rating = Helper::options()->commentsAvatarRating;
$hash = md5(strtolower($email));
$avatar = $host . $url . $hash . '?s=' . $size . '&r=' . $rating . '&d=' . urlencode($default);
$imgName = $hash . ".jpg";
$localImgFile = __TYPECHO_ROOT_DIR__ . $tempDir . $imgName;
if(!self::mkdirs(dirname($localImgFile))){
throw new exception('GravatarCache 缓存目录创建失败,请检查指定的目录是否可写' );
}
if(!file_exists($localImgFile) || (time() - filemtime($localImgFile)) > $timeCache){
if(!self::download($avatar, $host, $localImgFile)) return $default;
}
$fileSize = filesize($localImgFile);
if($fileSize < 1){
if(!self::download($avatar, $host, $localImgFile)) return $default;
}
return $tempDir . $imgName;
}
//递归建立目录
public static function mkdirs($dir){
return is_dir($dir) or (self::mkdirs(dirname($dir)) and mkdir($dir, 0777));
}
//下载头像
public static function download( $url, $referer, $imagePath ){
$fpLocal = @fopen( $imagePath, 'w' );
if( !$fpLocal ) {
return false;
}
if( is_callable('curl_init') ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_REFERER, $referer );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_FILE, $fpLocal );
if( !curl_exec($ch) ) {
fclose( $fpLocal );
curl_close( $ch );
return false;
}
curl_close( $ch );
}else {
$opts = array(
'http' => array(
'method' => "GET",
'header' => "Referer: $referer\r\n"
)
);
$context = stream_context_create( $opts );
$fpRemote = @fopen( $url, 'r', false, $context );
if( !$fpRemote ) {
fclose( $fpLocal );
return false;
}
while( !feof( $fpRemote ) ) {
fwrite( $fpLocal, fread($fpRemote, 8192) );
}
fclose( $fpRemote );
}
fclose( $fpLocal );
return true;
}
接着,找到getAvator($email)
函数,修改其中的3行:
public static function getAvator($email){
$options = mget();
$cdnUrl = $options->CDNURL;
if (@ in_array('emailToQQ',$options->featuresetup)){
$str = explode('@', $email);
if (@$str[1] == 'qq.com') {
$avatorSrc = 'https://q.qlogo.cn/g?b=qq&nk='.$str[0].'&s=40';
$avatorSrc = self::getQlogoCache($avatorSrc,$str[0]);//修改1:直接加这一句
}else{
$avatorSrc = Utils::getGravatorCache($email,$cdnUrl);//修改2:改函数名
}
}else{
$avatorSrc = Utils::getGravatorCache($email,$cdnUrl);//修改3:改函数名
}
return $avatorSrc;
}
后记
这样折腾其实还不如直接用好一点的 gravatar 镜像
参考
这次魔改参考了 羽飞 的 Gravatar 头像缓存插件 For Typecho,参考了其部分代码,省了很多事还学到了点新姿势(。