软删除功能作为trait扩展引入

This commit is contained in:
thinkphp
2016-08-06 11:47:15 +08:00
parent e4280c128e
commit 9441d10d67
2 changed files with 151 additions and 58 deletions

View File

@@ -41,7 +41,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
{ {
// 数据库对象池 // 数据库对象池
private static $links = []; protected static $links = [];
// 数据库配置 // 数据库配置
protected $connection = []; protected $connection = [];
// 当前模型名称 // 当前模型名称
@@ -85,8 +85,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
protected $createTime = 'create_time'; protected $createTime = 'create_time';
// 更新时间字段 // 更新时间字段
protected $updateTime = 'update_time'; protected $updateTime = 'update_time';
// 删除时间字段
protected static $deleteTime;
// 时间字段取出后的默认时间格式 // 时间字段取出后的默认时间格式
protected $dateFormat = 'Y-m-d H:i:s'; protected $dateFormat = 'Y-m-d H:i:s';
// 字段类型或者格式转换 // 字段类型或者格式转换
@@ -133,10 +131,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp'); $this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp');
} }
if (is_null(static::$deleteTime)) {
static::$deleteTime = $this->db()->getConfig('soft_delete_field');
}
// 执行初始化操作 // 执行初始化操作
$this->initialize(); $this->initialize();
} }
@@ -279,8 +273,37 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/ */
public function setAttr($name, $value, $data = []) public function setAttr($name, $value, $data = [])
{ {
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime, static::$deleteTime])) { if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
// 自动写入的时间戳字段 // 自动写入的时间戳字段
$value = $this->autoWriteTimestamp($name);
} else {
// 检测修改器
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
if (method_exists($this, $method)) {
$value = $this->$method($value, array_merge($data, $this->data));
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
}
}
// 标记字段更改
if (!isset($this->data[$name]) || ($this->data[$name] != $value && !in_array($name, $this->change))) {
$this->change[] = $name;
}
// 设置数据对象属性
$this->data[$name] = $value;
return $this;
}
/**
* 自动写入时间戳
* @access public
* @param string $name 时间戳字段
* @return mixed
*/
protected function autoWriteTimestamp($name)
{
if (isset($this->type[$name])) { if (isset($this->type[$name])) {
$type = $this->type[$name]; $type = $this->type[$name];
if (strpos($type, ':')) { if (strpos($type, ':')) {
@@ -300,24 +323,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
} else { } else {
$value = $_SERVER['REQUEST_TIME']; $value = $_SERVER['REQUEST_TIME'];
} }
} else { return $value;
// 检测修改器
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
if (method_exists($this, $method)) {
$value = $this->$method($value, array_merge($data, $this->data));
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
}
}
// 标记字段更改
if (!isset($this->data[$name]) || ($this->data[$name] != $value && !in_array($name, $this->change))) {
$this->change[] = $name;
}
// 设置数据对象属性
$this->data[$name] = $value;
return $this;
} }
/** /**
@@ -790,33 +796,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
return false; return false;
} }
if (static::$deleteTime && !$force) {
// 软删除
$this->setAttr(static::$deleteTime, null);
$result = $this->isUpdate()->save();
} else {
$result = $this->db()->delete($this->data); $result = $this->db()->delete($this->data);
}
$this->trigger('after_delete', $this); $this->trigger('after_delete', $this);
return $result; return $result;
} }
/**
* 恢复被软删除的记录
* @access public
* @return integer
*/
public function restore()
{
if (static::$deleteTime) {
// 恢复删除
$this->setAttr(static::$deleteTime, 0);
return $this->isUpdate()->save();
}
return false;
}
/** /**
* 设置自动完成的字段( 规则通过修改器定义) * 设置自动完成的字段( 规则通过修改器定义)
* @access public * @access public
@@ -986,7 +971,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/ */
public static function get($data = null, $with = [], $cache = false) public static function get($data = null, $with = [], $cache = false)
{ {
$query = self::parseQuery($data, $with, $cache); $query = static::parseQuery($data, $with, $cache);
return $query->find($data); return $query->find($data);
} }
@@ -1001,7 +986,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/ */
public static function all($data = null, $with = [], $cache = false) public static function all($data = null, $with = [], $cache = false)
{ {
$query = self::parseQuery($data, $with, $cache); $query = static::parseQuery($data, $with, $cache);
return $query->select($data); return $query->select($data);
} }
@@ -1026,10 +1011,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$result = $data->with($with)->cache($cache); $result = $data->with($with)->cache($cache);
$data = null; $data = null;
} }
if (static::$deleteTime) {
// 默认不查询软删除数据
$result->where(static::$deleteTime, 0);
}
return $result; return $result;
} }
@@ -1037,10 +1018,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
* 删除记录 * 删除记录
* @access public * @access public
* @param mixed $data 主键列表 支持闭包查询条件 * @param mixed $data 主键列表 支持闭包查询条件
* @param bool $force 是否强制删除
* @return integer 成功删除的记录数 * @return integer 成功删除的记录数
*/ */
public static function destroy($data, $force = false) public static function destroy($data)
{ {
$model = new static(); $model = new static();
$query = $model->db(); $query = $model->db();
@@ -1055,7 +1035,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$count = 0; $count = 0;
if ($resultSet) { if ($resultSet) {
foreach ($resultSet as $data) { foreach ($resultSet as $data) {
$result = $data->delete($force); $result = $data->delete();
$count += $result; $count += $result;
} }
} }

View File

@@ -0,0 +1,113 @@
<?php
namespace traits\model;
trait SoftDelete
{
/**
* 分析查询表达式
* @access public
* @param mixed $data 主键列表或者查询条件(闭包)
* @param string $with 关联预查询
* @param bool $cache 是否缓存
* @return Query
*/
protected static function parseQuery(&$data, $with, $cache)
{
$result = self::with($with)->cache($cache);
if (is_array($data) && key($data) !== 0) {
$result = $result->where($data);
$data = null;
} elseif ($data instanceof \Closure) {
call_user_func_array($data, [ & $result]);
$data = null;
} elseif ($data instanceof Query) {
$result = $data->with($with)->cache($cache);
$data = null;
}
if (static::$deleteTime) {
// 默认不查询软删除数据
$result->where(static::$deleteTime, 0);
}
return $result;
}
/**
* 查询软删除数据
* @access public
* @return \think\db\Query
*/
public static function withTrashed()
{
$model = new static();
return $model->db();
}
/**
* 删除当前的记录
* @access public
* @param bool $force 是否强制删除
* @return integer
*/
public function delete($force = false)
{
if (false === $this->trigger('before_delete', $this)) {
return false;
}
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
* @return integer
*/
public function restore()
{
if (static::$deleteTime) {
// 恢复删除
$this->setAttr(static::$deleteTime, 0);
return $this->isUpdate()->save();
}
return false;
}
public function __call($method, $args)
{
if (method_exists($this, 'scope' . $method)) {
// 动态调用命名范围
$method = 'scope' . $method;
array_unshift($args, $this->db());
call_user_func_array([$this, $method], $args);
return $this;
} else {
$query = $this->db();
$query->where(static::$deleteTime, 0);
return call_user_func_array([$this->db(), $method], $args);
}
}
public static function __callStatic($method, $params)
{
$model = get_called_class();
if (!isset(self::$links[$model])) {
self::$links[$model] = (new static())->db();
}
$query = self::$links[$model];
$query->where(static::$deleteTime, 0);
return call_user_func_array([$query, $method], $params);
}
}