[更新]ComposerUpdate

This commit is contained in:
Anyon 2018-09-04 09:49:49 +08:00
parent c9a6fa77f0
commit 60883ef259
18 changed files with 372 additions and 133 deletions

View File

@ -704,3 +704,17 @@ if (!function_exists('xml')) {
return Response::create($data, 'xml', $code, $header, $options);
}
}
if (!function_exists('yaconf')) {
/**
* 获取yaconf配置
*
* @param string $name 配置参数名
* @param mixed $default 默认值
* @return mixed
*/
function yaconf($name, $default = null)
{
return Config::yaconf($name, $default);
}
}

View File

@ -20,7 +20,7 @@ use think\route\Dispatch;
*/
class App extends Container
{
const VERSION = '5.1.22';
const VERSION = '5.1.23';
/**
* 当前模块路径

View File

@ -236,7 +236,7 @@ class Build
if ($suffix) {
// 控制器后缀
$controller = substr($controller, 0, -10);
$controller = substr($controller, 0, -strlen($layer));
}
if (strpos($layer, '\\')) {

View File

@ -69,18 +69,6 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return new static(array_merge($this->items, $this->convertToArray($items)));
}
/**
* 比较数组,返回差集
*
* @access public
* @param mixed $items
* @return static
*/
public function diff($items)
{
return new static(array_diff($this->items, $this->convertToArray($items)));
}
/**
* 交换数组中的键和值
*
@ -92,27 +80,108 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return new static(array_flip($this->items));
}
/**
* 按指定键整理数据
*
* @access public
* @param mixed $items 数据
* @param string $indexKey 键名
* @return array
*/
public function dictionary($items = null, &$indexKey = null)
{
if ($items instanceof self || $items instanceof Paginator) {
$items = $items->all();
}
$items = is_null($items) ? $this->items : $items;
if ($items && empty($indexKey)) {
$indexKey = is_array($items[0]) ? 'id' : $items[0]->getPk();
}
if (isset($indexKey) && is_string($indexKey)) {
return array_column($items, null, $indexKey);
}
return $items;
}
/**
* 比较数组,返回差集
*
* @access public
* @param mixed $items 数据
* @param string $indexKey 指定比较的键名
* @return static
*/
public function diff($items, $indexKey = null)
{
if ($this->isEmpty() || is_scalar($this->items[0])) {
return new static(array_diff($this->items, $this->convertToArray($items)));
}
$diff = [];
$dictionary = $this->dictionary($items, $indexKey);
if (is_string($indexKey)) {
foreach ($this->items as $item) {
if (!isset($dictionary[$item[$indexKey]])) {
$diff[] = $item;
}
}
}
return new static($diff);
}
/**
* 比较数组,返回交集
*
* @access public
* @param mixed $items
* @param mixed $items 数据
* @param string $indexKey 指定比较的键名
* @return static
*/
public function intersect($items)
public function intersect($items, $indexKey = null)
{
return new static(array_intersect($this->items, $this->convertToArray($items)));
if ($this->isEmpty() || is_scalar($this->items[0])) {
return new static(array_diff($this->items, $this->convertToArray($items)));
}
$intersect = [];
$dictionary = $this->dictionary($items, $indexKey);
if (is_string($indexKey)) {
foreach ($this->items as $item) {
if (isset($dictionary[$item[$indexKey]])) {
$intersect[] = $item;
}
}
}
return new static($intersect);
}
/**
* 返回数组中所有的键名
*
* @access public
* @return static
* @return array
*/
public function keys()
{
return new static(array_keys($this->items));
$current = current($this->items);
if (is_scalar($current)) {
$array = $this->items;
} elseif (is_array($current)) {
$array = $current;
} else {
$array = $current->toArray();
}
return array_keys($array);
}
/**
@ -234,6 +303,17 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return $this;
}
/**
* 用回调函数处理数组中的元素
* @access public
* @param callable|null $callback
* @return static
*/
public function map(callable $callback)
{
return new static(array_map($callback, $this->items));
}
/**
* 用回调函数过滤数组中的元素
* @access public
@ -344,6 +424,23 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
return new static($items);
}
/**
* 指定字段排序
* @access public
* @param string $field 排序字段
* @param string $order 排序
* @return $this
*/
public function order($field, $order = null)
{
return $this->sort(function ($a, $b) use ($field, $order) {
$fieldA = isset($a[$field]) ? $a[$field] : null;
$fieldB = isset($b[$field]) ? $b[$field] : null;
return 'desc' == strtolower($order) ? strcmp($fieldB, $fieldA) : strcmp($fieldA, $fieldB);
});
}
/**
* 将数组打乱
*

View File

@ -66,10 +66,10 @@ class Config implements \ArrayAccess
/**
* 设置开启Yaconf
* @access public
* @param bool $yaconf 是否使用Yaconf
* @param bool|string $yaconf 是否使用Yaconf
* @return void
*/
public function useYaconf($yaconf)
public function setYaconf($yaconf)
{
$this->yaconf = $yaconf;
}
@ -128,6 +128,41 @@ class Config implements \ArrayAccess
return $this->config;
}
/**
* 获取实际的yaconf配置参数
* @access protected
* @param string $name 配置参数名
* @return string
*/
protected function getYaconfName($name)
{
if ($this->yaconf && is_string($this->yaconf)) {
return $this->yaconf . '.' . $name;
}
return $name;
}
/**
* 获取yaconf配置
* @access public
* @param string $name 配置参数名
* @param mixed $default 默认值
* @return mixed
*/
public function yaconf($name, $default = null)
{
if ($this->yaconf) {
$yaconfName = $this->getYaconfName($name);
if (Yaconf::has($yaconfName)) {
return Yaconf::get($yaconfName);
}
}
return $default;
}
protected function loadFile($file, $name)
{
$name = strtolower($name);
@ -167,10 +202,14 @@ class Config implements \ArrayAccess
{
$name = strtolower($name);
if ($this->yaconf && Yaconf::has($name)) {
$config = Yaconf::get($name);
if ($this->yaconf) {
$yaconfName = $this->getYaconfName($name);
if (Yaconf::has($yaconfName)) {
$config = Yaconf::get($yaconfName);
return isset($this->config[$name]) ? array_merge($this->config[$name], $config) : $config;
}
}
return isset($this->config[$name]) ? $this->config[$name] : [];
}
@ -197,8 +236,12 @@ class Config implements \ArrayAccess
return $this->pull(substr($name, 0, -1));
}
if ($this->yaconf && Yaconf::has($name)) {
return Yaconf::get($name);
if ($this->yaconf) {
$yaconfName = $this->getYaconfName($name);
if (Yaconf::has($yaconfName)) {
return Yaconf::get($yaconfName);
}
}
$name = explode('.', $name);

View File

@ -64,12 +64,15 @@ class Redis extends Driver
} elseif (class_exists('\Predis\Client')) {
$params = [];
foreach ($this->options as $key => $val) {
if (in_array($key, ['aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication'])) {
if (in_array($key, ['aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication', 'parameters'])) {
$params[$key] = $val;
unset($this->options[$key]);
}
}
$this->handler = new \Predis\Client($this->options, $params);
$this->options['prefix'] = '';
} else {
throw new \BadFunctionCallException('not support: redis');
}

View File

@ -57,7 +57,8 @@ class Route extends Command
}
if (Container::get('config')->get('route_annotation')) {
include Container::get('build')->buildRoute();
$suffix = Container::get('config')->get('controller_suffix') || Container::get('config')->get('class_suffix');
include Container::get('build')->buildRoute($suffix);
}
$content = '<?php ' . PHP_EOL . 'return ';

View File

@ -866,11 +866,13 @@ abstract class Builder
$sort = $val;
}
if (false === strpos($key, ')') && false === strpos($key, '#')) {
$sort = strtoupper($sort);
$sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : '';
$array[] = $this->parseKey($query, $key, true) . $sort;
}
}
}
return ' ORDER BY ' . implode(',', $array);
}
@ -1171,7 +1173,6 @@ abstract class Builder
{
$options = $query->getOptions();
$table = $this->parseTable($query, $options['table']);
$data = $this->parseData($query, $options['data']);
if (empty($data)) {

View File

@ -23,6 +23,7 @@ use think\exception\DbException;
use think\exception\PDOException;
use think\Loader;
use think\Model;
use think\model\Collection as ModelCollection;
use think\model\Relation;
use think\model\relation\OneToOne;
use think\Paginator;
@ -1185,6 +1186,19 @@ class Query
return $this;
}
/**
* 设置是否返回数据集对象
* @access public
* @param bool $collection 是否返回数据集对象
* @return $this
*/
public function fetchCollection($collection = true)
{
$this->options['collection'] = $collection;
return $this;
}
/**
* 指定AND查询条件
* @access public
@ -2207,6 +2221,18 @@ class Query
return isset($this->options['field_type'][$field]) ? $this->options['field_type'][$field] : null;
}
/**
* 是否允许返回空数据(或空模型)
* @access public
* @param bool $allowEmpty 是否允许为空
* @return $this
*/
public function allowEmpty($allowEmpty = true)
{
$this->options['allow_empty'] = $allowEmpty;
return $this;
}
/**
* 添加查询范围
* @access public
@ -2247,19 +2273,20 @@ class Query
* @access public
* @param array $fields 搜索字段
* @param array $data 搜索数据
* @param string $prefix 字段前缀标识
* @return $this
*/
public function withSearch(array $fields, array $data = [])
public function withSearch(array $fields, array $data = [], $prefix = '')
{
foreach ($fields as $key => $field) {
if ($field instanceof \Closure) {
$field($this, isset($data[$key]) ? $data[$key] : null, $data);
$field($this, isset($data[$key]) ? $data[$key] : null, $data, $prefix);
} elseif ($this->model) {
// 检测搜索器
$method = 'search' . Loader::parseName($field, 1) . 'Attr';
if (method_exists($this->model, $method)) {
$this->model->$method($this, isset($data[$field]) ? $data[$field] : null, $data);
$this->model->$method($this, isset($data[$field]) ? $data[$field] : null, $data, $prefix);
}
}
}
@ -2935,10 +2962,34 @@ class Query
return $resultSet;
}
// 返回结果处理
if (!empty($this->options['fail']) && count($resultSet) == 0) {
$this->throwNotFound($this->options);
}
// 数据列表读取后的处理
if (!empty($this->model)) {
// 生成模型对象
if (count($resultSet) > 0) {
$resultSet = $this->resultSetToModelCollection($resultSet);
} else {
$this->resultSet($resultSet);
}
return $resultSet;
}
/**
* 查询数据转换为模型数据集对象
* @access protected
* @param array $resultSet 数据集
* @return ModelCollection
*/
protected function resultSetToModelCollection(array $resultSet)
{
if (empty($resultSet)) {
return $this->model->toCollection([]);
}
// 检查动态获取器
if (!empty($this->options['with_attr'])) {
foreach ($this->options['with_attr'] as $name => $val) {
@ -2969,25 +3020,7 @@ class Query
}
// 模型数据集转换
$resultSet = $result->toCollection($resultSet);
} else {
$resultSet = $this->model->toCollection($resultSet);
}
} else {
$this->resultSet($resultSet);
if ('collection' == $this->connection->getConfig('resultset_type')) {
// 返回Collection对象
$resultSet = new Collection($resultSet);
}
}
// 返回结果处理
if (!empty($this->options['fail']) && count($resultSet) == 0) {
$this->throwNotFound($this->options);
}
return $resultSet;
return $result->toCollection($resultSet);
}
/**
@ -3009,6 +3042,11 @@ class Query
$this->getResultAttr($result, $this->options['with_attr']);
}
}
if (!empty($this->options['collection']) || 'collection' == $this->connection->getConfig('resultset_type')) {
// 返回Collection对象
$resultSet = new Collection($resultSet);
}
}
/**
@ -3044,21 +3082,42 @@ class Query
return $result;
}
$this->removeOption('limit');
// 数据处理
if (!empty($result)) {
if (empty($result)) {
return $this->resultToEmpty();
}
if (!empty($this->model)) {
// 返回模型对象
$this->resultToModel($result, $this->options);
} else {
$this->result($result);
}
} elseif (!empty($this->options['fail'])) {
$this->throwNotFound($this->options);
}
return $result;
}
/**
* 处理空数据
* @access protected
* @return array|Model|null
* @throws DbException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
protected function resultToEmpty()
{
if (!empty($this->options['allow_empty'])) {
return !empty($this->model) ? $this->model->newInstance([], $this->getModelUpdateCondition($this->options)) : [];
} elseif (!empty($this->options['fail'])) {
$this->throwNotFound($this->options);
} else {
return;
}
}
/**
* 查找单条记录
* @access public
@ -3335,6 +3394,20 @@ class Query
return $this->failException(true)->find($data);
}
/**
* 查找单条记录 如果不存在则抛出异常
* @access public
* @param array|string|Query|\Closure $data
* @return array|\PDOStatement|string|Model
* @throws DbException
* @throws ModelNotFoundException
* @throws DataNotFoundException
*/
public function findOrEmpty($data = null)
{
return $this->allowEmpty(true)->find($data);
}
/**
* 分批数据返回处理
* @access public

View File

@ -15,10 +15,11 @@ class ValidateException extends \RuntimeException
{
protected $error;
public function __construct($error)
public function __construct($error, $code = 0)
{
$this->error = $error;
$this->message = is_array($error) ? implode("\n\r", $error) : $error;
$this->code = $code;
}
/**

View File

@ -16,18 +16,6 @@ use think\Model;
class Collection extends BaseCollection
{
/**
* 返回数组中指定的一列
* @access public
* @param string $column_key
* @param string|null $index_key
* @return array
*/
public function column($column_key, $index_key = null)
{
return array_column($this->toArray(), $column_key, $index_key);
}
/**
* 延迟预载入关联查询
* @access public

View File

@ -112,6 +112,21 @@ trait Attribute
return false;
}
/**
* 获取模型对象的主键值
* @access public
* @return integer
*/
public function getKey()
{
$pk = $this->getPk();
if (is_string($pk) && array_key_exists($pk, $this->data)) {
return $this->data[$pk];
}
return;
}
/**
* 设置允许写入的字段
* @access public

View File

@ -97,6 +97,7 @@ trait SoftDelete
return false;
}
$force = $force ?: $this->isForce();
$name = $this->getDeleteTimeField();
if ($name && !$force) {

View File

@ -108,10 +108,12 @@ class Redis implements SessionHandlerInterface
public function write($sessID, $sessData)
{
if ($this->config['expire'] > 0) {
return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData);
$result = $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData);
} else {
return $this->handler->set($this->config['session_name'] . $sessID, $sessData);
$result = $this->handler->set($this->config['session_name'] . $sessID, $sessData);
}
return $result ? true : false;
}
/**

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52::getLoader();
return ComposerAutoloaderInit1fe0085f96d2ca8d2e2a2e50651b591c::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52
class ComposerAutoloaderInit1fe0085f96d2ca8d2e2a2e50651b591c
{
private static $loader;
@ -19,15 +19,15 @@ class ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit1fe0085f96d2ca8d2e2a2e50651b591c', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit1fe0085f96d2ca8d2e2a2e50651b591c', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit8153982cf21eec76f214c39086ebcf52::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@ -48,19 +48,19 @@ class ComposerAutoloaderInit8153982cf21eec76f214c39086ebcf52
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$files;
$includeFiles = Composer\Autoload\ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire8153982cf21eec76f214c39086ebcf52($fileIdentifier, $file);
composerRequire1fe0085f96d2ca8d2e2a2e50651b591c($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire8153982cf21eec76f214c39086ebcf52($fileIdentifier, $file)
function composerRequire1fe0085f96d2ca8d2e2a2e50651b591c($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit8153982cf21eec76f214c39086ebcf52
class ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c
{
public static $files = array (
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
@ -303,9 +303,9 @@ class ComposerStaticInit8153982cf21eec76f214c39086ebcf52
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit8153982cf21eec76f214c39086ebcf52::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1fe0085f96d2ca8d2e2a2e50651b591c::$classMap;
}, null, ClassLoader::class);
}

View File

@ -50,17 +50,17 @@
},
{
"name": "topthink/framework",
"version": "v5.1.22",
"version_normalized": "5.1.22.0",
"version": "v5.1.23",
"version_normalized": "5.1.23.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "35e9878a6ba06257502c5ba664d8e3407012ad00"
"reference": "7b7f1b6b23897e7f0c7a98a56e61723a61fa27ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/35e9878a6ba06257502c5ba664d8e3407012ad00",
"reference": "35e9878a6ba06257502c5ba664d8e3407012ad00",
"url": "https://api.github.com/repos/top-think/framework/zipball/7b7f1b6b23897e7f0c7a98a56e61723a61fa27ce",
"reference": "7b7f1b6b23897e7f0c7a98a56e61723a61fa27ce",
"shasum": "",
"mirrors": [
{
@ -82,7 +82,7 @@
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "2.*"
},
"time": "2018-08-09T06:04:18+00:00",
"time": "2018-08-24T07:25:03+00:00",
"type": "think-framework",
"installation-source": "dist",
"notification-url": "https://packagist.org/downloads/",
@ -215,8 +215,8 @@
},
{
"name": "symfony/options-resolver",
"version": "v3.4.14",
"version_normalized": "3.4.14.0",
"version": "v3.4.15",
"version_normalized": "3.4.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",