From f5dffb2b7963c345bcc79fe8f18023d44c38ab15 Mon Sep 17 00:00:00 2001 From: Anyon Date: Mon, 8 Oct 2018 11:38:14 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=9B=B4=E6=96=B0]ComposerUpdate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- thinkphp/LICENSE.txt | 2 +- thinkphp/library/think/App.php | 11 +- thinkphp/library/think/Config.php | 4 +- thinkphp/library/think/Console.php | 10 -- thinkphp/library/think/Controller.php | 30 +++- thinkphp/library/think/Hook.php | 8 - thinkphp/library/think/Log.php | 6 + thinkphp/library/think/Route.php | 11 ++ thinkphp/library/think/db/Builder.php | 144 ++++++------------ thinkphp/library/think/db/Connection.php | 31 ++-- thinkphp/library/think/db/Query.php | 60 ++++---- thinkphp/library/think/db/Where.php | 3 +- thinkphp/library/think/log/driver/File.php | 19 ++- thinkphp/library/think/log/driver/Socket.php | 4 +- .../think/model/relation/BelongsTo.php | 20 +++ .../library/think/model/relation/HasOne.php | 20 +++ .../think/model/relation/MorphMany.php | 2 +- thinkphp/library/think/response/Redirect.php | 5 +- thinkphp/library/think/route/AliasRule.php | 5 + thinkphp/library/think/route/RuleGroup.php | 18 +++ thinkphp/library/think/route/RuleName.php | 10 ++ vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 14 +- vendor/composer/autoload_static.php | 8 +- vendor/composer/installed.json | 36 ++--- .../options-resolver/OptionsResolver.php | 90 +++-------- .../WeChat/Contracts/BasicWeChat.php | 19 +++ .../wechat-developer/WeChat/Custom.php | 16 +- .../wechat-developer/WePay/Refund.php | 25 +++ 29 files changed, 336 insertions(+), 297 deletions(-) diff --git a/thinkphp/LICENSE.txt b/thinkphp/LICENSE.txt index 574a39c40..774fa76fd 100644 --- a/thinkphp/LICENSE.txt +++ b/thinkphp/LICENSE.txt @@ -1,6 +1,6 @@ ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 -版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) All rights reserved。 ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index 9c5e3bd82..27f3251f3 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -20,7 +20,7 @@ use think\route\Dispatch; */ class App extends Container { - const VERSION = '5.1.24'; + const VERSION = '5.1.25'; /** * 当前模块路径 @@ -606,14 +606,9 @@ class App extends Container if (!empty($routeKey)) { try { if ($option) { - $this->cache - ->connect($option) - ->tag('route_cache') - ->set($routeKey, $dispatch); + $this->cache->connect($option)->tag('route_cache')->set($routeKey, $dispatch); } else { - $this->cache - ->tag('route_cache') - ->set($routeKey, $dispatch); + $this->cache->tag('route_cache')->set($routeKey, $dispatch); } } catch (\Exception $e) { // 存在闭包的时候缓存无效 diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php index afef6a987..5cf0df169 100644 --- a/thinkphp/library/think/Config.php +++ b/thinkphp/library/think/Config.php @@ -71,7 +71,9 @@ class Config implements \ArrayAccess */ public function setYaconf($yaconf) { - $this->yaconf = $yaconf; + if ($this->yaconf) { + $this->yaconf = $yaconf; + } } /** diff --git a/thinkphp/library/think/Console.php b/thinkphp/library/think/Console.php index 3a51f9f6d..d12129072 100644 --- a/thinkphp/library/think/Console.php +++ b/thinkphp/library/think/Console.php @@ -573,16 +573,6 @@ class Console throw new \InvalidArgumentException($message); } - if (count($commands) > 1) { - $commandList = $this->commands; - - $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { - $commandName = $commandList[$nameOrAlias]->getName(); - - return $commandName === $nameOrAlias || !in_array($commandName, $commands); - }); - } - $exact = in_array($name, $commands, true); if (count($commands) > 1 && !$exact) { $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php index 8edab8c67..e0966eb27 100644 --- a/thinkphp/library/think/Controller.php +++ b/thinkphp/library/think/Controller.php @@ -71,9 +71,21 @@ class Controller if ($this->middleware) { foreach ($this->middleware as $key => $val) { if (!is_int($key)) { - if (isset($val['only']) && !in_array($this->request->action(), $val['only'])) { + $only = $except = null; + + if (isset($val['only'])) { + $only = array_map(function ($item) { + return strtolower($item); + }, $val['only']); + } elseif (isset($val['except'])) { + $except = array_map(function ($item) { + return strtolower($item); + }, $val['except']); + } + + if (isset($only) && !in_array($this->request->action(), $only)) { continue; - } elseif (isset($val['except']) && in_array($this->request->action(), $val['except'])) { + } elseif (isset($except) && in_array($this->request->action(), $except)) { continue; } else { $val = $key; @@ -108,14 +120,24 @@ class Controller if (is_string($options['only'])) { $options['only'] = explode(',', $options['only']); } - if (!in_array($this->request->action(), $options['only'])) { + + $only = array_map(function ($val) { + return strtolower($val); + }, $options['only']); + + if (!in_array($this->request->action(), $only)) { return; } } elseif (isset($options['except'])) { if (is_string($options['except'])) { $options['except'] = explode(',', $options['except']); } - if (in_array($this->request->action(), $options['except'])) { + + $except = array_map(function ($val) { + return strtolower($val); + }, $options['except']); + + if (in_array($this->request->action(), $except)) { return; } } diff --git a/thinkphp/library/think/Hook.php b/thinkphp/library/think/Hook.php index b46684a58..b7e83deb7 100644 --- a/thinkphp/library/think/Hook.php +++ b/thinkphp/library/think/Hook.php @@ -187,8 +187,6 @@ class Hook */ protected function execTag($class, $tag = '', $params = null) { - $this->app->isDebug() && $this->app['debug']->remark('behavior_start', 'time'); - $method = Loader::parseName($tag, 1, false); if ($class instanceof \Closure) { @@ -209,12 +207,6 @@ class Hook $result = $this->app->invoke($call, [$params]); - if ($this->app->isDebug()) { - $debug = $this->app['debug']; - $debug->remark('behavior_end', 'time'); - $this->app->log('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . $debug->getRangeTime('behavior_start', 'behavior_end') . 's ]'); - } - return $result; } diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php index 351aae741..70c7bb9a5 100644 --- a/thinkphp/library/think/Log.php +++ b/thinkphp/library/think/Log.php @@ -211,12 +211,18 @@ class Log implements LoggerInterface if (!$this->app->isDebug() && isset($log['debug'])) { unset($log['debug']); } + + foreach ($log as $level => $info) { + $this->app['hook']->listen('log_level', [$level, $info]); + } } else { // 记录允许级别 $log = []; foreach ($this->config['level'] as $level) { if (isset($this->log[$level])) { $log[$level] = $this->log[$level]; + // 监听log_level + $this->app['hook']->listen('log_level', [$level, $log[$level]]); } } } diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index 933168bf4..ed66c51d0 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -957,6 +957,17 @@ class Route return $item; } + /** + * 清空路由规则 + * @access public + * @return void + */ + public function clear() + { + $this->app['rule_name']->clear(); + $this->group->clear(); + } + /** * 设置全局的路由分组参数 * @access public diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 12b9c780e..507cda98a 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -87,10 +87,9 @@ abstract class Builder * @param array $data 数据 * @param array $fields 字段信息 * @param array $bind 参数绑定 - * @param string $suffix 参数绑定后缀 * @return array */ - protected function parseData(Query $query, $data = [], $fields = [], $bind = [], $suffix = '') + protected function parseData(Query $query, $data = [], $fields = [], $bind = []) { if (empty($data)) { return []; @@ -120,7 +119,7 @@ abstract class Builder $result[$item] = $val->getValue(); continue; } elseif (!is_scalar($val) && (in_array($key, (array) $query->getOptions('json')) || 'json' == $this->connection->getFieldsType($options['table'], $key))) { - $val = json_encode($val); + $val = json_encode($val, JSON_UNESCAPED_UNICODE); } elseif (is_object($val) && method_exists($val, '__toString')) { // 对象数据写入 $val = $val->__toString(); @@ -129,7 +128,7 @@ abstract class Builder if (false !== strpos($key, '->')) { list($key, $name) = explode('->', $key); $item = $this->parseKey($query, $key); - $result[$item] = 'json_set(' . $item . ', \'$.' . $name . '\', ' . $this->parseDataBind($query, $key, $val, $bind, $suffix) . ')'; + $result[$item] = 'json_set(' . $item . ', \'$.' . $name . '\', ' . $this->parseDataBind($query, $key, $val, $bind) . ')'; } elseif (false === strpos($key, '.') && !in_array($key, $fields, true)) { if ($options['strict']) { throw new Exception('fields not exists:[' . $key . ']'); @@ -149,7 +148,7 @@ abstract class Builder } } elseif (is_scalar($val)) { // 过滤非标量数据 - $result[$item] = $this->parseDataBind($query, $key, $val, $bind, $suffix); + $result[$item] = $this->parseDataBind($query, $key, $val, $bind); } } @@ -163,22 +162,17 @@ abstract class Builder * @param string $key 字段名 * @param mixed $data 数据 * @param array $bind 绑定数据 - * @param string $suffix 绑定后缀 * @return string */ - protected function parseDataBind(Query $query, $key, $data, $bind = [], $suffix = '') + protected function parseDataBind(Query $query, $key, $data, $bind = []) { - // 过滤非标量数据 - if (0 === strpos($data, ':') && $query->isBind(substr($data, 1))) { - return $data; + if ($data instanceof Expression) { + return $data->getValue(); } - $key = str_replace(['.', '->'], '_', $key); - $name = 'data__' . $key . $suffix; + $query->bind($data, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); - $query->bind($name, $data, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); - - return ':' . $name; + return '?'; } /** @@ -362,7 +356,7 @@ abstract class Builder } // where子单元分析 - protected function parseWhereItem(Query $query, $field, $val, $rule = '', $binds = [], $bindName = null) + protected function parseWhereItem(Query $query, $field, $val, $rule = '', $binds = []) { // 字段分析 $key = $field ? $this->parseKey($query, $field, true) : ''; @@ -386,8 +380,7 @@ abstract class Builder } foreach ($val as $k => $item) { - $bindName = 'where_' . str_replace('.', '_', $field) . '_' . $k; - $str[] = $this->parseWhereItem($query, $field, $item, $rule, $binds, $bindName); + $str[] = $this->parseWhereItem($query, $field, $item, $rule, $binds); } return '( ' . implode(' ' . $rule . ' ', $str) . ' )'; @@ -399,13 +392,6 @@ abstract class Builder $exp = $this->exp[$exp]; } - $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field); - - if (preg_match('/\W/', $bindName)) { - // 处理带非单词字符的字段名 - $bindName = md5($bindName); - } - if ($value instanceof Expression) { } elseif (is_object($value) && method_exists($value, '__toString')) { @@ -421,20 +407,14 @@ abstract class Builder } if (is_scalar($value) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) { - if (strpos($value, ':') !== 0 || !$query->isBind(substr($value, 1))) { - if ($query->isBind($bindName)) { - $bindName .= '_' . str_replace('.', '_', uniqid('', true)); - } - - $query->bind($bindName, $value, $bindType); - $value = ':' . $bindName; - } + $query->bind($value, $bindType); + $value = '?'; } // 解析查询表达式 foreach ($this->parser as $fun => $parse) { if (in_array($exp, $parse)) { - $whereStr = $this->$fun($query, $key, $exp, $value, $field, $bindName, $bindType, isset($val[2]) ? $val[2] : 'AND'); + $whereStr = $this->$fun($query, $key, $exp, $value, $field, $bindType, isset($val[2]) ? $val[2] : 'AND'); break; } } @@ -454,19 +434,17 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @param string $logic * @return string */ - protected function parseLike(Query $query, $key, $exp, $value, $field, $bindName, $bindType, $logic) + protected function parseLike(Query $query, $key, $exp, $value, $field, $bindType, $logic) { // 模糊匹配 if (is_array($value)) { - foreach ($value as $k => $item) { - $bindKey = $bindName . '_' . intval($k); - $bind[$bindKey] = [$item, $bindType]; - $array[] = $key . ' ' . $exp . ' :' . $bindKey; + foreach ($value as $item) { + $bind[] = [$item, $bindType]; + $array[] = $key . ' ' . $exp . ' ?'; } $query->bind($bind); @@ -487,11 +465,10 @@ abstract class Builder * @param string $exp * @param array $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseColumn(Query $query, $key, $exp, array $value, $field, $bindName, $bindType) + protected function parseColumn(Query $query, $key, $exp, array $value, $field, $bindType) { // 字段比较查询 list($op, $field2) = $value; @@ -511,11 +488,10 @@ abstract class Builder * @param string $exp * @param Expression $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseExp(Query $query, $key, $exp, Expression $value, $field, $bindName, $bindType) + protected function parseExp(Query $query, $key, $exp, Expression $value, $field, $bindType) { // 表达式查询 return '( ' . $key . ' ' . $value->getValue() . ' )'; @@ -529,11 +505,10 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseNull(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseNull(Query $query, $key, $exp, $value, $field, $bindType) { // NULL 查询 return $key . ' IS ' . $exp; @@ -547,33 +522,20 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseBetween(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseBetween(Query $query, $key, $exp, $value, $field, $bindType) { // BETWEEN 查询 $data = is_array($value) ? $value : explode(',', $value); - if ($query->isBind($bindName . '_between_1')) { - $bindKey1 = $bindName . '_between_1' . uniqid(); - $bindKey2 = $bindName . '_between_2' . uniqid(); - } else { - $bindKey1 = $bindName . '_between_1'; - $bindKey2 = $bindName . '_between_2'; - } - - $bind = [ - $bindKey1 => [$data[0], $bindType], - $bindKey2 => [$data[1], $bindType], - ]; + $bind[] = [$data[0], $bindType]; + $bind[] = [$data[1], $bindType]; $query->bind($bind); - $between = ':' . $bindKey1 . ' AND :' . $bindKey2; - - return $key . ' ' . $exp . ' ' . $between; + return $key . ' ' . $exp . ' ? AND ? '; } /** @@ -584,11 +546,10 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseExists(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseExists(Query $query, $key, $exp, $value, $field, $bindType) { // EXISTS 查询 if ($value instanceof \Closure) { @@ -610,13 +571,12 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseTime(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseTime(Query $query, $key, $exp, $value, $field, $bindType) { - return $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($query, $value, $field, $bindName, $bindType); + return $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($query, $value, $field, $bindType); } /** @@ -627,11 +587,10 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseCompare(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseCompare(Query $query, $key, $exp, $value, $field, $bindType) { if (is_array($value)) { throw new Exception('where express error:' . $exp . var_export($value, true)); @@ -653,20 +612,19 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseBetweenTime(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseBetweenTime(Query $query, $key, $exp, $value, $field, $bindType) { if (is_string($value)) { $value = explode(',', $value); } return $key . ' ' . substr($exp, 0, -4) - . $this->parseDateTime($query, $value[0], $field, $bindName . '_between_1', $bindType) + . $this->parseDateTime($query, $value[0], $field, $bindType) . ' AND ' - . $this->parseDateTime($query, $value[1], $field, $bindName . '_between_2', $bindType); + . $this->parseDateTime($query, $value[1], $field, $bindType); } @@ -678,11 +636,10 @@ abstract class Builder * @param string $exp * @param mixed $value * @param string $field - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseIn(Query $query, $key, $exp, $value, $field, $bindName, $bindType) + protected function parseIn(Query $query, $key, $exp, $value, $field, $bindType) { // IN 查询 if ($value instanceof \Closure) { @@ -692,17 +649,10 @@ abstract class Builder $bind = []; $array = []; - $i = 0; foreach ($value as $k => $v) { - $i++; - if ($query->isBind($bindName . '_in_' . $i)) { - $bindKey = $bindName . '_in_' . uniqid() . '_' . $i; - } else { - $bindKey = $bindName . '_in_' . $i; - } - $bind[$bindKey] = [$v, $bindType]; - $array[] = ':' . $bindKey; + $bind[] = [$v, $bindType]; + $array[] = '?'; } $zone = implode(',', $array); @@ -736,12 +686,10 @@ abstract class Builder * @param Query $query 查询对象 * @param string $value * @param string $key - * @param array $options - * @param string $bindName * @param integer $bindType * @return string */ - protected function parseDateTime(Query $query, $value, $key, $bindName = null, $bindType = null) + protected function parseDateTime(Query $query, $value, $key, $bindType = null) { $options = $query->getOptions(); @@ -776,15 +724,9 @@ abstract class Builder } } - $bindName = $bindName ?: $key; + $query->bind($value, $bindType); - if ($query->isBind($bindName)) { - $bindName .= '_' . str_replace('.', '_', uniqid('', true)); - } - - $query->bind($bindName, $value, $bindType); - - return ':' . $bindName; + return '?'; } /** @@ -855,11 +797,11 @@ abstract class Builder foreach ($order as $key => $val) { if ($val instanceof Expression) { $array[] = $val->getValue(); - } elseif (is_array($val)) { + } elseif (is_array($val) && !preg_match('/\W/', $key)) { $array[] = $this->parseOrderField($query, $key, $val); } elseif ('[rand]' == $val) { $array[] = $this->parseRand($query); - } else { + } elseif (is_string($val)) { if (is_numeric($key)) { list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' '); } else { @@ -901,7 +843,7 @@ abstract class Builder $bind = $this->connection->getFieldsBind($options['table']); foreach ($val as $k => $item) { - $val[$k] = $this->parseDataBind($query, $key, $item, $bind, $k); + $val[$k] = $this->parseDataBind($query, $key, $item, $bind); } return 'field(' . $this->parseKey($query, $key, true) . ',' . implode(',', $val) . ')' . $sort; @@ -1114,8 +1056,8 @@ abstract class Builder // 获取绑定信息 $bind = $this->connection->getFieldsBind($options['table']); - foreach ($dataSet as $k => $data) { - $data = $this->parseData($query, $data, $allowFields, $bind, '_' . $k); + foreach ($dataSet as $data) { + $data = $this->parseData($query, $data, $allowFields, $bind); $values[] = 'SELECT ' . implode(',', array_values($data)); diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index 412dd3d87..d2bad3c0a 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -24,6 +24,7 @@ use think\Loader; abstract class Connection { + const PARAM_FLOAT = 21; protected static $instance = []; /** @var PDOStatement PDO操作实例 */ protected $PDOStatement; @@ -303,7 +304,9 @@ abstract class Connection { if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { $bind = PDO::PARAM_STR; - } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { + } elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) { + $bind = self::PARAM_FLOAT; + } elseif (preg_match('/(int|serial|bit)/is', $type)) { $bind = PDO::PARAM_INT; } elseif (preg_match('/bool/is', $type)) { $bind = PDO::PARAM_BOOL; @@ -1343,13 +1346,14 @@ abstract class Connection } if (is_null($field)) { - $field = '*'; - } elseif ($key && '*' != $field) { - $field = $key . ',' . $field; + $field = ['*']; + } elseif (is_string($field)) { + $field = array_map('trim', explode(',', $field)); } - if (is_string($field)) { - $field = array_map('trim', explode(',', $field)); + if ($key && ['*'] != $field) { + array_unshift($field, $key); + $field = array_unique($field); } $query->setOption('field', $field); @@ -1357,6 +1361,7 @@ abstract class Connection // 生成查询SQL $sql = $this->builder->select($query); + // 还原field参数 if (isset($options['field'])) { $query->setOption('field', $options['field']); } else { @@ -1378,7 +1383,7 @@ abstract class Connection } else { $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC); - if ('*' == $field && $key) { + if (['*'] == $field && $key) { $result = array_column($resultSet, null, $key); } elseif ($resultSet) { $fields = array_keys($resultSet[0]); @@ -1454,10 +1459,10 @@ abstract class Connection $value = is_array($val) ? $val[0] : $val; $type = is_array($val) ? $val[1] : PDO::PARAM_STR; - if (PDO::PARAM_STR == $type) { - $value = '\'' . addslashes($value) . '\''; - } elseif (PDO::PARAM_INT == $type) { + if (PDO::PARAM_INT == $type || self::PARAM_FLOAT == $type) { $value = (float) $value; + } elseif (PDO::PARAM_STR == $type) { + $value = '\'' . addslashes($value) . '\''; } // 判断占位符 @@ -1490,7 +1495,11 @@ abstract class Connection if (is_array($val)) { if (PDO::PARAM_INT == $val[1] && '' === $val[0]) { $val[0] = 0; + } elseif (self::PARAM_FLOAT == $val[1]) { + $val[0] = (float) $val[0]; + $val[1] = PDO::PARAM_STR; } + $result = $this->PDOStatement->bindValue($param, $val[0], $val[1]); } else { $result = $this->PDOStatement->bindValue($param, $val); @@ -2023,7 +2032,7 @@ abstract class Connection // 分布式数据库配置解析 foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { - $_config[$name] = explode(',', $this->config[$name]); + $_config[$name] = is_string($this->config[$name]) ? explode(',', $this->config[$name]) : $this->config[$name]; } // 主服务器序号 diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 35d2db19d..bcf6964c5 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -177,7 +177,7 @@ class Query call_user_func_array([$this->model, $method], $args); return $this; } else { - throw new Exception('method not exist:' . static::class . '->' . $method); + throw new Exception('method not exist:' . ($this->model ? get_class($this->model) : static::class) . '->' . $method); } } @@ -628,6 +628,9 @@ class Query $result = (float) $result; } + // 查询完成后清空聚合字段信息 + $this->removeOption('field'); + return $result; } @@ -653,10 +656,12 @@ class Query $query->fetchSql(true); } - return $query->aggregate('COUNT', '*', true); + $count = $query->aggregate('COUNT', '*'); + } else { + $count = $this->aggregate('COUNT', $field); } - return $this->aggregate('COUNT', $field, true); + return is_string($count) ? $count : (int) $count; } /** @@ -1024,17 +1029,12 @@ class Query * 表达式方式指定查询字段 * @access public * @param string $field 字段名 - * @param array $bind 参数绑定 * @return $this */ - public function fieldRaw($field, array $bind = []) + public function fieldRaw($field) { $this->options['field'][] = $this->raw($field); - if ($bind) { - $this->bind($bind); - } - return $this; } @@ -1424,11 +1424,17 @@ class Query */ public function whereExp($field, $condition, $bind = [], $logic = 'AND') { + if ($bind) { + foreach ($bind as $key => $value) { + if (!is_numeric($key)) { + $where = str_replace(':' . $key, '?', $where); + } + } + $this->bind(array_values($bind)); + } + $this->options['where'][$logic][] = [$field, 'EXP', $this->raw($condition)]; - if ($bind) { - $this->bind($bind); - } return $this; } @@ -1442,12 +1448,18 @@ class Query */ public function whereRaw($where, $bind = [], $logic = 'AND') { - $this->options['where'][$logic][] = $this->raw($where); - if ($bind) { - $this->bind($bind); + foreach ($bind as $key => $value) { + if (!is_numeric($key)) { + $where = str_replace(':' . $key, '?', $where); + } + } + + $this->bind(array_values($bind)); } + $this->options['where'][$logic][] = $this->raw($where); + return $this; } @@ -1875,17 +1887,12 @@ class Query * 表达式方式指定Field排序 * @access public * @param string $field 排序字段 - * @param array $bind 参数绑定 * @return $this */ - public function orderRaw($field, array $bind = []) + public function orderRaw($field) { $this->options['order'][] = $this->raw($field); - if ($bind) { - $this->bind($bind); - } - return $this; } @@ -2424,17 +2431,16 @@ class Query /** * 参数绑定 * @access public - * @param mixed $key 参数名 * @param mixed $value 绑定变量值 * @param integer $type 绑定类型 * @return $this */ - public function bind($key, $value = false, $type = PDO::PARAM_STR) + public function bind($value = false, $type = PDO::PARAM_STR) { - if (is_array($key)) { - $this->bind = array_merge($this->bind, $key); + if (is_array($value)) { + $this->bind = array_merge($this->bind, $value); } else { - $this->bind[$key] = [$value, $type]; + $this->bind[] = [$value, $type]; } return $this; @@ -3197,7 +3203,7 @@ class Query { $result = $this->with($with)->cache($cache); - if (is_array($data) && key($data) !== 0) { + if ((is_array($data) && key($data) !== 0) || $data instanceof Where) { $result = $result->where($data); $data = null; } elseif ($data instanceof \Closure) { diff --git a/thinkphp/library/think/db/Where.php b/thinkphp/library/think/db/Where.php index 8db7c31eb..9132e5461 100644 --- a/thinkphp/library/think/db/Where.php +++ b/thinkphp/library/think/db/Where.php @@ -79,8 +79,7 @@ class Where implements ArrayAccess * 分析查询表达式 * @access protected * @param string $field 查询字段 - * @param string $op 查询表达式 - * @param mixed $condition 查询条件 + * @param array $where 查询条件 * @return array */ protected function parseItem($field, $where = []) diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php index dfd963c28..10f745d26 100644 --- a/thinkphp/library/think/log/driver/File.php +++ b/thinkphp/library/think/log/driver/File.php @@ -129,6 +129,17 @@ class File */ protected function getMasterLogFile() { + if ($this->config['max_files']) { + $files = glob($this->config['path'] . '*.log'); + + try { + if (count($files) > $this->config['max_files']) { + unlink($files[0]); + } + } catch (\Exception $e) { + } + } + if ($this->config['single']) { $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; @@ -138,14 +149,6 @@ class File if ($this->config['max_files']) { $filename = date('Ymd') . $cli . '.log'; - $files = glob($this->config['path'] . '*.log'); - - try { - if (count($files) > $this->config['max_files']) { - unlink($files[0]); - } - } catch (\Exception $e) { - } } else { $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . $cli . '.log'; } diff --git a/thinkphp/library/think/log/driver/Socket.php b/thinkphp/library/think/log/driver/Socket.php index b4a2cadc7..5e4f8bfd8 100644 --- a/thinkphp/library/think/log/driver/Socket.php +++ b/thinkphp/library/think/log/driver/Socket.php @@ -30,6 +30,8 @@ class Socket 'force_client_ids' => [], // 限制允许读取日志的client_id 'allow_client_ids' => [], + //输出到浏览器默认展开的日志级别 + 'expand_level' => ['debug'], ]; protected $css = [ @@ -95,7 +97,7 @@ class Socket foreach ($log as $type => $val) { $trace[] = [ - 'type' => 'groupCollapsed', + 'type' => in_array($type, $this->config['expand_level']) ? 'group' : 'groupCollapsed', 'msg' => '[ ' . $type . ' ]', 'css' => isset($this->css[$type]) ? $this->css[$type] : '', ]; diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php index 8ffa9ea16..a1d2b23c8 100644 --- a/thinkphp/library/think/model/relation/BelongsTo.php +++ b/thinkphp/library/think/model/relation/BelongsTo.php @@ -68,6 +68,26 @@ class BelongsTo extends OneToOne return $relationModel; } + /** + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $aggregate 聚合查询方法 + * @param string $field 字段 + * @return string + */ + public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*') + { + if ($closure) { + $closure($this->query); + } + + return $this->query + ->whereExp($this->localKey, '=' . $this->parent->getTable() . '.' . $this->foreignKey) + ->fetchSql() + ->$aggregate($field); + } + /** * 根据关联条件查询当前模型 * @access public diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php index 3ce5fea03..1ccb6adc6 100644 --- a/thinkphp/library/think/model/relation/HasOne.php +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -68,6 +68,26 @@ class HasOne extends OneToOne return $relationModel; } + /** + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $aggregate 聚合查询方法 + * @param string $field 字段 + * @return string + */ + public function getRelationCountQuery($closure, $aggregate = 'count', $field = '*') + { + if ($closure) { + $closure($this->query); + } + + return $this->query + ->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $this->parent->getPk()) + ->fetchSql() + ->$aggregate($field); + } + /** * 根据关联条件查询当前模型 * @access public diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php index 3e913ccd0..7c083dd79 100644 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -195,7 +195,7 @@ class MorphMany extends Relation if (isset($result->$pk)) { if ($closure) { - $closur($this->query); + $closure($this->query); } $count = $this->query diff --git a/thinkphp/library/think/response/Redirect.php b/thinkphp/library/think/response/Redirect.php index 62fa83a7a..73729ce88 100644 --- a/thinkphp/library/think/response/Redirect.php +++ b/thinkphp/library/think/response/Redirect.php @@ -99,15 +99,18 @@ class Redirect extends Response /** * 跳转到上次记住的url * @access public + * @param string $url 闪存数据不存在时的跳转地址 * @return $this */ - public function restore() + public function restore($url = null) { $session = $this->app['session']; if ($session->has('redirect_url')) { $this->data = $session->get('redirect_url'); $session->delete('redirect_url'); + } elseif ($url) { + $this->data = $url; } return $this; diff --git a/thinkphp/library/think/route/AliasRule.php b/thinkphp/library/think/route/AliasRule.php index daf59fe13..393cb3107 100644 --- a/thinkphp/library/think/route/AliasRule.php +++ b/thinkphp/library/think/route/AliasRule.php @@ -75,6 +75,11 @@ class AliasRule extends Domain $this->mergeGroupOptions(); } + if (isset($this->option['ext'])) { + // 路由ext参数 优先于系统配置的URL伪静态后缀参数 + $bind = preg_replace('/\.(' . $request->ext() . ')$/i', '', $bind); + } + $this->parseBindAppendParam($this->route); if (0 === strpos($this->route, '\\')) { diff --git a/thinkphp/library/think/route/RuleGroup.php b/thinkphp/library/think/route/RuleGroup.php index 57b8e28f0..3ebb40995 100644 --- a/thinkphp/library/think/route/RuleGroup.php +++ b/thinkphp/library/think/route/RuleGroup.php @@ -584,4 +584,22 @@ class RuleGroup extends Rule return isset($this->rules[strtolower($method)]) ? $this->rules[strtolower($method)] : []; } + /** + * 清空分组下的路由规则 + * @access public + * @return void + */ + public function clear() + { + $this->rules = [ + '*' => [], + 'get' => [], + 'post' => [], + 'put' => [], + 'patch' => [], + 'delete' => [], + 'head' => [], + 'options' => [], + ]; + } } diff --git a/thinkphp/library/think/route/RuleName.php b/thinkphp/library/think/route/RuleName.php index 026cb6206..46481f8c5 100644 --- a/thinkphp/library/think/route/RuleName.php +++ b/thinkphp/library/think/route/RuleName.php @@ -133,4 +133,14 @@ class RuleName return $result; } + /** + * 清空路由规则 + * @access public + * @return void + */ + public function clear() + { + $this->item = []; + $this->rule = []; + } } diff --git a/vendor/autoload.php b/vendor/autoload.php index db1ddd414..10f85353b 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26::getLoader(); +return ComposerAutoloaderInit7ac0a16c6bb261e6fc9b66fbcc229d16::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 2ab9f0cc9..46afd63e7 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26 +class ComposerAutoloaderInit7ac0a16c6bb261e6fc9b66fbcc229d16 { private static $loader; @@ -19,15 +19,15 @@ class ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit7ac0a16c6bb261e6fc9b66fbcc229d16', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit7ac0a16c6bb261e6fc9b66fbcc229d16', '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\ComposerStaticInit1d3094fd985c01a522304485af2b5f26::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -48,19 +48,19 @@ class ComposerAutoloaderInit1d3094fd985c01a522304485af2b5f26 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit1d3094fd985c01a522304485af2b5f26::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire1d3094fd985c01a522304485af2b5f26($fileIdentifier, $file); + composerRequire7ac0a16c6bb261e6fc9b66fbcc229d16($fileIdentifier, $file); } return $loader; } } -function composerRequire1d3094fd985c01a522304485af2b5f26($fileIdentifier, $file) +function composerRequire7ac0a16c6bb261e6fc9b66fbcc229d16($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a5f8faca5..735497876 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit1d3094fd985c01a522304485af2b5f26 +class ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16 { public static $files = array ( '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', @@ -303,9 +303,9 @@ class ComposerStaticInit1d3094fd985c01a522304485af2b5f26 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit1d3094fd985c01a522304485af2b5f26::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit1d3094fd985c01a522304485af2b5f26::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit1d3094fd985c01a522304485af2b5f26::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit7ac0a16c6bb261e6fc9b66fbcc229d16::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 82662acc7..9435932ed 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -50,17 +50,17 @@ }, { "name": "topthink/framework", - "version": "v5.1.24", - "version_normalized": "5.1.24.0", + "version": "v5.1.25", + "version_normalized": "5.1.25.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "03ee17d1ea9c432a698fa1d2411df53974420187" + "reference": "2e684d5fa38bd2d8ee864982f3114a28992da895" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/03ee17d1ea9c432a698fa1d2411df53974420187", - "reference": "03ee17d1ea9c432a698fa1d2411df53974420187", + "url": "https://api.github.com/repos/top-think/framework/zipball/2e684d5fa38bd2d8ee864982f3114a28992da895", + "reference": "2e684d5fa38bd2d8ee864982f3114a28992da895", "shasum": "", "mirrors": [ { @@ -82,7 +82,7 @@ "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, - "time": "2018-09-05T03:37:46+00:00", + "time": "2018-10-04T05:04:50+00:00", "type": "think-framework", "installation-source": "dist", "notification-url": "https://packagist.org/downloads/", @@ -215,17 +215,17 @@ }, { "name": "symfony/options-resolver", - "version": "v3.4.15", - "version_normalized": "3.4.15.0", + "version": "v3.4.17", + "version_normalized": "3.4.17.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "6debc476953a45969ab39afe8dee0b825f356dc7" + "reference": "1cf7d8e704a9cc4164c92e430f2dfa3e6983661d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/6debc476953a45969ab39afe8dee0b825f356dc7", - "reference": "6debc476953a45969ab39afe8dee0b825f356dc7", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/1cf7d8e704a9cc4164c92e430f2dfa3e6983661d", + "reference": "1cf7d8e704a9cc4164c92e430f2dfa3e6983661d", "shasum": "", "mirrors": [ { @@ -237,7 +237,7 @@ "require": { "php": "^5.5.9|>=7.0.8" }, - "time": "2018-07-26T08:45:46+00:00", + "time": "2018-09-17T17:29:18+00:00", "type": "library", "extra": { "branch-alias": { @@ -443,17 +443,17 @@ }, { "name": "zoujingli/wechat-developer", - "version": "v1.1.13", - "version_normalized": "1.1.13.0", + "version": "v1.1.14", + "version_normalized": "1.1.14.0", "source": { "type": "git", "url": "https://github.com/zoujingli/WeChatDeveloper.git", - "reference": "39682a047e5c8f9c66107924dfed4e2080e97eb4" + "reference": "328d21d32c3d06f5f050185a740f00fe475b6a03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/39682a047e5c8f9c66107924dfed4e2080e97eb4", - "reference": "39682a047e5c8f9c66107924dfed4e2080e97eb4", + "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/328d21d32c3d06f5f050185a740f00fe475b6a03", + "reference": "328d21d32c3d06f5f050185a740f00fe475b6a03", "shasum": "", "mirrors": [ { @@ -467,7 +467,7 @@ "ext-openssl": "*", "php": ">=5.4" }, - "time": "2018-07-11T02:02:41+00:00", + "time": "2018-09-12T06:12:49+00:00", "type": "library", "installation-source": "dist", "autoload": { diff --git a/vendor/symfony/options-resolver/OptionsResolver.php b/vendor/symfony/options-resolver/OptionsResolver.php index 79a6c0897..83d81969c 100644 --- a/vendor/symfony/options-resolver/OptionsResolver.php +++ b/vendor/symfony/options-resolver/OptionsResolver.php @@ -353,11 +353,9 @@ class OptionsResolver implements Options * * The normalizer should be a closure with the following signature: * - * ```php - * function (Options $options, $value) { - * // ... - * } - * ``` + * function (Options $options, $value) { + * // ... + * } * * The closure is invoked when {@link resolve()} is called. The closure * has access to the resolved values of other options through the passed @@ -383,11 +381,7 @@ class OptionsResolver implements Options } if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } $this->normalizers[$option] = $normalizer; @@ -426,11 +420,7 @@ class OptionsResolver implements Options } if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } $this->allowedValues[$option] = \is_array($allowedValues) ? $allowedValues : array($allowedValues); @@ -471,11 +461,7 @@ class OptionsResolver implements Options } if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } if (!\is_array($allowedValues)) { @@ -516,11 +502,7 @@ class OptionsResolver implements Options } if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } $this->allowedTypes[$option] = (array) $allowedTypes; @@ -555,11 +537,7 @@ class OptionsResolver implements Options } if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } if (!isset($this->allowedTypes[$option])) { @@ -664,11 +642,7 @@ class OptionsResolver implements Options ksort($clone->defined); ksort($diff); - throw new UndefinedOptionsException(sprintf( - (\count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.').' Defined options are: "%s".', - implode('", "', array_keys($diff)), - implode('", "', array_keys($clone->defined)) - )); + throw new UndefinedOptionsException(sprintf((\count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.').' Defined options are: "%s".', implode('", "', array_keys($diff)), implode('", "', array_keys($clone->defined)))); } // Override options set by the user @@ -683,10 +657,7 @@ class OptionsResolver implements Options if (\count($diff) > 0) { ksort($diff); - throw new MissingOptionsException(sprintf( - \count($diff) > 1 ? 'The required options "%s" are missing.' : 'The required option "%s" is missing.', - implode('", "', array_keys($diff)) - )); + throw new MissingOptionsException(sprintf(\count($diff) > 1 ? 'The required options "%s" are missing.' : 'The required option "%s" is missing.', implode('", "', array_keys($diff)))); } // Lock the container @@ -730,17 +701,10 @@ class OptionsResolver implements Options // Check whether the option is set at all if (!array_key_exists($option, $this->defaults)) { if (!isset($this->defined[$option])) { - throw new NoSuchOptionException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); + throw new NoSuchOptionException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined)))); } - throw new NoSuchOptionException(sprintf( - 'The optional option "%s" has no value set. You should make sure it is set with "isset" before reading it.', - $option - )); + throw new NoSuchOptionException(sprintf('The optional option "%s" has no value set. You should make sure it is set with "isset" before reading it.', $option)); } $value = $this->defaults[$option]; @@ -750,10 +714,7 @@ class OptionsResolver implements Options // If the closure is already being called, we have a cyclic // dependency if (isset($this->calling[$option])) { - throw new OptionDefinitionException(sprintf( - 'The options "%s" have a cyclic dependency.', - implode('", "', array_keys($this->calling)) - )); + throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', implode('", "', array_keys($this->calling)))); } // The following section must be protected from cyclic @@ -809,7 +770,9 @@ class OptionsResolver implements Options // Don't include closures in the exception message continue; - } elseif ($value === $allowedValue) { + } + + if ($value === $allowedValue) { $success = true; break; } @@ -840,10 +803,7 @@ class OptionsResolver implements Options // If the closure is already being called, we have a cyclic // dependency if (isset($this->calling[$option])) { - throw new OptionDefinitionException(sprintf( - 'The options "%s" have a cyclic dependency.', - implode('", "', array_keys($this->calling)) - )); + throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', implode('", "', array_keys($this->calling)))); } $normalizer = $this->normalizers[$option]; @@ -1102,20 +1062,4 @@ class OptionsResolver implements Options { return (\function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type; } - - /** - * @return array - */ - private function getInvalidValues(array $arrayValues, $type) - { - $invalidValues = array(); - - foreach ($arrayValues as $key => $value) { - if (!self::isValueValidType($type, $value)) { - $invalidValues[$key] = $value; - } - } - - return $invalidValues; - } } diff --git a/vendor/zoujingli/wechat-developer/WeChat/Contracts/BasicWeChat.php b/vendor/zoujingli/wechat-developer/WeChat/Contracts/BasicWeChat.php index 83c9a3d1f..30bbc25f1 100644 --- a/vendor/zoujingli/wechat-developer/WeChat/Contracts/BasicWeChat.php +++ b/vendor/zoujingli/wechat-developer/WeChat/Contracts/BasicWeChat.php @@ -108,6 +108,25 @@ class BasicWeChat return $this->access_token = $result['access_token']; } + /** + * 设置外部接口 AccessToken + * @param string $access_token + * @throws \WeChat\Exceptions\LocalCacheException + * @author 高一平 + * + * 当用户使用自己的缓存驱动时,直接实例化对象后可直接设置 AccessToekn + * - 多用于分布式项目时保持 AccessToken 统一 + * - 使用此方法后就由用户来保证传入的 AccessToekn 为有效 AccessToekn + */ + public function setAccessToken($access_token) + { + if (!is_string($access_token)) { + throw new InvalidArgumentException("Invalid AccessToken type, need string."); + } + $cache = $this->config->get('appid') . '_access_token'; + Tools::setCache($cache, $this->access_token = $access_token); + } + /** * 清理删除accessToken * @return bool diff --git a/vendor/zoujingli/wechat-developer/WeChat/Custom.php b/vendor/zoujingli/wechat-developer/WeChat/Custom.php index bdd288781..12e505142 100644 --- a/vendor/zoujingli/wechat-developer/WeChat/Custom.php +++ b/vendor/zoujingli/wechat-developer/WeChat/Custom.php @@ -28,14 +28,13 @@ class Custom extends BasicWeChat * 添加客服帐号 * @param string $kf_account 客服账号 * @param string $nickname 客服昵称 - * @param string $password 账号密码 * @return array * @throws Exceptions\InvalidResponseException * @throws Exceptions\LocalCacheException */ - public function addAccount($kf_account, $nickname, $password) + public function addAccount($kf_account, $nickname) { - $data = ['kf_account' => $kf_account, 'nickname' => $nickname, 'password' => $password]; + $data = ['kf_account' => $kf_account, 'nickname' => $nickname]; $url = "https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN"; $this->registerApi($url, __FUNCTION__, func_get_args()); return $this->httpPostForJson($url, $data); @@ -45,14 +44,13 @@ class Custom extends BasicWeChat * 修改客服帐号 * @param string $kf_account 客服账号 * @param string $nickname 客服昵称 - * @param string $password 账号密码 * @return array * @throws Exceptions\InvalidResponseException * @throws Exceptions\LocalCacheException */ - public function updateAccount($kf_account, $nickname, $password) + public function updateAccount($kf_account, $nickname) { - $data = ['kf_account' => $kf_account, 'nickname' => $nickname, 'password' => $password]; + $data = ['kf_account' => $kf_account, 'nickname' => $nickname]; $url = "https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN"; $this->registerApi($url, __FUNCTION__, func_get_args()); return $this->httpPostForJson($url, $data); @@ -61,15 +59,13 @@ class Custom extends BasicWeChat /** * 删除客服帐号 * @param string $kf_account 客服账号 - * @param string $nickname 客服昵称 - * @param string $password 账号密码 * @return array * @throws Exceptions\InvalidResponseException * @throws Exceptions\LocalCacheException */ - public function deleteAccount($kf_account, $nickname, $password) + public function deleteAccount($kf_account) { - $data = ['kf_account' => $kf_account, 'nickname' => $nickname, 'password' => $password]; + $data = ['kf_account' => $kf_account]; $url = "https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN"; $this->registerApi($url, __FUNCTION__, func_get_args()); return $this->httpPostForJson($url, $data); diff --git a/vendor/zoujingli/wechat-developer/WePay/Refund.php b/vendor/zoujingli/wechat-developer/WePay/Refund.php index a91493ee9..da8152204 100644 --- a/vendor/zoujingli/wechat-developer/WePay/Refund.php +++ b/vendor/zoujingli/wechat-developer/WePay/Refund.php @@ -15,6 +15,8 @@ namespace WePay; use WeChat\Contracts\BasicPay; +use WeChat\Contracts\Tools; +use WeChat\Exceptions\InvalidResponseException; /** * 微信商户退款 @@ -48,4 +50,27 @@ class Refund extends BasicPay return $this->callPostApi($url, $options); } + /** + * 获取退款通知 + * @return array + * @throws InvalidResponseException + */ + public function getNotify() + { + $data = Tools::xml2arr(file_get_contents("php://input")); + if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS') { + throw new InvalidResponseException('获取退款通知XML失败!'); + } + if (!class_exists('Prpcrypt', false)) { + include dirname(__DIR__) . '/WeChat/Contracts/Prpcrypt.php'; + } + $pc = new \Prpcrypt(md5($this->config->get('mch_key'))); + $array = $pc->decrypt(base64_decode($data['req_info'])); + if (intval($array[0]) > 0) { + throw new InvalidResponseException($array[1], $array[0]); + } + $data['decode'] = $array[1]; + return $data; + } + } \ No newline at end of file