[success]这个想法很久就有了。可惜自己实在太忙,所以就先放在那了,不过最近刚好有时间所以就试着把它做出来了,这个东西也是搞了我好久才搞出来,其中也收获了不少知识[/success]
[infobox title=”注意”]本方法只完全适用于本主题,其他的主题我也没试过,不过大概的内容是一样的,有些代码是完全可以拿来用的,大家知道大概思路就好了[/infobox]
主要流程
大概流程就是点击发送评论的时候,会事先通过ajax提交到wordpress后台,然后wordpress就会把评论给存到数据库里面。下次你刷新的时候就会直接从数据库获取评论。然后显示出来。我的思路大概是下面这样的。在提交评论前,先通过调用api获取头像,昵称,等级,挂件的相关信息。然后把这些信息一次性提交到wordpress后台,这样就会把这些信息保存起来。最后再显示评论的时候就可以判断用户是否有uid。如果有的话就显示相关信息,如果没有就默认显示随机头像。
api的搭建
api之前写B博的时候有现成的,所以我就直接拿过来了。不过要注意把防跨越去掉,这样ajax才能正常调用[highlight lanaguage=”PHP”]
<?php
/*允许跨域请求*/
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
$uid=$_REQUEST['uid'];
$photo="";
$nickname="";
$hang="";
$level="";
if($uid)
{
$url="https://api.bilibili.com/x/space/acc/info?mid=$uid&jsonp=jsonp";
//获取头像挂件
$url2="https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?visitor_uid=$uid&host_uid=$uid&offset_dynamic_id=0";
$ch = curl_init(); //初始化curl模块
curl_setopt($ch, CURLOPT_URL, $url); //登录提交的地址
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);//这个很关键就是把获取到的数据以文件流的方式返回,而不是直接输出
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
//发送请求头
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36",
"Referer: https://www.bilibili.com/",
));
$info=json_decode(curl_exec($ch),true);
curl_setopt($ch, CURLOPT_URL, $url2); //登录提交的地址
$info2=json_decode(curl_exec($ch),true);
curl_close($ch);//关闭连接
$nickname=$info["data"]["name"];
if(!$nickname){echo "";return;}
// $sign=$info["data"]["sign"];
// $isvip=$info["data"]["vip"]["status"];
$level=$info["data"]["level"];
$photo=$info["data"]["face"];
$hang=$info2["data"]["cards"][0]['desc']['user_profile']['pendant']['image'];
$photo=str_replace("http:","",$photo);
$hang=str_replace("https:","",$hang);
echo $uid.",".$nickname.",".$photo.",".$level.",".$hang;
}
else
{
echo "";
}
[/highlight]
这个api可以直接使用get请求来获取相关信息。然后会用逗号把信息分割开来,自己获取数据后可以把它转换成数组。
ajax提交系统
就是在提交的时候先通过jQuery获取输入框的uid,然后调用api把我们的信息获取出来,最后提交后台数据的时候直接把我们获取的数据也提交过去。这里我就直接把关键部分代码给贴出来,大家感兴趣的可以到我主题的kratos.js里面找到
[highlight lanaguage=”JavaScript”]
var uid,nickname,photo,hang,level;
//先获取uid
uid=$('#uid').val();
if(uid)
{
/*发出ajax请求获B站信息*/
myajax=$.ajax({
url:"//api.xiaoyou66.com/theme/bilibili/?uid="+uid,
type:'get',
success:function(res){
if(!res)
{
window.alert("uid错误,请重新填写!");
return false;
}
var list=res.split(",");
nickname=list[1];
photo=list[2];
level=list[3];
hang=list[4];
$("#author").val(nickname);
//console.log(nickname+photo+hang);
}
});
/*等待ajax请求完毕*/
$.when(myajax).done(function () {
//console.log(jQuery(that).serialize())
if(nickname)
{
SetCookie('Buid',uid,365);
jQuery.ajax({
url:xb.ajax_url,
data:jQuery(that).serialize()+'&photo='+photo+'&hang='+hang+'&level='+level+'&action=ajax_comment',
type:jQuery(that).attr('method'),
beforeSend:addComment.createButterbar('正在提交'),
error:function(request){
var t = addComment;
t.createButterbar(request.responseText)
},
success:function(data){
jQuery('textarea').each(function(){that.value = ''});
var t = addComment,cancel = t.I('cancel-comment-reply-link'),temp = t.I('wp-temp-form-div'),respond = t.I(t.respondId),post = t.I('comment_post_ID').value,parent = t.I('comment_parent').value;
if(parent!='0'){
jQuery('#respond').before('<ol class="children">'+data+'</ol>')
}else if(!jQuery('.'+__list).length){
jQuery('#comments-nav').before('<ol class="'+__list+'">'+data+'</ol>')
}else{
if(xb.order=='asc'){
jQuery('.'+__list).append(data)
}else{
jQuery('.'+__list).prepend(data)
}
}
t.createButterbar('提交成功');
cancel.style.display = 'none';
cancel.onclick = null;
t.I('comment_parent').value = '0';
if(temp&&respond){
temp.parentNode.insertBefore(respond,temp);
temp.parentNode.removeChild(temp)
}
}
});
}
});
[/highlight]
PHP后台
当然我们还需要修改wordpress后台处理内容,让它接受并保存我们的参数。这里大家可以根据自己的要求按照要求添加就可以了
[highlight lanaguage=”PHP”]
//存储数据
add_action('wp_insert_comment','wp_insert_weibo',10,2);
function wp_insert_weibo($comment_ID,$commmentdata) {
$uid= isset($_POST['uid']) ? $_POST['uid'] : false;
$bilibiliphoto= isset($_REQUEST['photo']) ? $_REQUEST['photo'] : "";
$avatarshang= isset($_REQUEST['hang']) ? $_REQUEST['hang'] : "";
$level= isset($_REQUEST['level']) ? $_REQUEST['level'] : "0";
//下面是把数据保存到数据库中
update_comment_meta($comment_ID,'uid',$uid);
update_comment_meta($comment_ID,'photo',$bilibiliphoto);
update_comment_meta($comment_ID,'hang',$avatarshang);
update_comment_meta($comment_ID,'level',$level);
}
[/highlight]
保存好数据后我们想在后台显示就还需要添加下面的函数
[highlight lanaguage=”PHP”]
//后台显示uid
add_filter( 'manage_edit-comments_columns', 'my_comments_columns' );
add_action( 'manage_comments_custom_column', 'output_my_comments_columns', 10, 2 );
function my_comments_columns( $columns ){
$columns[ 'uid' ] = __( 'uid' ); //uid是代表列的名字
$columns[ 'photo' ] = __( '照片地址' );
$columns[ 'hang' ] = __( '头像挂件' );
$columns[ 'level' ] = __( '等级' );
return $columns;
}
function output_my_comments_columns( $column_name, $comment_id ){
switch( $column_name ) {
case "uid" :
echo get_comment_meta( $comment_id, 'uid', true );
break;
case "photo" :
echo get_comment_meta( $comment_id, 'photo', true );
break;
case "hang" :
echo get_comment_meta( $comment_id, 'hang', true );
break;
case "level" :
echo get_comment_meta( $comment_id, 'level', true );
break;
}
}
[/highlight]
大概效果就是下面这样
前端显示
我们保存好数据后,在评论区就要想办法显示出来我们可以使用wplist的回调函数来解决这个问题,但是这个需要自己重写前端,非常麻烦。
[highlight lanaguage=”PHP”]
<?php wp_list_comments(array('style'=>'ol','short_ping'=>true,'avatar_size'=>50,'callback'=>'函数名字不需要加括号')); ?>
//这里我拿一个非常简陋的来说一下
function kratos_comment_callback(){
do_action('set_comment_cookies',$comment,$user);
$GLOBALS['comment'] = $comment; ?>
<li <?php comment_class(); ?>>
<div id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<div class="comment-author vcard">
<?php echo get_avatar($comment,$size='50')?>
<cite class="fn">
<?php echo get_comment_author_link();?>
</cite>
</div>
<div class="comment-meta commentmetadata">
<?php echo get_comment_date();echo get_comment_date(' H:i'); ?>
</div>
<?php comment_text(); ?>
</div>
</li>
}
[/highlight]
我这里是直接偷懒,在随机头像显示那里改了代码。。。这里改代码虽然不方便,但是很简单。。。
我们获取数据库的信息是直接通过评论id和get_comment_meta函数实现的。
[highlight lanaguage=”PHP”]
//随机显示头像
function local_random_avatar( $avatar, $id_or_email, $size, $default, $alt) {
$imgs=getfilecouts(dirname(dirname(__FILE__)).'/static/images/avatar/*');
$comment_ID=get_comment_ID();
$photo=get_comment_meta($comment_ID,'photo',true);
$hang=get_comment_meta($comment_ID,'hang',true);
$uid=get_comment_meta($comment_ID,'uid',true);
$level=get_comment_meta($comment_ID,'level',true);
if ($id_or_email->user_id ==0) {
$random = mt_rand(0,count($imgs)-1);
if($uid) {
$avatar ='<div class="entry-header pull-left"><a bilibili="" href="//space.bilibili.com/'.$uid.'/dynamic" target="_blank" class="user-head c-pointer" style="background-image: url('.$photo.'); border-radius: 50%;" data-userinfo-popup-inited="true"><div data-v-4077d7b8="" class="user-decorator" style="background-image: url('.$hang.');"></div></a><a href="//www.bilibili.com/blackboard/help.html#会员等级相关" target="_blank" lvl="'.$level.'" class="h-level m-level"></a></div>';
}
else {
$avatar = get_bloginfo('template_url') . "/static/images/avatar/" . substr($imgs[$random], strripos($imgs[$random], '/') + 1);
$avatar = "<img alt='{$alt}' src='{$avatar}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}'/><div style='position: absolute;'><a href='//www.bilibili.com/blackboard/help.html#会员等级相关' target='_blank' lvl='0' class='n-level m-level'></a></div>";
}
}else{
$avatar.="<div style='position: absolute;'><a href='//www.bilibili.com/blackboard/help.html#会员等级相关' target='_blank' lvl='6' class='n-level m-level'></a></div>";
}
return $avatar;
}
add_filter( 'get_avatar' , 'local_random_avatar' , 1 , 5 );
[/highlight]
实际代码,自己可以随意。
cookie数据保存
这个是最麻烦的。因为在wordpress直接使用setcookie是不行的。要在初始化的时候设置才可以。不过这个是不能满足我的要求的。我当初谷歌了一大堆,全部说的是这个。。。所以没办法了,只能自己想办法了。首先我是想使用wordpress保存评论者的cookie数据来实现的,不过很可惜,里面只会保存作者名字,邮箱和网址。所以PHP是没办法了。
然后我又想用js来实现,不过保存很简单,但是什么时候赋值又是一个问题。因为主题使用了pjax,所以无法卡好保存时机。。。
就在我想放弃的时候我想到一个好办法,可不可以用js来保存cookie数据,然后用PHP读取呢。然后稍微看了一下网上的说明,说是可以的。因为cookie是一样的。
所以最好我就用这个方法完美解决!
下面贴一下js保存cookie的函数
[highlight lanaguage=”JavaScript”]
function SetCookie(sName, sValue,iExpireDays) {
if (iExpireDays){
var dExpire = new Date();
dExpire.setTime(dExpire.getTime()+parseInt(iExpireDays*24*60*60*1000));
document.cookie = sName + "=" + escape(sValue) + "; expires=" + dExpire.toGMTString()+ "; path=/;domain=xiaoyou66.com";
}
else{
document.cookie = sName + "=" + escape(sValue)+ "; path=/;domain=xiaoyou66.com";
}
}
[/highlight]
PHP读取cookie数据很简单,下面贴一下我的PHP代码
作者,网址,邮箱直接用wordpress自带的cookie,uid用自己的方法来实现
[highlight lanaguage=”PHP”]
$fields=array(
'uid'=>'<div class="comment-form-bilibili form-group has-feedback"><div class="input-group"><div class="input-group-addon"><i class="fa fa-id-card-o" aria-hidden="true"></i></div><input class="form-control" placeholder="'.__('B站uid','xiaoyou').'" id="uid" name="uid" type="text" value="'.esc_attr($_COOKIE["Buid"]).'" size="30" /><span class="form-control-feedback required">*</span></div></div>',
'author'=>'<div class="comment-form-author form-group has-feedback"><div class="input-group"><div class="input-group-addon"><i class="fa fa-user"></i></div><input class="form-control" placeholder="'.__('昵称','xiaoyou').'" id="author" name="author" type="text" value="'.esc_attr($commenter['comment_author']).'" size="30" /><span class="form-control-feedback required">*</span></div></div>',
'email'=>'<div class="comment-form-email form-group has-feedback"><div class="input-group"><div class="input-group-addon"><i class="fa fa-envelope-o"></i></div><input class="form-control" placeholder="'.__('邮箱','xiaoyou').'" id="email" name="email" type="text" value="'.esc_attr($commenter['comment_author_email']).'" size="30" /><span class="form-control-feedback required">*</span></div></div>',
'url'=>'<div class="comment-form-url form-group has-feedback"><div class="input-group"><div class="input-group-addon"><i class="fa fa-link"></i></div><input class="form-control" placeholder="'.__('网站','xiaoyou').'" id="url" name="url" type="text" value="'.esc_attr($commenter['comment_author_url']).'" size="30" /></div></div>',
'cookies'=>'',
);
[/highlight]
其他的就不多说了,差不多就这些内容