垃圾评论一波接一波,私密评论的垃圾评论居然过滤不掉,只能再把算数验证加上。效果如图所示。
以下内容样式是能用于pigeon,通用的算数验证在这里查看typecho纯代码算术验证码
话不多说,上代码。
一:
完整pigeon/functions.php
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;?>
<?php
$GLOBALS['config'] = require_once "libs/config.inc.php";
require_once 'libs/Settings.php';
require_once 'libs/Utils.php';
require_once 'libs/ImgCompress.php';
require_once 'libs/Ajax.php';
require_once 'libs/core.php';
require_once 'libs/feature.php';
require_once 'libs/Shortcode.php';
require_once 'libs/plate.php';
require_once 'libs/admin.php';
function themeInit($archive){
$archive = spam_protection_pre($archive, $post, $result);
if ($archive->is('single'))
{ $archive->content = image_class_replace($archive->content);
}
if($archive->request->isPost() && $archive->request->likeup && $archive->request->do_action){
likeup($archive->request->likeup,$archive->request->do_action);
exit;
}
Helper::options()->commentsAntiSpam = false; //关闭反垃圾
Helper::options()->commentsCheckReferer = false; //关闭检查评论来源URL与文章链接是否一致判断(否则会无法评论)
Helper::options()->commentsMaxNestingLevels = '999'; //最大嵌套层数
Helper::options()->commentsPageDisplay = 'first'; //强制评论第一页
Helper::options()->commentsOrder = 'DESC'; //将最新的评论展示在前
Helper::options()->commentsHTMLTagAllowed = '<a href=""> <img src=""> <img src="" class=""> <code> <del>';
Helper::options()->commentsMarkdown = true;
// //gravatar.loli.net/avatar/
if(isset($_GET['action']) == 'ajax_avatar_get' && 'GET' == $_SERVER['REQUEST_METHOD'] ) {
$host = 'https://cravatar.com/avatar/';
$email = strtolower( $_GET['email']);
$hash = md5($email);
$sjtx = 'mm';
$avatar = $host . $hash . '?d='.$sjtx;
echo $avatar;
die();
}else { return; }
}
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('Shortcode','parseContent');//文章短代码解析
Typecho_Plugin::factory('Widget_Feedback')->comment_1000 = array('feature', 'insertSecret');//隐私评论
Typecho_Plugin::factory('Widget_Abstract_Comments')->contentEx = array('feature','parseContent');//评论表情
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('Utils', 'addButton');//后台按钮
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('Utils', 'addButton');//后台按钮
function spam_protection_math() {
$num1 = rand(0, 10);
$num2 = rand(0, 10);
echo "<div class=\"comment_xin\"><input type=\"text\" name=\"sum\" class=\"text\" value=\"\" id=\"sum\" tabindex=\"4\" placeholder=\"".numToWord($num1)." + ".numToWord($num2)." = 多少? \"></div>";
echo "<input type=\"hidden\" name=\"num1\" value=\"$num1\">\n";
echo "<input type=\"hidden\" name=\"num2\" value=\"$num2\">";
}
function spam_protection_pre($archive, $post, $result) {
$user = Typecho_Widget::widget('Widget_User');
if ($_REQUEST['text'] != null) {
If($user->hasLogin()){
return $archive;//判断已登录用户直接返回,无需验证 /使用Typecho_Widget获取用户登录信息 $user = Typecho_Widget::widget('Widget_User');
}elseIf($_POST['num1'] == null || $_POST['num2'] == null ) {
throw new Typecho_Widget_Exception(_t('验证码异常.', '评论失败'));
} else {
$sum = $_POST['sum'];
switch ($sum) {
case $_POST['num1'] + $_POST['num2'] : break;
case null:
throw new Typecho_Widget_Exception(_t('请输入验证码.', '评论失败'));
break;
default:
throw new Typecho_Widget_Exception(_t('验证码错误,请认真答题', '评论失败'));
}
}
}
return $archive;
}
function likeup($ccid,$kg) {
$cid = $ccid;
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
if (!array_key_exists('likes', $db->fetchRow($db->select()->from('table.contents')))) {
$db->query('ALTER TABLE `' . $prefix . 'contents` ADD `likes` INT(10) DEFAULT 0;');
return;
}
$row = $db->fetchRow($db->select('likes')->from('table.contents')->where('cid = ?', $cid));
$num=$row['likes'];
if($kg=="do"){
$db->query($db->update('table.contents')->rows(array('likes' => (int)$row['likes']+1))->where('cid = ?', $cid));
$num=$num+1;
setcookie("like_".$cid, $cid, time()+31536000);
}
if($kg=="undo"){
$db->query($db->update('table.contents')->rows(array('likes' => (int)$row['likes']-1))->where('cid = ?', $cid));
$num=$num-1;
setcookie("like_".$cid, "");
}
echo $num;
}
function image_class_replace($content)
{
$content = preg_replace('#<a(.*?) href="([^"]*/)?(([^"/]*)\.[^"]*)"(.*?)>#',
'<a$1 href="$2$3"$5 target="_blank">', $content);
return $content;
}
function numToWord($num)
{
$chiNum = array("零","一","二","三","四","五","六","七","八","九");
$chiUni = array('','十', '百', '千', '万', '亿', '十', '百', '千');
$chiStr = '';
$num_str = (string)$num;
$count = strlen($num_str);
$last_flag = true; //上一个 是否为0
$zero_flag = true; //是否第一个
$temp_num = null; //临时数字
$chiStr = '';//拼接结果
if ($count == 2) {//两位数
$temp_num = $num_str[0];
$chiStr = $temp_num == 1 ? $chiUni[1] : $chiNum[$temp_num].$chiUni[1];
$temp_num = $num_str[1];
$chiStr .= $temp_num == 0 ? '' : $chiNum[$temp_num];
}else if($count > 2){
$index = 0;
for ($i=$count-1; $i >= 0 ; $i--) {
$temp_num = $num_str[$i];
if ($temp_num == 0) {
if (!$zero_flag && !$last_flag ) {
$chiStr = $chiNum[$temp_num]. $chiStr;
$last_flag = true;
}
}else{
$chiStr = $chiNum[$temp_num].$chiUni[$index%9] .$chiStr;
$zero_flag = false;
$last_flag = false;
}
$index ++;
}
}else{
$chiStr = $chiNum[$num_str[0]];
}
return $chiStr;
}
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('myyodu', 'one');
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('myyodu', 'one');
class myyodu {
public static function one()
{
?>
<style>
.field.is-grouped{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start; -ms-flex-wrap: wrap;flex-wrap: wrap;}.field.is-grouped>.control{-ms-flex-negative:0;flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:.5rem;margin-right:.75rem}.field.is-grouped>.control.is-expanded{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-negative:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.field.is-grouped.is-grouped-right{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.field.is-grouped.is-grouped-multiline{-ms-flex-wrap:wrap;flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}.tags{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.tags.has-addons .tag:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.tag{-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#f5f5f5;border-radius:3px;color:#4a4a4a;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-size:.75rem;height:2em;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag .delete{margin-left:.25em;margin-right:-.375em}.tag.is-white{background-color:#fff;color:#0a0a0a}.tag.is-black{background-color:#0a0a0a;color:#fff}.tag.is-light{background-color:#fff;color:#363636}.tag.is-dark{background-color:#363636;color:#f5f5f5}.tag.is-primary{background-color:#00d1b2;color:#fff}.tag.is-info{background-color:#3273dc;color:#fff}.tag.is-success{background-color:#23d160;color:#fff}.tag.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.tag.is-danger{background-color:#ff3860;color:#fff}.tag.is-large{font-size:1.25rem}.tag.is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag.is-delete:after,.tag.is-delete:before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.tag.is-delete:before{height:1px;width:50%}.tag.is-delete:after{height:50%;width:1px}.tag.is-delete:focus,.tag.is-delete:hover{background-color:#e8e8e8}.tag.is-delete:active{background-color:#dbdbdb}.tag.is-rounded{border-radius:290486px}
</style>
<script language="javascript">
var EventUtil = function() {};
EventUtil.addEventHandler = function(obj, EventType, Handler) {
if (obj.addEventListener) {
obj.addEventListener(EventType, Handler, false);
}
else if (obj.attachEvent) {
obj.attachEvent('on' + EventType, Handler);
} else {
obj['on' + EventType] = Handler;
}
}
if (document.getElementById("text")) {
EventUtil.addEventHandler(document.getElementById('text'), 'propertychange', CountChineseCharacters);
EventUtil.addEventHandler(document.getElementById('text'), 'input', CountChineseCharacters);
}
function showit(Word) {
alert(Word);
}
function CountChineseCharacters() {
Words = document.getElementById('text').value;
var W = new Object();
var Result = new Array();
var iNumwords = 0;
var sNumwords = 0;
var sTotal = 0;
var iTotal = 0;
var eTotal = 0;
var otherTotal = 0;
var bTotal = 0;
var inum = 0;
var znum = 0;
var gl = 0;
var paichu = 0;
for (i = 0; i < Words.length; i++) {
var c = Words.charAt(i);
if (c.match(/[\u4e00-\u9fa5]/) || c.match(/[\u0800-\u4e00]/) || c.match(/[\uac00-\ud7ff]/)) {
if (isNaN(W[c])) {
iNumwords++;
W[c] = 1;
}
iTotal++;
}
}
for (i = 0; i < Words.length; i++) {
var c = Words.charAt(i);
if (c.match(/[^\x00-\xff]/)) {
if (isNaN(W[c])) {
sNumwords++;
}
sTotal++;
} else {
eTotal++;
}
if (c.match(/[0-9]/)) {
inum++;
}
if (c.match(/[a-zA-Z]/)) {
znum++;
}
if (c.match(/[\s]/)) {
gl++;
}
if (c.match(/[ ◕‿↑↓←→↖↗↘↙↔↕。《》、【】“”•‘’❝❞′……—―‐〈〉„╗╚┐└‖〃「」‹›『』〖〗〔〕∶〝〞″≌∽≦≧≒≠≤≥㏒≡≈✓✔◐◑◐◑✕✖★☆₸₹€₴₰₤₳र₨₲₪₵₣₱฿₡₮₭₩₢₧₥₫₦₠₯○㏄㎏㎎㏎㎞㎜㎝㏕㎡‰〒々℃℉ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ]/)) {
paichu++;
}
}
document.getElementById('hanzi').innerText = iTotal - paichu;
document.getElementById('zishu').innerText = inum + iTotal - paichu;
document.getElementById('biaodian').innerText = sTotal - iTotal + eTotal - inum - znum - gl + paichu;
document.getElementById('zimu').innerText = znum;
document.getElementById('shuzi').innerText = inum;
document.getElementById("zifu").innerHTML = iTotal * 2 + (sTotal - iTotal) * 2 + eTotal;
}
</script>
<script>
$(document).ready(function(){
$("#wmd-editarea").append('<div class="field is-grouped"><span class="tag">共计:</span><div class="control"><div class="tags has-addons"><span class="tag is-dark" id="zishu">0</span> <span class="tag is-primary">个字数</span></div></div><div class="control"><div class="tags has-addons"><span class="tag is-dark" id="zifu">0</span> <span class="tag is-primary">个字符</span></div></div><span class="tag">包含:</span><div class="control"><div class="tags has-addons"><span class="tag is-light" id="hanzi">0</span> <span class="tag is-danger">个文字</span></div></div><div class="control"><div class="tags has-addons"><span class="tag is-light" id="biaodian">0</span> <span class="tag is-info">个符号</span></div></div><div class="control"><div class="tags has-addons"><span class="tag is-light" id="zimu">0</span> <span class="tag is-success">个字母</span></div></div><div class="control"><div class="tags has-addons"><span class="tag is-light" id="shuzi">0</span> <span class="tag is-warning">个数字</span></div></div></div>');
CountChineseCharacters();
});
</script>
<script>
Config = {cdnUrl: '<?php if(Helper::options()->optionalcdn == "zdycdn"){ ?><?= customcdnbq ?><?php } else {?><?=feature::ThemeUrl()?><?php } ?>',};
</script>
<?php
}
}
二:
以下内容要放到/pigeon/common/comments.php
<div class="comment_xin_name"><?php spam_protection_math();?></div>
完整comments.php
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php
$GLOBALS['isLogin'] = $this->user->hasLogin();
$GLOBALS['rememberEmail'] = $this->remember('mail',true);
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';
if ($comments->url) {
$author = '<a href="' . $comments->url . '"' . '" target="_blank"' . ' rel="external nofollow">' . $comments->author . '</a>';
} else {
$author = $comments->author;
}
?>
<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_list_box">
<div class="comment_list_avatar"><img class="avatar" src="<?php echo feature::avatarHtml($comments); ?>" /></div>
<div class="comment_main">
<div class="comment_author"><?php echo $author ?> <?php
if ($comments->authorId) {
if ($comments->authorId == $comments->ownerId) {
_e(' <span class="comment_admin"><i class="iconfont icon-safetycertificate-f"></i></span> ');
}
}
?></div>
<div class="comment_excerpt">
<?php echo feature::reply($comments->parent); ?>
<?php $parentMail = feature::get_comment_at($comments->coid)?>
<?php echo core::postCommentContent($comments->content,$GLOBALS['isLogin'],$GLOBALS['rememberEmail'],$comments->mail,$parentMail);?>
</div>
<div class="comment_meta">
<span class="comment_time"><?php echo feature::formatTime($comments->created); ?></span><i class="text-primary">•</i><span><?php echo feature::convertip($comments->ip); ?></span><i class="text-primary">•</i><span class="comment-reply cp-<?php $comments->theId(); ?> text-muted comment-reply-link"><?php $comments->reply('回复'); ?></span><span id="cancel-comment-reply" class="cancel-comment-reply cl-<?php $comments->theId(); ?> text-muted comment-reply-link" style="display:none" ><?php $comments->cancelReply('取消'); ?></span>
</div>
</div>
</div>
</div>
<?php if ($comments->children) { ?><div class="comment-children"><?php $comments->threadedComments($options); ?></div><?php } ?>
</li>
<?php } ?>
<div id="comments" class="jia">
<?php $this->comments()->to($comments); ?>
<?php if ($this->allow('comment')) : ?>
<div id="<?php $this->respondId(); ?>" class="respond">
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form" class="new_comment_form">
<div class="comment_box">
<div class="comment_box_avatar">
<?php if ($this->user->hasLogin()) : ?>
<img class="avatars" src="<?php echo feature::avatarHtml($this->author); ?>">
<?php else : ?>
<img class="avatars" src="<?= customcdn . 'img/moren.png'; ?>">
<?php endif; ?>
</div>
<div class="comment_right">
<div class="comment-inputs">
<?php if ($this->user->hasLogin()) : ?>
<div class="comment_admin"><?php _e('尊敬的站长:'); ?><a class="admin_name" href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a></div>
<?php else : ?>
<div class="comment_xin_name"><input type="text" name="author" id="comment-name" class="text" placeholder="<?php _e('名字'); ?>" value="<?php $this->remember('author'); ?>" required /></div>
<div class="comment_xin_box">
<div class="comment_xin"><input type="email" name="mail" id="comment-mail" class="text" placeholder="<?php _e('邮箱'); ?>" value="<?php $this->remember('mail'); ?>" <?php if ($this->options->commentsRequireMail) : ?> required<?php endif; ?> /></div>
<div class="comment_xin"><input type="url" name="url" id="comment-url" class="text" placeholder="<?php _e('网址'); ?>" value="<?php $this->remember('url'); ?>" <?php if ($this->options->commentsRequireURL) : ?> required<?php endif; ?> /></div>
<!--算数验证start-->
<div class="comment_xin_name"><?php spam_protection_math();?></div>
<!--算数验证end-->
</div>
<?php endif; ?>
</div>
<div class="comment_editor">
<div class="comment-editor_box">
<textarea name="text" id="textarea" placeholder="撰写评论" class="textarea textarea_box OwO-textarea" required onkeydown="if((event.ctrlKey||event.metaKey)&&event.keyCode==13){document.getElementById('submitComment').click();return false};"><?php $this->remember('text'); ?></textarea>
</div>
<div class="comment-huifu">
<div class="comment_left">
<div class="rko"><div class="OwO">OωO</div></div>
<div class="privacy">
<div class="privacy_btn">
<input type="checkbox" id="inset_3" name="secret" />
<label for="inset_3" class="green"></label>
</div>
<div class="privacy_text">隐私评论</div>
</div>
</div>
<div class="comment_huifu_right">
<div class="comment-buttons">
<button id="submitComment" type="submit" class="submit">发表评论</button>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<?php else : ?>
<div class="comments_off"><?php _e('评论已关闭'); ?></div>
<?php endif; ?>
<div class="comments_lie">
<?php if ($comments->have()) : ?>
<?php $comments->listComments(); ?>
<div class="paging">
<?php $comments->pageNav('<i class="iconfont icon-icon-test"></i>', '<i class="iconfont icon-icon-test1"></i>', 3, '...', array('wrapTag' => 'ol', 'wrapClass' => 'page-navigator', 'itemTag' => 'li', 'textTag' => 'span', 'currentClass' => 'current', 'prevClass' => 'prev', 'nextClass' => 'next')); ?>
</div>
<?php endif; ?>
</div>
</div>
<script type="text/javascript">
function showhidediv(id){var sbtitle=document.getElementById(id);if(sbtitle){if(sbtitle.style.display=='flex'){sbtitle.style.display='none';}else{sbtitle.style.display='flex';}}}
(function(){window.TypechoComment={dom:function(id){return document.getElementById(id)},pom:function(id){return document.getElementsByClassName(id)[0]},iom:function(id,dis){var alist=document.getElementsByClassName(id);if(alist){for(var idx=0;idx<alist.length;idx++){var mya=alist[idx];mya.style.display=dis}}},create:function(tag,attr){var el=document.createElement(tag);for(var key in attr){el.setAttribute(key,attr[key])}return el},reply:function(cid,coid){var comment=this.dom(cid),parent=comment.parentNode,response=this.dom("<?php echo $this->respondId(); ?>"),input=this.dom("comment-parent"),form="form"==response.tagName?response:response.getElementsByTagName("form")[0],textarea=response.getElementsByTagName("textarea")[0];if(null==input){input=this.create("input",{"type":"hidden","name":"parent","id":"comment-parent"});form.appendChild(input)}input.setAttribute("value",coid);if(null==this.dom("comment-form-place-holder")){var holder=this.create("div",{"id":"comment-form-place-holder"});response.parentNode.insertBefore(holder,response)}comment.appendChild(response);this.iom("comment-reply","");this.pom("cp-"+cid).style.display="none";this.iom("cancel-comment-reply","none");this.pom("cl-"+cid).style.display="";if(null!=textarea&&"text"==textarea.name){textarea.focus()}return false},cancelReply:function(){var response=this.dom("<?php echo $this->respondId(); ?>"),holder=this.dom("comment-form-place-holder"),input=this.dom("comment-parent");if(null!=input){input.parentNode.removeChild(input)}if(null==holder){return true}this.iom("comment-reply","");this.iom("cancel-comment-reply","none");holder.parentNode.insertBefore(response,holder);return false}}})();
</script>
<?php if ($this->allow('comment')) : ?>
<script>
var OwO_demo = new OwO({
logo: 'OωO表情',
container: document.getElementsByClassName('OwO')[0],
target: document.getElementsByClassName('OwO-textarea')[0],
api: '<?= customcdn . 'owo/OwO.json'; ?>',
position: 'down',
width: '100%',
maxHeight: '250px'
});
$("input#comment-mail").blur(function() {
var _email = $(this).val();
if (_email != '') {
$.ajax({
type: 'GET',
data: {
action: 'ajax_avatar_get',
form: '<?php $this->permalink() ?>',
email: _email
},
success: function(data) {
$('.avatars').attr('src', data);
}
});
}
return false;
});
</script>
<?php endif; ?>
评论