From 9441d10d67e3246406e346bcde58530b4b8b205e Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 6 Aug 2016 11:47:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=AF=E5=88=A0=E9=99=A4=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BD=9C=E4=B8=BAtrait=E6=89=A9=E5=B1=95=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Model.php | 96 ++++++++++------------- library/traits/model/SoftDelete.php | 113 ++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 58 deletions(-) create mode 100644 library/traits/model/SoftDelete.php diff --git a/library/think/Model.php b/library/think/Model.php index 3c90b3b7..12a7e0e2 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -41,7 +41,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { // 数据库对象池 - private static $links = []; + protected static $links = []; // 数据库配置 protected $connection = []; // 当前模型名称 @@ -85,8 +85,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected $createTime = 'create_time'; // 更新时间字段 protected $updateTime = 'update_time'; - // 删除时间字段 - protected static $deleteTime; // 时间字段取出后的默认时间格式 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'); } - if (is_null(static::$deleteTime)) { - static::$deleteTime = $this->db()->getConfig('soft_delete_field'); - } - // 执行初始化操作 $this->initialize(); } @@ -279,27 +273,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ 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])) { // 自动写入的时间戳字段 - if (isset($this->type[$name])) { - $type = $this->type[$name]; - if (strpos($type, ':')) { - list($type, $param) = explode(':', $type, 2); - } - switch ($type) { - case 'datetime': - $format = !empty($param) ? $param : $this->dateFormat; - $value = date($format, $_SERVER['REQUEST_TIME']); - break; - case 'timestamp': - $value = $_SERVER['REQUEST_TIME']; - break; - } - } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) { - $value = date($this->dateFormat, $_SERVER['REQUEST_TIME']); - } else { - $value = $_SERVER['REQUEST_TIME']; - } + $value = $this->autoWriteTimestamp($name); } else { // 检测修改器 $method = 'set' . Loader::parseName($name, 1) . 'Attr'; @@ -320,6 +296,36 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $this; } + /** + * 自动写入时间戳 + * @access public + * @param string $name 时间戳字段 + * @return mixed + */ + protected function autoWriteTimestamp($name) + { + if (isset($this->type[$name])) { + $type = $this->type[$name]; + if (strpos($type, ':')) { + list($type, $param) = explode(':', $type, 2); + } + switch ($type) { + case 'datetime': + $format = !empty($param) ? $param : $this->dateFormat; + $value = date($format, $_SERVER['REQUEST_TIME']); + break; + case 'timestamp': + $value = $_SERVER['REQUEST_TIME']; + break; + } + } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) { + $value = date($this->dateFormat, $_SERVER['REQUEST_TIME']); + } else { + $value = $_SERVER['REQUEST_TIME']; + } + return $value; + } + /** * 数据写入 类型转换 * @access public @@ -790,33 +796,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess 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); 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 @@ -986,7 +971,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ 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); } @@ -1001,7 +986,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ 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); } @@ -1026,10 +1011,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $result = $data->with($with)->cache($cache); $data = null; } - if (static::$deleteTime) { - // 默认不查询软删除数据 - $result->where(static::$deleteTime, 0); - } return $result; } @@ -1037,10 +1018,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 删除记录 * @access public * @param mixed $data 主键列表 支持闭包查询条件 - * @param bool $force 是否强制删除 * @return integer 成功删除的记录数 */ - public static function destroy($data, $force = false) + public static function destroy($data) { $model = new static(); $query = $model->db(); @@ -1055,7 +1035,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $count = 0; if ($resultSet) { foreach ($resultSet as $data) { - $result = $data->delete($force); + $result = $data->delete(); $count += $result; } } diff --git a/library/traits/model/SoftDelete.php b/library/traits/model/SoftDelete.php new file mode 100644 index 00000000..ee120ae5 --- /dev/null +++ b/library/traits/model/SoftDelete.php @@ -0,0 +1,113 @@ +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); + } +}