给自己的博客加一个B站uid评论功能


[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]

其他的就不多说了,差不多就这些内容

 

 

 


文章作者: 小游
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小游 !
  目录