WordPress中利用AJAX技术进行评论提交的实现示例


Posted in Javascript onJanuary 12, 2016

一直对 WordPress 的 Ajax 交互研究感兴趣,也一直很关注于这方面的技术,谈到 WordPress Ajax 就不得不谈到评论 Ajax提交,作为一个博客、论坛评论的 Ajax 提交不仅可以改善用户体验,还可以大幅缩减服务器开支,毕竟输出单条评论内容比重新组织输出一个页面要简单的多。 虽说现在访问量一直比较低,不存在服务器压力的问题,但一向注重用户体验的我,当然不能放弃这么一个提升用户体验的机会。今天抽了一下午的空,把这个主题的 Ajax 评论提交初步完成了。

直接开门见山,直接上代码:(原理及思路在最后)
根据自己主题不同结构,以下代码请自行调整。

WordPress Ajax 提交评论 PHP 代码
在主题 function.php 文件中加入如下部分。

//以下大部分代码出自 yinheli 经由该部分代码,排除部分错误、优化精简得出以下代码。
//yinheli博客不做了,所以这里就不给链接了。
//Edited by XiangZi DEC.17TH 2011
function fail($s) {//虚拟错误头部分
  header('HTTP/1.0 500 Internal Server Error');
  echo $s;
  exit;
}
function ajax_post_comment_slow (){
 fail('用不用说这么快?想好了再说!');
}
//评论太快输出代码。
add_filter('comment_flood_trigger','ajax_post_comment_slow', 0);
//挂一个评论太快,返回内容的钩子
function ajax_comment(){
// Ajax php 响应部分代码
if($_POST['action'] == 'ajax_comment') {
  global $wpdb, $db_check;
    // Check DB
    if(!$wpdb->dbh) {
      echo('Our database has issues. Try again later.');
  die();
    } 
nocache_headers();
$comment_post_ID = (int) $_POST['comment_post_ID'];
 $status = $wpdb->get_row("SELECT post_status, comment_status FROM $wpdb->posts WHERE ID = '$comment_post_ID'");
if ( empty($status->comment_status) ) {
//这一套判断貌似抄的 wp 源代码 。详见:include/comment.php
  do_action('comment_id_not_found', $comment_post_ID);
  fail('The post you are trying to comment on does not currently exist in the database.');
} elseif ( 'closed' == $status->comment_status ) {
  do_action('comment_closed', $comment_post_ID);;
  fail('Sorry, comments are closed for this item.');
} elseif ( in_array($status->post_status, array('draft', 'pending') ) ) {
  do_action('comment_on_draft', $comment_post_ID);
  fail('The post you are trying to comment on has not been published.');
}
$comment_author    = trim(strip_tags($_POST['author']));
$comment_author_email = trim($_POST['email']);
$comment_author_url  = trim($_POST['url']);
$comment_content   = trim($_POST['comment']);
// If the user is logged in
$user = wp_get_current_user();
if ( $user->ID ) {
  $comment_author    = $wpdb->escape($user->display_name);
  $comment_author_email = $wpdb->escape($user->user_email);
  $comment_author_url  = $wpdb->escape($user->user_url);
  if ( current_user_can('unfiltered_html') ) {
    if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) {
      kses_remove_filters(); // start with a clean slate
      kses_init_filters(); // set up the filters
    }
  }
} else {
  if ( get_option('comment_registration') )
    fail('火星人?注册个?');
}
$comment_type = '';
if ( get_option('require_name_email') && !$user->ID ) {
  if ( 6> strlen($comment_author_email) || '' == $comment_author )
    fail('Oopps,名字[Name]或邮箱[email]不对。');
  elseif ( !is_email($comment_author_email))
    fail('Oopps,邮箱地址[Email]不对。');
}
if ( '' == $comment_content )
  fail('是不是应该写点什么再提交?');
// Simple duplicate check
$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
if ( $comment_author_email ) $dupe .= "OR comment_author_email = '$comment_author_email' ";
$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
if ( $wpdb->get_var($dupe) ) {
  fail('评论重复了!有木有!');
}
$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID');
if( !$user->ID ){
 $result_set = $wpdb->get_results("SELECT display_name, user_email FROM $wpdb->users WHERE display_name = '" . $comment_author . "' OR user_email = '" . $comment_author_email . "'");
 if ($result_set) {
 if ($result_set[0]->display_name == $comment_author){
 fail('博主你也敢冒充?');
 } else {
 fail('博主你也敢冒充?');
 }
 }
}
$comment_id = wp_new_comment( $commentdata );
$comment = get_comment($comment_id);
 
if( !$user->ID ){
 setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
 setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
 setcookie('comment_author_url_' . COOKIEHASH, clean_url($comment->comment_author_url), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
}
@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
 xz_comment($comment, null);//这是我的调用评论函数,换成你的函数名。
 die();
}
}
add_action('init', 'ajax_comment');

Javascript 中代码
注意:以下代码需要 Jquery 框架支援。
javascript onload 代码中加入以下部分。

if (jQuery('#commentform').length) {
  jQuery('#commentform').submit(function(){  
// 截获提交动作
//ID为 commentform 的表单提交时发生的函数,也就是整个留言输入框 form 的ID。
 var ajaxCommentsURL = window.location.href;
    jQuery.ajax({
      url: ajaxCommentsURL,
      data: jQuery('#commentform').serialize()+'&action=ajax_comment',  
      type: 'POST',
      beforeSend: function() {
        jQuery('#commenterror').hide();
        jQuery('#commentload').fadeIn();
      },
      error: function(request) {  //发生错误时
        jQuery('#commenterror').html(request.responseText);
        jQuery('#commentload').hide();  //隐藏 submit
        jQuery('#commenterror').fadeIn(); //显示 error 
      },
      success: function(data) {
        jQuery('textarea').each(function(){
          this.value='';
        });
        jQuery('#commenterror').fadeOut();
        if(jQuery(".commentlist li.comment").first().length != 0){jQuery(".commentlist li.comment").first().before(data)}  
        else {jQuery("ol.commentlist").append(data)}
        jQuery(".commentlist li.comment").first().hide(0,function(){$(this).slideDown(1000)});
        jQuery('#cmt-submit').attr('disabled', true).css({"background-color":"#6C6C6C","color":"#E0E0E0"});
        jQuery('#commentload').fadeOut(1600);
 setTimeout(function() {
        jQuery('#cmt-submit').removeAttr('disabled').css({"background-color":"#0086C5","color":"#FFFFFF"});
        },3000); 
      }
    });
    return false;
  } );
}

注:代码仍有改进需求,因为没有时间,所以就没有再进化。

CSS 代码
css 随意部分添加。

#commentload,#commenterror{
 display: none;
 margin: 5px 0 0 0;
 color:#D29A04;
 float: left;
 font-size:16px;
 padding:0 0 0 20px;
}
#commentload{
 background: url("img/loading.gif") no-repeat bottom left ;
}
#commenterror{
 background: url("img/error.png") no-repeat bottom left ;
}

原理、思路
原理:
Javascript 提交数据
php响应并输出结果
Javascript 得到结果并显示
思路:
点击提交按钮后,Javascript 截获提交动作
截获提交的各项数据(Name、Email、Web、Comment-text)
利用 Javascript Jquery 模拟浏览器提交POST(Name、Email、Web、Comment-text)请求之WordPress
Function.php 文件中构造一个接受请求的函数,即本列中ajax_comment函数
如果请求无错误,输出正确结果
如果请求有错误,输出错误结果
Javascript 获得正确结果,动态添加到评论列表中
Javascript 获得错误结果,动态添加到提交提示栏
改进
样式方面,我确实没什么美感,所以正在学习中。
提交按钮在点击至获得返回结果后3秒的时间里应该都是变灰失效状态,这一点之前因为在本机测试,提交瞬间完成没有注意到,远程测试的时候发现了,但要改的话还要进行测试,时间太紧就不改了,有机会再改进一下。

总结
因为 WordPress 主题中评论样式的自由性、多样性,所以貌似至今一直没有一款通用性的AJAX 评论插件,
一些高手也只能在优化自己博客之余,把思路和部分通用核心代码做一下公布,
所以想要实现一些炫酷的功能要不有高人帮你,
要不你就只能好好学代码,期待有一日能够厚积薄发了。
效果请自行提交评论验证。

Javascript 相关文章推荐
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
javascript 正则表达式相关应介绍
Nov 27 Javascript
javascript刷新父页面的各种方法汇总
Sep 03 Javascript
js 右侧浮动层效果实现代码(跟随滚动)
Nov 22 Javascript
jquery动态遍历Json对象的属性和值的方法
Jul 27 Javascript
JS实现字符串转驼峰格式的方法
Dec 16 Javascript
RequireJs的使用详解
Feb 19 Javascript
vue2 中如何实现动态表单增删改查实例
Jun 09 Javascript
Vue组件通信实践记录(推荐)
Aug 15 Javascript
Vue 2.0学习笔记之Vue中的computed属性
Oct 16 Javascript
微信小程序数据分析之自定义分析的实现
Aug 17 Javascript
小程序input数据双向绑定实现方法
Oct 17 Javascript
基于JavaScript实现div层跟随滚动条滑动
Jan 12 #Javascript
JavaScript继承模式粗探
Jan 12 #Javascript
轻松实现Bootstrap图片轮播
Apr 20 #Javascript
探析浏览器执行JavaScript脚本加载与代码执行顺序
Jan 12 #Javascript
学习JavaScript设计模式之策略模式
Jan 12 #Javascript
基于jQuery1.9版本如何判断浏览器版本类型
Jan 12 #Javascript
jQuery版本升级踩坑大全
Jan 12 #Javascript
You might like
PHP 程序员应该使用的10个组件
2009/10/31 PHP
关于session在PHP5的配置文件中的详细设置参数说明
2011/04/20 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
Jquery 例外被抛出且未被接住原因介绍
2013/09/04 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
2014/01/31 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
js实现跟随鼠标移动且带关闭功能的图片广告实例
2015/02/26 Javascript
JQuery中serialize() 序列化
2015/03/13 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
jQuery、layer实现弹出层的打开、关闭功能
2017/06/28 jQuery
vue cli3.0 引入eslint 结合vscode使用
2019/05/27 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
2020/07/21 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
python实现矩阵乘法的方法
2015/06/28 Python
Python 提取dict转换为xml/json/table并输出的实现代码
2016/08/28 Python
Python使用matplotlib实现绘制自定义图形功能示例
2018/01/18 Python
python自动化报告的输出用例详解
2018/05/30 Python
Python实现压缩文件夹与解压缩zip文件的方法
2018/09/01 Python
python 爬取学信网登录页面的例子
2019/08/13 Python
如何基于Python获取图片的物理尺寸
2019/11/25 Python
python requests.get带header
2020/05/05 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
Python使用grequests并发发送请求的示例
2020/11/05 Python
如何强制垃圾回收
2015/10/06 面试题
Android面试宝典
2013/08/06 面试题
活动总结报告怎么写
2014/07/03 职场文书
镇副书记专题民主生活会对照检查材料思想汇报
2014/10/02 职场文书
光棍节联谊晚会活动策划书
2014/10/10 职场文书
工艺技术员岗位职责
2015/02/04 职场文书
公司优秀员工推荐信
2015/03/24 职场文书
分享15个Webpack实用的插件!!!
2021/03/31 Javascript
python中取整数的几种方法
2021/11/07 Python
Python 绘制多因子柱状图
2022/05/11 Python