有人问到点赞功能,这里抽取代码分享一下,因为去掉了部分敏感信息,可能需要调试一下。
我的设计思路是使用自定义字段来存储点赞次数。和市面上的方案不一样,不过大同小异。
增加接口
首先要修改functions.php
的themeInit
函数,加入点赞接口
function themeInit($archive)
{
if ($archive->is('single')) {
if ($archive->request->isPost()) {
if ($archive->request->is('themeAction=promo')) {
promo($archive);
}
}
}
}
接着要加入点赞核心函数,下面的函数可以扩展
/**
* Post Action AJAX接口
*
* @param Widget_Archive $widget
* @return void
* @date 2020-05-04
*/
function promo($widget)
{
$user = $widget->widget('Widget_User');
$db = Typecho_Db::get();
$fields = unserialize($widget->fields);
$allowOperates = array('get', 'set', 'inc', 'dec'); // 这里可以扩展操作,建议屏蔽get/set
$allowFields = array('likes'); // 这里可以扩展修改字段
// 获取操作
$operate = $widget->request->get('operate');
$field = $widget->request->get('field');
$value = $widget->request->filter('int')->get('value');
$value = $value === null ? 100 : $value; // 100 起步
$result = array('cid' => $widget->cid);
if ($operate === "get") {
$result['operate'] = 'get';
if (array_key_exists($field, $fields)) {
$result[$field] = $fields[$field];
} else {
$result[$field] = -1;
}
$widget->response->throwJson(array('status' => 1, 'msg' => _t('已获取参数'), 'result' => json_encode($result)));
} elseif ($operate === "set") {
$result['operate'] = 'set';
if ($value > 0) {
$widget->setField($field, 'str', $value, $widget->cid);
} else {
$db->query($db->delete('table.fields')
->where('cid = ? AND name = ?', $widget->cid, $field));
}
$widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result)));
} elseif ($operate === "inc") {
$result['operate'] = 'inc';
$value = intval($fields[$field]) + 1;
$widget->setField($field, 'str', $value, $widget->cid);
$result[$field] = $value;
$widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result)));
} elseif ($operate === "dec") {
$result['operate'] = 'dec';
$value = intval($fields[$field]) - 1;
$result[$field] = $value;
if ($value > 0) {
$widget->setField($field, 'str', $value, $widget->cid);
} else {
$db->query($db->delete('table.fields')
->where('cid = ? AND name = ?', $widget->cid, $field));
}
$widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result)));
}
}
Post 请求参数说明
operate:操作
field: 操作字段
value:操作值,inc/dec 操作用不到
前端方面
这里我给出我的参考 js 代码,实际建议自己写一下,使用 jq 也不复杂。
function likesCallback(count) {
$("#likesPostCount").value(count);
}
$("#likesPost").click(function () {
posturl = $(location).attr("href").split("?")[0] + "?themeAction=promo";
$.ajax({
url: posturl,
type: "POST",
data: { operate: "inc", field: "likes" },
dataType: "json",
success: function (result) {
if (1 == result.status) {
result = JSON.parse(result.result)
likes =
undefined === result.likes ?
-1 :
result.likes;
likesCallback(result.likes);
} else {
// 提醒错误消息
alert(
undefined === result.msg ?
'点赞失败' :
result.msg
);
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert('点赞失败' + ajaxOptions);
},
});
});
输出
<?php echo $this->fields->likes; ?>
做个插件吧,不动源码最好。
这个修改的是主题代码啊