<?php

namespace traits\model;

trait SoftDelete
{

    /**
     * 判断当前实例是否被软删除
     * @access public
     * @return boolean
     */
    public function trashed()
    {
        if (!empty($this->data[static::$deleteTime])) {
            return true;
        }
        return false;
    }// 判断 当前实例 是否被软删除,所谓的软删除,就是设置了删除时间

    /**
     * 查询软删除数据
     * @access public
     * @return \think\db\Query
     */
    public static function withTrashed()
    {
        $model = new static();// 此地方使用 static 是关键的, 原因在于  此部分作为被包含的地方 调用父亲的 静态实例化属性
        return $model->db();// 返回全部连接数据
    }

    /**
     * 只查询软删除数据
     * @access public
     * @return \think\db\Query
     */
    public static function onlyTrashed()
    {
        $model = new static();
        return $model->db()->where(static::$deleteTime, 'exp', 'is not null');
    }// 仅仅 查询 软删除数据 增加了判断条件

    /**
     * 删除当前的记录
     * @access public
     * @param bool  $force 是否强制删除
     * @return integer
     */
    public function delete($force = false)
    {// 删除 当前记录
        if (false === $this->trigger('before_delete', $this)) {
            return false;
        }// 如果当前 函数没有启动 删除前的行动,函数直接over

        if (static::$deleteTime && !$force) {// 如果已经软删除,并且 没有被强制删除
            // 软删除
            $name              = static::$deleteTime;// 获得删除时间
            $this->change[]    = $name;// 放到 改变记录里面
            $this->data[$name] = $this->autoWriteTimestamp($name);// 自动时间记录
            $result            = $this->isUpdate()->save();// 保存结果
        } else {// 否则强制删除
            $result = $this->db()->delete($this->data);//删除数据
        }

        $this->trigger('after_delete', $this);// 启动删除后的事情, 这种钩子行为,我觉得还是挺不错的
        return $result;
    }

    /**
     * 删除记录
     * @access public
     * @param mixed $data 主键列表 支持闭包查询条件
     * @param bool  $force 是否强制删除
     * @return integer 成功删除的记录数
     */
    public static function destroy($data, $force = false)
    {// 强制删除,就是 毁灭
        $model = new static();// 获取当前模型
        $query = $model->db();// 获取 sql 语句 句柄条件
        if (is_array($data) && key($data) !== 0) {
            $query->where($data);//where 执行
            $data = null;
        } elseif ($data instanceof \Closure) {// 如果数据是个闭包 资源
            call_user_func_array($data, [ & $query]);// 传入 数据,跟 对应的 句柄集合
            $data = null;
        } elseif (is_null($data)) {// 为空,返回假
            return 0;
        }

        $resultSet = $query->select($data);// 根据结果获取条件
        $count     = 0;// 统计结果
        if ($resultSet) {// 如果有结果
            foreach ($resultSet as $data) {
                $result = $data->delete($force);
                $count += $result;
            }
        }
        return $count;// 返回 条数,删除的条数
    }

    /**
     * 恢复被软删除的记录
     * @access public
     * @param array $where 更新条件
     * @return integer
     */
    public function restore($where = [])
    {
        if (static::$deleteTime) {
            // 恢复删除
            $name = static::$deleteTime;
            return $this->isUpdate()->save([$name => null], $where);
        }
        return false;
    }// 恢复被删除的记录,就是把 deletime 的时间抹掉

    /**
     * 查询默认不包含软删除数据
     * @access protected
     * @param \think\db\Query $query 查询对象
     * @return void
     */
    protected static function base($query)
    {
        if (static::$deleteTime) {
            $query->where(static::$deleteTime, 'null');
        }
    }// 查询没有被标记删除的数据

}