[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]
其他的就不多说了,差不多就这些内容