内核更新

This commit is contained in:
2016-12-28 10:41:09 +08:00
parent c89254e12a
commit ffab826db0
65 changed files with 1194 additions and 610 deletions

View File

@@ -12,14 +12,8 @@
namespace think;
use InvalidArgumentException;
use think\Cache;
use think\Collection;
use think\Config;
use think\Db;
use think\db\Query;
use think\Exception;
use think\Exception\ValidateException;
use think\Loader;
use think\model\Relation;
use think\model\relation\BelongsTo;
use think\model\relation\BelongsToMany;
@@ -96,7 +90,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 更新时间字段
protected $updateTime = 'update_time';
// 时间字段取出后的默认时间格式
protected $dateFormat = 'Y-m-d H:i:s';
protected $dateFormat;
// 字段类型或者格式转换
protected $type = [];
// 是否为更新数据
@@ -151,7 +145,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (is_null($this->autoWriteTimestamp)) {
// 自动写入时间戳
$this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp');
$this->autoWriteTimestamp = $this->db(false)->getConfig('auto_timestamp');
}
if (is_null($this->dateFormat)) {
// 设置时间戳格式
$this->dateFormat = $this->db(false)->getConfig('datetime_format');
}
// 执行初始化操作
@@ -169,13 +168,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$model = $this->class;
if (!isset(self::$links[$model])) {
// 合并数据库配置
if (is_array($this->connection)) {
$connection = array_merge(Config::get('database'), $this->connection);
if (!empty($this->connection)) {
if (is_array($this->connection)) {
$connection = array_merge(Config::get('database'), $this->connection);
} else {
$connection = $this->connection;
}
} else {
$connection = $this->connection;
$connection = [];
}
// 设置当前模型 确保查询返回模型对象
$query = Db::connect($connection)->model($model, $this->query);
$query = Db::connect($connection)->getQuery($model, $this->query);
// 设置当前数据表和模型名
if (!empty($this->table)) {
@@ -319,21 +322,40 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
case 'datetime':
case 'date':
$format = !empty($param) ? $param : $this->dateFormat;
$value = date($format, $_SERVER['REQUEST_TIME']);
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $format);
break;
case 'timestamp':
case 'int':
case 'integer':
default:
$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']);
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $this->dateFormat);
} else {
$value = $_SERVER['REQUEST_TIME'];
$value = $this->formatDateTime($_SERVER['REQUEST_TIME'], $this->dateFormat, true);
}
return $value;
}
/**
* 时间日期字段格式化处理
* @access public
* @param mixed $time 时间日期表达式
* @param mixed $format 日期格式
* @param bool $timestamp 是否进行时间戳转换
* @return mixed
*/
protected function formatDateTime($time, $format, $timestamp = false)
{
if (false !== strpos($format, '\\')) {
$time = new $format($time);
} elseif (!$timestamp) {
$time = date($format, $time);
}
return $time;
}
/**
* 数据写入 类型转换
* @access public
@@ -369,7 +391,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
break;
case 'datetime':
$format = !empty($param) ? $param : $this->dateFormat;
$value = date($format, is_numeric($value) ? $value : strtotime($value));
$value = is_numeric($value) ? $value : strtotime($value);
$value = $this->formatDateTime($value, $format);
break;
case 'object':
if (is_object($value)) {
@@ -385,6 +408,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
case 'serialize':
$value = serialize($value);
break;
}
return $value;
}
@@ -414,7 +438,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 类型转换
$value = $this->readTransform($value, $this->type[$name]);
} elseif ($notFound) {
$method = Loader::parseName($name, 1);
$method = Loader::parseName($name, 1, false);
if (method_exists($this, $method) && $this->$method() instanceof Relation) {
// 不存在该字段 获取关联数据
$value = $this->$method()->getRelation();
@@ -458,13 +482,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
case 'timestamp':
if (!is_null($value)) {
$format = !empty($param) ? $param : $this->dateFormat;
$value = date($format, $value);
$value = $this->formatDateTime($value, $format);
}
break;
case 'datetime':
if (!is_null($value)) {
$format = !empty($param) ? $param : $this->dateFormat;
$value = date($format, strtotime($value));
$value = $this->formatDateTime(strtotime($value), $format);
}
break;
case 'json':
@@ -479,6 +503,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
case 'serialize':
$value = unserialize($value);
break;
default:
if (false !== strpos($type, '\\')) {
// 对象类型
$value = new $type($value);
}
}
return $value;
}
@@ -496,6 +525,32 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
return $this;
}
/**
* 设置附加关联对象的属性
* @access public
* @param string $relation 关联方法
* @param string|array $append 追加属性名
* @return $this
*/
public function appendRelationAttr($relation, $append)
{
if (is_string($append)) {
$append = explode(',', $append);
}
$model = $this->getAttr($relation);
if ($model instanceof Model) {
foreach ($append as $key => $attr) {
$key = is_numeric($key) ? $attr : $key;
if ($this->__isset($key)) {
throw new Exception('bind attr has exists:' . $key);
} else {
$this->setAttr($key, $model->$attr);
}
}
}
return $this;
}
/**
* 设置需要隐藏的输出属性
* @access public
@@ -603,10 +658,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public function getPk($name = '')
{
if (!empty($name)) {
$table = $this->db()->getTable($name);
return $this->db()->getPk($table);
$table = $this->db(false)->getTable($name);
return $this->db(false)->getPk($table);
} elseif (empty($this->pk)) {
$this->pk = $this->db()->getPk();
$this->pk = $this->db(false)->getPk();
}
return $this->pk;
}
@@ -665,7 +720,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$this->autoCompleteData($this->auto);
// 自动写入更新时间
if ($this->autoWriteTimestamp && $this->updateTime) {
if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) {
$this->setAttr($this->updateTime, null);
}
@@ -722,7 +777,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$this->autoCompleteData($this->insert);
// 自动写入创建时间
if ($this->autoWriteTimestamp && $this->createTime) {
if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) {
$this->setAttr($this->createTime, null);
}
@@ -803,7 +858,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public function allowField($field)
{
if (true === $field) {
$field = $this->db()->getTableInfo('', 'fields');
$field = $this->db(false)->getTableInfo('', 'fields');
}
$this->field = $field;
return $this;
@@ -1156,8 +1211,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
*/
public static function useGlobalScope($use)
{
$model = new static();
self::$db = $model->db($use);
$model = new static();
static::$db = $model->db($use);
return $model;
}
@@ -1245,6 +1300,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (strpos($relation, '.')) {
list($relation, $subRelation) = explode('.', $relation);
}
$relation = Loader::parseName($relation, 1, false);
$this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $class);
}
}
@@ -1271,10 +1327,34 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
if (strpos($relation, '.')) {
list($relation, $subRelation) = explode('.', $relation);
}
$relation = Loader::parseName($relation, 1, false);
$this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure, $class);
}
}
/**
* 关联统计
* @access public
* @param Model $result 数据对象
* @param string|array $relation 关联名
* @return void
*/
public function relationCount(&$result, $relation)
{
$relations = is_string($relation) ? explode(',', $relation) : $relation;
foreach ($relations as $key => $relation) {
$closure = false;
if ($relation instanceof \Closure) {
$closure = $relation;
$relation = $key;
}
$relation = Loader::parseName($relation, 1, false);
$count = $this->$relation()->relationCount($result, $closure);
$result->setAttr(Loader::parseName($relation) . '_count', $count);
}
}
/**
* HAS ONE 关联定义
* @access public
@@ -1369,7 +1449,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 记录当前关联信息
$model = $this->parseModel($model);
$name = Loader::parseName(basename(str_replace('\\', '/', $model)));
$table = $table ?: $this->db()->getTable(Loader::parseName($this->name) . '_' . $name);
$table = $table ?: $this->db(false)->getTable(Loader::parseName($this->name) . '_' . $name);
$foreignKey = $foreignKey ?: $name . '_id';
$localKey = $localKey ?: Loader::parseName($this->name) . '_id';
return new BelongsToMany($this, $model, $table, $foreignKey, $localKey, $alias);
@@ -1426,7 +1506,13 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public function __call($method, $args)
{
$query = $this->db();
if (isset(static::$db)) {
$query = static::$db;
static::$db = null;
} else {
$query = $this->db();
}
if (method_exists($this, 'scope' . $method)) {
// 动态调用命名范围
$method = 'scope' . $method;
@@ -1441,7 +1527,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
public static function __callStatic($method, $params)
{
if (isset(static::$db)) {
$query = static::$db;
$query = static::$db;
static::$db = null;
} else {
$query = (new static())->db();
}