内核更新

bug修复
This commit is contained in:
2016-10-02 11:50:36 +08:00
parent 7608d4d0f7
commit a70c700b04
27 changed files with 201 additions and 141 deletions

View File

@@ -34,9 +34,6 @@ class User extends Base {
array('title' => '密码修改', 'url' => 'user/profile/editpw', 'icon' => 'key'),
array('title' => '更换头像', 'url' => 'user/profile/avatar', 'icon' => 'male'),
);
$menu['订单管理'] = array(
array('title' => '我的订单', 'url' => 'user/order/index', 'icon' => 'shopping-bag'),
);
$contetnmenu = $this->getContentMenu();
if (!empty($contetnmenu)) {
$menu['内容管理'] = $contetnmenu;

View File

@@ -73,7 +73,7 @@ class Document extends \think\model\Merge{
if (is_numeric($name)) {
$name = db('model')->where(array('id'=>$name))->value('name');
}
self::$relationModel = array('document_' . $name);
$this->relationModel = array('document_' . $name);
return $this;
}

View File

@@ -9,7 +9,7 @@
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
define('THINK_VERSION', '5.0.0');
define('THINK_VERSION', '5.0.2dev');
define('THINK_START_TIME', microtime(true));
define('THINK_START_MEM', memory_get_usage());
define('EXT', '.php');

View File

@@ -79,32 +79,35 @@ class App
{
is_null($request) && $request = Request::instance();
$config = self::initCommon();
if (defined('BIND_MODULE')) {
// 模块/控制器绑定
BIND_MODULE && Route::bind(BIND_MODULE);
} elseif ($config['auto_bind_module']) {
// 入口自动绑定
$name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
Route::bind($name);
}
}
$request->filter($config['default_filter']);
try {
// 开启多语言机制
if ($config['lang_switch_on']) {
// 获取当前语言
$request->langset(Lang::detect());
// 加载系统语言包
Lang::load(THINK_PATH . 'lang' . DS . $request->langset() . EXT);
if (!$config['app_multi_module']) {
Lang::load(APP_PATH . 'lang' . DS . $request->langset() . EXT);
$config = self::initCommon();
if (defined('BIND_MODULE')) {
// 模块/控制器绑定
BIND_MODULE && Route::bind(BIND_MODULE);
} elseif ($config['auto_bind_module']) {
// 入口自动绑定
$name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
Route::bind($name);
}
}
$request->filter($config['default_filter']);
if ($config['lang_switch_on']) {
// 开启多语言机制 检测当前语言
Lang::detect();
} else {
// 读取默认语言
Lang::range($config['default_lang']);
}
$request->langset(Lang::range());
// 加载系统语言包
Lang::load([
THINK_PATH . 'lang' . DS . $request->langset() . EXT,
APP_PATH . 'lang' . DS . $request->langset() . EXT,
]);
// 获取应用调度信息
$dispatch = self::$dispatch;
if (empty($dispatch)) {
@@ -496,7 +499,7 @@ class App
}
// 加载当前模块语言包
if ($config['lang_switch_on'] && $module) {
if ($module) {
Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);
}
}

View File

@@ -40,7 +40,7 @@ use think\paginator\Collection as PaginatorCollection;
* @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据
* @method mixed query(string $sql, array $bind = [], boolean $fetch = false, boolean $master = false, mixed $class = false) static SQL查询
* @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行
* @method PaginatorCollection paginate(integer $listRows = 15, boolean $simple = false, array $config = []) static 分页查询
* @method PaginatorCollection paginate(integer $listRows = 15, mixed $simple = false, array $config = []) static 分页查询
* @method mixed transaction(callable $callback) static 执行数据库事务
* @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句
*/

View File

@@ -403,4 +403,9 @@ class File extends SplFileObject
{
return $this->error;
}
public function __call($method, $args)
{
return $this->hash($method);
}
}

View File

@@ -25,6 +25,8 @@ class Lang
protected static $langDetectVar = 'lang';
// 语言Cookie变量
protected static $langCookieVar = 'think_var';
// 语言Cookie的过期时间
protected static $langCookieExpire = 3600;
// 允许语言列表
protected static $allowLangList = [];
@@ -81,10 +83,8 @@ class Lang
// 记录加载信息
App::$debug && Log::record('[ LANG ] ' . $_file, 'info');
$_lang = include $_file;
} else {
$_lang = [];
$lang = array_change_key_case($_lang) + $lang;
}
$lang = array_change_key_case($_lang) + $lang;
}
if (!empty($lang)) {
self::$lang[$range] = $lang + self::$lang[$range];
@@ -157,7 +157,7 @@ class Lang
if (isset($_GET[self::$langDetectVar])) {
// url中设置了语言变量
$langSet = strtolower($_GET[self::$langDetectVar]);
Cookie::set(self::$langCookieVar, $langSet, 3600);
Cookie::set(self::$langCookieVar, $langSet, self::$langCookieExpire);
} elseif (Cookie::get(self::$langCookieVar)) {
// 获取上次用户的选择
$langSet = strtolower(Cookie::get(self::$langCookieVar));
@@ -165,7 +165,7 @@ class Lang
// 自动侦测浏览器语言
preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$langSet = strtolower($matches[1]);
Cookie::set(self::$langCookieVar, $langSet, 3600);
Cookie::set(self::$langCookieVar, $langSet, self::$langCookieExpire);
}
if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) {
// 合法的语言
@@ -197,6 +197,16 @@ class Lang
self::$langCookieVar = $var;
}
/**
* 设置语言的cookie的过期时间
* @param string $expire 过期时间
* @return void
*/
public static function setLangCookieExpire($expire)
{
self::$langCookieExpire = $expire;
}
/**
* 设置允许的语言列表
* @param array $list 语言列表

View File

@@ -322,7 +322,7 @@ class Loader
//加载当前模块应用类库
$baseUrl = App::$modulePath;
} elseif (is_dir(EXTEND_PATH . $name)) {
$baseUrl = EXTEND_PATH;
$baseUrl = EXTEND_PATH . $name . DS;
} else {
// 加载其它模块的类库
$baseUrl = APP_PATH . $name . DS;

View File

@@ -13,6 +13,7 @@ namespace think;
use InvalidArgumentException;
use think\Cache;
use think\Config;
use think\Db;
use think\db\Query;
use think\Exception;
@@ -99,7 +100,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 验证失败是否抛出异常
protected $failException = false;
// 全局查询范围
protected static $useGlobalScope = true;
protected $useGlobalScope = true;
/**
* 初始化过的模型.
@@ -126,7 +127,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (empty($this->name)) {
// 当前模型名
$this->name = basename(str_replace('\\', '/', $this->class));
$name = str_replace('\\', '/', $this->class);
$this->name = basename($name);
if (Config::get('class_suffix')) {
$suffix = basename(dirname($name));
$this->name = substr($this->name, 0, -strlen($suffix));
}
}
if (is_null($this->autoWriteTimestamp)) {
@@ -141,9 +147,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
/**
* 获取当前模型的数据库查询对象
* @access public
* @param bool $baseQuery 是否调用全局查询范围
* @return Query
*/
public function db()
public function db($baseQuery = true)
{
$model = $this->class;
if (!isset(self::$links[$model])) {
@@ -163,6 +170,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
self::$links[$model] = $query;
}
// 全局作用域
if ($baseQuery && method_exists($this, 'base')) {
call_user_func_array([$this, 'base'], [ & self::$links[$model]]);
}
// 返回当前模型的数据库查询对象
return self::$links[$model];
}
@@ -401,9 +412,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 类型转换
$value = $this->readTransform($value, $this->type[$name]);
} elseif ($notFound) {
if (method_exists($this, $name) && !method_exists('\think\Model', $name)) {
$method = Loader::parseName($name, 1);
if (method_exists($this, $method) && !method_exists('\think\Model', $method)) {
// 不存在该字段 获取关联数据
$value = $this->relation()->getRelation($name);
$value = $this->relation()->getRelation($method);
// 保存关联对象值
$this->data[$name] = $value;
} else {
@@ -1109,8 +1121,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/
public static function useGlobalScope($use)
{
$model = new static();
static::$useGlobalScope = $use;
$model = new static();
$model->useGlobalScope = $use;
return $model;
}
@@ -1333,10 +1345,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public function __call($method, $args)
{
$query = $this->db();
// 全局作用域
if (static::$useGlobalScope && method_exists($this, 'base')) {
call_user_func_array('static::base', [ & $query]);
}
if (method_exists($this, 'scope' . $method)) {
// 动态调用命名范围
$method = 'scope' . $method;
@@ -1351,11 +1359,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public static function __callStatic($method, $params)
{
$query = self::getDb();
$model = get_called_class();
// 全局作用域
if (static::$useGlobalScope && method_exists($model, 'base')) {
call_user_func_array('static::base', [ & $query]);
}
return call_user_func_array([$query, $method], $params);
}

View File

@@ -1476,23 +1476,37 @@ class Request
*/
public function cache($key, $expire = null)
{
if (false !== strpos($key, ':')) {
$param = $this->param();
foreach ($param as $item => $val) {
if (is_string($val) && false !== strpos($key, ':' . $item)) {
$key = str_replace(':' . $item, $val, $key);
if ($this->isGet()) {
if (false !== strpos($key, ':')) {
$param = $this->param();
foreach ($param as $item => $val) {
if (is_string($val) && false !== strpos($key, ':' . $item)) {
$key = str_replace(':' . $item, $val, $key);
}
}
} elseif ('__URL__' == $key) {
// 当前URL地址作为缓存标识
$key = md5($this->url());
} elseif (strpos($key, ']')) {
if ('[' . $this->ext() . ']' == $key) {
// 缓存某个后缀的请求
$key = md5($this->url());
} else {
return;
}
}
}
if (Cache::has($key)) {
// 读取缓存
$content = Cache::get($key);
$response = Response::create($content)
->code(304)
->header('Content-Type', Cache::get($key . '_header'));
throw new \think\exception\HttpResponseException($response);
} else {
$this->cache = [$key, $expire];
if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) {
// 读取缓存
$response = Response::create()->code(304);
throw new \think\exception\HttpResponseException($response);
} elseif (Cache::has($key)) {
list($content, $header) = Cache::get($key);
$response = Response::create($content)->header($header);
throw new \think\exception\HttpResponseException($response);
} else {
$this->cache = [$key, $expire];
}
}
}

View File

@@ -111,15 +111,17 @@ class Response
header($name . ':' . $val);
}
}
echo $data;
if (200 == $this->code) {
$cache = Request::instance()->getCache();
if ($cache) {
Cache::set($cache[0], $data, $cache[1]);
Cache::set($cache[0] . '_header', $this->header['Content-Type']);
header('Cache-Control: max-age=' . $cache[1] . ',must-revalidate');
header('Last-Modified:' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Expires:' . gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT');
$header['Content-Type'] = $this->header['Content-Type'];
Cache::set($cache[0], [$data, $header], $cache[1]);
}
}
echo $data;
if (function_exists('fastcgi_finish_request')) {
// 提高页面响应

View File

@@ -830,7 +830,7 @@ class Route
if (true === $rule) {
$rule = self::getRouteExpress($url);
}
if (!empty($rule['route'])) {
if (!empty($rule['route']) && self::checkOption($rule['option'], $url, $request)) {
return self::parseRule($url, $rule['route'], $url, $rule['option']);
}
}

View File

@@ -977,14 +977,14 @@ class Template
break;
case 'COOKIE':
if (isset($vars[2])) {
$parseStr = '$_COOKIE[\'' . $vars[1] . '\'][\'' . $vars[2] . '\']';
$parseStr = '\\think\\Cookie::get(\'' . $vars[1] . '.' . $vars[2] . '\')';
} else {
$parseStr = '\\think\\Cookie::get(\'' . $vars[1] . '\')';
}
break;
case 'SESSION':
if (isset($vars[2])) {
$parseStr = '$_SESSION[\'' . $vars[1] . '\'][\'' . $vars[2] . '\']';
$parseStr = '\\think\\Session::get(\'' . $vars[1] . '.' . $vars[2] . '\')';
} else {
$parseStr = '\\think\\Session::get(\'' . $vars[1] . '\')';
}

View File

@@ -16,6 +16,7 @@ namespace think\cache;
*/
abstract class Driver
{
protected $handler = null;
protected $options = [];
protected $tag;
@@ -173,4 +174,15 @@ abstract class Driver
return [];
}
}
/**
* 返回句柄对象,可执行其它高级方法
*
* @access public
* @return object
*/
public function handler()
{
return $this->handler;
}
}

View File

@@ -221,9 +221,13 @@ class File extends Driver
$this->rm('tag_' . md5($tag));
return true;
}
$fileLsit = (array) glob($this->options['path'] . '*');
foreach ($fileLsit as $path) {
is_file($path) && unlink($path);
$files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*');
foreach ($files as $path) {
if (is_dir($path)) {
array_map('unlink', glob($path . '/*.php'));
} else {
unlink($path);
}
}
return true;
}

View File

@@ -180,6 +180,6 @@ class Lite extends Driver
$this->rm('tag_' . md5($tag));
return true;
}
array_map("unlink", glob($this->options['path'] . $this->options['prefix'] . '*.php'));
array_map("unlink", glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*.php'));
}
}

View File

@@ -16,7 +16,6 @@ use think\Exception;
class Memcache extends Driver
{
protected $handler = null;
protected $options = [
'host' => '127.0.0.1',
'port' => 11211,

View File

@@ -15,7 +15,6 @@ use think\cache\Driver;
class Memcached extends Driver
{
protected $handler;
protected $options = [
'host' => '127.0.0.1',
'port' => 11211,

View File

@@ -22,7 +22,6 @@ use think\cache\Driver;
*/
class Redis extends Driver
{
protected $handler = null;
protected $options = [
'host' => '127.0.0.1',
'port' => 6379,
@@ -174,14 +173,4 @@ class Redis extends Driver
return $this->handler->flushDB();
}
/**
* 返回句柄对象,可执行其它高级方法
*
* @access public
* @return object
*/
public function handler()
{
return $this->handler;
}
}

View File

@@ -20,7 +20,6 @@ use think\Exception;
*/
class Sqlite extends Driver
{
protected $options = [
'db' => ':memory:',
'table' => 'sharedmemory',

View File

@@ -25,8 +25,6 @@ class Wincache extends Driver
'expire' => 0,
];
protected $tag;
/**
* 架构函数
* @param array $options 缓存参数

View File

@@ -489,51 +489,51 @@ class Query
*/
public function count($field = '*')
{
return $this->value('COUNT(' . $field . ') AS tp_count', 0);
return (int) $this->value('COUNT(' . $field . ') AS tp_count', 0);
}
/**
* SUM查询
* @access public
* @param string $field 字段名
* @return integer
* @return float|int
*/
public function sum($field = '*')
{
return $this->value('SUM(' . $field . ') AS tp_sum', 0);
return $this->value('SUM(' . $field . ') AS tp_sum', 0) + 0;
}
/**
* MIN查询
* @access public
* @param string $field 字段名
* @return integer
* @return float|int
*/
public function min($field = '*')
{
return $this->value('MIN(' . $field . ') AS tp_min', 0);
return $this->value('MIN(' . $field . ') AS tp_min', 0) + 0;
}
/**
* MAX查询
* @access public
* @param string $field 字段名
* @return integer
* @return float|int
*/
public function max($field = '*')
{
return $this->value('MAX(' . $field . ') AS tp_max', 0);
return $this->value('MAX(' . $field . ') AS tp_max', 0) + 0;
}
/**
* AVG查询
* @access public
* @param string $field 字段名
* @return integer
* @return float|int
*/
public function avg($field = '*')
{
return $this->value('AVG(' . $field . ') AS tp_avg', 0);
return $this->value('AVG(' . $field . ') AS tp_avg', 0) + 0;
}
/**
@@ -972,7 +972,7 @@ class Query
/**
* 分页查询
* @param int|null $listRows 每页数量
* @param bool $simple 简洁模式
* @param int|bool $simple 简洁模式或者总记录数
* @param array $config 配置参数
* page:当前页,
* path:url路径,
@@ -986,6 +986,10 @@ class Query
*/
public function paginate($listRows = null, $simple = false, $config = [])
{
if (is_int($simple)) {
$total = $simple;
$simple = false;
}
$config = array_merge(Config::get('paginate'), $config);
$listRows = $listRows ?: $config['list_rows'];
@@ -1000,16 +1004,17 @@ class Query
$config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']);
if (!$simple) {
if (!isset($total) && !$simple) {
$options = $this->getOptions();
$total = $this->count();
$bind = $this->bind;
$results = $this->options($options)->bind($bind)->page($page, $listRows)->select();
} else {
} elseif ($simple) {
$results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select();
$total = null;
} else {
$results = $this->page($page, $listRows)->select();
}
return $class::make($results, $listRows, $page, $total, $simple, $config);
}
@@ -1482,7 +1487,11 @@ class Query
*/
public function getOptions($name = '')
{
return isset($this->options[$name]) ? $this->options[$name] : $this->options;
if ('' === $name) {
return $this->options;
} else {
return isset($this->options[$name]) ? $this->options[$name] : null;
}
}
/**

View File

@@ -32,7 +32,7 @@ class Mysql extends Builder
if (strpos($key, '$.') && false === strpos($key, '(')) {
// JSON字段支持
list($field, $name) = explode('$.', $key);
$key = 'jsn_extract(' . $field . ', \'$.\'.' . $name . ')';
$key = 'json_extract(' . $field . ', \'$.' . $name . '\')';
}
if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
$key = '`' . $key . '`';

View File

@@ -203,10 +203,6 @@ class Handle
if (IS_CLI) {
return $message;
}
// 导入语言包
if (!Config::get('lang_switch_on')) {
Lang::load(THINK_PATH . 'lang' . DS . Lang::detect() . EXT);
}
if (strpos($message, ':')) {
$name = strstr($message, ':', true);

View File

@@ -17,9 +17,9 @@ use think\Model;
class Merge extends Model
{
protected static $relationModel = []; // HAS ONE 关联的模型列表
protected $fk = ''; // 外键名 默认为主表名_id
protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' )
protected $relationModel = []; // HAS ONE 关联的模型列表
protected $fk = ''; // 外键名 默认为主表名_id
protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' )
/**
* 架构函数
@@ -64,7 +64,7 @@ class Merge extends Model
$fields = self::getModelField($query, $master, '', $class->mapFields);
$query->alias($master)->field($fields);
foreach (static::$relationModel as $key => $model) {
foreach ($class->relationModel as $key => $model) {
$name = is_int($key) ? $model : $key;
$table = is_int($key) ? $query->getTable($name) : $model;
$query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk());
@@ -126,7 +126,7 @@ class Merge extends Model
$item = [];
foreach ($data as $key => $val) {
if ($insert || in_array($key, $this->change) || $this->isPk($key)) {
if (array_key_exists($key, $this->mapFields)) {
if ($this->fk != $key && array_key_exists($key, $this->mapFields)) {
list($name, $key) = explode('.', $this->mapFields[$key]);
if ($model == $name) {
$item[$key] = $val;
@@ -203,7 +203,7 @@ class Merge extends Model
$result = $db->strict(false)->where($where)->update($data);
// 写入附表数据
foreach (static::$relationModel as $key => $model) {
foreach ($this->relationModel as $key => $model) {
$name = is_int($key) ? $model : $key;
$table = is_int($key) ? $db->getTable($model) : $model;
// 处理关联模型数据
@@ -213,6 +213,8 @@ class Merge extends Model
$result = 1;
}
}
// 清空change
$this->change = [];
// 新增回调
$this->trigger('after_update', $this);
} else {
@@ -239,16 +241,19 @@ class Merge extends Model
if ($insertId) {
if (is_string($pk)) {
$this->data[$pk] = $insertId;
if ($this->fk == $pk) {
$this->change[] = $pk;
}
}
$this->data[$this->fk] = $insertId;
}
// 写入附表数据
$source = $this->data;
if ($insertId && is_string($pk) && isset($source[$pk])) {
if ($insertId && is_string($pk) && isset($source[$pk]) && $this->fk != $pk) {
unset($source[$pk]);
}
foreach (static::$relationModel as $key => $model) {
foreach ($this->relationModel as $key => $model) {
$name = is_int($key) ? $model : $key;
$table = is_int($key) ? $db->getTable($model) : $model;
// 处理关联模型数据
@@ -257,6 +262,10 @@ class Merge extends Model
$query->table($table)->strict(false)->insert($data);
}
}
// 标记为更新
$this->isUpdate = true;
// 清空change
$this->change = [];
// 新增回调
$this->trigger('after_insert', $this);
}
@@ -288,7 +297,7 @@ class Merge extends Model
$pk = $this->data[$this->getPk()];
// 删除关联数据
foreach (static::$relationModel as $key => $model) {
foreach ($this->relationModel as $key => $model) {
$table = is_int($key) ? $db->getTable($model) : $model;
$query = clone $db;
$query->table($table)->where($this->fk, $pk)->delete();

View File

@@ -318,11 +318,7 @@ class Relation
}
}
if (!isset($list[$relation])) {
// 设置关联模型属性
$list[$relation] = [];
}
$result->setAttr($relation, (new $model($list[$relation]))->isUpdate(true));
$result->setAttr($relation, !isset($list[$relation]) ? null : (new $model($list[$relation]))->isUpdate(true));
}
/**

View File

@@ -12,7 +12,8 @@ trait SoftDelete
*/
public function trashed()
{
if (!empty($this->data[static::$deleteTime])) {
$field = $this->getDeleteTimeField();
if (!empty($this->data[$field])) {
return true;
}
return false;
@@ -37,7 +38,8 @@ trait SoftDelete
public static function onlyTrashed()
{
$model = new static();
return $model->db()->where(static::$deleteTime, 'exp', 'is not null');
$field = $model->getDeleteTimeField();
return $model->db()->where($field, 'exp', 'is not null');
}
/**
@@ -51,10 +53,9 @@ trait SoftDelete
if (false === $this->trigger('before_delete', $this)) {
return false;
}
if (static::$deleteTime && !$force) {
$name = $this->getDeleteTimeField();
if (!$force) {
// 软删除
$name = static::$deleteTime;
$this->change[] = $name;
$this->data[$name] = $this->autoWriteTimestamp($name);
$result = $this->isUpdate()->save();
@@ -106,12 +107,10 @@ trait SoftDelete
*/
public function restore($where = [])
{
if (static::$deleteTime) {
// 恢复删除
$name = static::$deleteTime;
return $this->isUpdate()->save([$name => null], $where);
}
return false;
$name = $this->getDeleteTimeField();
// 恢复删除
return $this->isUpdate()->save([$name => null], $where);
}
/**
@@ -120,11 +119,28 @@ trait SoftDelete
* @param \think\db\Query $query 查询对象
* @return void
*/
protected static function base($query)
protected function base($query)
{
if (static::$deleteTime) {
$query->where(static::$deleteTime, 'null');
}
$field = $this->getDeleteTimeField(true);
$query->where($field, 'null');
}
/**
* 获取软删除字段
* @access public
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
* @return string
*/
protected function getDeleteTimeField($read = false)
{
if (isset($this->deleteTime)) {
$field = $this->deleteTime;
} else {
$field = 'delete_time';
}
if (!$read && strpos($field, '.')) {
list($alias, $field) = explode('.', $field);
}
return $field;
}
}