最近对博客评论功能做了一些调整,防垃圾评论便是其一。即便作为一个无名小站每天也会收到几条垃圾评论,这之前一直用 Akismet 插件来防垃圾评论,Akismet 阻止下来的垃圾评论仍需要手动清理,久而久之快要被动地锻炼成定期查看垃圾评论的强迫症了,便想着要换掉 Akismet。

搜集了一些关于 WordPress 垃圾邮件工作机制介绍的资料,一般情况下垃圾评论是通过机器发送了,机器会向id="comment"name="comment"的文本框填充垃圾评论内容,并直接提交给 wp-comments-post.php 文件生成评论。

既如此,可不可以用一个取巧的办法:

  1. 将评论表单默认的comment文本框通过display:none隐藏掉(或者直接移除之);
  2. 单独增加一个对访客可见的替代文本框,取名为real_comment,用户在页面填写的评论内容实际是放在 real_comment 文本框的;
  3. 由于 WordPress 通过 comment 文本框取评论内容,所以,在评论提交给 wp-comments-post.php 前需要判断处理一下:comment 文本框不为空,说明是垃圾邮件,直接返回错误就行了;comment 文本框为空,说明是用户填写的,提交前需要进行一次置换,即把 comment_content 文本框的内容填充到 comment 文本框,完成置换后再进行提交。

改造评论表单

这个主题评论框用的是<?php comment_form(); ?>(一般是在主题文件夹的 comments.php 文件里),加额外字段需要对comment_form()做处理。

添加额外文本框

把要加的文本框

<textarea id="real_comment" name="real_comment" class="comment-textarea"></textarea>

加入文件 comments.php 之后得到如下代码:

<?php comment_form( array(
            'fields' => array(
                'author' => '<p class="commentform"><input type="text" name="author" id="author" class="ipt cmt-input" placeholder="昵称" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author'] ) . '"></p>',
                'email' => '<p class="commentform"><input type="text" name="email" id="email" class="ipt cmt-input" placeholder="邮箱[保密]" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author_email'] ) . '"></p>',
                'url' => '<p class="commentform"><input type="text" name="url" id="url" class="ipt cmt-input" placeholder="网址[可不填]" size="30" value="'.$comment_author_url.'"></p>'
                ),
            'comment_field' => '<p><textarea id="comment" name="comment"></textarea></p>
            <p><textarea id="real_comment" name="real_comment" class="ipt comment-textarea" placeholder="添加评论..." aria-required="true" cols="45" rows="8"></textarea></p>',
            'comment_notes_before' => '',
            'comment_notes_after' => '',
            'action' => '/stop-spam.php',
            'class_submit' => 'submit'
        ));
    ?>

替换表单 action

下一步需要对 wp-comments-post.php 做修改,考虑到 WordPress 版本更新覆盖旧文件问题,最好不要直接改动 wp-comments-post.php 文件,建议在博客根目录(wp-comments-post.php 所在的文件夹)新建一个单独的文件做跳板,如:wp-stop-spam.php,comment_form()默认的action是 wp-comments-post.php,现在要把action改为 wp-stop-spam.php,只需将'action' => '/wp-stop-spam.php',放到上面代码'class_submit' => 'submit'的前一行即可。

跳板文件

接下来打开 wp-stop-spam.php,把下面代码放入并保存:

<?php
nocache_headers();
$comment = trim($_POST['comment']);
// Proceed with regular comments.
if ( empty( $comment ) ) {
    $_POST['comment'] = trim($_POST['real_comment']);
    require( dirname(__FILE__) . '/wp-comments-post.php' );
}
if ( ! empty( $comment ) ) {
    require( dirname(__FILE__) . '/wp-load.php' );
    wp_die('You are not a human!');
}

大功告成,一旦 wp-stop-spam.php 收到提交上来的表单,首先检查comment文本框是否为空,不为空就是机器填写的(comment文本框做了隐藏后正常人是看不到的),直接组织评论生成并给出提示。

如果为空,则认为是正常访客提交的(正常访客只会在他们看到的real_comment文本框内填写评论内容,接着将real_comment文本框里的内容取作评论传给 wp-comments-post.php 生成评论。

禁止直接访问 wp-comments-post.php

如果还是不放心,那就直接禁止对 wp-comments-post.php 文件的直接访问,这个博客搭建在 nginx 上,把下面这段代码加入到 nginx 的主机配置文件重启 nginx 即可实现禁止直接访问 wp-comments-post.php 文件的目的(不影响 wp-stop-spam.php 文件 require 它)。

location = /wp-comments-post.php {
	return 404;
}

用了两周效果很不错,没有一条垃圾评论!

以上方法对使用机器通过 wp-comment-post.php 提交的垃圾评论有效(对人工提交的垃圾评论爱莫能助),往往还有一些垃圾评论是通过 trackback 发送的,如需屏蔽 trackback 请参照如何屏蔽 trackback/pingback 垃圾评论

上个月的这个时候在郑州经历的一场雪

雪下的很大,一大早街道上满是积雪

雪下了一整天:
冬季·河南·郑州·大雪

积雪的梧桐树:
大雪天的法国梧桐

公交车开的非常非常慢

下了雪,落了叶,这辆车真幸福:
积雪落叶

雪给人们带来了惊喜

积雪的法国梧桐

两三个月前开始手机时常无缘无故自动关机,不管剩余多少电量一旦自动关机必须充电才能开机,低于 50% 电量随时可能关机。最严重的一次发生在青岛,晚间应约到饭店吃饭,当晚最低气温1度,走在大街上 70% 的剩余电量时活生生被关机…后来苹果公司公布手机自动关机原因、解决方案以及受影响的产品批次,很不幸而又很幸运的是两部手机均赫然在列。

既然符合免费更换政策那就准备换吧,致电 Apple 客服咨询,得知符合免费更换电池政策可前往 Apple 授权服务提供商或 Apple store 免费更换,但运营商定制机只能走授权维修渠道到 Apple 授权服务提供商处更换电池。
很不幸本人手机正是电信合约机,京东自营渠道所购,按政策规定只能走授权维修渠道,于是打通就近的一家授权维修商,答复是若符合政策可免费更换,但有条件限制,被明确告知必须提供购机发票和购机合约合同,否则拒绝服务。

四美俱,二难并,都这么长时间了,发票和合同哪里凑得齐,看来授权维修商这条路走不通了。网上看了一些维修经历,有人的合约机在 Apple store 成功免费更换电池。觉得有必要试一试 Apple store,Apple store 需要预约天才吧,可能换电池的人实在太多连续两周没能约到天才吧,一直到本周二终于预约到七宝万科城 Apple store 的天才吧,时间是周三晚间。

上班地点离这个店最近,周二下班后带上身份证提前到店,对接到服务人员,只验了身份证确认预约信息,之后做了设备检测和问询,告知可以免费更换,但现在更换电池手机需要留店24小时,也就是要第二天晚才能前来取手机,不得不说换电池的人实在太多,等待区坐着的人几乎全是前来更换电池的,确认可以等待24小时,来之前手机已做备份,当面抹掉数据,在工作授权函上签了字,工作人员收走手机,维修暂时告一段落。

周三晚间按约定时间段到店顺利取到手机,换上新电池,手机电力明显强了很多。Apple store 售后服务还是非常好的,没有废话,只是天才吧太难预约,Apple 工作人员告知下午两点左右比较容易约到好,好像那个时段会放号。

昨晚刷微信朋友圈看到公司另一部门同事两天前分享了一篇文章:《打工的最高境界:和老板一起干!》,如果把和老板一起干看成打工的最高境界,那我见过走更高的火入魔的打工境界:事情发生在浙江杭州某地,开始时张姓员工为李姓老板打工,仅一年张姓员工翻身当家作主成了老板,李姓老板则不幸沦为员工,二人角色互换。千万不要把这当成一则笑话,真人真事,隐约闪现着创业的路上充满风险,一些人成功了,一些人失败了。

不管怎么说,事实上本人已将博客当微博使用了,经常神经质地一天连发数条状态,这些不痛不痒的足迹统统要输出到 feed 中,毫无保留,而这些状态对他人来说是没有任何价值的,甚至像小广告一样令人生厌,给订阅的朋友造成了困扰,在此郑重向订阅木瓜园的朋友说一声“非常抱歉!”

昨天,路易大叔就表达了不满,所以,决定将足迹(状态)从 feed 中移除。我用post-format-status这一日志形式在足迹页面发状态,因此,只要把post-format-status这一日志形式从 feed 中排除即可,复制下面这段代码到主题的functions.php文件中即可达到目的:

function exclude_post_format_from_feed( $wp_query ){
    if ( $wp_query->is_feed() ) {
        $post_format_tax_query = array( array(
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => 'post-format-status',//想要排除的日志形式
            'operator' => 'NOT IN'
        ));
        $wp_query->set( 'tax_query', $post_format_tax_query );
    }
}
add_action( 'pre_get_posts', 'exclude_post_format_from_feed' );