本书未发布

78. 删除回复

未匹配的标注

简介

在本节里,我们完成删除评论功能。

需求分解

  • 登录用户只能删除自己创建的回复或自己创建话题的所有回复;
  • 回复删除成功后关联删除的回复数量减一;
  • 当用户删除话题时同时删除话题的所有回复。

观察者

首先,我们在话题观察者里添加 afterDelete 事件监听:

application/common/observer/Topic.php

<?php
.
.
.
use think\Db;

class Topic
{
    .
    .
    .
    public function afterDelete(TopicModel $topic)
    {
        // 这里不要使用 Model 删除方法,否则会出现监听事件循环调用
        // Db::name接收的参数「表名」,不用包含数据库表名辍
        Db::name('reply')->where('topic_id', $topic->id)->delete();
    }
}

接着,我们在话题观察者里添加 afterDelete 事件监听:

application/common/observer/Reply.php

<?php

namespace app\common\observer;

use app\common\model\User as UserModel;
use app\common\model\Reply as ReplyModel;

class Reply
{
    .
    .
    .
    public function afterDelete(ReplyModel $reply)
    {
        $topic = $reply->topic;
        if(!empty($topic)){
            $topic->reply_count = $topic->replies()->count();
            $topic->save();
        }
    }
}

数据模型

因为在创建回复时我们已经在回复模型文件里已经注册了观察者类,所以这次我们只需要在回复模型文件里添加方法判断用户是否可以删除回复。

application/common/model/Reply.php

<?php

namespace app\common\model;

use think\Model;
use app\common\validate\Reply as Validate;
use app\common\exception\ValidateException;

class Reply extends Model
{
    .
    .
    .
    /**
     * 是否可以删除回复
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2019-06-25
     * @return   boolean             [description]
     */
    public function canDelete()
    {
        $current_user = User::currentUser();
        if(empty($current_user)){
            return false;
        }

        if($current_user->isAuthorOf($this)){
            return true;
        }

        $topic = $this->topic;
        if(empty($topic)){
            return false;
        }else if($current_user->isAuthorOf($topic)){
            return true;
        }

        return false;
    }
}

控制器

接下来,完成回复控制器里的删除方法:

application/index/controller/Reply.php

<?php
.
.
.
use think\facade\Session;

class Reply extends Base
{
    .
    .
    .
    /**
     * 删除指定资源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function delete($id)
    {
        $reply = ReplyModel::find($id);

        if(empty($reply)){
            $this->error('删除回复不存在', '[page.root]');
        }else if(!$reply->canDelete()){
            $this->error('对不起,您没有权限删除该回复', url('[topic.read]', ['id' => $reply->topic_id]));
        }

        $reply->delete();

        $message = '删除成功';
        Session::set('success', $message);
        $this->success($message, url('[topic.read]', ['id' => $reply->topic_id]));
    }
}

路由

配置删除回复路由访问规则:

route/route.php

<?php
.
.
.
// 评论管理
Route::post('reply', 'reply/save')->name('reply.save');
Route::delete('reply/<id>', 'reply/delete')->name('reply.delete');

视图模板

  1. 给话题详情页的回复列表添加删除按钮:

application/index/view/topic/_reply_list.html

<div class="media-heading mt-0 mb-1 text-secondary">
    .
    .
    .
    <!-- 回复删除按钮 -->
    <span class="meta float-right ">
        {if($reply->canDelete())}
            <form class="delete-reply" action="{:url('[reply.delete]', ['id' => $reply->id])}"
            onsubmit="return confirm('确定要删除此评论?');"
            method="post">
                <input type="hidden" name="_method" value="DELETE">
                <button type="submit" class="btn btn-secondary btn-xs pull-left text-secondary">
                    <i class="far fa-trash-alt"></i>
                </button>
            </form>
        {/if}
    </span>
</div>
  1. 在话题详情页底部添加删除回复JS方法调用:

application/index/view/topic/read.html

.
.
.
{block name="scripts"}
{js href="/static/assets/plugins/jquery-validate/jquery.validate.min.js" /}
<script type="text/javascript">
    jQuery(function($){
        // 删除话题
        validAndSubmitForm(
            "form#delete-topic",
            {}, {}
        );

        // 删除回复
        validAndSubmitForm(
            "form.delete-reply",
            {}, {}
        );
        .
        .
        .
    });
</script>
{/block}

效果预览

Git 版本控制

下面把代码纳入到版本管理。

$ git add -A
$ git commit -m "用户删除回复"

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~