通过评论简单制作的朋友圈独立页面模板演示
Typecho 提供了一个 functions.php,可以用来定义函数,数据库相关的操作就放在 functions.php 中,当然也可直接添加到相关文中,并不是一定要添加到functions.php中。
“pinga”这个函数是获取点赞数据(最重要的是初始化添加相关字段),判断存储点赞数量的字段是否存在。如果点赞数的字段不存在就创建,查询点赞记录的 Cookie(容易被刷,只能防君子)用于判断评论是否点赞过,在返回点赞数量和点赞记录。
“$cid”参数为评论的“coid”
function pinga($cid) {
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
// 判断点赞数量字段是否存在
if (!array_key_exists('agree', $db->fetchRow($db->select()->from('table.comments')))) {
// 在评论表中创建一个“agree”字段用来存储点赞数量
$db->query('ALTER TABLE `' . $prefix . 'comments` ADD `agree` INT(10) NOT NULL DEFAULT 0;');
}
// 查询出点赞数量
$agree = $db->fetchRow($db->select('table.comments.agree')->from('table.comments')->where('coid = ?', $cid));
// 获取记录点赞的 Cookie
$AgreeRecording = Typecho_Cookie::get('typechoAgreegRecording');
// 判断记录点赞的 Cookie 是否存在
if (empty($AgreeRecording)) {
// 如果不存在就写入 Cookie
Typecho_Cookie::set('typechoAgreegRecording', json_encode(array(0)));
}
// 返回
return array(
// 点赞数量
'agree' => $agree['agree'],
// 评论是否点赞过
'recording' => in_array($cid, json_decode(Typecho_Cookie::get('typechoAgreegRecording')))?true:false
);
}
“pingb”函数通过cookie判断是否点赞过,如果不存在就执行点数数据更新操作,如果存在就直接输出点赞数据,在把评论的 coid 添加到点赞记录的 Cookie 中。
“$cid”参数为评论的“coid”
function pingb($cid) {
$db = Typecho_Db::get();
// 根据评论的 `coid` 查询出点赞数量
$agree = $db->fetchRow($db->select('table.comments.agree')->from('table.comments')->where('coid = ?', $cid));
// 获取点赞记录的 Cookie
$agreeRecording = Typecho_Cookie::get('typechoAgreegRecording');
// 判断 Cookie 是否存在
if (empty($agreeRecording)) {
// 如果 cookie 不存在就创建 cookie
Typecho_Cookie::set('typechoAgreegRecording', json_encode(array($cid)));
}else {
// 把 Cookie 的 JSON 字符串转换为 PHP 对象
$agreeRecording = json_decode($agreeRecording);
// 判断评论是否点赞过
if (in_array($cid, $agreeRecording)) {
// 如果当前评论的 coid 在 cookie 中就返回文章的赞数,不再往下执行
return $agree['agree'];
}
// 添加点赞评论的 coid
array_push($agreeRecording, $cid);
// 保存 Cookie
Typecho_Cookie::set('typechoAgreegRecording', json_encode($agreeRecording));
}
// 更新点赞字段,让点赞字段 +1
$db->query($db->update('table.comments')->rows(array('agree' => (int)$agree['agree'] + 1))->where('coid = ?', $cid));
// 查询出点赞数量
$agree = $db->fetchRow($db->select('table.comments.agree')->from('table.comments')->where('coid = ?', $cid));
// 返回点赞数量
return $agree['agree'];
}
Typecho 用来输出评论的文件是 comments.php,处理点赞和展示点赞数量就需要在这个文件中编写。
下面是判断点赞的post请求部分需要放到 comments.php 的顶部,避免之前有内容输出:
// 判断是否是点赞的 POST 请求
if (isset($_POST['agree'])) {
//使用点赞函数,传入评论的“coid”参数(其中的“$_POST['agree']”就是提交的评论“coid”),在禁止代码继续往下面执行。
exit(pingb($_POST['agree']));
}
点赞和获取点赞数据的相关代码:
//通过函数获取评论点赞数据
<?php $agree = $options->hidden?array('agree' => 0, 'recording' => true):pinga($comments->coid); ?>
<span onclick="PYZ('<?php $comments->coid(); ?>');">
<span <?php echo $agree['recording']?'disabled':''; ?> type="button" id="agree-btn-<?php echo $comments->coid; ?>" data-url="?"><span class="iconfont icon-dianzan"></span> <span class="agree-num"><?php echo $agree['agree']; ?>位访客</span>
</span>
</span>
注意评论按钮有两个自定义属性,data-cid 存储文章的 coid,JS 发送 AJAX 请求的时候会用到,data-url 评论的 URL,发送 AJAX 请求的 URL。
(反正测试的时候感觉没有用)上面如果评论被点赞过 PHP 就会输出 disabled 来禁用按钮。
我这里用到了 jQuery(自行找个版本引入),下面是点赞代码:
<script>
function PYZ(cid){
$('#agree-btn-'+cid).get(0).disabled = true;
$.ajax({
type: 'post',
url: $('#agree-btn-'+cid).attr('data-url'),
data: 'agree='+cid,
async: true,
timeout: 30000,
cache: false,
success: function(data) {
var re = /\d/;
if (re.test(data)) {
alert("成功");
}
},
error: function() {
alert("失败");
$('#agree-btn-'+cid).get(0).disabled = false;
},
});
}
</script>
点赞后被点赞的评论的点赞按钮会被禁用,只有点赞记录的 Cookie 到期或清除后才能再次点赞。
暴力代码测试(只为做测试用),
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
// 判断是否是点赞的 POST 请求
if (isset($_POST['agree'])) {
// 调用点赞函数,传入评论的 coid,然后通过 exit 输出点赞数量
exit(pingb($_POST['agree']));
}
?>
<?php define("XM_TPL",__TYPECHO_THEME_DIR__.'/default/'); ?>
<script src="<?php echo XM_TPL.'jquery.min.js'; ?>" defer></script>
<script>
function PYZ(cid){
$('#agree-btn-'+cid).get(0).disabled = true;
$.ajax({
type: 'post',
url: $('#agree-btn-'+cid).attr('data-url'),
data: 'agree='+cid,
async: true,
timeout: 30000,
cache: false,
success: function(data) {
var re = /\d/;
if (re.test(data)) {
alert("成功");
}
},
error: function() {
alert("失败");
$('#agree-btn-'+cid).get(0).disabled = false;
},
});
}
</script>
<?php function threadedComments($comments, $options) {
$commentClass = '';
if ($comments->authorId) {
if ($comments->authorId == $comments->ownerId) {
$commentClass .= ' comment-by-author';
} else {
$commentClass .= ' comment-by-user';
}
}
$commentLevelClass = $comments->levels > 0 ? ' comment-child' : ' comment-parent';
?>
<li id="li-<?php $comments->theId(); ?>" class="comment-body<?php
if ($comments->levels > 0) {
echo ' comment-child';
$comments->levelsAlt(' comment-level-odd', ' comment-level-even');
} else {
echo ' comment-parent';
}
$comments->alt(' comment-odd', ' comment-even');
echo $commentClass;
?>">
<div id="<?php $comments->theId(); ?>">
<div class="comment-author">
<?php $comments->gravatar('40', ''); ?>
<cite class="fn"><?php $comments->author(); ?></cite>
</div>
<div class="comment-meta">
<a href="<?php $comments->permalink(); ?>"><?php $comments->date('Y-m-d H:i'); ?></a>
<span class="comment-reply"><?php $comments->reply(); ?></span>
</div>
<?php $comments->content(); ?>
<?php $agree = $options->hidden?array('agree' => 0, 'recording' => true):pinga($comments->coid); ?>
<span onclick="PYZ('<?php $comments->coid(); ?>');">
<span <?php echo $agree['recording']?'disabled':''; ?> type="button" id="agree-btn-<?php echo $comments->coid; ?>" data-url="?"><span class="iconfont icon-dianzan"></span> <span class="agree-num"><?php echo $agree['agree']; ?>位访客</span>
</span>
</span>
</div>
<?php if ($comments->children) { ?>
<div class="comment-children">
<?php $comments->threadedComments($options); ?>
</div>
<?php } ?>
</li>
<?php } ?>
<div id="comments">
<?php $this->comments()->to($comments); ?>
<?php if ($comments->have()): ?>
<h3><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h3>
<?php $comments->listComments(); ?>
<?php $comments->pageNav('« 前一页', '后一页 »'); ?>
<?php endif; ?>
<?php if ($this->allow('comment')): ?>
<div id="<?php $this->respondId(); ?>" class="respond">
<div class="cancel-comment-reply">
<?php $comments->cancelReply(); ?>
</div>
<h3 id="response"><?php _e('添加新评论'); ?></h3>
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form">
<?php if ($this->user->hasLogin()): ?>
<p><?php _e('登录身份: '); ?><a
href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a
href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a>
</p>
<?php else: ?>
<p>
<label for="author" class="required"><?php _e('称呼'); ?></label>
<input type="text" name="author" id="author" class="text"
value="<?php $this->remember('author'); ?>" required/>
</p>
<p>
<label
for="mail"<?php if ($this->options->commentsRequireMail): ?> class="required"<?php endif; ?>><?php _e('Email'); ?></label>
<input type="email" name="mail" id="mail" class="text"
value="<?php $this->remember('mail'); ?>"<?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?> />
</p>
<p>
<label
for="url"<?php if ($this->options->commentsRequireURL): ?> class="required"<?php endif; ?>><?php _e('网站'); ?></label>
<input type="url" name="url" id="url" class="text" placeholder="<?php _e('http://'); ?>"
value="<?php $this->remember('url'); ?>"<?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?> />
</p>
<?php endif; ?>
<p>
<label for="textarea" class="required"><?php _e('内容'); ?></label>
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea"
required><?php $this->remember('text'); ?></textarea>
</p>
<p>
<button type="submit" class="submit"><?php _e('提交评论'); ?></button>
</p>
</form>
</div>
<?php else: ?>
<h3><?php _e('评论已关闭'); ?></h3>
<?php endif; ?>
</div>
参考原文转载:https://www.misterma.com/archives/880/
阿度
1年前 . LV.1
大佬真是无私奉献吖,如果我是个女的我就嫁给你。
寻梦xunm
1年前 . LV.0
@阿度
我也是修改了一下别人的代码实现的