本书未发布

72. 编辑话题

未匹配的标注

简介

在本节里,我们完成话题编辑功能。

需求分解

编辑话题的要求如下:

  • 只有作者可以编辑自己创建的话题;
  • 编辑表单里用户只能修改话题的标题、分类和正文这三项内容;
  • 保存时自动截取正文前 200 个文字作为话题的摘要信息;
  • 编辑表单提交方式必须是 PUT 请求;
  • 编辑保存成功后转到话题详情页。

数据模型

因为我们在 Topic 观察者类里把摘要( excerpt)赋值写在 beforeWrite 事件里,所以编辑保存时会自动触发该事件,所以观察者类不需要更新。

另外,在创建话题时我们已经创建了验证器,编辑话题时的验证规则和创建一样,所以我们不需要创建新的验证器或修改已有验证器验证规则。

所以,我们只需要在数据模型里实现编辑需求。我们在 Topic 模型里添加两个实例方法:

  1. canUpdate 用来判断当前用户是否有编辑 topic 记录权限;
  2. updateInfo 验证提交数据是否有效,当验证通过时保存数据。

application/common/model/Topic.php

<?php
.
.
.
class Topic extends Model
{
    .
    .
    .
    /**
     * 是否可以编辑记录
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2019-06-21
     * @return   boolean            [description]
     */
    public function canUpdate(){
        $current_user = User::currentUser();
        if(empty($current_user)){
            return false;
        }else if($this->user_id != $current_user->id){
            return false;
        }
        return true;
    }

    /**
     * 更新记录
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2019-06-21
     * @param    array              $data 表单提交数据
     * @return   boolean                  是否成功
     */
    public function updateInfo($data)
    {
        $data['id'] = $this->id;

        $validate = new Validate;
        if(!$validate->batch(true)->check($data)){
            $e = new ValidateException('数据验证失败');
            $e->setData($validate->getError());
            throw $e;
        }

        $this->allowField(true)->save($data, ['id' => $this->id]);
        return $this;
    }
}

控制器

接下来,完成控制器里的控制( action )方法 editupdate 处理逻辑:

application/index/controller/Topic.php

<?php
.
.
.
use app\common\exception\ValidateException;
class Topic extends Base
{
    .
    .
    .
    /**
     * 显示编辑资源表单页.
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function edit($id)
    {
        $topic = TopicModel::find($id);

        $message = null;
        if(empty($topic)){
            $message = '编辑话题不存在';
        }else if(!$topic->canUpdate()){
            $message = '对不起,您没有权限编辑该话题';
        }

        if(!empty($message)){
            $this->redirect('[topic.index]');
        }

        $this->assign('topic', $topic);

        $categories = CategoryModel::all();
        $this->assign('categories', $categories);

        return $this->fetch('form');
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request  $request
     * @param  int  $id
     * @return \think\Response
     */
    public function update(Request $request, $id)
    {
        if(!$request->isAjax()){
            $this->redirect('[topic.create]');
        }

        $topic = TopicModel::find($id);

        if(empty($topic)){
            $this->error('编辑话题不存在', '[topic.index]');
        }else if(!$topic->canUpdate()){
            $this->error('对不起,您没有权限编辑该话题', '[topic.index]');
        }

        try{
            $data = $request->post();
            $topic->updateInfo($data);
        }catch (ValidateException $e){
            $this->error($e->getMessage(), '', ['errors' => $e->getData()]);
        }catch (\Exception $e){
            $this->error($e->getMessage());
        }

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

路由

在路由文件里添加 editupdate 方法路由规则。

route/route.php

<?php
.
.
.
// 话题管理
Route::get('topic/create', 'topic/create')->name('topic.create');
Route::post('topic', 'topic/save')->name('topic.save');
Route::get('topic/<id>/edit', 'topic/edit')->name('topic.edit');
Route::put('topic/<id>', 'topic/update')->name('topic.update');
Route::get('topic/<id>', 'topic/read')->name('topic.read');
Route::get('topic', 'topic/index')->name('topic.index');
Route::get('category/<id>', 'category/read')->name('category.read');

视图模板

修改视图模板,使得编辑话题时的标题和创建页面不一样,另外编辑表单提交时的请求方式是 put 请求,并且编辑时默认选中话题当前分类,标题和正文输入框分别显示话题当前信息。

application/index/view/topic/form.html

.
.
.
<div class="card-body">
    <h2>
        <i class="far fa-edit"></i>
        {if(isset($topic['id']))}
            编辑话题
        {else /}
            新建话题
        {/if}
    </h1>
</div>

{if(isset($topic['id']))}
<form id="model-form" class="needs-validation" novalidate action="{:url('[topic.update]', ['id' => $topic->id])}" method="POST" accept-charset="UTF-8">
    <input type="hidden" name="_method" value="PUT">
{else /}
<form id="model-form" class="needs-validation" novalidate action="{:url('[topic.save]')}" method="POST" accept-charset="UTF-8">
{/if}
    <div class="form-group">
        <input class="form-control" type="text" name="title" value="{$topic['title']|default=''}" placeholder="请填写标题" required />
    </div>
    <div class="form-group">
        <select class="form-control" name="category_id" required>
            <option value="" hidden disabled selected <?php if(!isset($topic['id'])){ echo('selected'); } ?>>请选择分类</option>
            {volist name='categories' id='category'}
                <option value="{$category->id}" <?php if(isset($topic['category_id']) && $topic['category_id']==$category->id){ echo('selected'); } ?>>
                    {$category->name}
                </option>
            {/volist}
        </select>
    </div>
    <div class="form-group">
        <textarea name="body" id="body-field" class="form-control" rows="3">{$topic['body']|default=''}</textarea>
    </div>
    <div class="well well-sm">
        <button type="submit" class="btn btn-primary">
            <i class="far fa-save mr-2" aria-hidden="true"></i> 保存
        </button>
    </div>
</form>
.
.
.

当用户可以编辑当前话题时,在话题详情页面添加到编辑页面入口:

application/index/view/topic/read.html

.
.
.
<div class="operate">
    <hr>
    <?php if($topic->canUpdate()): ?>
        <a href="{:url('[topic.edit]', ['id' => $topic->id])}" class="btn btn-default btn-xs pull-left" role="button">
            <i class="glyphicon glyphicon-edit"></i> 编辑
        </a>
    <?php endif; ?>

    <a href="#" class="btn btn-default btn-xs pull-left" role="button">
        <i class="glyphicon glyphicon-trash"></i> 删除
    </a>
</div>
.
.
.

效果预览

Git 版本控制

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

$ git add -A
$ git commit -m "用户可以编辑话题"

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

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


暂无话题~