提交 96c38449 编写于 作者: D devil_gong

tp框架更新

上级 7165bc29
......@@ -26,7 +26,7 @@
"require-dev": {
"phpunit/phpunit": "^5.0|^6.0",
"johnkary/phpunit-speedtrap": "^1.0",
"mikey179/vfsstream": "~1.6",
"mikey179/vfsStream": "~1.6",
"phploc/phploc": "2.*",
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "2.*",
......
......@@ -313,9 +313,9 @@ if (!function_exists('download')) {
* @param integer $expire 有效期(秒)
* @return \think\response\Download
*/
function download($filename, $name = '', $content = false, $expire = 360, $openinBrowser = false)
function download($filename, $name = '', $content = false, $expire = 360, $openinBrower = false)
{
return Response::create($filename, 'download')->name($name)->isContent($content)->expire($expire)->openinBrowser($openinBrowser);
return Response::create($filename, 'download')->name($name)->isContent($content)->expire($expire)->openinBrower($openinBrower);
}
}
......@@ -533,7 +533,7 @@ if (!function_exists('response')) {
* @param string $type
* @return Response
*/
function response($data = '', $code = 200, $header = [], $type = 'html')
function response($data = [], $code = 200, $header = [], $type = 'html')
{
return Response::create($data, $type, $code, $header);
}
......@@ -686,13 +686,7 @@ if (!function_exists('widget')) {
*/
function widget($name, $data = [])
{
$result = app()->action($name, $data, 'widget');
if (is_object($result)) {
$result = $result->getContent();
}
return $result;
return app()->action($name, $data, 'widget');
}
}
......
......@@ -20,7 +20,7 @@ use think\route\Dispatch;
*/
class App extends Container
{
const VERSION = '5.1.38 LTS';
const VERSION = '5.1.32 LTS';
/**
* 当前模块路径
......@@ -179,11 +179,6 @@ class App extends Container
$this->instance('app', $this);
// 加载环境变量配置文件
if (is_file($this->rootPath . '.env')) {
$this->env->load($this->rootPath . '.env');
}
$this->configExt = $this->env->get('config_ext', '.php');
// 加载惯例配置文件
......@@ -201,6 +196,11 @@ class App extends Container
'vendor_path' => $this->rootPath . 'vendor' . DIRECTORY_SEPARATOR,
]);
// 加载环境变量配置文件
if (is_file($this->rootPath . '.env')) {
$this->env->load($this->rootPath . '.env');
}
$this->namespace = $this->env->get('app_namespace', $this->namespace);
$this->env->set('app_namespace', $this->namespace);
......
......@@ -353,7 +353,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
$result = isset($data[$field]) ? $data[$field] : null;
}
switch (strtolower($operator)) {
switch ($operator) {
case '===':
return $result === $value;
case '!==':
......
......@@ -487,17 +487,12 @@ class Console
public function getNamespaces()
{
$namespaces = [];
foreach ($this->commands as $name => $command) {
if (is_string($command)) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($name));
} else {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
foreach ($this->commands as $command) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
foreach ($command->getAliases() as $alias) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
}
foreach ($command->getAliases() as $alias) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
}
}
return array_values(array_unique(array_filter($namespaces)));
......
......@@ -158,7 +158,7 @@ class Controller
*/
protected function fetch($template = '', $vars = [], $config = [])
{
return Response::create($template, 'view')->assign($vars)->config($config);
return $this->view->fetch($template, $vars, $config);
}
/**
......@@ -171,7 +171,7 @@ class Controller
*/
protected function display($content = '', $vars = [], $config = [])
{
return Response::create($content, 'view')->assign($vars)->config($config)->isContent(true);
return $this->view->display($content, $vars, $config);
}
/**
......
......@@ -300,7 +300,7 @@ class File extends SplFileObject
*/
public function checkSize($size)
{
if ($this->getSize() > (int) $size) {
if ($this->getSize() > $size) {
$this->error = 'filesize not match';
return false;
}
......
......@@ -127,10 +127,8 @@ class Log implements LoggerInterface
}
if (PHP_SAPI == 'cli') {
if (empty($this->config['level']) || in_array($type, $this->config['level'])) {
// 命令行日志实时写入
$this->write($msg, $type, true);
}
// 命令行日志实时写入
$this->write($msg, $type, true);
} else {
$this->log[$type][] = $msg;
}
......
......@@ -18,33 +18,6 @@ use think\db\Query;
* Class Model
* @package think
* @mixin Query
* @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件
* @method Query whereRaw(string $where, array $bind = []) static 表达式查询
* @method Query whereExp(string $field, string $condition, array $bind = []) static 字段表达式查询
* @method Query when(mixed $condition, mixed $query, mixed $otherwise = null) static 条件查询
* @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询
* @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询
* @method Query with(mixed $with) static 关联预载入
* @method Query count(string $field) static Count统计查询
* @method Query min(string $field) static Min统计查询
* @method Query max(string $field) static Max统计查询
* @method Query sum(string $field) static SUM统计查询
* @method Query avg(string $field) static Avg统计查询
* @method Query field(mixed $field, boolean $except = false) static 指定查询字段
* @method Query fieldRaw(string $field, array $bind = []) static 指定查询字段
* @method Query union(mixed $union, boolean $all = false) static UNION查询
* @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT
* @method Query order(mixed $field, string $order = null) static 查询ORDER
* @method Query orderRaw(string $field, array $bind = []) static 查询ORDER
* @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存
* @method mixed value(string $field) static 获取某个字段的值
* @method array column(string $field, string $key = '') static 获取某个列的值
* @method mixed find(mixed $data = null) static 查询单个记录
* @method mixed select(mixed $data = null) static 查询多个记录
* @method mixed get(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 支持关联预载入
* @method mixed getOrFail(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则抛出异常
* @method mixed findOrEmpty(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则返回空模型
* @method mixed all(mixed $data = null,mixed $with =[],bool $cache= false) static 查询多个记录 支持关联预载入
* @method \think\Model withAttr(array $name,\Closure $closure) 动态定义获取器
*/
abstract class Model implements \JsonSerializable, \ArrayAccess
......@@ -437,16 +410,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
return $this->exists;
}
/**
* 判断模型是否为空
* @access public
* @return bool
*/
public function isEmpty()
{
return empty($this->data);
}
/**
* 保存当前数据对象
* @access public
......@@ -571,7 +534,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$this->autoRelationUpdate();
}
return true;
return false;
} elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {
// 自动写入更新时间
$data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
......@@ -780,19 +743,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
// 删除条件
$pk = $this->getPk();
$where = [];
if (is_string($pk) && isset($this->data[$pk])) {
$where[] = [$pk, '=', $this->data[$pk]];
} elseif (is_array($pk)) {
foreach ($pk as $field) {
if (isset($this->data[$field])) {
$where[] = [$field, '=', $this->data[$field]];
}
}
}
if (empty($where)) {
$where = empty($this->updateWhere) ? null : $this->updateWhere;
} elseif (!empty($this->updateWhere)) {
$where = $this->updateWhere;
} else {
$where = null;
}
return $where;
......
......@@ -682,7 +682,6 @@ class Request
// 判断URL里面是否有兼容模式参数
$pathinfo = $_GET[$this->config['var_pathinfo']];
unset($_GET[$this->config['var_pathinfo']]);
unset($this->get[$this->config['var_pathinfo']]);
} elseif ($this->isCli()) {
// CLI模式下 index.php module/controller/action/params/...
$pathinfo = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
......@@ -703,10 +702,6 @@ class Request
}
}
if (!empty($pathinfo)) {
unset($this->get[$pathinfo], $this->request[$pathinfo]);
}
$this->pathinfo = empty($pathinfo) || '/' == $pathinfo ? '' : ltrim($pathinfo, '/');
}
......@@ -814,14 +809,9 @@ class Request
return $this->server('REQUEST_METHOD') ?: 'GET';
} elseif (!$this->method) {
if (isset($_POST[$this->config['var_method']])) {
$method = strtolower($_POST[$this->config['var_method']]);
if (in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) {
$this->method = strtoupper($method);
$this->{$method} = $_POST;
} else {
$this->method = 'POST';
}
unset($_POST[$this->config['var_method']]);
$this->method = strtoupper($_POST[$this->config['var_method']]);
$method = strtolower($this->method);
$this->{$method} = $_POST;
} elseif ($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')) {
$this->method = strtoupper($this->server('HTTP_X_HTTP_METHOD_OVERRIDE'));
} else {
......@@ -1044,7 +1034,7 @@ class Request
protected function getInputData($content)
{
if (false !== strpos($this->contentType(), 'json')) {
if (false !== strpos($this->contentType(), 'application/json') || 0 === strpos($content, '{"')) {
return (array) json_decode($content, true);
} elseif (strpos($content, '=')) {
parse_str($content, $data);
......@@ -1330,8 +1320,7 @@ class Request
* @param array $data 数据源
* @return void
*/
public function arrayReset(array &$data)
{
public function arrayReset(array &$data) {
foreach ($data as &$value) {
if (is_array($value)) {
$this->arrayReset($value);
......@@ -1534,7 +1523,7 @@ class Request
*/
public function has($name, $type = 'param', $checkEmpty = false)
{
if (!in_array($type, ['param', 'get', 'post', 'request', 'put', 'patch', 'file', 'session', 'cookie', 'env', 'header', 'route'])) {
if (!in_array($type, ['param', 'get', 'post', 'request', 'put', 'file', 'session', 'cookie', 'env', 'header', 'route'])) {
return false;
}
......@@ -1636,16 +1625,6 @@ class Request
return false;
}
/**
* 当前是否JSON请求
* @access public
* @return bool
*/
public function isJson()
{
return false !== strpos($this->type(), 'json');
}
/**
* 当前是否Ajax请求
* @access public
......
......@@ -408,7 +408,7 @@ class Route
$result = $this->bind[$domain];
} elseif (isset($name) && isset($this->bind[$name])) {
$result = $this->bind[$name];
} elseif (!empty($subDomain) && isset($this->bind['*'])) {
} elseif (isset($this->bind['*'])) {
$result = $this->bind['*'];
} else {
$result = null;
......
......@@ -1311,7 +1311,7 @@ class Template
public function __debugInfo()
{
$data = get_object_vars($this);
unset($data['app'], $data['storage']);
unset($data['app'], $data['storege']);
return $data;
}
......
......@@ -130,9 +130,7 @@ class Url
// 匹配路由命名标识
$url = $match[0];
if ($domain) {
$domain = $match[1];
}
$domain = $match[1];
if (!is_null($match[2])) {
$suffix = $match[2];
......@@ -349,7 +347,6 @@ class Url
// 匹配路由地址
public function getRuleUrl($rule, &$vars = [], $allowDomain = '')
{
$port = $this->app['request']->port();
foreach ($rule as $item) {
list($url, $pattern, $domain, $suffix, $method) = $item;
......@@ -357,8 +354,8 @@ class Url
continue;
}
if ($port && !in_array($port, [80, 443])) {
$domain .= ':' . $port;
if (!in_array($this->app['request']->port(), [80, 443])) {
$domain .= ':' . $this->app['request']->port();
}
if (empty($pattern)) {
......
......@@ -131,7 +131,7 @@ class Validate
* 内置正则验证规则
* @var array
*/
protected $defaultRegex = [
protected $regex = [
'alphaDash' => '/^[A-Za-z0-9\-\_]+$/',
'chs' => '/^[\x{4e00}-\x{9fa5}]+$/u',
'chsAlpha' => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u',
......@@ -178,12 +178,6 @@ class Validate
*/
protected $append = [];
/**
* 验证正则定义
* @var array
*/
protected $regex = [];
/**
* 架构函数
* @access public
......@@ -519,7 +513,7 @@ class Validate
if (isset($this->append[$field])) {
// 追加额外的验证规则
$rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR);
$rules = array_merge($rules, $this->append[$field]);
}
$i = 0;
......@@ -567,11 +561,10 @@ class Validate
} elseif (true !== $result) {
// 返回自定义错误信息
if (is_string($result) && false !== strpos($result, ':')) {
$result = str_replace(':attribute', $title, $result);
if (strpos($result, ':rule') && is_scalar($rule)) {
$result = str_replace(':rule', (string) $rule, $result);
}
$result = str_replace(
[':attribute', ':rule'],
[$title, (string) $rule],
$result);
}
return $result;
......@@ -934,8 +927,8 @@ class Validate
if (isset($rule[2])) {
$imageType = strtolower($rule[2]);
if ('jpg' == $imageType) {
$imageType = 'jpeg';
if ('jpeg' == $imageType) {
$imageType = 'jpg';
}
if (image_type_to_extension($type, false) != $imageType) {
......@@ -1013,8 +1006,6 @@ class Validate
$map[] = [$key, '=', $data[$key]];
}
}
} elseif (strpos($key, '=')) {
parse_str($key, $map);
} elseif (isset($data[$field])) {
$map[] = [$key, '=', $data[$field]];
} else {
......@@ -1369,8 +1360,6 @@ class Validate
{
if (isset($this->regex[$rule])) {
$rule = $this->regex[$rule];
} elseif (isset($this->defaultRegex[$rule])) {
$rule = $this->defaultRegex[$rule];
}
if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) {
......@@ -1472,17 +1461,13 @@ class Validate
$msg = $title . $lang->get('not conform to the rules');
}
if (!is_string($msg)) {
return $msg;
}
if (0 === strpos($msg, '{%')) {
if (is_string($msg) && 0 === strpos($msg, '{%')) {
$msg = $lang->get(substr($msg, 2, -1));
} elseif ($lang->has($msg)) {
$msg = $lang->get($msg);
}
if (is_scalar($rule) && false !== strpos($msg, ':')) {
if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) {
// 变量替换
if (is_string($rule) && strpos($rule, ',')) {
$array = array_pad(explode(',', $rule), 3, '');
......@@ -1490,12 +1475,9 @@ class Validate
$array = array_pad([], 3, '');
}
$msg = str_replace(
[':attribute', ':1', ':2', ':3'],
[$title, $array[0], $array[1], $array[2]],
[':attribute', ':rule', ':1', ':2', ':3'],
[$title, (string) $rule, $array[0], $array[1], $array[2]],
$msg);
if (strpos($msg, ':rule')) {
$msg = str_replace(':rule', (string) $rule, $msg);
}
}
return $msg;
......@@ -1514,12 +1496,12 @@ class Validate
$scene = $this->currentScene;
}
$this->only = $this->append = $this->remove = [];
if (empty($scene)) {
return;
}
$this->only = $this->append = $this->remove = [];
if (method_exists($this, 'scene' . $scene)) {
call_user_func([$this, 'scene' . $scene]);
} elseif (isset($this->scene[$scene])) {
......
......@@ -160,10 +160,7 @@ class View
*/
public function filter($filter)
{
if ($filter) {
$this->filter = $filter;
}
$this->filter = $filter;
return $this;
}
......
......@@ -249,6 +249,7 @@ abstract class Driver
{
if ($this->tag) {
$key = $this->getTagkey($this->tag);
$prev = $this->tag;
$this->tag = null;
if ($this->has($key)) {
......@@ -265,6 +266,7 @@ abstract class Driver
}
$this->set($key, $value, 0);
$this->tag = $prev;
}
}
......@@ -358,9 +360,4 @@ abstract class Driver
{
return $this->writeTimes;
}
public function __call($method, $args)
{
return call_user_func_array([$this->handler, $method], $args);
}
}
......@@ -278,13 +278,11 @@ class File extends Driver
if (is_dir($path)) {
$matches = glob($path . DIRECTORY_SEPARATOR . '*.php');
if (is_array($matches)) {
array_map(function ($v) {
$this->unlink($v);
}, $matches);
array_map('unlink', $matches);
}
rmdir($path);
} else {
$this->unlink($path);
unlink($path);
}
}
......
......@@ -67,7 +67,7 @@ class Memcached extends Driver
}
$this->handler->addServers($servers);
$this->handler->setOption(\Memcached::OPT_COMPRESSION, false);
if ('' != $this->options['username']) {
$this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$this->handler->setSaslAuthData($this->options['username'], $this->options['password']);
......@@ -232,7 +232,7 @@ class Memcached extends Driver
$this->handler->delete($tagName);
}
if (!$this->has($tagName)) {
if (!$this->handler->has($tagName)) {
$this->handler->set($tagName, '');
}
......@@ -255,7 +255,7 @@ class Memcached extends Driver
if ($this->tag) {
$tagName = $this->getTagKey($this->tag);
if ($this->has($tagName)) {
if ($this->handler->has($tagName)) {
$this->handler->append($tagName, ',' . $name);
} else {
$this->handler->set($tagName, $name);
......
......@@ -313,10 +313,9 @@ abstract class Builder
// 使用闭包查询
$newQuery = $query->newQuery()->setConnection($this->connection);
$value($newQuery);
$whereClause = $this->buildWhere($newQuery, $newQuery->getOptions('where'));
$whereClause = $this->buildWhere($query, $newQuery->getOptions('where'));
if (!empty($whereClause)) {
$query->bind($newQuery->getBind(false));
$str[] = ' ' . $logic . ' ( ' . $whereClause . ' )';
}
} elseif (is_array($field)) {
......@@ -408,7 +407,7 @@ abstract class Builder
$jsonType = $query->getJsonFieldType($field);
$bindType = $this->connection->getFieldBindType($jsonType);
} else {
$bindType = isset($binds[$field]) && 'LIKE' != $exp ? $binds[$field] : PDO::PARAM_STR;
$bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
}
if (is_scalar($value) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
......@@ -451,11 +450,11 @@ abstract class Builder
// 模糊匹配
if (is_array($value)) {
foreach ($value as $item) {
$name = $query->bind($item, PDO::PARAM_STR);
$name = $query->bind($item, $bindType);
$array[] = $key . ' ' . $exp . ' :' . $name;
}
$whereStr = '(' . implode(' ' . strtoupper($logic) . ' ', $array) . ')';
$whereStr = '(' . implode($array, ' ' . strtoupper($logic) . ' ') . ')';
} else {
$whereStr = $key . ' ' . $exp . ' ' . $value;
}
......@@ -605,10 +604,6 @@ abstract class Builder
$value = $this->parseClosure($query, $value);
}
if ('=' == $exp && is_null($value)) {
return $key . ' IS NULL';
}
return $key . ' ' . $exp . ' ' . $value;
}
......@@ -652,10 +647,9 @@ abstract class Builder
// IN 查询
if ($value instanceof \Closure) {
$value = $this->parseClosure($query, $value, false);
} elseif ($value instanceof Expression) {
$value = $value->getValue();
} else {
$value = array_unique(is_array($value) ? $value : explode(',', $value));
$array = [];
foreach ($value as $k => $v) {
......@@ -663,12 +657,9 @@ abstract class Builder
$array[] = ':' . $name;
}
if (count($array) == 1) {
return $key . ('IN' == $exp ? ' = ' : ' <> ') . $array[0];
} else {
$zone = implode(',', $array);
$value = empty($zone) ? "''" : $zone;
}
$zone = implode(',', $array);
$value = empty($zone) ? "''" : $zone;
}
return $key . ' ' . $exp . ' (' . $value . ')';
......
......@@ -1246,24 +1246,13 @@ abstract class Connection
* @access public
* @param Query $query 查询对象
* @param string $field 字段名
* @param mixed $default 默认值
* @param bool $one 是否返回一个值
* @param bool $default 默认值
* @return mixed
*/
public function value(Query $query, $field, $default = null, $one = true)
public function value(Query $query, $field, $default = null)
{
$options = $query->getOptions();
if (isset($options['field'])) {
$query->removeOption('field');
}
if (is_string($field)) {
$field = array_map('trim', explode(',', $field));
}
$query->setOption('field', $field);
if (empty($options['fetch_sql']) && !empty($options['cache'])) {
$cache = $options['cache'];
$result = $this->getCacheData($query, $cache, null, $key);
......@@ -1273,10 +1262,17 @@ abstract class Connection
}
}
if ($one) {
$query->setOption('limit', 1);
if (isset($options['field'])) {
$query->removeOption('field');
}
if (is_string($field)) {
$field = array_map('trim', explode(',', $field));
}
$query->setOption('field', $field);
$query->setOption('limit', 1);
// 生成查询SQL
$sql = $this->builder->select($query);
......@@ -1324,7 +1320,7 @@ abstract class Connection
$field = $aggregate . '(' . (!empty($distinct) ? 'DISTINCT ' : '') . $this->builder->parseKey($query, $field, true) . ') AS tp_' . strtolower($aggregate);
return $this->value($query, $field, 0, false);
return $this->value($query, $field, 0);
}
/**
......@@ -1339,6 +1335,16 @@ abstract class Connection
{
$options = $query->getOptions();
if (empty($options['fetch_sql']) && !empty($options['cache'])) {
// 判断查询缓存
$cache = $options['cache'];
$result = $this->getCacheData($query, $cache, null, $guid);
if (false !== $result) {
return $result;
}
}
if (isset($options['field'])) {
$query->removeOption('field');
}
......@@ -1356,16 +1362,6 @@ abstract class Connection
$query->setOption('field', $field);
if (empty($options['fetch_sql']) && !empty($options['cache'])) {
// 判断查询缓存
$cache = $options['cache'];
$result = $this->getCacheData($query, $cache, null, $guid);
if (false !== $result) {
return $result;
}
}
// 生成查询SQL
$sql = $this->builder->select($query);
......@@ -1467,7 +1463,9 @@ abstract class Connection
$value = is_array($val) ? $val[0] : $val;
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
if ((self::PARAM_FLOAT == $type || PDO::PARAM_STR == $type) && is_string($value)) {
if (self::PARAM_FLOAT == $type) {
$value = (float) $value;
} elseif (PDO::PARAM_STR == $type) {
$value = '\'' . addslashes($value) . '\'';
} elseif (PDO::PARAM_INT == $type && '' === $value) {
$value = 0;
......@@ -1501,7 +1499,7 @@ abstract class Connection
if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {
$val[0] = 0;
} elseif (self::PARAM_FLOAT == $val[1]) {
$val[0] = is_string($val[0]) ? (float) $val[0] : $val[0];
$val[0] = (float) $val[0];
$val[1] = PDO::PARAM_STR;
}
......
......@@ -95,14 +95,14 @@ class Query
* @var array
*/
protected $timeRule = [
'today' => ['today', 'tomorrow -1second'],
'yesterday' => ['yesterday', 'today -1second'],
'week' => ['this week 00:00:00', 'next week 00:00:00 -1second'],
'last week' => ['last week 00:00:00', 'this week 00:00:00 -1second'],
'month' => ['first Day of this month 00:00:00', 'first Day of next month 00:00:00 -1second'],
'last month' => ['first Day of last month 00:00:00', 'first Day of this month 00:00:00 -1second'],
'year' => ['this year 1/1', 'next year 1/1 -1second'],
'last year' => ['last year 1/1', 'this year 1/1 -1second'],
'today' => ['today', 'tomorrow'],
'yesterday' => ['yesterday', 'today'],
'week' => ['this week 00:00:00', 'next week 00:00:00'],
'last week' => ['last week 00:00:00', 'this week 00:00:00'],
'month' => ['first Day of this month 00:00:00', 'first Day of next month 00:00:00'],
'last month' => ['first Day of last month 00:00:00', 'first Day of this month 00:00:00'],
'year' => ['this year 1/1', 'next year 1/1'],
'last year' => ['last year 1/1', 'this year 1/1'],
];
/**
......@@ -133,27 +133,7 @@ class Query
*/
public function newQuery()
{
$query = new static($this->connection);
if ($this->model) {
$query->model($this->model);
}
if (isset($this->options['table'])) {
$query->table($this->options['table']);
} else {
$query->name($this->name);
}
if (isset($this->options['json'])) {
$query->json($this->options['json'], $this->options['json_assoc']);
}
if (isset($this->options['field_type'])) {
$query->setJsonFieldType($this->options['field_type']);
}
return $query;
return new static($this->connection);
}
/**
......@@ -631,9 +611,9 @@ class Query
/**
* 聚合查询
* @access public
* @param string $aggregate 聚合方法
* @param string|Expression $field 字段名
* @param bool $force 强制转为数字类型
* @param string $aggregate 聚合方法
* @param string $field 字段名
* @param bool $force 强制转为数字类型
* @return mixed
*/
public function aggregate($aggregate, $field, $force = false)
......@@ -654,7 +634,7 @@ class Query
/**
* COUNT查询
* @access public
* @param string|Expression $field 字段名
* @param string $field 字段名
* @return float|string
*/
public function count($field = '*')
......@@ -684,7 +664,7 @@ class Query
/**
* SUM查询
* @access public
* @param string|Expression $field 字段名
* @param string $field 字段名
* @return float
*/
public function sum($field)
......@@ -695,8 +675,8 @@ class Query
/**
* MIN查询
* @access public
* @param string|Expression $field 字段名
* @param bool $force 强制转为数字类型
* @param string $field 字段名
* @param bool $force 强制转为数字类型
* @return mixed
*/
public function min($field, $force = true)
......@@ -707,8 +687,8 @@ class Query
/**
* MAX查询
* @access public
* @param string|Expression $field 字段名
* @param bool $force 强制转为数字类型
* @param string $field 字段名
* @param bool $force 强制转为数字类型
* @return mixed
*/
public function max($field, $force = true)
......@@ -719,7 +699,7 @@ class Query
/**
* AVG查询
* @access public
* @param string|Expression $field 字段名
* @param string $field 字段名
* @return float
*/
public function avg($field)
......@@ -854,10 +834,9 @@ class Query
* @param mixed $join 关联的表名
* @param mixed $condition 条件
* @param string $type JOIN类型
* @param array $bind 参数绑定
* @return $this
*/
public function join($join, $condition = null, $type = 'INNER', $bind = [])
public function join($join, $condition = null, $type = 'INNER')
{
if (empty($condition)) {
// 如果为组数,则循环调用join
......@@ -868,9 +847,7 @@ class Query
}
} else {
$table = $this->getJoinTable($join);
if ($bind) {
$this->bindParams($condition, $bind);
}
$this->options['join'][] = [$table, strtoupper($type), $condition];
}
......@@ -882,10 +859,9 @@ class Query
* @access public
* @param mixed $join 关联的表名
* @param mixed $condition 条件
* @param array $bind 参数绑定
* @return $this
*/
public function leftJoin($join, $condition = null, $bind = [])
public function leftJoin($join, $condition = null)
{
return $this->join($join, $condition, 'LEFT');
}
......@@ -895,10 +871,9 @@ class Query
* @access public
* @param mixed $join 关联的表名
* @param mixed $condition 条件
* @param array $bind 参数绑定
* @return $this
*/
public function rightJoin($join, $condition = null, $bind = [])
public function rightJoin($join, $condition = null)
{
return $this->join($join, $condition, 'RIGHT');
}
......@@ -908,10 +883,9 @@ class Query
* @access public
* @param mixed $join 关联的表名
* @param mixed $condition 条件
* @param array $bind 参数绑定
* @return $this
*/
public function fullJoin($join, $condition = null, $bind = [])
public function fullJoin($join, $condition = null)
{
return $this->join($join, $condition, 'FULL');
}
......@@ -969,10 +943,6 @@ class Query
*/
public function union($union, $all = false)
{
if (empty($union)) {
return $this;
}
$this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION';
if (is_array($union)) {
......@@ -1532,7 +1502,6 @@ class Query
{
if ($field instanceof $this) {
$this->options['where'] = $field->getOptions('where');
$this->bind($field->getBind(false));
return $this;
}
......@@ -1548,10 +1517,10 @@ class Query
}
if ($field instanceof Expression) {
return $this->whereRaw($field, is_array($op) ? $op : [], $logic);
return $this->whereRaw($field, is_array($op) ? $op : []);
} elseif ($strict) {
// 使用严格模式查询
$where = [$field, $op, $condition, $logic];
$where = [$field, $op, $condition];
} elseif (is_array($field)) {
// 解析数组批量查询
return $this->parseArrayWhereItems($field, $logic);
......@@ -1559,7 +1528,7 @@ class Query
$where = $field;
} elseif (is_string($field)) {
if (preg_match('/[,=\<\'\"\(\s]/', $field)) {
return $this->whereRaw($field, $op, $logic);
return $this->whereRaw($field, $op);
} elseif (is_string($op) && strtolower($op) == 'exp') {
$bind = isset($param[2]) && is_array($param[2]) ? $param[2] : null;
return $this->whereExp($field, $condition, $bind, $logic);
......@@ -1603,7 +1572,7 @@ class Query
// 字段相等查询
$where = [$field, '=', $op];
}
} elseif (in_array(strtoupper($op), ['EXISTS', 'NOT EXISTS', 'NOTEXISTS'], true)) {
} elseif (in_array(strtoupper($op), ['REGEXP', 'NOT REGEXP', 'EXISTS', 'NOT EXISTS', 'NOTEXISTS'], true)) {
$where = [$field, $op, is_string($condition) ? $this->raw($condition) : $condition];
} else {
$where = $field ? [$field, $op, $condition, isset($param[2]) ? $param[2] : null] : null;
......@@ -1676,7 +1645,6 @@ class Query
{
if (true === $option) {
$this->options = [];
$this->bind = [];
} elseif (is_string($option) && isset($this->options[$option])) {
unset($this->options[$option]);
}
......@@ -2218,12 +2186,12 @@ class Query
}
/**
* 设置需要附加的输出属性
* 设置需要追加输出的属性
* @access public
* @param array $append 属性列表
* @param array $append 需要追加的属性
* @return $this
*/
public function append(array $append = [])
public function append(array $append)
{
$this->options['append'] = $append;
return $this;
......@@ -2490,7 +2458,7 @@ class Query
if (is_array($value)) {
$this->bind = array_merge($this->bind, $value);
} else {
$name = $name ?: 'ThinkBind_' . (count($this->bind) + 1) . '_' . mt_rand() . '_';
$name = $name ?: 'ThinkBind_' . (count($this->bind) + 1) . '_';
$this->bind[$name] = [$value, $type];
return $name;
......@@ -3376,13 +3344,13 @@ class Query
// 输出属性控制
if (!empty($options['visible'])) {
$result->visible($options['visible'], true);
$result->visible($options['visible']);
} elseif (!empty($options['hidden'])) {
$result->hidden($options['hidden'], true);
$result->hidden($options['hidden']);
}
if (!empty($options['append'])) {
$result->append($options['append'], true);
$result->append($options['append']);
}
// 关联查询
......
......@@ -62,7 +62,7 @@ class Mysql extends Builder
$bind = $this->connection->getFieldsBind($options['table']);
foreach ($dataSet as $k => $data) {
$data = $this->parseData($query, $data, $allowFields, $bind);
$data = $this->parseData($query, $data, $allowFields, $bind, '_' . $k);
$values[] = '( ' . implode(',', array_values($data)) . ' )';
......@@ -94,17 +94,13 @@ class Mysql extends Builder
* @param Query $query 查询对象
* @param string $key
* @param string $exp
* @param mixed $value
* @param Expression $value
* @param string $field
* @return string
*/
protected function parseRegexp(Query $query, $key, $exp, $value, $field)
protected function parseRegexp(Query $query, $key, $exp, Expression $value, $field)
{
if ($value instanceof Expression) {
$value = $value->getValue();
}
return $key . ' ' . $exp . ' ' . $value;
return $key . ' ' . $exp . ' ' . $value->getValue();
}
/**
......@@ -129,7 +125,7 @@ class Mysql extends Builder
// JSON字段支持
list($field, $name) = explode('->', $key, 2);
return 'json_extract(' . $this->parseKey($query, $field, true) . ', \'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->', '.', $name) . '\')';
return 'json_extract(' . $this->parseKey($query, $field, true) . ', \'$.' . str_replace('->', '.', $name) . '\')';
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
list($table, $key) = explode('.', $key, 2);
......@@ -149,7 +145,7 @@ class Mysql extends Builder
throw new Exception('not support data:' . $key);
}
if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) {
$key = '`' . $key . '`';
}
......
......@@ -114,7 +114,7 @@ class Sqlsrv extends Builder
throw new Exception('not support data:' . $key);
}
if ('*' != $key && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) {
if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) {
$key = '[' . $key . ']';
}
......
......@@ -136,27 +136,7 @@ class Mysql extends Connection
*/
protected function getExplain($sql)
{
$pdo = $this->linkID->prepare("EXPLAIN " . $this->queryStr);
foreach ($this->bind as $key => $val) {
// 占位符
$param = is_int($key) ? $key + 1 : ':' . $key;
if (is_array($val)) {
if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {
$val[0] = 0;
} elseif (self::PARAM_FLOAT == $val[1]) {
$val[0] = is_string($val[0]) ? (float) $val[0] : $val[0];
$val[1] = PDO::PARAM_STR;
}
$result = $pdo->bindValue($param, $val[0], $val[1]);
} else {
$result = $pdo->bindValue($param, $val);
}
}
$pdo->execute();
$pdo = $this->linkID->query("EXPLAIN " . $sql);
$result = $pdo->fetch(PDO::FETCH_ASSOC);
$result = array_change_key_case($result);
......
......@@ -37,10 +37,6 @@ DECLARE
v_sql varchar;
v_rec RECORD;
v_key varchar;
v_conkey smallint[];
v_pk varchar[];
v_len smallint;
v_pos smallint := 1;
BEGIN
SELECT
pg_class.oid INTO v_oid
......@@ -53,31 +49,6 @@ BEGIN
RETURN;
END IF;
SELECT
pg_constraint.conkey INTO v_conkey
FROM
pg_constraint
INNER JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
INNER JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid
INNER JOIN pg_type ON pg_type.oid = pg_attribute.atttypid
WHERE
pg_class.relname = a_table_name
AND pg_constraint.contype = 'p';
v_len := array_length(v_conkey,1) + 1;
WHILE v_pos < v_len LOOP
SELECT
pg_attribute.attname INTO v_key
FROM pg_constraint
INNER JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
INNER JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = pg_constraint.conkey [ v_conkey[v_pos] ]
INNER JOIN pg_type ON pg_type.oid = pg_attribute.atttypid
WHERE pg_class.relname = a_table_name AND pg_constraint.contype = 'p';
v_pk := array_append(v_pk,v_key);
v_pos := v_pos + 1;
END LOOP;
v_sql='
SELECT
pg_attribute.attname AS fields_name,
......@@ -112,19 +83,12 @@ BEGIN
v_ret.fields_not_null=v_rec.fields_not_null;
v_ret.fields_default=v_rec.fields_default;
v_ret.fields_comment=v_rec.fields_comment;
v_ret.fields_key_name='';
v_len := array_length(v_pk,1) + 1;
v_pos := 1;
WHILE v_pos < v_len LOOP
IF v_rec.fields_name = v_pk[v_pos] THEN
v_ret.fields_key_name=v_pk[v_pos];
EXIT;
END IF;
v_pos := v_pos + 1;
END LOOP;
SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name;
IF FOUND THEN
v_ret.fields_key_name=v_key;
ELSE
v_ret.fields_key_name='';
END IF;
RETURN NEXT v_ret;
END LOOP;
RETURN ;
......
......@@ -26,7 +26,7 @@ class DbException extends Exception
* @param string $sql
* @param int $code
*/
public function __construct($message, array $config = [], $sql = '', $code = 10500)
public function __construct($message, array $config, $sql, $code = 10500)
{
$this->message = $message;
$this->code = $code;
......
......@@ -18,7 +18,7 @@ class ValidateException extends \RuntimeException
public function __construct($error, $code = 0)
{
$this->error = $error;
$this->message = is_array($error) ? implode(PHP_EOL, $error) : $error;
$this->message = is_array($error) ? implode("\n\r", $error) : $error;
$this->code = $code;
}
......
......@@ -16,14 +16,11 @@ use think\Facade;
/**
* @see \think\Config
* @mixin \think\Config
* @method array load(string $file, string $name = '') static 加载配置文件
* @method bool has(string $name) static 检测配置是否存在
* @method array pull(string $name) static 获取一级配置参数
* @method array pull(string $name) static 获取一级配置
* @method mixed get(string $name,mixed $default = null) static 获取配置参数
* @method array set(mixed $name, mixed $value = null) static 设置配置参数
* @method array reset(string $name ='') static 重置配置参数
* @method void remove(string $name = '') static 移除配置
* @method void setYaconf(mixed $yaconf) static 设置开启Yaconf 或者指定配置文件名
* @method mixed set(string $name, mixed $value = null) static 设置配置参数
* @method array reset(string $prefix ='') static 重置配置参数
*/
class Config extends Facade
{
......
......@@ -21,7 +21,6 @@ use think\Facade;
* @method \think\Log record(mixed $msg, string $type = 'info', array $context = []) static 记录日志信息
* @method \think\Log clear() static 清空日志信息
* @method \think\Log key(string $key) static 当前日志记录的授权key
* @method \think\Log close() static 关闭本次请求日志写入
* @method bool check(array $config) static 检查日志写入权限
* @method bool save() static 保存调试信息
* @method void write(mixed $msg, string $type = 'info', bool $force = false) static 实时写入日志信息
......
......@@ -19,7 +19,7 @@ use think\App;
class File
{
protected $config = [
'time_format' => 'c',
'time_format' => ' c ',
'single' => false,
'file_size' => 2097152,
'path' => '',
......@@ -107,13 +107,7 @@ class File
$info['timestamp'] = date($this->config['time_format']);
foreach ($message as $type => $msg) {
$msg = is_array($msg) ? implode(PHP_EOL, $msg) : $msg;
if (PHP_SAPI == 'cli') {
$info['msg'] = $msg;
$info['type'] = $type;
} else {
$info[$type] = $msg;
}
$info[$type] = is_array($msg) ? implode("\r\n", $msg) : $msg;
}
if (PHP_SAPI == 'cli') {
......@@ -146,13 +140,13 @@ class File
}
}
$cli = PHP_SAPI == 'cli' ? '_cli' : '';
if ($this->config['single']) {
$name = is_string($this->config['single']) ? $this->config['single'] : 'single';
$destination = $this->config['path'] . $name . $cli . '.log';
$destination = $this->config['path'] . $name . '.log';
} else {
$cli = PHP_SAPI == 'cli' ? '_cli' : '';
if ($this->config['max_files']) {
$filename = date('Ymd') . $cli . '.log';
} else {
......@@ -178,13 +172,15 @@ class File
if ($this->config['single']) {
$name = is_string($this->config['single']) ? $this->config['single'] : 'single';
$name .= '_' . $type;
} elseif ($this->config['max_files']) {
$name = date('Ymd');
$name = date('Ymd') . '_' . $type . $cli;
} else {
$name = date('d');
$name = date('d') . '_' . $type . $cli;
}
return $path . DIRECTORY_SEPARATOR . $name . '_' . $type . $cli . '.log';
return $path . DIRECTORY_SEPARATOR . $name . '.log';
}
/**
......@@ -212,14 +208,14 @@ class File
protected function parseCliLog($info)
{
if ($this->config['json']) {
$message = json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
$message = json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n";
} else {
$now = $info['timestamp'];
unset($info['timestamp']);
$message = implode(PHP_EOL, $info);
$message = implode("\r\n", $info);
$message = "[{$now}]" . $message . PHP_EOL;
$message = "[{$now}]" . $message . "\r\n";
}
return $message;
......@@ -242,13 +238,13 @@ class File
if ($this->config['json']) {
$info = $requestInfo + $info;
return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n";
}
array_unshift($info, "---------------------------------------------------------------" . PHP_EOL . "\r\n[{$info['timestamp']}] {$requestInfo['ip']} {$requestInfo['method']} {$requestInfo['host']}{$requestInfo['uri']}");
array_unshift($info, "---------------------------------------------------------------\r\n[{$info['timestamp']}] {$requestInfo['ip']} {$requestInfo['method']} {$requestInfo['host']}{$requestInfo['uri']}");
unset($info['timestamp']);
return implode(PHP_EOL, $info) . PHP_EOL;
return implode("\r\n", $info) . "\r\n";
}
protected function getDebugLog(&$info, $append, $apart)
......
......@@ -24,10 +24,8 @@ class Collection extends BaseCollection
*/
public function load($relation)
{
if (!$this->isEmpty()) {
$item = current($this->items);
$item->eagerlyResultSet($this->items, $relation);
}
$item = current($this->items);
$item->eagerlyResultSet($this->items, $relation);
return $this;
}
......
......@@ -58,16 +58,6 @@ abstract class Relation
return $this->query->getModel();
}
/**
* 获取当前的关联模型类的实例
* @access public
* @return Query
*/
public function getQuery()
{
return $this->query;
}
/**
* 设置当前关联为自关联
* @access public
......@@ -139,17 +129,6 @@ abstract class Relation
}
}
/**
* 更新数据
* @access public
* @param array $data 更新数据
* @return integer|string
*/
public function update(array $data = [])
{
return $this->query->update($data);
}
/**
* 删除记录
* @access public
......
......@@ -12,7 +12,6 @@
namespace think\model\concern;
use InvalidArgumentException;
use think\db\Expression;
use think\Exception;
use think\Loader;
use think\model\Relation;
......@@ -327,13 +326,9 @@ trait Attribute
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
if (method_exists($this, $method)) {
$origin = $this->data;
$value = $this->$method($value, array_merge($this->data, $data));
$value = $this->$method($value, array_merge($this->data, $data));
$this->set[$name] = true;
if (is_null($value) && $origin !== $this->data) {
return;
}
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
......@@ -375,7 +370,9 @@ trait Attribute
switch ($type) {
case 'datetime':
case 'date':
$value = $this->formatDateTime('Y-m-d H:i:s.u');
$format = !empty($param) ? $param : $this->dateFormat;
$format .= strpos($format, 'u') || false !== strpos($format, '\\') ? '' : '.u';
$value = $this->formatDateTime($format);
break;
case 'timestamp':
case 'integer':
......@@ -388,7 +385,8 @@ trait Attribute
'date',
'timestamp',
])) {
$value = $this->formatDateTime('Y-m-d H:i:s.u');
$format = strpos($this->dateFormat, 'u') || false !== strpos($this->dateFormat, '\\') ? '' : '.u';
$value = $this->formatDateTime($this->dateFormat . $format);
} else {
$value = time();
}
......@@ -409,10 +407,6 @@ trait Attribute
return;
}
if ($value instanceof Expression) {
return $value;
}
if (is_array($type)) {
list($type, $param) = $type;
} elseif (strpos($type, ':')) {
......@@ -439,8 +433,9 @@ trait Attribute
}
break;
case 'datetime':
$value = is_numeric($value) ? $value : strtotime($value);
$value = $this->formatDateTime('Y-m-d H:i:s.u', $value);
$format = !empty($param) ? $param : $this->dateFormat;
$value = is_numeric($value) ? $value : strtotime($value);
$value = $this->formatDateTime($format, $value);
break;
case 'object':
if (is_object($value)) {
......
......@@ -130,52 +130,34 @@ trait Conversion
*/
public function toArray()
{
$item = [];
$hasVisible = false;
foreach ($this->visible as $key => $val) {
if (is_string($val)) {
if (strpos($val, '.')) {
list($relation, $name) = explode('.', $val);
$this->visible[$relation][] = $name;
} else {
$this->visible[$val] = true;
$hasVisible = true;
}
unset($this->visible[$key]);
}
}
foreach ($this->hidden as $key => $val) {
if (is_string($val)) {
if (strpos($val, '.')) {
list($relation, $name) = explode('.', $val);
$this->hidden[$relation][] = $name;
} else {
$this->hidden[$val] = true;
}
unset($this->hidden[$key]);
}
}
$item = [];
$visible = [];
$hidden = [];
// 合并关联数据
$data = array_merge($this->data, $this->relation);
// 过滤属性
if (!empty($this->visible)) {
$array = $this->parseAttr($this->visible, $visible);
$data = array_intersect_key($data, array_flip($array));
} elseif (!empty($this->hidden)) {
$array = $this->parseAttr($this->hidden, $hidden, false);
$data = array_diff_key($data, array_flip($array));
}
foreach ($data as $key => $val) {
if ($val instanceof Model || $val instanceof ModelCollection) {
// 关联模型对象
if (isset($this->visible[$key]) && is_array($this->visible[$key])) {
$val->visible($this->visible[$key]);
} elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {
$val->hidden($this->hidden[$key]);
if (isset($visible[$key])) {
$val->visible($visible[$key]);
} elseif (isset($hidden[$key])) {
$val->hidden($hidden[$key]);
}
// 关联模型对象
if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {
$item[$key] = $val->toArray();
}
} elseif (isset($this->visible[$key])) {
$item[$key] = $this->getAttr($key);
} elseif (!isset($this->hidden[$key]) && !$hasVisible) {
$item[$key] = $val->toArray();
} else {
// 模型属性
$item[$key] = $this->getAttr($key);
}
}
......@@ -189,12 +171,10 @@ trait Conversion
if (!$relation) {
$relation = $this->getAttr($key);
if ($relation) {
$relation->visible($name);
}
$relation->visible($name);
}
$item[$key] = $relation ? $relation->append($name)->toArray() : [];
$item[$key] = $relation->append($name)->toArray();
} elseif (strpos($name, '.')) {
list($key, $attr) = explode('.', $name);
// 追加关联对象属性
......@@ -202,14 +182,15 @@ trait Conversion
if (!$relation) {
$relation = $this->getAttr($key);
if ($relation) {
$relation->visible([$attr]);
}
$relation->visible([$attr]);
}
$item[$key] = $relation ? $relation->append([$attr])->toArray() : [];
$item[$key] = $relation->append([$attr])->toArray();
} else {
$item[$name] = $this->getAttr($name, $item);
$value = $this->getAttr($name, $item);
if (false !== $value) {
$item[$name] = $value;
}
}
}
}
......@@ -270,4 +251,38 @@ trait Conversion
return $collection;
}
/**
* 解析隐藏及显示属性
* @access protected
* @param array $attrs 属性
* @param array $result 结果集
* @param bool $visible
* @return array
*/
protected function parseAttr($attrs, &$result, $visible = true)
{
$array = [];
foreach ($attrs as $key => $val) {
if (is_array($val)) {
if ($visible) {
$array[] = $key;
}
$result[$key] = $val;
} elseif (strpos($val, '.')) {
list($key, $name) = explode('.', $val);
if ($visible) {
$array[] = $key;
}
$result[$key][] = $name;
} else {
$array[] = $val;
}
}
return $array;
}
}
......@@ -204,7 +204,7 @@ trait RelationShip
$relationResult = $this->$method();
if (isset($withRelationAttr[$relationName])) {
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
$relationResult->withAttr($withRelationAttr[$relationName]);
}
$this->relation[$relation] = $relationResult->getRelation($subRelation, $closure);
......@@ -248,7 +248,7 @@ trait RelationShip
$relationResult = $this->$relation();
if (isset($withRelationAttr[$relationName])) {
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
$relationResult->withAttr($withRelationAttr[$relationName]);
}
$relationResult->eagerlyResultSet($resultSet, $relation, $subRelation, $closure, $join);
......@@ -290,7 +290,7 @@ trait RelationShip
$relationResult = $this->$relation();
if (isset($withRelationAttr[$relationName])) {
$relationResult->getQuery()->withAttr($withRelationAttr[$relationName]);
$relationResult->withAttr($withRelationAttr[$relationName]);
}
$relationResult->eagerlyResult($result, $relation, $subRelation, $closure, $join);
......
......@@ -235,8 +235,7 @@ trait SoftDelete
$field = $this->getDeleteTimeField(true);
if ($field) {
$condition = is_null($this->defaultSoftDelete) ? ['null', ''] : ['=', $this->defaultSoftDelete];
$query->useSoftDelete($field, $condition);
$query->useSoftDelete($field, $this->defaultSoftDelete);
}
}
}
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\Loader;
use think\Model;
......@@ -50,7 +49,7 @@ class BelongsTo extends OneToOne
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -80,7 +79,7 @@ class BelongsTo extends OneToOne
*/
public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*', &$aggregateAlias = '')
{
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -112,7 +111,7 @@ class BelongsTo extends OneToOne
return 0;
}
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -141,17 +140,13 @@ class BelongsTo extends OneToOne
$relation = basename(str_replace('\\', '/', $this->model));
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$softDelete = $this->query->getOptions('soft_delete');
return $this->parent->db()
->alias($model)
->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) {
$query->table([$table => $relation])
->field($relation . '.' . $localKey)
->whereExp($model . '.' . $foreignKey, '=' . $relation . '.' . $localKey)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
});
->whereExp($model . '.' . $foreignKey, '=' . $relation . '.' . $localKey);
});
}
......@@ -172,16 +167,12 @@ class BelongsTo extends OneToOne
$this->getQueryWhere($where, $relation);
}
$fields = $this->getRelationQueryFields($fields, $model);
$softDelete = $this->query->getOptions('soft_delete');
$fields = $this->getRelationQueryFields($fields, $model);
return $this->parent->db()
->alias($model)
->field($fields)
->join([$table => $relation], $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
}
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\Collection;
use think\db\Query;
use think\Exception;
......@@ -167,7 +166,7 @@ class BelongsToMany extends Relation
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -378,7 +377,7 @@ class BelongsToMany extends Relation
$pk = $result->$pk;
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -402,7 +401,7 @@ class BelongsToMany extends Relation
*/
public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*', &$aggregateAlias = '')
{
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -429,7 +428,7 @@ class BelongsToMany extends Relation
protected function eagerlyManyToMany($where, $relation, $subRelation = '', $closure = null)
{
// 预载入关联查询 支持嵌套预载入
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -562,7 +561,6 @@ class BelongsToMany extends Relation
$pivot[$this->foreignKey] = $id;
$this->pivot->replace()
->exists(false)
->data([])
->save($pivot);
$result[] = $this->newPivot($pivot, true);
}
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Loader;
use think\Model;
......@@ -49,7 +48,7 @@ class HasMany extends Relation
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -164,7 +163,7 @@ class HasMany extends Relation
return 0;
}
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
$name = $return;
......@@ -187,7 +186,7 @@ class HasMany extends Relation
*/
public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*', &$aggregateAlias = '')
{
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -195,8 +194,8 @@ class HasMany extends Relation
}
}
return $this->query->alias($aggregate . '_table')
->whereExp($aggregate . '_table.' . $this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->localKey)
return $this->query
->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->localKey)
->fetchSql()
->$aggregate($field);
}
......@@ -217,7 +216,7 @@ class HasMany extends Relation
$this->query->removeWhereField($this->foreignKey);
// 预载入关联查询 支持嵌套预载入
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -267,11 +266,11 @@ class HasMany extends Relation
/**
* 批量保存当前关联数据对象
* @access public
* @param array|\think\Collection $dataSet 数据集
* @param array $dataSet 数据集
* @param boolean $replace 是否自动识别更新和写入
* @return array|false
*/
public function saveAll($dataSet, $replace = true)
public function saveAll(array $dataSet, $replace = true)
{
$result = [];
......@@ -293,18 +292,14 @@ class HasMany extends Relation
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
$table = $this->query->getTable();
$model = basename(str_replace('\\', '/', get_class($this->parent)));
$relation = basename(str_replace('\\', '/', $this->model));
$softDelete = $this->query->getOptions('soft_delete');
$table = $this->query->getTable();
$model = basename(str_replace('\\', '/', get_class($this->parent)));
$relation = basename(str_replace('\\', '/', $this->model));
return $this->parent->db()
->alias($model)
->field($model . '.*')
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->group($relation . '.' . $this->foreignKey)
->having('count(' . $id . ')' . $operator . $count);
}
......@@ -326,17 +321,13 @@ class HasMany extends Relation
$this->getQueryWhere($where, $relation);
}
$fields = $this->getRelationQueryFields($fields, $model);
$softDelete = $this->query->getOptions('soft_delete');
$fields = $this->getRelationQueryFields($fields, $model);
return $this->parent->db()
->alias($model)
->group($model . '.' . $this->localKey)
->field($fields)
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
}
......
......@@ -11,8 +11,8 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Exception;
use think\Loader;
use think\Model;
use think\model\Relation;
......@@ -24,12 +24,6 @@ class HasManyThrough extends Relation
// 中间表模型
protected $through;
/**
* 中间主键
* @var string
*/
protected $throughPk;
/**
* 架构函数
* @access public
......@@ -44,10 +38,9 @@ class HasManyThrough extends Relation
{
$this->parent = $parent;
$this->model = $model;
$this->through = (new $through)->db();
$this->through = $through;
$this->foreignKey = $foreignKey;
$this->throughKey = $throughKey;
$this->throughPk = $this->through->getPk();
$this->localKey = $localKey;
$this->query = (new $model)->db();
}
......@@ -61,7 +54,7 @@ class HasManyThrough extends Relation
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -81,28 +74,7 @@ class HasManyThrough extends Relation
*/
public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')
{
$model = App::parseName(App::classBaseName($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$relation = (new $this->model)->db();
$relationTable = $relation->getTable();
$softDelete = $this->query->getOptions('soft_delete');
if ('*' != $id) {
$id = $relationTable . '.' . $relation->getPk();
}
return $this->parent->db()
->alias($model)
->field($model . '.*')
->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
->join($relationTable, $relationTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk)
->when($softDelete, function ($query) use ($softDelete, $relationTable) {
$query->where($relationTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->group($relationTable . '.' . $this->throughKey)
->having('count(' . $id . ')' . $operator . $count);
return $this->parent;
}
/**
......@@ -114,225 +86,45 @@ class HasManyThrough extends Relation
*/
public function hasWhere($where = [], $fields = null)
{
$model = App::parseName(App::classBaseName($this->parent));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = (new $this->model)->db()->getTable();
if (is_array($where)) {
$this->getQueryWhere($where, $modelTable);
}
$fields = $this->getRelationQueryFields($fields, $model);
$softDelete = $this->query->getOptions('soft_delete');
return $this->parent->db()
->alias($model)
->join($throughTable, $throughTable . '.' . $this->foreignKey . '=' . $model . '.' . $this->localKey)
->join($modelTable, $modelTable . '.' . $throughKey . '=' . $throughTable . '.' . $this->throughPk)
->when($softDelete, function ($query) use ($softDelete, $modelTable) {
$query->where($modelTable . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->group($modelTable . '.' . $this->throughKey)
->where($where)
->field($fields);
throw new Exception('relation not support: hasWhere');
}
/**
* 预载入关联查询(数据集)
* @access protected
* @param array $resultSet 数据集
* @param string $relation 当前关联名
* @param mixed $subRelation 子关联名
* @param Closure $closure 闭包
* 预载入关联查询
* @access public
* @param array $resultSet 数据集
* @param string $relation 当前关联名
* @param string $subRelation 子关联名
* @param \Closure $closure 闭包
* @return void
*/
public function eagerlyResultSet(array &$resultSet, $relation, $subRelation = '', $closure = null)
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$range = [];
foreach ($resultSet as $result) {
// 获取关联外键列表
if (isset($result->$localKey)) {
$range[] = $result->$localKey;
}
}
if (!empty($range)) {
$this->query->removeWhereField($foreignKey);
$data = $this->eagerlyWhere([
[$this->foreignKey, 'in', $range],
], $foreignKey, $relation, $subRelation, $closure);
// 关联属性名
$attr = App::parseName($relation);
// 关联数据封装
foreach ($resultSet as $result) {
$pk = $result->$localKey;
if (!isset($data[$pk])) {
$data[$pk] = [];
}
foreach ($data[$pk] as &$relationModel) {
$relationModel->setParent(clone $result);
}
// 设置关联属性
$result->setRelation($attr, $this->resultSetBuild($data[$pk]));
}
}
}
public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)
{}
/**
* 预载入关联查询(数据)
* @access protected
* @param Model $result 数据对象
* @param string $relation 当前关联名
* @param mixed $subRelation 子关联名
* @param Closure $closure 闭包
* @return void
*/
public function eagerlyResult($result, $relation, $subRelation = '', $closure = null)
{
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$pk = $result->$localKey;
$this->query->removeWhereField($foreignKey);
$data = $this->eagerlyWhere([
[$foreignKey, '=', $pk],
], $foreignKey, $relation, $subRelation, $closure);
// 关联数据封装
if (!isset($data[$pk])) {
$data[$pk] = [];
}
foreach ($data[$pk] as &$relationModel) {
$relationModel->setParent(clone $result);
}
$result->setRelation(App::parseName($relation), $this->resultSetBuild($data[$pk]));
}
/**
* 关联模型预查询
* 预载入关联查询 返回模型对象
* @access public
* @param array $where 关联预查询条件
* @param string $key 关联键名
* @param string $relation 关联名
* @param mixed $subRelation 子关联
* @param Closure $closure
* @return array
* @param Model $result 数据对象
* @param string $relation 当前关联名
* @param string $subRelation 子关联名
* @param \Closure $closure 闭包
* @return void
*/
protected function eagerlyWhere(array $where, $key, $relation, $subRelation = '', $closure = null)
{
// 预载入关联查询 支持嵌套预载入
$throughList = $this->through->where($where)->select();
$keys = $throughList->column($this->throughPk, $this->throughPk);
if ($closure instanceof Closure) {
$closure($this->query);
}
$list = $this->query->where($this->throughKey, 'in', $keys)->select();
// 组装模型数据
$data = [];
$keys = $throughList->column($this->foreignKey, $this->throughPk);
foreach ($list as $set) {
$data[$keys[$set->{$this->throughKey}]][] = $set;
}
return $data;
}
public function eagerlyResult(&$result, $relation, $subRelation, $closure)
{}
/**
* 关联统计
* @access public
* @param Model $result 数据对象
* @param Closure $closure 闭包
* @param string $aggregate 聚合查询方法
* @param string $field 字段
* @param string $name 统计字段别名
* @param Model $result 数据对象
* @param \Closure $closure 闭包
* @param string $aggregate 聚合查询方法
* @param string $field 字段
* @param string $name 统计字段别名
* @return integer
*/
public function relationCount($result, $closure, $aggregate = 'count', $field = '*', &$name = null)
{
$localKey = $this->localKey;
if (!isset($result->$localKey)) {
return 0;
}
if ($closure instanceof Closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
$name = $return;
}
}
$alias = App::parseName(App::classBaseName($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
if (false === strpos($field, '.')) {
$field = $alias . '.' . $field;
}
return $this->query
->alias($alias)
->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey)
->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey)
->where($throughTable . '.' . $this->foreignKey, $result->$localKey)
->$aggregate($field);
}
/**
* 创建关联统计子查询
* @access public
* @param Closure $closure 闭包
* @param string $aggregate 聚合查询方法
* @param string $field 字段
* @param string $name 统计字段别名
* @return string
*/
public function getRelationCountQuery($closure = null, $aggregate = 'count', $field = '*', &$name = null)
{
if ($closure instanceof Closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
$name = $return;
}
}
$alias = App::parseName(App::classBaseName($this->model));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
if (false === strpos($field, '.')) {
$field = $alias . '.' . $field;
}
return $this->query
->alias($alias)
->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey)
->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey)
->whereExp($throughTable . '.' . $this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->localKey)
->fetchSql()
->$aggregate($field);
}
public function relationCount($result, $closure, $aggregate = 'count', $field = '*', &$name = '')
{}
/**
* 执行基础查询(仅执行一次)
......@@ -342,9 +134,10 @@ class HasManyThrough extends Relation
protected function baseQuery()
{
if (empty($this->baseQuery) && $this->parent->getData()) {
$through = $this->through;
$alias = Loader::parseName(basename(str_replace('\\', '/', $this->model)));
$throughTable = $this->through->getTable();
$pk = $this->throughPk;
$throughTable = $through::getTable();
$pk = (new $through)->getPk();
$throughKey = $this->throughKey;
$modelTable = $this->parent->getTable();
$fields = $this->getQueryFields($alias);
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Loader;
use think\Model;
......@@ -51,7 +50,7 @@ class HasOne extends OneToOne
{
$localKey = $this->localKey;
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -80,7 +79,7 @@ class HasOne extends OneToOne
*/
public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*', &$aggregateAlias = '')
{
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -112,7 +111,7 @@ class HasOne extends OneToOne
return 0;
}
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
$name = $return;
......@@ -140,17 +139,13 @@ class HasOne extends OneToOne
$relation = basename(str_replace('\\', '/', $this->model));
$localKey = $this->localKey;
$foreignKey = $this->foreignKey;
$softDelete = $this->query->getOptions('soft_delete');
return $this->parent->db()
->alias($model)
->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) {
$query->table([$table => $relation])
->field($relation . '.' . $foreignKey)
->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
});
->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey);
});
}
......@@ -171,16 +166,12 @@ class HasOne extends OneToOne
$this->getQueryWhere($where, $relation);
}
$fields = $this->getRelationQueryFields($fields, $model);
$softDelete = $this->query->getOptions('soft_delete');
$fields = $this->getRelationQueryFields($fields, $model);
return $this->parent->db()
->alias($model)
->field($fields)
->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType)
->when($softDelete, function ($query) use ($softDelete, $relation) {
$query->where($relation . strstr($softDelete[0], '.'), '=' == $softDelete[1][0] ? $softDelete[1][1] : null);
})
->where($where);
}
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Exception;
use think\Loader;
......@@ -54,7 +53,7 @@ class MorphMany extends Relation
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -198,7 +197,7 @@ class MorphMany extends Relation
return 0;
}
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -225,7 +224,7 @@ class MorphMany extends Relation
*/
public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*', &$aggregateAlias = '')
{
if ($closure instanceof Closure) {
if ($closure) {
$return = $closure($this->query);
if ($return && is_string($return)) {
......@@ -254,7 +253,7 @@ class MorphMany extends Relation
// 预载入关联查询 支持嵌套预载入
$this->query->removeOption('where');
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Exception;
use think\Loader;
......@@ -54,7 +53,7 @@ class MorphOne extends Relation
*/
public function getRelation($subRelation = '', $closure = null)
{
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......@@ -187,7 +186,7 @@ class MorphOne extends Relation
protected function eagerlyMorphToOne($where, $relation, $subRelation = '', $closure = null)
{
// 预载入关联查询 支持嵌套预载入
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
}
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\Exception;
use think\Loader;
use think\Model;
......
......@@ -11,7 +11,6 @@
namespace think\model\relation;
use Closure;
use think\db\Query;
use think\Exception;
use think\Loader;
......@@ -88,7 +87,7 @@ abstract class OneToOne extends Relation
$joinOn = $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey;
}
if ($closure instanceof Closure) {
if ($closure) {
// 执行闭包查询
$closure($query);
// 使用withField指定获取关联的字段,如
......@@ -312,7 +311,7 @@ abstract class OneToOne extends Relation
protected function eagerlyWhere($where, $key, $relation, $subRelation = '', $closure = null)
{
// 预载入关联查询 支持嵌套预载入
if ($closure instanceof Closure) {
if ($closure) {
$closure($this->query);
if ($field = $this->query->getOptions('with_field')) {
......
......@@ -20,7 +20,7 @@ class Download extends Response
protected $name;
protected $mimeType;
protected $isContent = false;
protected $openinBrowser = false;
protected $openinBrower = false;
/**
* 处理数据
* @access protected
......@@ -53,7 +53,7 @@ class Download extends Response
$this->header['Pragma'] = 'public';
$this->header['Content-Type'] = $mimeType ?: 'application/octet-stream';
$this->header['Cache-control'] = 'max-age=' . $this->expire;
$this->header['Content-Disposition'] = $this->openinBrowser ? 'inline' : 'attachment; filename="' . $name . '"';
$this->header['Content-Disposition'] = $this->openinBrower ? 'inline' : 'attachment; filename="' . $name . '"';
$this->header['Content-Length'] = $size;
$this->header['Content-Transfer-Encoding'] = 'binary';
$this->header['Expires'] = gmdate("D, d M Y H:i:s", time() + $this->expire) . ' GMT';
......@@ -138,11 +138,11 @@ class Download extends Response
/**
* 设置是否在浏览器中显示文件
* @access public
* @param bool $openinBrowser 是否在浏览器中显示文件
* @param bool $openinBrower 是否在浏览器中显示文件
* @return $this
*/
public function openinBrowser($openinBrowser) {
$this->openinBrowser = $openinBrowser;
public function openinBrower($openinBrower) {
$this->openinBrower = $openinBrower;
return $this;
}
}
......@@ -87,12 +87,11 @@ class Redirect extends Response
/**
* 记住当前url后跳转
* @access public
* @param string $url 指定记住的url
* @return $this
*/
public function remember($url = null)
public function remember()
{
$this->app['session']->set('redirect_url', $url ?: $this->app['request']->url());
$this->app['session']->set('redirect_url', $this->app['request']->url());
return $this;
}
......
......@@ -18,16 +18,9 @@ class View extends Response
// 输出参数
protected $options = [];
protected $vars = [];
protected $config = [];
protected $filter;
protected $contentType = 'text/html';
/**
* 是否内容渲染
* @var bool
*/
protected $isContent = false;
/**
* 处理数据
* @access protected
......@@ -39,19 +32,7 @@ class View extends Response
// 渲染模板输出
return $this->app['view']
->filter($this->filter)
->fetch($data, $this->vars, $this->config, $this->isContent);
}
/**
* 设置是否为内容渲染
* @access public
* @param bool $content
* @return $this
*/
public function isContent($content = true)
{
$this->isContent = $content;
return $this;
->fetch($data, $this->vars);
}
/**
......@@ -87,12 +68,6 @@ class View extends Response
return $this;
}
public function config($config)
{
$this->config = $config;
return $this;
}
/**
* 视图内容过滤
* @access public
......
......@@ -11,9 +11,9 @@
namespace think\route;
use think\App;
use think\Container;
use think\exception\ValidateException;
use think\App;
use think\Request;
use think\Response;
......@@ -181,10 +181,9 @@ abstract class Dispatch
$response = Response::create($data, $type);
} else {
$data = ob_get_clean();
$content = false === $data ? '' : $data;
$status = '' === $content && $this->request->isJson() ? 204 : 200;
$data = ob_get_clean();
$content = false === $data ? '' : $data;
$status = '' === $content && $this->request->isAjax() ? 204 : 200;
$response = Response::create($content, '', $status);
}
......
......@@ -642,26 +642,17 @@ abstract class Rule
protected function checkCrossDomain($request)
{
if (!empty($this->option['cross_domain'])) {
$header = [
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE',
'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE',
'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With',
];
if (!empty($this->option['header'])) {
$header = array_merge($header, $this->option['header']);
}
if (!isset($header['Access-Control-Allow-Origin'])) {
$httpOrigin = $request->header('origin');
if ($httpOrigin && strpos(config('cookie.domain'), $httpOrigin)) {
$header['Access-Control-Allow-Origin'] = $httpOrigin;
} else {
$header['Access-Control-Allow-Origin'] = '*';
}
}
$this->option['header'] = $header;
if ($request->method(true) == 'OPTIONS') {
......@@ -1010,7 +1001,7 @@ abstract class Rule
}
}
$regex = str_replace(array_unique($match), array_unique($replace), $rule);
$regex = str_replace($match, $replace, $rule);
$regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex);
if (isset($hasSlash)) {
......
......@@ -118,8 +118,8 @@ class RuleGroup extends Rule
*/
public function check($request, $url, $completeMatch = false)
{
// 跨域OPTIONS请求
if ($dispatch = $this->checkCrossDomain($request)) {
// 跨域OPTIONS请求
return $dispatch;
}
......@@ -151,6 +151,10 @@ class RuleGroup extends Rule
$method = strtolower($request->method());
$rules = $this->getMethodRules($method);
if (count($rules) == 0) {
return false;
}
if ($this->parent) {
// 合并分组参数
$this->mergeGroupOptions();
......
......@@ -149,6 +149,11 @@ class RuleItem extends Rule
*/
public function checkRule($request, $url, $match = null, $completeMatch = false)
{
if ($dispatch = $this->checkCrossDomain($request)) {
// 允许跨域
return $dispatch;
}
// 检查参数有效性
if (!$this->checkOption($this->option, $request)) {
return false;
......@@ -164,15 +169,6 @@ class RuleItem extends Rule
}
if (false !== $match) {
if (!empty($option['cross_domain'])) {
if ($dispatch = $this->checkCrossDomain($request)) {
// 允许跨域
return $dispatch;
}
$option['header'] = $this->option['header'];
}
// 检查前置行为
if (isset($option['before']) && false === $this->checkBefore($option['before'])) {
return false;
......
......@@ -12,6 +12,7 @@
namespace think\route\dispatch;
use ReflectionMethod;
use think\Controller;
use think\exception\ClassNotFoundException;
use think\exception\HttpException;
use think\Loader;
......
......@@ -124,7 +124,7 @@ class Redis implements SessionHandlerInterface
*/
public function destroy($sessID)
{
return $this->handler->del($this->config['session_name'] . $sessID) > 0;
return $this->handler->delete($this->config['session_name'] . $sessID) > 0;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册