From 9cca1a81d927083274737515749c2ed07b472108 Mon Sep 17 00:00:00 2001 From: Anyon Date: Mon, 16 Apr 2018 19:57:42 +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/library/think/App.php | 2 +- thinkphp/library/think/Loader.php | 8 +- .../library/think/console/command/Clear.php | 38 +++- thinkphp/library/think/db/Builder.php | 63 ++++-- thinkphp/library/think/db/Query.php | 31 ++- thinkphp/library/think/db/builder/Mysql.php | 41 +--- thinkphp/library/think/db/builder/Pgsql.php | 2 +- thinkphp/library/think/db/builder/Sqlsrv.php | 2 +- thinkphp/library/think/route/Rule.php | 13 +- vendor/autoload.php | 2 +- vendor/composer/autoload_classmap.php | 2 + vendor/composer/autoload_real.php | 14 +- vendor/composer/autoload_static.php | 10 +- vendor/composer/installed.json | 28 +-- vendor/symfony/options-resolver/CHANGELOG.md | 10 +- .../Debug/OptionsResolverIntrospector.php | 102 +++++++++ .../Exception/NoConfigurationException.php | 26 +++ vendor/symfony/options-resolver/LICENSE | 2 +- .../options-resolver/OptionsResolver.php | 108 +++++++--- .../Debug/OptionsResolverIntrospectorTest.php | 203 ++++++++++++++++++ .../Tests/OptionsResolverTest.php | 106 ++++++++- vendor/symfony/options-resolver/composer.json | 4 +- 22 files changed, 666 insertions(+), 151 deletions(-) create mode 100644 vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php create mode 100644 vendor/symfony/options-resolver/Exception/NoConfigurationException.php create mode 100644 vendor/symfony/options-resolver/Tests/Debug/OptionsResolverIntrospectorTest.php diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index 02a2e6fb4..d9344791e 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -20,7 +20,7 @@ use think\route\Dispatch; */ class App implements \ArrayAccess { - const VERSION = '5.1.9'; + const VERSION = '5.1.10'; /** * 当前模块路径 diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php index e2bed16f4..af9f6bb4e 100644 --- a/thinkphp/library/think/Loader.php +++ b/thinkphp/library/think/Loader.php @@ -56,13 +56,7 @@ class Loader public static function getRootPath() { if ('cli' == PHP_SAPI) { - $cwdPath = getcwd(); - - if (0 === strpos($_SERVER['argv'][0], $cwdPath)) { - $scriptName = $_SERVER['argv'][0]; - } else { - $scriptName = $cwdPath . DIRECTORY_SEPARATOR . $_SERVER['argv'][0]; - } + $scriptName = realpath($_SERVER['argv'][0]); } else { $scriptName = $_SERVER['SCRIPT_FILENAME']; } diff --git a/thinkphp/library/think/console/command/Clear.php b/thinkphp/library/think/console/command/Clear.php index 9896aea56..7ee31ea73 100644 --- a/thinkphp/library/think/console/command/Clear.php +++ b/thinkphp/library/think/console/command/Clear.php @@ -24,22 +24,40 @@ class Clear extends Command $this ->setName('clear') ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null) + ->addOption('cache', 'c', Option::VALUE_NONE, 'clear cache file') + ->addOption('log', 'l', Option::VALUE_NONE, 'clear log file') + ->addOption('dir', 'r', Option::VALUE_NONE, 'clear empty dir') ->setDescription('Clear runtime file'); } protected function execute(Input $input, Output $output) { - $path = $input->getOption('path') ?: App::getRuntimePath(); - $files = scandir($path); - if ($files) { - foreach ($files as $file) { - if ('.' != $file && '..' != $file && is_dir($path . $file)) { - array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*')); - } elseif ('.gitignore' != $file && is_file($path . $file)) { - unlink($path . $file); - } - } + if ($input->getOption('cache')) { + $path = App::getRuntimePath() . 'cache'; + } elseif ($input->getOption('log')) { + $path = App::getRuntimePath() . 'log'; + } else { + $path = $input->getOption('path') ?: App::getRuntimePath(); } + + $rmdir = $input->getOption('dir') ? true : false; + $this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir); $output->writeln("Clear Successed"); } + + protected function clear($path, $rmdir) + { + $files = is_dir($path) ? scandir($path) : []; + + foreach ($files as $file) { + if ('.' != $file && '..' != $file && is_dir($path . $file)) { + array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*')); + if ($rmdir) { + rmdir($path . $file); + } + } elseif ('.gitignore' != $file && is_file($path . $file)) { + unlink($path . $file); + } + } + } } diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 31e5fc5e9..e61e6502c 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -136,7 +136,7 @@ abstract class Builder } elseif (is_null($val)) { $result[$item] = 'NULL'; } elseif (is_array($val) && !empty($val)) { - switch ($val[0]) { + switch (strtoupper($val[0])) { case 'INC': $result[$item] = $item . ' + ' . floatval($val[1]); break; @@ -563,6 +563,10 @@ abstract class Builder // EXISTS 查询 if ($value instanceof \Closure) { $value = $this->parseClosure($query, $value, false); + } elseif ($value instanceof Expression) { + $value = $value->getValue(); + } else { + throw new Exception('where express error:' . $value); } return $exp . ' (' . $value . ')'; @@ -744,6 +748,10 @@ abstract class Builder $bindName = $bindName ?: $key; + if ($query->isBind($bindName)) { + $bindName .= '_' . str_replace('.', '_', uniqid('', true)); + } + $query->bind($bindName, $value, $bindType); return ':' . $bindName; @@ -815,21 +823,7 @@ abstract class Builder if ($val instanceof Expression) { $array[] = $val->getValue(); } elseif (is_array($val)) { - if (isset($val['sort'])) { - $sort = ' ' . $val['sort']; - unset($val['sort']); - } else { - $sort = ''; - } - - $options = $query->getOptions(); - $bind = $this->connection->getFieldsBind($options['table']); - - foreach ($val as $k => $item) { - $val[$k] = $this->parseDataBind($query, $key, $item, $bind, $k); - } - - $array[] = 'field(' . $this->parseKey($query, $key, true) . ',' . implode(',', $val) . ')' . $sort; + $array[] = $this->parseOrderField($query, $key, $val); } elseif ('[rand]' == $val) { $array[] = $this->parseRand($query); } else { @@ -839,14 +833,43 @@ abstract class Builder $sort = $val; } - $sort = in_array(strtolower($sort), ['asc', 'desc'], true) ? ' ' . $sort : ''; + $sort = strtoupper($sort); + $sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : ''; $array[] = $this->parseKey($query, $key, true) . $sort; } } - $order = implode(',', $array); + return ' ORDER BY ' . implode(',', $array); + } - return ' ORDER BY ' . $order; + /** + * group分析 + * @access protected + * @param Query $query 查询对象 + * @param mixed $key + * @param array $val + * @return string + */ + protected function parseOrderField($query, $key, $val) + { + if (isset($val['sort'])) { + $sort = $val['sort']; + unset($val['sort']); + } else { + $sort = ''; + } + + $sort = strtoupper($sort); + $sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : ''; + + $options = $query->getOptions(); + $bind = $this->connection->getFieldsBind($options['table']); + + foreach ($val as $k => $item) { + $val[$k] = $this->parseDataBind($query, $key, $item, $bind, $k); + } + + return 'field(' . $this->parseKey($query, $key, true) . ',' . implode(',', $val) . ')' . $sort; } /** @@ -1065,7 +1088,7 @@ abstract class Builder $fields = []; foreach ($insertFields as $field) { - $fields[] = $this->parseKey($query, $field, true); + $fields[] = $this->parseKey($query, $field); } return str_replace( diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 0329e1c29..965b8f81d 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -1233,6 +1233,10 @@ class Query */ public function whereExists($condition, $logic = 'AND') { + if (is_string($condition)) { + $condition = $this->raw($condition); + } + $this->options['where'][strtoupper($logic)][] = ['', 'EXISTS', $condition]; return $this; } @@ -1246,6 +1250,10 @@ class Query */ public function whereNotExists($condition, $logic = 'AND') { + if (is_string($condition)) { + $condition = $this->raw($condition); + } + $this->options['where'][strtoupper($logic)][] = ['', 'NOT EXISTS', $condition]; return $this; } @@ -1485,14 +1493,16 @@ class Query if (in_array(strtoupper($op), ['NULL', 'NOTNULL', 'NOT NULL'], true)) { // null查询 $where = [$field, $op, '']; - } elseif (in_array(strtolower($op), ['=', 'eq', null], true)) { + } elseif (in_array($op, ['=', 'eq', 'EQ', null], true)) { $where = [$field, 'NULL', '']; - } elseif (in_array(strtolower($op), ['<>', 'neq'], true)) { + } elseif (in_array($op, ['<>', 'neq', 'NEQ'], true)) { $where = [$field, 'NOTNULL', '']; } else { // 字段相等查询 $where = [$field, '=', $op]; } + } 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] : null; } @@ -1537,8 +1547,12 @@ class Query { $logic = strtoupper($logic); - if (isset($this->options['where'][$logic][$field])) { - unset($this->options['where'][$logic][$field]); + if (isset($this->options['where'][$logic])) { + foreach ($this->options['where'][$logic] as $key => $val) { + if (is_array($val) && $val[0] == $field) { + unset($this->options['where'][$logic][$key]); + } + } } return $this; @@ -1827,11 +1841,14 @@ class Query * @param string $order * @return $this */ - public function orderField($field, array $values = [], $order = '') + public function orderField($field, array $values, $order = '') { - $values['sort'] = $order; + if (!empty($values)) { + $values['sort'] = $order; + + $this->options['order'][$field] = $values; + } - $this->options['order'][$field] = $values; return $this; } diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index a17657d9f..9663dca60 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -12,6 +12,7 @@ namespace think\db\builder; use think\db\Builder; +use think\db\Expression; use think\db\Query; /** @@ -88,16 +89,16 @@ class Mysql extends Builder /** * 正则查询 * @access protected - * @param Query $query 查询对象 - * @param string $key - * @param string $exp - * @param mixed $value - * @param string $field + * @param Query $query 查询对象 + * @param string $key + * @param string $exp + * @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) { - return $key . ' ' . $exp . ' ' . $value; + return $key . ' ' . $exp . ' ' . $value->getValue(); } /** @@ -135,7 +136,7 @@ class Mysql extends Builder } } - if ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) { $key = '`' . $key . '`'; } @@ -150,30 +151,6 @@ class Mysql extends Builder return $key; } - /** - * field分析 - * @access protected - * @param Query $query 查询对象 - * @param mixed $fields 字段名 - * @return string - */ - protected function parseField(Query $query, $fields) - { - $fieldsStr = parent::parseField($query, $fields); - $options = $query->getOptions(); - - if (!empty($options['point'])) { - $array = []; - foreach ($options['point'] as $key => $field) { - $key = !is_numeric($key) ? $key : $field; - $array[] = 'AsText(' . $this->parseKey($query, $key) . ') AS ' . $this->parseKey($query, $field); - } - $fieldsStr .= ',' . implode(',', $array); - } - - return $fieldsStr; - } - /** * 随机排序 * @access protected diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php index 32373b64d..7d2f72a15 100644 --- a/thinkphp/library/think/db/builder/Pgsql.php +++ b/thinkphp/library/think/db/builder/Pgsql.php @@ -51,7 +51,7 @@ class Pgsql extends Builder * @access public * @param Query $query 查询对象 * @param string $key 字段名 - * @param bool $strict 严格检测 + * @param bool $strict 严格检测 * @return string */ public function parseKey(Query $query, $key, $strict = false) diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php index 4d3dc15bc..b37f01a63 100644 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -104,7 +104,7 @@ class Sqlsrv extends Builder } } - if ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { + if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { $key = '[' . $key . ']'; } diff --git a/thinkphp/library/think/route/Rule.php b/thinkphp/library/think/route/Rule.php index 8f9d47e92..96f86d935 100644 --- a/thinkphp/library/think/route/Rule.php +++ b/thinkphp/library/think/route/Rule.php @@ -985,13 +985,22 @@ abstract class Rule } // 是否区分 / 地址访问 - if (!empty($option['remove_slash']) && '/' != $rule) { - $rule = rtrim($rule, '/'); + if ('/' != $rule) { + if (!empty($option['remove_slash'])) { + $rule = rtrim($rule, '/'); + } elseif (substr($rule, -1) == '/') { + $rule = rtrim($rule, '/'); + $hasSlash = true; + } } $regex = str_replace($match, $replace, $rule); $regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex); + if (isset($hasSlash)) { + $regex .= '\/'; + } + return $regex . ($completeMatch ? '$' : ''); } diff --git a/vendor/autoload.php b/vendor/autoload.php index b43db8758..d114c2528 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32::getLoader(); +return ComposerAutoloaderInit7f21c27a120d47e6491fd4a016f044cb::getLoader(); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 1d267a20c..a750b2486 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -101,11 +101,13 @@ return array( 'Qiniu\\Storage\\ResumeUploader' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/Storage/ResumeUploader.php', 'Qiniu\\Storage\\UploadManager' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/Storage/UploadManager.php', 'Qiniu\\Zone' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/Zone.php', + 'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => $vendorDir . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php', 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Exception/AccessException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Exception/ExceptionInterface.php', 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/options-resolver/Exception/InvalidArgumentException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/InvalidOptionsException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/MissingOptionsException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\NoConfigurationException' => $vendorDir . '/symfony/options-resolver/Exception/NoConfigurationException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => $vendorDir . '/symfony/options-resolver/Exception/NoSuchOptionException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => $vendorDir . '/symfony/options-resolver/Exception/OptionDefinitionException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/UndefinedOptionsException.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 4aed4751e..019c01640 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32 +class ComposerAutoloaderInit7f21c27a120d47e6491fd4a016f044cb { private static $loader; @@ -19,15 +19,15 @@ class ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit7f21c27a120d47e6491fd4a016f044cb', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit7f21c27a120d47e6491fd4a016f044cb', '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\ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -48,19 +48,19 @@ class ComposerAutoloaderInite11d5d0f579f9ff8739edc30bb4f8f32 $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequiree11d5d0f579f9ff8739edc30bb4f8f32($fileIdentifier, $file); + composerRequire7f21c27a120d47e6491fd4a016f044cb($fileIdentifier, $file); } return $loader; } } -function composerRequiree11d5d0f579f9ff8739edc30bb4f8f32($fileIdentifier, $file) +function composerRequire7f21c27a120d47e6491fd4a016f044cb($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 3e32647b7..ef1ac09c2 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32 +class ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb { public static $files = array ( '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', @@ -179,11 +179,13 @@ class ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32 'Qiniu\\Storage\\ResumeUploader' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/Storage/ResumeUploader.php', 'Qiniu\\Storage\\UploadManager' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/Storage/UploadManager.php', 'Qiniu\\Zone' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/Zone.php', + 'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => __DIR__ . '/..' . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php', 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/AccessException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/ExceptionInterface.php', 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/InvalidArgumentException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/InvalidOptionsException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/MissingOptionsException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\NoConfigurationException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/NoConfigurationException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/NoSuchOptionException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/OptionDefinitionException.php', 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/UndefinedOptionsException.php', @@ -256,9 +258,9 @@ class ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInite11d5d0f579f9ff8739edc30bb4f8f32::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit7f21c27a120d47e6491fd4a016f044cb::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 15e38b73b..057cb0a38 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -175,17 +175,17 @@ }, { "name": "topthink/framework", - "version": "v5.1.9", - "version_normalized": "5.1.9.0", + "version": "v5.1.10", + "version_normalized": "5.1.10.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "c49df2fa54879105e451f7eaaf841d218206f02f" + "reference": "66b546f7cac130712d1e08fe2620105228f4bd8a" }, "dist": { "type": "zip", - "url": "https://files.phpcomposer.com/files/top-think/framework/c49df2fa54879105e451f7eaaf841d218206f02f.zip", - "reference": "c49df2fa54879105e451f7eaaf841d218206f02f", + "url": "https://files.phpcomposer.com/files/top-think/framework/66b546f7cac130712d1e08fe2620105228f4bd8a.zip", + "reference": "66b546f7cac130712d1e08fe2620105228f4bd8a", "shasum": "" }, "require": { @@ -201,7 +201,7 @@ "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, - "time": "2018-04-12T11:16:28+00:00", + "time": "2018-04-16T05:33:00+00:00", "type": "think-framework", "installation-source": "dist", "notification-url": "https://packagist.org/downloads/", @@ -269,27 +269,27 @@ }, { "name": "symfony/options-resolver", - "version": "v3.3.6", - "version_normalized": "3.3.6.0", + "version": "v3.4.8", + "version_normalized": "3.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0" + "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e" }, "dist": { "type": "zip", - "url": "https://files.phpcomposer.com/files/symfony/options-resolver/ff48982d295bcac1fd861f934f041ebc73ae40f0.zip", - "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0", + "url": "https://files.phpcomposer.com/files/symfony/options-resolver/f3109a6aedd20e35c3a33190e932c2b063b7b50e.zip", + "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, - "time": "2017-04-12T14:14:56+00:00", + "time": "2018-01-11T07:56:07+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", diff --git a/vendor/symfony/options-resolver/CHANGELOG.md b/vendor/symfony/options-resolver/CHANGELOG.md index 5f6d15b2c..6e9d49fb6 100644 --- a/vendor/symfony/options-resolver/CHANGELOG.md +++ b/vendor/symfony/options-resolver/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +3.4.0 +----- + + * added `OptionsResolverIntrospector` to inspect options definitions inside an `OptionsResolver` instance + * added array of types support in allowed types (e.g int[]) + 2.6.0 ----- @@ -25,7 +31,7 @@ CHANGELOG * deprecated OptionsResolver::isKnown() in favor of isDefined() * [BC BREAK] OptionsResolver::isRequired() returns true now if a required option has a default value set - * [BC BREAK] merged Options into OptionsResolver and turned Options into an + * [BC BREAK] merged Options into OptionsResolver and turned Options into an interface * deprecated Options::overload() (now in OptionsResolver) * deprecated Options::set() (now in OptionsResolver) @@ -36,7 +42,7 @@ CHANGELOG lazy option/normalizer closures now * [BC BREAK] removed Traversable interface from Options since using within lazy option/normalizer closures resulted in exceptions - * [BC BREAK] removed Options::all() since using within lazy option/normalizer + * [BC BREAK] removed Options::all() since using within lazy option/normalizer closures resulted in exceptions * [BC BREAK] OptionDefinitionException now extends LogicException instead of RuntimeException diff --git a/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php new file mode 100644 index 000000000..60317243e --- /dev/null +++ b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\OptionsResolver\Debug; + +use Symfony\Component\OptionsResolver\Exception\NoConfigurationException; +use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * @author Maxime Steinhausser + * + * @final + */ +class OptionsResolverIntrospector +{ + private $get; + + public function __construct(OptionsResolver $optionsResolver) + { + $this->get = \Closure::bind(function ($property, $option, $message) { + /** @var OptionsResolver $this */ + if (!$this->isDefined($option)) { + throw new UndefinedOptionsException(sprintf('The option "%s" does not exist.', $option)); + } + + if (!array_key_exists($option, $this->{$property})) { + throw new NoConfigurationException($message); + } + + return $this->{$property}[$option]; + }, $optionsResolver, $optionsResolver); + } + + /** + * @param string $option + * + * @return mixed + * + * @throws NoConfigurationException on no configured value + */ + public function getDefault($option) + { + return call_user_func($this->get, 'defaults', $option, sprintf('No default value was set for the "%s" option.', $option)); + } + + /** + * @param string $option + * + * @return \Closure[] + * + * @throws NoConfigurationException on no configured closures + */ + public function getLazyClosures($option) + { + return call_user_func($this->get, 'lazy', $option, sprintf('No lazy closures were set for the "%s" option.', $option)); + } + + /** + * @param string $option + * + * @return string[] + * + * @throws NoConfigurationException on no configured types + */ + public function getAllowedTypes($option) + { + return call_user_func($this->get, 'allowedTypes', $option, sprintf('No allowed types were set for the "%s" option.', $option)); + } + + /** + * @param string $option + * + * @return mixed[] + * + * @throws NoConfigurationException on no configured values + */ + public function getAllowedValues($option) + { + return call_user_func($this->get, 'allowedValues', $option, sprintf('No allowed values were set for the "%s" option.', $option)); + } + + /** + * @param string $option + * + * @return \Closure + * + * @throws NoConfigurationException on no configured normalizer + */ + public function getNormalizer($option) + { + return call_user_func($this->get, 'normalizers', $option, sprintf('No normalizer was set for the "%s" option.', $option)); + } +} diff --git a/vendor/symfony/options-resolver/Exception/NoConfigurationException.php b/vendor/symfony/options-resolver/Exception/NoConfigurationException.php new file mode 100644 index 000000000..6693ec14d --- /dev/null +++ b/vendor/symfony/options-resolver/Exception/NoConfigurationException.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\OptionsResolver\Exception; + +use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector; + +/** + * Thrown when trying to introspect an option definition property + * for which no value was configured inside the OptionsResolver instance. + * + * @see OptionsResolverIntrospector + * + * @author Maxime Steinhausser + */ +class NoConfigurationException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/options-resolver/LICENSE b/vendor/symfony/options-resolver/LICENSE index 17d16a133..21d7fb9e2 100644 --- a/vendor/symfony/options-resolver/LICENSE +++ b/vendor/symfony/options-resolver/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2017 Fabien Potencier +Copyright (c) 2004-2018 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/symfony/options-resolver/OptionsResolver.php b/vendor/symfony/options-resolver/OptionsResolver.php index 32ac5663f..95a492de9 100644 --- a/vendor/symfony/options-resolver/OptionsResolver.php +++ b/vendor/symfony/options-resolver/OptionsResolver.php @@ -28,29 +28,21 @@ class OptionsResolver implements Options { /** * The names of all defined options. - * - * @var array */ private $defined = array(); /** * The default option values. - * - * @var array */ private $defaults = array(); /** * The names of required options. - * - * @var array */ private $required = array(); /** * The resolved option values. - * - * @var array */ private $resolved = array(); @@ -63,22 +55,16 @@ class OptionsResolver implements Options /** * A list of accepted values for each option. - * - * @var array */ private $allowedValues = array(); /** * A list of accepted types for each option. - * - * @var array */ private $allowedTypes = array(); /** * A list of closures for evaluating lazy options. - * - * @var array */ private $lazy = array(); @@ -86,8 +72,6 @@ class OptionsResolver implements Options * A list of lazy options whose closure is currently being called. * * This list helps detecting circular dependencies between lazy options. - * - * @var array */ private $calling = array(); @@ -98,8 +82,6 @@ class OptionsResolver implements Options * necessary in order to avoid inconsistencies during the resolving * process. If any option is changed after being read, all evaluated * lazy options that depend on this option would become invalid. - * - * @var bool */ private $locked = false; @@ -792,21 +774,12 @@ class OptionsResolver implements Options // Validate the type of the resolved option if (isset($this->allowedTypes[$option])) { $valid = false; + $invalidTypes = array(); foreach ($this->allowedTypes[$option] as $type) { $type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type; - if (function_exists($isFunction = 'is_'.$type)) { - if ($isFunction($value)) { - $valid = true; - break; - } - - continue; - } - - if ($value instanceof $type) { - $valid = true; + if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) { break; } } @@ -818,7 +791,7 @@ class OptionsResolver implements Options $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), - $this->formatTypeOf($value) + implode('|', array_keys($invalidTypes)) )); } } @@ -895,6 +868,45 @@ class OptionsResolver implements Options return $value; } + /** + * @param string $type + * @param mixed $value + * @param array &$invalidTypes + * + * @return bool + */ + private function verifyTypes($type, $value, array &$invalidTypes) + { + if ('[]' === substr($type, -2) && is_array($value)) { + $originalType = $type; + $type = substr($type, 0, -2); + $invalidValues = array_filter( // Filter out valid values, keeping invalid values in the resulting array + $value, + function ($value) use ($type) { + return !self::isValueValidType($type, $value); + } + ); + + if (!$invalidValues) { + return true; + } + + $invalidTypes[$this->formatTypeOf($value, $originalType)] = true; + + return false; + } + + if (self::isValueValidType($type, $value)) { + return true; + } + + if (!$invalidTypes) { + $invalidTypes[$this->formatTypeOf($value, null)] = true; + } + + return false; + } + /** * Returns whether a resolved option with the given name exists. * @@ -963,13 +975,38 @@ class OptionsResolver implements Options * parameters should usually not be included in messages aimed at * non-technical people. * - * @param mixed $value The value to return the type of + * @param mixed $value The value to return the type of + * @param string $type * * @return string The type of the value */ - private function formatTypeOf($value) + private function formatTypeOf($value, $type) { - return is_object($value) ? get_class($value) : gettype($value); + $suffix = ''; + + if ('[]' === substr($type, -2)) { + $suffix = '[]'; + $type = substr($type, 0, -2); + while ('[]' === substr($type, -2)) { + $type = substr($type, 0, -2); + $value = array_shift($value); + if (!is_array($value)) { + break; + } + $suffix .= '[]'; + } + + if (is_array($value)) { + $subTypes = array(); + foreach ($value as $val) { + $subTypes[$this->formatTypeOf($val, null)] = true; + } + + return implode('|', array_keys($subTypes)).$suffix; + } + } + + return (is_object($value) ? get_class($value) : gettype($value)).$suffix; } /** @@ -1036,4 +1073,9 @@ class OptionsResolver implements Options return implode(', ', $values); } + + private static function isValueValidType($type, $value) + { + return (function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type; + } } diff --git a/vendor/symfony/options-resolver/Tests/Debug/OptionsResolverIntrospectorTest.php b/vendor/symfony/options-resolver/Tests/Debug/OptionsResolverIntrospectorTest.php new file mode 100644 index 000000000..7c4753ab5 --- /dev/null +++ b/vendor/symfony/options-resolver/Tests/Debug/OptionsResolverIntrospectorTest.php @@ -0,0 +1,203 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\OptionsResolver\Tests\Debug; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class OptionsResolverIntrospectorTest extends TestCase +{ + public function testGetDefault() + { + $resolver = new OptionsResolver(); + $resolver->setDefault($option = 'foo', 'bar'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getDefault($option)); + } + + public function testGetDefaultNull() + { + $resolver = new OptionsResolver(); + $resolver->setDefault($option = 'foo', null); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertNull($debug->getDefault($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException + * @expectedExceptionMessage No default value was set for the "foo" option. + */ + public function testGetDefaultThrowsOnNoConfiguredValue() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getDefault($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException + * @expectedExceptionMessage The option "foo" does not exist. + */ + public function testGetDefaultThrowsOnNotDefinedOption() + { + $resolver = new OptionsResolver(); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getDefault('foo')); + } + + public function testGetLazyClosures() + { + $resolver = new OptionsResolver(); + $closures = array(); + $resolver->setDefault($option = 'foo', $closures[] = function (Options $options) {}); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame($closures, $debug->getLazyClosures($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException + * @expectedExceptionMessage No lazy closures were set for the "foo" option. + */ + public function testGetLazyClosuresThrowsOnNoConfiguredValue() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getLazyClosures($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException + * @expectedExceptionMessage The option "foo" does not exist. + */ + public function testGetLazyClosuresThrowsOnNotDefinedOption() + { + $resolver = new OptionsResolver(); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getLazyClosures('foo')); + } + + public function testGetAllowedTypes() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + $resolver->setAllowedTypes($option = 'foo', $allowedTypes = array('string', 'bool')); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame($allowedTypes, $debug->getAllowedTypes($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException + * @expectedExceptionMessage No allowed types were set for the "foo" option. + */ + public function testGetAllowedTypesThrowsOnNoConfiguredValue() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getAllowedTypes($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException + * @expectedExceptionMessage The option "foo" does not exist. + */ + public function testGetAllowedTypesThrowsOnNotDefinedOption() + { + $resolver = new OptionsResolver(); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getAllowedTypes('foo')); + } + + public function testGetAllowedValues() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + $resolver->setAllowedValues($option = 'foo', $allowedValues = array('bar', 'baz')); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame($allowedValues, $debug->getAllowedValues($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException + * @expectedExceptionMessage No allowed values were set for the "foo" option. + */ + public function testGetAllowedValuesThrowsOnNoConfiguredValue() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getAllowedValues($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException + * @expectedExceptionMessage The option "foo" does not exist. + */ + public function testGetAllowedValuesThrowsOnNotDefinedOption() + { + $resolver = new OptionsResolver(); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getAllowedValues('foo')); + } + + public function testGetNormalizer() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + $resolver->setNormalizer($option = 'foo', $normalizer = function () {}); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame($normalizer, $debug->getNormalizer($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\NoConfigurationException + * @expectedExceptionMessage No normalizer was set for the "foo" option. + */ + public function testGetNormalizerThrowsOnNoConfiguredValue() + { + $resolver = new OptionsResolver(); + $resolver->setDefined($option = 'foo'); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getNormalizer($option)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException + * @expectedExceptionMessage The option "foo" does not exist. + */ + public function testGetNormalizerThrowsOnNotDefinedOption() + { + $resolver = new OptionsResolver(); + + $debug = new OptionsResolverIntrospector($resolver); + $this->assertSame('bar', $debug->getNormalizer('foo')); + } +} diff --git a/vendor/symfony/options-resolver/Tests/OptionsResolverTest.php b/vendor/symfony/options-resolver/Tests/OptionsResolverTest.php index d09dece33..440af8b57 100644 --- a/vendor/symfony/options-resolver/Tests/OptionsResolverTest.php +++ b/vendor/symfony/options-resolver/Tests/OptionsResolverTest.php @@ -486,6 +486,15 @@ class OptionsResolverTest extends TestCase $this->resolver->setAllowedTypes('foo', 'string'); } + public function testResolveTypedArray() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'string[]'); + $options = $this->resolver->resolve(array('foo' => array('bar', 'baz'))); + + $this->assertSame(array('foo' => array('bar', 'baz')), $options); + } + /** * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException */ @@ -500,6 +509,65 @@ class OptionsResolverTest extends TestCase $this->resolver->resolve(); } + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "DateTime[]". + */ + public function testResolveFailsIfInvalidTypedArray() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[]'); + + $this->resolver->resolve(array('foo' => array(new \DateTime()))); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value "bar" is expected to be of type "int[]", but is of type "string". + */ + public function testResolveFailsWithNonArray() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[]'); + + $this->resolver->resolve(array('foo' => 'bar')); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[]", but is of type "integer|stdClass|array|DateTime[]". + */ + public function testResolveFailsIfTypedArrayContainsInvalidTypes() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[]'); + $values = range(1, 5); + $values[] = new \stdClass(); + $values[] = array(); + $values[] = new \DateTime(); + $values[] = 123; + + $this->resolver->resolve(array('foo' => $values)); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + * @expectedExceptionMessage The option "foo" with value array is expected to be of type "int[][]", but is of type "double[][]". + */ + public function testResolveFailsWithCorrectLevelsButWrongScalar() + { + $this->resolver->setDefined('foo'); + $this->resolver->setAllowedTypes('foo', 'int[][]'); + + $this->resolver->resolve( + array( + 'foo' => array( + array(1.2), + ), + ) + ); + } + /** * @dataProvider provideInvalidTypes */ @@ -568,6 +636,32 @@ class OptionsResolverTest extends TestCase $this->assertNotEmpty($this->resolver->resolve()); } + public function testResolveSucceedsIfTypedArray() + { + $this->resolver->setDefault('foo', null); + $this->resolver->setAllowedTypes('foo', array('null', 'DateTime[]')); + + $data = array( + 'foo' => array( + new \DateTime(), + new \DateTime(), + ), + ); + $result = $this->resolver->resolve($data); + $this->assertEquals($data, $result); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testResolveFailsIfNotInstanceOfClass() + { + $this->resolver->setDefault('foo', 'bar'); + $this->resolver->setAllowedTypes('foo', '\stdClass'); + + $this->resolver->resolve(); + } + //////////////////////////////////////////////////////////////////////////// // addAllowedTypes() //////////////////////////////////////////////////////////////////////////// @@ -1419,12 +1513,12 @@ class OptionsResolverTest extends TestCase }); $this->resolver->setDefault('lazy2', function (Options $options) { - Assert::assertTrue(isset($options['default1'])); - Assert::assertTrue(isset($options['default2'])); - Assert::assertTrue(isset($options['required'])); - Assert::assertTrue(isset($options['lazy1'])); - Assert::assertTrue(isset($options['lazy2'])); - Assert::assertFalse(isset($options['defined'])); + Assert::assertArrayHasKey('default1', $options); + Assert::assertArrayHasKey('default2', $options); + Assert::assertArrayHasKey('required', $options); + Assert::assertArrayHasKey('lazy1', $options); + Assert::assertArrayHasKey('lazy2', $options); + Assert::assertArrayNotHasKey('defined', $options); Assert::assertSame(0, $options['default1']); Assert::assertSame(42, $options['default2']); diff --git a/vendor/symfony/options-resolver/composer.json b/vendor/symfony/options-resolver/composer.json index a751730af..895847ea5 100644 --- a/vendor/symfony/options-resolver/composer.json +++ b/vendor/symfony/options-resolver/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\OptionsResolver\\": "" }, @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } } }