Update vendored libs

This commit is contained in:
Frédéric Guillot 2020-06-08 22:46:20 -07:00
parent dfb0a2d915
commit f60e4a0c59
292 changed files with 9402 additions and 9487 deletions

View File

@ -31,7 +31,7 @@
"erusev/parsedown" : "^1.7",
"pimple/pimple" : "3.2.2",
"psr/log": "~1.0",
"swiftmailer/swiftmailer" : "6.2.3",
"swiftmailer/swiftmailer" : "5.4.8",
"symfony/console" : "4.2.12",
"symfony/event-dispatcher" : "3.4.2",
"gregwar/captcha": "1.1.8"

462
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8e726f52ab3006ef6d39a727c544a8b1",
"content-hash": "0f6452f203d40962c9d66b14f72e16fa",
"packages": [
{
"name": "christian-riesen/base32",
@ -112,126 +112,6 @@
],
"time": "2015-10-08T08:17:59+00:00"
},
{
"name": "doctrine/lexer",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "e864bbf5904cb8f5bb334f99209b48018522f042"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042",
"reference": "e864bbf5904cb8f5bb334f99209b48018522f042",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^6.0",
"phpstan/phpstan": "^0.11.8",
"phpunit/phpunit": "^8.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"keywords": [
"annotations",
"docblock",
"lexer",
"parser",
"php"
],
"time": "2020-05-25T17:44:05+00:00"
},
{
"name": "egulias/email-validator",
"version": "2.1.17",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a",
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a",
"shasum": ""
},
"require": {
"doctrine/lexer": "^1.0.1",
"php": ">=5.5",
"symfony/polyfill-intl-idn": "^1.10"
},
"require-dev": {
"dominicsayers/isemail": "^3.0.7",
"phpunit/phpunit": "^4.8.36|^7.5.15",
"satooshi/php-coveralls": "^1.0.1"
},
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Egulias\\EmailValidator\\": "EmailValidator"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eduardo Gulias Davis"
}
],
"description": "A library for validating emails against several RFCs",
"homepage": "https://github.com/egulias/EmailValidator",
"keywords": [
"email",
"emailvalidation",
"emailvalidator",
"validation",
"validator"
],
"time": "2020-02-13T22:36:52+00:00"
},
{
"name": "eluceo/ical",
"version": "0.10.1",
@ -434,6 +314,52 @@
],
"time": "2017-07-23T07:32:15+00:00"
},
{
"name": "psr/cache",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"time": "2016-08-06T20:24:11+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
@ -532,37 +458,29 @@
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.2.3",
"version": "v5.4.8",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/9a06dc570a0367850280eefd3f1dc2da45aef517",
"reference": "9a06dc570a0367850280eefd3f1dc2da45aef517",
"shasum": ""
},
"require": {
"egulias/email-validator": "~2.0",
"php": ">=7.0.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
"php": ">=5.3.3"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "^3.4.19|^4.1.8"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses",
"true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
"symfony/phpunit-bridge": "~3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
"dev-master": "5.4-dev"
}
},
"autoload": {
@ -584,13 +502,13 @@
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "https://swiftmailer.symfony.com",
"homepage": "http://swiftmailer.org",
"keywords": [
"email",
"mail",
"mailer"
],
"time": "2019-11-12T09:31:26+00:00"
"time": "2017-05-01T15:54:03+00:00"
},
{
"name": "symfony/console",
@ -666,34 +584,40 @@
},
{
"name": "symfony/contracts",
"version": "v1.1.0",
"version": "v1.1.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/contracts.git",
"reference": "d3636025e8253c6144358ec0a62773cae588395b"
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/contracts/zipball/d3636025e8253c6144358ec0a62773cae588395b",
"reference": "d3636025e8253c6144358ec0a62773cae588395b",
"url": "https://api.github.com/repos/symfony/contracts/zipball/f51bca9de06b7a25b19a4155da7bebad099a5def",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def",
"shasum": ""
},
"require": {
"php": "^7.1.3"
"php": "^7.1.3",
"psr/cache": "^1.0",
"psr/container": "^1.0"
},
"replace": {
"symfony/cache-contracts": "self.version",
"symfony/event-dispatcher-contracts": "self.version",
"symfony/http-client-contracts": "self.version",
"symfony/service-contracts": "self.version",
"symfony/translation-contracts": "self.version"
},
"require-dev": {
"psr/cache": "^1.0",
"psr/container": "^1.0",
"symfony/polyfill-intl-idn": "^1.10"
},
"suggest": {
"psr/cache": "When using the Cache contracts",
"psr/container": "When using the Service contracts",
"symfony/cache-contracts-implementation": "",
"psr/event-dispatcher": "When using the EventDispatcher contracts",
"symfony/cache-implementation": "",
"symfony/event-dispatcher-implementation": "",
"symfony/http-client-contracts-implementation": "",
"symfony/service-contracts-implementation": "",
"symfony/translation-contracts-implementation": ""
"symfony/http-client-implementation": "",
"symfony/service-implementation": "",
"symfony/translation-implementation": ""
},
"type": "library",
"extra": {
@ -733,7 +657,7 @@
"interoperability",
"standards"
],
"time": "2019-04-27T14:29:50+00:00"
"time": "2019-11-07T12:44:51+00:00"
},
{
"name": "symfony/event-dispatcher",
@ -847,127 +771,6 @@
"homepage": "https://symfony.com",
"time": "2018-04-04T05:07:11+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c4de7601eefbf25f9d47190abe07f79fe0a27424",
"reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Iconv\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Iconv extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"iconv",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a",
"reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.17.0",
@ -1026,61 +829,6 @@
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "f048e612a3905f34931127360bdd2def19a5e582"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
"reference": "f048e612a3905f34931127360bdd2def19a5e582",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
}
],
"packages-dev": [
@ -2864,64 +2612,6 @@
],
"time": "2020-05-12T16:14:59+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/66a8f0957a3ca54e4f724e49028ab19d75a8918b",
"reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"psr/container": "^1.0"
},
"suggest": {
"symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\Service\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to writing services",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"time": "2020-05-20T17:43:50+00:00"
},
{
"name": "symfony/stopwatch",
"version": "v4.4.9",

2
vendor/autoload.php vendored
View File

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

View File

@ -782,6 +782,10 @@ return array(
'PostgresSchemaTest' => $baseDir . '/libs/picodb/tests/PostgresSchemaTest.php',
'PostgresTableTest' => $baseDir . '/libs/picodb/tests/PostgresTableTest.php',
'ProcedureHandlerTest' => $baseDir . '/libs/jsonrpc/tests/ProcedureHandlerTest.php',
'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php',
'Psr\\Cache\\InvalidArgumentException' => $vendorDir . '/psr/cache/src/InvalidArgumentException.php',
'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
@ -857,19 +861,20 @@ return array(
'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php',
'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php',
'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php',
'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php',
'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php',
'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php',
'Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => $vendorDir . '/symfony/console/Exception/NamespaceNotFoundException.php',
'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
'Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php',
'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php',
'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php',
@ -884,6 +889,7 @@ return array(
'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php',
'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php',
'Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php',
@ -900,6 +906,7 @@ return array(
'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php',
'Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => $vendorDir . '/symfony/console/Output/ConsoleSectionOutput.php',
'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php',
'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php',
'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php',
@ -913,24 +920,7 @@ return array(
'Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php',
'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php',
'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php',
'Symfony\\Component\\Debug\\BufferingLogger' => $vendorDir . '/symfony/debug/BufferingLogger.php',
'Symfony\\Component\\Debug\\Debug' => $vendorDir . '/symfony/debug/Debug.php',
'Symfony\\Component\\Debug\\DebugClassLoader' => $vendorDir . '/symfony/debug/DebugClassLoader.php',
'Symfony\\Component\\Debug\\ErrorHandler' => $vendorDir . '/symfony/debug/ErrorHandler.php',
'Symfony\\Component\\Debug\\ExceptionHandler' => $vendorDir . '/symfony/debug/ExceptionHandler.php',
'Symfony\\Component\\Debug\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/debug/Exception/ClassNotFoundException.php',
'Symfony\\Component\\Debug\\Exception\\ContextErrorException' => $vendorDir . '/symfony/debug/Exception/ContextErrorException.php',
'Symfony\\Component\\Debug\\Exception\\FatalErrorException' => $vendorDir . '/symfony/debug/Exception/FatalErrorException.php',
'Symfony\\Component\\Debug\\Exception\\FatalThrowableError' => $vendorDir . '/symfony/debug/Exception/FatalThrowableError.php',
'Symfony\\Component\\Debug\\Exception\\FlattenException' => $vendorDir . '/symfony/debug/Exception/FlattenException.php',
'Symfony\\Component\\Debug\\Exception\\OutOfMemoryException' => $vendorDir . '/symfony/debug/Exception/OutOfMemoryException.php',
'Symfony\\Component\\Debug\\Exception\\SilencedErrorContext' => $vendorDir . '/symfony/debug/Exception/SilencedErrorContext.php',
'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => $vendorDir . '/symfony/debug/Exception/UndefinedFunctionException.php',
'Symfony\\Component\\Debug\\Exception\\UndefinedMethodException' => $vendorDir . '/symfony/debug/Exception/UndefinedMethodException.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface' => $vendorDir . '/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php',
'Symfony\\Component\\Console\\Tester\\TesterTrait' => $vendorDir . '/symfony/console/Tester/TesterTrait.php',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php',
@ -964,6 +954,42 @@ return array(
'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php',
'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php',
'Symfony\\Contracts\\Cache\\CacheInterface' => $vendorDir . '/symfony/contracts/Cache/CacheInterface.php',
'Symfony\\Contracts\\Cache\\CacheTrait' => $vendorDir . '/symfony/contracts/Cache/CacheTrait.php',
'Symfony\\Contracts\\Cache\\CallbackInterface' => $vendorDir . '/symfony/contracts/Cache/CallbackInterface.php',
'Symfony\\Contracts\\Cache\\ItemInterface' => $vendorDir . '/symfony/contracts/Cache/ItemInterface.php',
'Symfony\\Contracts\\Cache\\TagAwareCacheInterface' => $vendorDir . '/symfony/contracts/Cache/TagAwareCacheInterface.php',
'Symfony\\Contracts\\EventDispatcher\\Event' => $vendorDir . '/symfony/contracts/EventDispatcher/Event.php',
'Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/contracts/EventDispatcher/EventDispatcherInterface.php',
'Symfony\\Contracts\\HttpClient\\ChunkInterface' => $vendorDir . '/symfony/contracts/HttpClient/ChunkInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ClientExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/ClientExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\DecodingExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/DecodingExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/ExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\HttpExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/HttpExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\RedirectionExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/RedirectionExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ServerExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/ServerExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\TransportExceptionInterface' => $vendorDir . '/symfony/contracts/HttpClient/Exception/TransportExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\HttpClientInterface' => $vendorDir . '/symfony/contracts/HttpClient/HttpClientInterface.php',
'Symfony\\Contracts\\HttpClient\\ResponseInterface' => $vendorDir . '/symfony/contracts/HttpClient/ResponseInterface.php',
'Symfony\\Contracts\\HttpClient\\ResponseStreamInterface' => $vendorDir . '/symfony/contracts/HttpClient/ResponseStreamInterface.php',
'Symfony\\Contracts\\HttpClient\\Test\\HttpClientTestCase' => $vendorDir . '/symfony/contracts/HttpClient/Test/HttpClientTestCase.php',
'Symfony\\Contracts\\HttpClient\\Test\\TestHttpServer' => $vendorDir . '/symfony/contracts/HttpClient/Test/TestHttpServer.php',
'Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/contracts/Service/ResetInterface.php',
'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => $vendorDir . '/symfony/contracts/Service/ServiceLocatorTrait.php',
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/contracts/Service/ServiceProviderInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/contracts/Service/ServiceSubscriberInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/contracts/Service/ServiceSubscriberTrait.php',
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => $vendorDir . '/symfony/contracts/Service/Test/ServiceLocatorTest.php',
'Symfony\\Contracts\\Tests\\Cache\\CacheTraitTest' => $vendorDir . '/symfony/contracts/Tests/Cache/CacheTraitTest.php',
'Symfony\\Contracts\\Tests\\Cache\\TestPool' => $vendorDir . '/symfony/contracts/Tests/Cache/CacheTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ChildTestService' => $vendorDir . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ParentTestService' => $vendorDir . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ServiceSubscriberTraitTest' => $vendorDir . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\TestService' => $vendorDir . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Translation\\LocaleAwareInterface' => $vendorDir . '/symfony/contracts/Translation/LocaleAwareInterface.php',
'Symfony\\Contracts\\Translation\\Test\\TranslatorTest' => $vendorDir . '/symfony/contracts/Translation/Test/TranslatorTest.php',
'Symfony\\Contracts\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/contracts/Translation/TranslatorInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorTrait' => $vendorDir . '/symfony/contracts/Translation/TranslatorTrait.php',
'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
'UrlParserTest' => $baseDir . '/libs/picodb/tests/UrlParserTest.php',
'UserValidatorTest' => $baseDir . '/libs/jsonrpc/tests/Validator/UserValidatorTest.php',

View File

@ -7,12 +7,13 @@ $baseDir = dirname($vendorDir);
return array(
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Contracts\\' => array($vendorDir . '/symfony/contracts'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'Kanboard\\' => array($baseDir . '/app'),
'Gregwar\\' => array($vendorDir . '/gregwar/captcha/src/Gregwar'),
'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit094f3eabe2924332bc2198a9ba245f27
class ComposerAutoloaderInit80f59a55e693f3d5493bcaaa968d1851
{
private static $loader;
@ -19,15 +19,15 @@ class ComposerAutoloaderInit094f3eabe2924332bc2198a9ba245f27
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit094f3eabe2924332bc2198a9ba245f27', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit80f59a55e693f3d5493bcaaa968d1851', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit094f3eabe2924332bc2198a9ba245f27', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit80f59a55e693f3d5493bcaaa968d1851', '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\ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@ -48,19 +48,19 @@ class ComposerAutoloaderInit094f3eabe2924332bc2198a9ba245f27
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$files;
$includeFiles = Composer\Autoload\ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire094f3eabe2924332bc2198a9ba245f27($fileIdentifier, $file);
composerRequire80f59a55e693f3d5493bcaaa968d1851($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire094f3eabe2924332bc2198a9ba245f27($fileIdentifier, $file)
function composerRequire80f59a55e693f3d5493bcaaa968d1851($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
class ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -16,15 +16,16 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'S' =>
array (
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Contracts\\' => 18,
'Symfony\\Component\\Finder\\' => 25,
'Symfony\\Component\\EventDispatcher\\' => 34,
'Symfony\\Component\\Debug\\' => 24,
'Symfony\\Component\\Console\\' => 26,
),
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Container\\' => 14,
'Psr\\Cache\\' => 10,
),
'K' =>
array (
@ -45,6 +46,10 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Contracts\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/contracts',
),
'Symfony\\Component\\Finder\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/finder',
@ -53,10 +58,6 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\Debug\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/debug',
),
'Symfony\\Component\\Console\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/console',
@ -69,6 +70,10 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/cache/src',
),
'Kanboard\\' =>
array (
0 => __DIR__ . '/../..' . '/app',
@ -892,6 +897,10 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'PostgresSchemaTest' => __DIR__ . '/../..' . '/libs/picodb/tests/PostgresSchemaTest.php',
'PostgresTableTest' => __DIR__ . '/../..' . '/libs/picodb/tests/PostgresTableTest.php',
'ProcedureHandlerTest' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/ProcedureHandlerTest.php',
'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php',
'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php',
'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php',
'Psr\\Cache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/cache/src/InvalidArgumentException.php',
'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
@ -967,19 +976,20 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleCommandEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleErrorEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleExceptionEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleTerminateEvent.php',
'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/CommandNotFoundException.php',
'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/console/Exception/ExceptionInterface.php',
'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidArgumentException.php',
'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidOptionException.php',
'Symfony\\Component\\Console\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/console/Exception/LogicException.php',
'Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/NamespaceNotFoundException.php',
'Symfony\\Component\\Console\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/console/Exception/RuntimeException.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatter.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyle.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
'Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php',
'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DebugFormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DescriptorHelper.php',
'Symfony\\Component\\Console\\Helper\\FormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/FormatterHelper.php',
@ -994,6 +1004,7 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/SymfonyQuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\Table' => __DIR__ . '/..' . '/symfony/console/Helper/Table.php',
'Symfony\\Component\\Console\\Helper\\TableCell' => __DIR__ . '/..' . '/symfony/console/Helper/TableCell.php',
'Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php',
@ -1010,6 +1021,7 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'Symfony\\Component\\Console\\Output\\BufferedOutput' => __DIR__ . '/..' . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutputInterface.php',
'Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleSectionOutput.php',
'Symfony\\Component\\Console\\Output\\NullOutput' => __DIR__ . '/..' . '/symfony/console/Output/NullOutput.php',
'Symfony\\Component\\Console\\Output\\Output' => __DIR__ . '/..' . '/symfony/console/Output/Output.php',
'Symfony\\Component\\Console\\Output\\OutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/OutputInterface.php',
@ -1023,24 +1035,7 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'Symfony\\Component\\Console\\Terminal' => __DIR__ . '/..' . '/symfony/console/Terminal.php',
'Symfony\\Component\\Console\\Tester\\ApplicationTester' => __DIR__ . '/..' . '/symfony/console/Tester/ApplicationTester.php',
'Symfony\\Component\\Console\\Tester\\CommandTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandTester.php',
'Symfony\\Component\\Debug\\BufferingLogger' => __DIR__ . '/..' . '/symfony/debug/BufferingLogger.php',
'Symfony\\Component\\Debug\\Debug' => __DIR__ . '/..' . '/symfony/debug/Debug.php',
'Symfony\\Component\\Debug\\DebugClassLoader' => __DIR__ . '/..' . '/symfony/debug/DebugClassLoader.php',
'Symfony\\Component\\Debug\\ErrorHandler' => __DIR__ . '/..' . '/symfony/debug/ErrorHandler.php',
'Symfony\\Component\\Debug\\ExceptionHandler' => __DIR__ . '/..' . '/symfony/debug/ExceptionHandler.php',
'Symfony\\Component\\Debug\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/debug/Exception/ClassNotFoundException.php',
'Symfony\\Component\\Debug\\Exception\\ContextErrorException' => __DIR__ . '/..' . '/symfony/debug/Exception/ContextErrorException.php',
'Symfony\\Component\\Debug\\Exception\\FatalErrorException' => __DIR__ . '/..' . '/symfony/debug/Exception/FatalErrorException.php',
'Symfony\\Component\\Debug\\Exception\\FatalThrowableError' => __DIR__ . '/..' . '/symfony/debug/Exception/FatalThrowableError.php',
'Symfony\\Component\\Debug\\Exception\\FlattenException' => __DIR__ . '/..' . '/symfony/debug/Exception/FlattenException.php',
'Symfony\\Component\\Debug\\Exception\\OutOfMemoryException' => __DIR__ . '/..' . '/symfony/debug/Exception/OutOfMemoryException.php',
'Symfony\\Component\\Debug\\Exception\\SilencedErrorContext' => __DIR__ . '/..' . '/symfony/debug/Exception/SilencedErrorContext.php',
'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => __DIR__ . '/..' . '/symfony/debug/Exception/UndefinedFunctionException.php',
'Symfony\\Component\\Debug\\Exception\\UndefinedMethodException' => __DIR__ . '/..' . '/symfony/debug/Exception/UndefinedMethodException.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => __DIR__ . '/..' . '/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface' => __DIR__ . '/..' . '/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => __DIR__ . '/..' . '/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php',
'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler' => __DIR__ . '/..' . '/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php',
'Symfony\\Component\\Console\\Tester\\TesterTrait' => __DIR__ . '/..' . '/symfony/console/Tester/TesterTrait.php',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => __DIR__ . '/..' . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => __DIR__ . '/..' . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php',
@ -1074,6 +1069,42 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SortableIterator.php',
'Symfony\\Component\\Finder\\SplFileInfo' => __DIR__ . '/..' . '/symfony/finder/SplFileInfo.php',
'Symfony\\Contracts\\Cache\\CacheInterface' => __DIR__ . '/..' . '/symfony/contracts/Cache/CacheInterface.php',
'Symfony\\Contracts\\Cache\\CacheTrait' => __DIR__ . '/..' . '/symfony/contracts/Cache/CacheTrait.php',
'Symfony\\Contracts\\Cache\\CallbackInterface' => __DIR__ . '/..' . '/symfony/contracts/Cache/CallbackInterface.php',
'Symfony\\Contracts\\Cache\\ItemInterface' => __DIR__ . '/..' . '/symfony/contracts/Cache/ItemInterface.php',
'Symfony\\Contracts\\Cache\\TagAwareCacheInterface' => __DIR__ . '/..' . '/symfony/contracts/Cache/TagAwareCacheInterface.php',
'Symfony\\Contracts\\EventDispatcher\\Event' => __DIR__ . '/..' . '/symfony/contracts/EventDispatcher/Event.php',
'Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface' => __DIR__ . '/..' . '/symfony/contracts/EventDispatcher/EventDispatcherInterface.php',
'Symfony\\Contracts\\HttpClient\\ChunkInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/ChunkInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ClientExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/ClientExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\DecodingExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/DecodingExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/ExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\HttpExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/HttpExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\RedirectionExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/RedirectionExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\ServerExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/ServerExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\Exception\\TransportExceptionInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Exception/TransportExceptionInterface.php',
'Symfony\\Contracts\\HttpClient\\HttpClientInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/HttpClientInterface.php',
'Symfony\\Contracts\\HttpClient\\ResponseInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/ResponseInterface.php',
'Symfony\\Contracts\\HttpClient\\ResponseStreamInterface' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/ResponseStreamInterface.php',
'Symfony\\Contracts\\HttpClient\\Test\\HttpClientTestCase' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Test/HttpClientTestCase.php',
'Symfony\\Contracts\\HttpClient\\Test\\TestHttpServer' => __DIR__ . '/..' . '/symfony/contracts/HttpClient/Test/TestHttpServer.php',
'Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/contracts/Service/ResetInterface.php',
'Symfony\\Contracts\\Service\\ServiceLocatorTrait' => __DIR__ . '/..' . '/symfony/contracts/Service/ServiceLocatorTrait.php',
'Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/contracts/Service/ServiceProviderInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/contracts/Service/ServiceSubscriberInterface.php',
'Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/contracts/Service/ServiceSubscriberTrait.php',
'Symfony\\Contracts\\Service\\Test\\ServiceLocatorTest' => __DIR__ . '/..' . '/symfony/contracts/Service/Test/ServiceLocatorTest.php',
'Symfony\\Contracts\\Tests\\Cache\\CacheTraitTest' => __DIR__ . '/..' . '/symfony/contracts/Tests/Cache/CacheTraitTest.php',
'Symfony\\Contracts\\Tests\\Cache\\TestPool' => __DIR__ . '/..' . '/symfony/contracts/Tests/Cache/CacheTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ChildTestService' => __DIR__ . '/..' . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ParentTestService' => __DIR__ . '/..' . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\ServiceSubscriberTraitTest' => __DIR__ . '/..' . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Tests\\Service\\TestService' => __DIR__ . '/..' . '/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php',
'Symfony\\Contracts\\Translation\\LocaleAwareInterface' => __DIR__ . '/..' . '/symfony/contracts/Translation/LocaleAwareInterface.php',
'Symfony\\Contracts\\Translation\\Test\\TranslatorTest' => __DIR__ . '/..' . '/symfony/contracts/Translation/Test/TranslatorTest.php',
'Symfony\\Contracts\\Translation\\TranslatorInterface' => __DIR__ . '/..' . '/symfony/contracts/Translation/TranslatorInterface.php',
'Symfony\\Contracts\\Translation\\TranslatorTrait' => __DIR__ . '/..' . '/symfony/contracts/Translation/TranslatorTrait.php',
'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php',
'UrlParserTest' => __DIR__ . '/../..' . '/libs/picodb/tests/UrlParserTest.php',
'UserValidatorTest' => __DIR__ . '/../..' . '/libs/jsonrpc/tests/Validator/UserValidatorTest.php',
@ -1082,11 +1113,11 @@ class ComposerStaticInit094f3eabe2924332bc2198a9ba245f27
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$prefixesPsr0;
$loader->fallbackDirsPsr0 = ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$fallbackDirsPsr0;
$loader->classMap = ComposerStaticInit094f3eabe2924332bc2198a9ba245f27::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$prefixesPsr0;
$loader->fallbackDirsPsr0 = ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$fallbackDirsPsr0;
$loader->classMap = ComposerStaticInit80f59a55e693f3d5493bcaaa968d1851::$classMap;
}, null, ClassLoader::class);
}

View File

@ -214,29 +214,29 @@
},
{
"name": "gregwar/captcha",
"version": "v1.1.4",
"version_normalized": "1.1.4.0",
"version": "v1.1.8",
"version_normalized": "1.1.8.0",
"source": {
"type": "git",
"url": "https://github.com/Gregwar/Captcha.git",
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c"
"reference": "6088ad3db59bc226423ad1476a9f0424b19b1866"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/0185f4a64faef65612792f0d9a48dbe8d70c585c",
"reference": "0185f4a64faef65612792f0d9a48dbe8d70c585c",
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/6088ad3db59bc226423ad1476a9f0424b19b1866",
"reference": "6088ad3db59bc226423ad1476a9f0424b19b1866",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-mbstring": "*",
"php": ">=5.3.0",
"symfony/finder": "~3.0"
"symfony/finder": "*"
},
"require-dev": {
"phpunit/phpunit": "^6.4"
},
"time": "2017-12-01T13:59:36+00:00",
"time": "2020-01-22T14:54:02+00:00",
"type": "captcha",
"installation-source": "dist",
"autoload": {
@ -319,6 +319,54 @@
"dependency injection"
]
},
{
"name": "psr/cache",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
"reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2016-08-06T20:24:11+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
]
},
{
"name": "psr/container",
"version": "1.0.0",
@ -477,35 +525,38 @@
},
{
"name": "symfony/console",
"version": "v3.4.2",
"version_normalized": "3.4.2.0",
"version": "v4.2.12",
"version_normalized": "4.2.12.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e"
"reference": "fc2e274aade6567a750551942094b2145ade9b6c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/9f21adfb92a9315b73ae2ed43138988ee4913d4e",
"reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e",
"url": "https://api.github.com/repos/symfony/console/zipball/fc2e274aade6567a750551942094b2145ade9b6c",
"reference": "fc2e274aade6567a750551942094b2145ade9b6c",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8",
"symfony/debug": "~2.8|~3.0|~4.0",
"php": "^7.1.3",
"symfony/contracts": "^1.0",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
"symfony/process": "<3.3"
},
"provide": {
"psr/log-implementation": "1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.3|~4.0",
"symfony/config": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/event-dispatcher": "~3.4|~4.0",
"symfony/lock": "~3.4|~4.0",
"symfony/process": "~3.3|~4.0"
"symfony/process": "~3.4|~4.0"
},
"suggest": {
"psr/log": "For using the console logger",
@ -513,11 +564,11 @@
"symfony/lock": "",
"symfony/process": ""
},
"time": "2017-12-14T19:40:10+00:00",
"time": "2019-07-24T17:13:20+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
"dev-master": "4.2-dev"
}
},
"installation-source": "dist",
@ -547,44 +598,57 @@
"homepage": "https://symfony.com"
},
{
"name": "symfony/debug",
"version": "v3.4.2",
"version_normalized": "3.4.2.0",
"name": "symfony/contracts",
"version": "v1.1.8",
"version_normalized": "1.1.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "543deab3ffff94402440b326fc94153bae2dfa7a"
"url": "https://github.com/symfony/contracts.git",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/543deab3ffff94402440b326fc94153bae2dfa7a",
"reference": "543deab3ffff94402440b326fc94153bae2dfa7a",
"url": "https://api.github.com/repos/symfony/contracts/zipball/f51bca9de06b7a25b19a4155da7bebad099a5def",
"reference": "f51bca9de06b7a25b19a4155da7bebad099a5def",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8",
"psr/log": "~1.0"
"php": "^7.1.3",
"psr/cache": "^1.0",
"psr/container": "^1.0"
},
"conflict": {
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
"replace": {
"symfony/cache-contracts": "self.version",
"symfony/event-dispatcher-contracts": "self.version",
"symfony/http-client-contracts": "self.version",
"symfony/service-contracts": "self.version",
"symfony/translation-contracts": "self.version"
},
"require-dev": {
"symfony/http-kernel": "~2.8|~3.0|~4.0"
"symfony/polyfill-intl-idn": "^1.10"
},
"time": "2017-12-12T08:27:14+00:00",
"suggest": {
"psr/event-dispatcher": "When using the EventDispatcher contracts",
"symfony/cache-implementation": "",
"symfony/event-dispatcher-implementation": "",
"symfony/http-client-implementation": "",
"symfony/service-implementation": "",
"symfony/translation-implementation": ""
},
"time": "2019-11-07T12:44:51+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
"dev-master": "1.1-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Debug\\": ""
"Symfony\\Contracts\\": ""
},
"exclude-from-classmap": [
"/Tests/"
"**/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@ -593,16 +657,24 @@
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com"
"description": "A set of abstractions extracted out of the Symfony components",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
]
},
{
"name": "symfony/event-dispatcher",

View File

@ -122,6 +122,12 @@ You can also pass directly the wanted phrase to the builder:
$captcha = new CaptchaBuilder('hello');
```
Complete example
================
If you want to see an example you can have a look at he ``demo/form.php``, which uses ``demo/session.php`` to
render a captcha and check it after the submission
Symfony Bundle
================

View File

@ -20,7 +20,7 @@
"php": ">=5.3.0",
"ext-gd": "*",
"ext-mbstring": "*",
"symfony/finder": "~3.0"
"symfony/finder": "*"
},
"autoload": {
"psr-4": {

32
vendor/gregwar/captcha/demo/form.php vendored Normal file
View File

@ -0,0 +1,32 @@
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Gregwar\Captcha\PhraseBuilder;
// We need the session to check the phrase after submitting
session_start();
?>
<html>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Checking that the posted phrase match the phrase stored in the session
if (isset($_SESSION['phrase']) && PhraseBuilder::comparePhrases($_SESSION['phrase'], $_POST['phrase'])) {
echo "<h1>Captcha is valid !</h1>";
} else {
echo "<h1>Captcha is not valid!</h1>";
}
// The phrase can't be used twice
unset($_SESSION['phrase']);
}
?>
<form method="post">
Copy the CAPTCHA:
<?php
// See session.php, where the captcha is actually rendered and the session phrase
// is set accordingly to the image displayed
?>
<img src="session.php" />
<input type="text" name="phrase" />
<input type="submit" />
</form>
</html>

22
vendor/gregwar/captcha/demo/inline.php vendored Normal file
View File

@ -0,0 +1,22 @@
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Gregwar\Captcha\CaptchaBuilder;
$captcha = new CaptchaBuilder();
$captcha->build();
?>
<!DOCTYPE html>
<body>
<html>
<meta charset="utf-8" />
</html>
<body>
<h1>Inline Captcha</h1>
<img src="<?php echo $captcha->inline(); ?>"/><br/>
Phrase: <?php echo $captcha->getPhrase(); ?>
</body>
</body>

22
vendor/gregwar/captcha/demo/session.php vendored Normal file
View File

@ -0,0 +1,22 @@
<?php
// We need the session to store the correct phrase for later check
session_start();
// Including the autoload (you need to composer install in the main directory)
require_once __DIR__.'/../vendor/autoload.php';
use Gregwar\Captcha\CaptchaBuilder;
// Creating the captcha instance and setting the phrase in the session to store
// it for check when the form is submitted
$captcha = new CaptchaBuilder;
$_SESSION['phrase'] = $captcha->getPhrase();
// Setting the header to image jpeg because we here render an image
header('Content-Type: image/jpeg');
// Running the actual rendering of the captcha image
$captcha
->build()
->output()
;

View File

@ -26,7 +26,7 @@ class CaptchaBuilder implements CaptchaBuilderInterface
/**
* @var array
*/
protected $textColor = null;
protected $textColor = array();
/**
* @var array
@ -135,12 +135,8 @@ class CaptchaBuilder implements CaptchaBuilderInterface
} else {
$this->builder = $builder;
}
if ($phrase === null) {
$phrase = $this->builder->build();
}
$this->phrase = $phrase;
$this->phrase = is_string($phrase) ? $phrase : $this->builder->build($phrase);
}
/**

View File

@ -21,7 +21,7 @@ class PhraseBuilder implements PhraseBuilderInterface
/**
* Constructs a PhraseBuilder with given parameters
*/
public function __construct($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789')
public function __construct($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
$this->length = $length;
$this->charset = $charset;
@ -53,7 +53,23 @@ class PhraseBuilder implements PhraseBuilderInterface
* "Niceize" a code
*/
public function niceize($str)
{
return self::doNiceize($str);
}
/**
* A static helper to niceize
*/
public static function doNiceize($str)
{
return strtr(strtolower($str), '01', 'ol');
}
/**
* A static helper to compare
*/
public static function comparePhrases($str1, $str2)
{
return self::doNiceize($str1) === self::doNiceize($str2);
}
}

16
vendor/psr/cache/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,16 @@
# Changelog
All notable changes to this project will be documented in this file, in reverse chronological order by release.
## 1.0.1 - 2016-08-06
### Fixed
- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr
- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr
- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell
- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell
## 1.0.0 - 2015-12-11
Initial stable release; reflects accepted PSR-6 specification

19
vendor/psr/cache/LICENSE.txt vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2015 PHP Framework Interoperability Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

9
vendor/psr/cache/README.md vendored Normal file
View File

@ -0,0 +1,9 @@
PSR Cache
=========
This repository holds all interfaces defined by
[PSR-6](http://www.php-fig.org/psr/psr-6/).
Note that this is not a Cache implementation of its own. It is merely an
interface that describes a Cache implementation. See the specification for more
details.

25
vendor/psr/cache/composer.json vendored Normal file
View File

@ -0,0 +1,25 @@
{
"name": "psr/cache",
"description": "Common interface for caching libraries",
"keywords": ["psr", "psr-6", "cache"],
"license": "MIT",
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

10
vendor/psr/cache/src/CacheException.php vendored Normal file
View File

@ -0,0 +1,10 @@
<?php
namespace Psr\Cache;
/**
* Exception interface for all exceptions thrown by an Implementing Library.
*/
interface CacheException
{
}

View File

@ -0,0 +1,105 @@
<?php
namespace Psr\Cache;
/**
* CacheItemInterface defines an interface for interacting with objects inside a cache.
*
* Each Item object MUST be associated with a specific key, which can be set
* according to the implementing system and is typically passed by the
* Cache\CacheItemPoolInterface object.
*
* The Cache\CacheItemInterface object encapsulates the storage and retrieval of
* cache items. Each Cache\CacheItemInterface is generated by a
* Cache\CacheItemPoolInterface object, which is responsible for any required
* setup as well as associating the object with a unique Key.
* Cache\CacheItemInterface objects MUST be able to store and retrieve any type
* of PHP value defined in the Data section of the specification.
*
* Calling Libraries MUST NOT instantiate Item objects themselves. They may only
* be requested from a Pool object via the getItem() method. Calling Libraries
* SHOULD NOT assume that an Item created by one Implementing Library is
* compatible with a Pool from another Implementing Library.
*/
interface CacheItemInterface
{
/**
* Returns the key for the current cache item.
*
* The key is loaded by the Implementing Library, but should be available to
* the higher level callers when needed.
*
* @return string
* The key string for this cache item.
*/
public function getKey();
/**
* Retrieves the value of the item from the cache associated with this object's key.
*
* The value returned must be identical to the value originally stored by set().
*
* If isHit() returns false, this method MUST return null. Note that null
* is a legitimate cached value, so the isHit() method SHOULD be used to
* differentiate between "null value was found" and "no value was found."
*
* @return mixed
* The value corresponding to this cache item's key, or null if not found.
*/
public function get();
/**
* Confirms if the cache item lookup resulted in a cache hit.
*
* Note: This method MUST NOT have a race condition between calling isHit()
* and calling get().
*
* @return bool
* True if the request resulted in a cache hit. False otherwise.
*/
public function isHit();
/**
* Sets the value represented by this cache item.
*
* The $value argument may be any item that can be serialized by PHP,
* although the method of serialization is left up to the Implementing
* Library.
*
* @param mixed $value
* The serializable value to be stored.
*
* @return static
* The invoked object.
*/
public function set($value);
/**
* Sets the expiration time for this cache item.
*
* @param \DateTimeInterface|null $expiration
* The point in time after which the item MUST be considered expired.
* If null is passed explicitly, a default value MAY be used. If none is set,
* the value should be stored permanently or for as long as the
* implementation allows.
*
* @return static
* The called object.
*/
public function expiresAt($expiration);
/**
* Sets the expiration time for this cache item.
*
* @param int|\DateInterval|null $time
* The period of time from the present after which the item MUST be considered
* expired. An integer parameter is understood to be the time in seconds until
* expiration. If null is passed explicitly, a default value MAY be used.
* If none is set, the value should be stored permanently or for as long as the
* implementation allows.
*
* @return static
* The called object.
*/
public function expiresAfter($time);
}

View File

@ -0,0 +1,138 @@
<?php
namespace Psr\Cache;
/**
* CacheItemPoolInterface generates CacheItemInterface objects.
*
* The primary purpose of Cache\CacheItemPoolInterface is to accept a key from
* the Calling Library and return the associated Cache\CacheItemInterface object.
* It is also the primary point of interaction with the entire cache collection.
* All configuration and initialization of the Pool is left up to an
* Implementing Library.
*/
interface CacheItemPoolInterface
{
/**
* Returns a Cache Item representing the specified key.
*
* This method must always return a CacheItemInterface object, even in case of
* a cache miss. It MUST NOT return null.
*
* @param string $key
* The key for which to return the corresponding Cache Item.
*
* @throws InvalidArgumentException
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return CacheItemInterface
* The corresponding Cache Item.
*/
public function getItem($key);
/**
* Returns a traversable set of cache items.
*
* @param string[] $keys
* An indexed array of keys of items to retrieve.
*
* @throws InvalidArgumentException
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return array|\Traversable
* A traversable collection of Cache Items keyed by the cache keys of
* each item. A Cache item will be returned for each key, even if that
* key is not found. However, if no keys are specified then an empty
* traversable MUST be returned instead.
*/
public function getItems(array $keys = array());
/**
* Confirms if the cache contains specified cache item.
*
* Note: This method MAY avoid retrieving the cached value for performance reasons.
* This could result in a race condition with CacheItemInterface::get(). To avoid
* such situation use CacheItemInterface::isHit() instead.
*
* @param string $key
* The key for which to check existence.
*
* @throws InvalidArgumentException
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return bool
* True if item exists in the cache, false otherwise.
*/
public function hasItem($key);
/**
* Deletes all items in the pool.
*
* @return bool
* True if the pool was successfully cleared. False if there was an error.
*/
public function clear();
/**
* Removes the item from the pool.
*
* @param string $key
* The key to delete.
*
* @throws InvalidArgumentException
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return bool
* True if the item was successfully removed. False if there was an error.
*/
public function deleteItem($key);
/**
* Removes multiple items from the pool.
*
* @param string[] $keys
* An array of keys that should be removed from the pool.
* @throws InvalidArgumentException
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return bool
* True if the items were successfully removed. False if there was an error.
*/
public function deleteItems(array $keys);
/**
* Persists a cache item immediately.
*
* @param CacheItemInterface $item
* The cache item to save.
*
* @return bool
* True if the item was successfully persisted. False if there was an error.
*/
public function save(CacheItemInterface $item);
/**
* Sets a cache item to be persisted later.
*
* @param CacheItemInterface $item
* The cache item to save.
*
* @return bool
* False if the item could not be queued or if a commit was attempted and failed. True otherwise.
*/
public function saveDeferred(CacheItemInterface $item);
/**
* Persists any deferred cache items.
*
* @return bool
* True if all not-yet-saved items were successfully saved or there were none. False otherwise.
*/
public function commit();
}

View File

@ -0,0 +1,13 @@
<?php
namespace Psr\Cache;
/**
* Exception interface for invalid cache arguments.
*
* Any time an invalid argument is passed into a method it must throw an
* exception class which implements Psr\Cache\InvalidArgumentException.
*/
interface InvalidArgumentException extends CacheException
{
}

View File

View File

@ -11,35 +11,36 @@
namespace Symfony\Component\Console;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\NamespaceNotFoundException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@ -61,7 +62,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*/
class Application
{
private $commands = array();
private $commands = [];
private $wantHelps = false;
private $runningCommand;
private $name;
@ -74,14 +75,14 @@ class Application
private $dispatcher;
private $terminal;
private $defaultCommand;
private $singleCommand;
private $singleCommand = false;
private $initialized;
/**
* @param string $name The name of the application
* @param string $version The version of the application
*/
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN')
{
$this->name = $name;
$this->version = $version;
@ -131,17 +132,13 @@ class Application
};
if ($phpHandler = set_exception_handler($renderException)) {
restore_exception_handler();
if (!is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
$debugHandler = true;
} elseif ($debugHandler = $phpHandler[0]->setExceptionHandler($renderException)) {
$phpHandler[0]->setExceptionHandler($debugHandler);
}
}
if (null !== $this->dispatcher && $this->dispatcher->hasListeners(ConsoleEvents::EXCEPTION)) {
@trigger_error(sprintf('The "ConsoleEvents::EXCEPTION" event is deprecated since Symfony 3.3 and will be removed in 4.0. Listen to the "ConsoleEvents::ERROR" event instead.'), E_USER_DEPRECATED);
}
$this->configureIO($input, $output);
try {
@ -163,10 +160,18 @@ class Application
$exitCode = 1;
}
} finally {
// if the exception handler changed, keep it
// otherwise, unregister $renderException
if (!$phpHandler) {
if (set_exception_handler($renderException) === $renderException) {
restore_exception_handler();
}
restore_exception_handler();
} elseif (!$debugHandler) {
$phpHandler[0]->setExceptionHandler(null);
$finalHandler = $phpHandler[0]->setExceptionHandler(null);
if ($finalHandler !== $renderException) {
$phpHandler[0]->setExceptionHandler($finalHandler);
}
}
}
@ -188,17 +193,24 @@ class Application
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--version', '-V'), true)) {
if (true === $input->hasParameterOption(['--version', '-V'], true)) {
$output->writeln($this->getLongVersion());
return 0;
}
try {
// Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument.
$input->bind($this->getDefinition());
} catch (ExceptionInterface $e) {
// Errors must be ignored, full binding/validation happens later when the command is known.
}
$name = $this->getCommandName($input);
if (true === $input->hasParameterOption(array('--help', '-h'), true)) {
if (true === $input->hasParameterOption(['--help', '-h'], true)) {
if (!$name) {
$name = 'help';
$input = new ArrayInput(array('command_name' => $this->defaultCommand));
$input = new ArrayInput(['command_name' => $this->defaultCommand]);
} else {
$this->wantHelps = true;
}
@ -209,31 +221,48 @@ class Application
$definition = $this->getDefinition();
$definition->setArguments(array_merge(
$definition->getArguments(),
array(
[
'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),
)
]
));
}
try {
$e = $this->runningCommand = null;
$this->runningCommand = null;
// the command name MUST be the first element of the input
$command = $this->find($name);
} catch (\Exception $e) {
} catch (\Throwable $e) {
}
if (null !== $e) {
if (null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
$e = $event->getError();
if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) {
if (null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
if (0 === $event->getExitCode()) {
return 0;
if (0 === $event->getExitCode()) {
return 0;
}
$e = $event->getError();
}
throw $e;
}
throw $e;
$alternative = $alternatives[0];
$style = new SymfonyStyle($input, $output);
$style->block(sprintf("\nCommand \"%s\" is not defined.\n", $name), null, 'error');
if (!$style->confirm(sprintf('Do you want to run "%s" instead? ', $alternative), false)) {
if (null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
return $event->getExitCode();
}
return 1;
}
$command = $this->find($alternative);
}
$this->runningCommand = $command;
@ -443,11 +472,11 @@ class Application
}
if (null === $command->getDefinition()) {
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', \get_class($command)));
}
if (!$command->getName()) {
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($command)));
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', \get_class($command)));
}
$this->commands[$command->getName()] = $command;
@ -513,7 +542,7 @@ class Application
*/
public function getNamespaces()
{
$namespaces = array();
$namespaces = [];
foreach ($this->all() as $command) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
@ -532,7 +561,7 @@ class Application
*
* @return string A registered namespace
*
* @throws CommandNotFoundException When namespace is incorrect or ambiguous
* @throws NamespaceNotFoundException When namespace is incorrect or ambiguous
*/
public function findNamespace($namespace)
{
@ -544,7 +573,7 @@ class Application
$message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
if (1 == count($alternatives)) {
if (1 == \count($alternatives)) {
$message .= "\n\nDid you mean this?\n ";
} else {
$message .= "\n\nDid you mean one of these?\n ";
@ -553,12 +582,12 @@ class Application
$message .= implode("\n ", $alternatives);
}
throw new CommandNotFoundException($message, $alternatives);
throw new NamespaceNotFoundException($message, $alternatives);
}
$exact = in_array($namespace, $namespaces, true);
if (count($namespaces) > 1 && !$exact) {
throw new CommandNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
$exact = \in_array($namespace, $namespaces, true);
if (\count($namespaces) > 1 && !$exact) {
throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
}
return $exact ? $namespace : reset($namespaces);
@ -580,6 +609,16 @@ class Application
{
$this->init();
$aliases = [];
foreach ($this->commands as $command) {
foreach ($command->getAliases() as $alias) {
if (!$this->has($alias)) {
$this->commands[$alias] = $command;
}
}
}
$allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
$commands = preg_grep('{^'.$expr.'}', $allCommands);
@ -589,7 +628,7 @@ class Application
}
// if no commands matched or we just matched namespaces
if (empty($commands) || count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
if (false !== $pos = strrpos($name, ':')) {
// check if a namespace exists and contains commands
$this->findNamespace(substr($name, 0, $pos));
@ -598,7 +637,7 @@ class Application
$message = sprintf('Command "%s" is not defined.', $name);
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
if (1 == count($alternatives)) {
if (1 == \count($alternatives)) {
$message .= "\n\nDid you mean this?\n ";
} else {
$message .= "\n\nDid you mean one of these?\n ";
@ -610,17 +649,18 @@ class Application
}
// filter out aliases for commands which are already on the list
if (count($commands) > 1) {
if (\count($commands) > 1) {
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) {
$commandName = $commandList[$nameOrAlias] instanceof Command ? $commandList[$nameOrAlias]->getName() : $nameOrAlias;
$aliases[$nameOrAlias] = $commandName;
return $commandName === $nameOrAlias || !in_array($commandName, $commands);
return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
}));
}
$exact = in_array($name, $commands, true);
if (count($commands) > 1 && !$exact) {
$exact = \in_array($name, $commands, true) || isset($aliases[$name]);
if (\count($commands) > 1 && !$exact) {
$usableWidth = $this->terminal->getWidth() - 10;
$abbrevs = array_values($commands);
$maxLen = 0;
@ -671,7 +711,7 @@ class Application
return $commands;
}
$commands = array();
$commands = [];
foreach ($this->commands as $name => $command) {
if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
$commands[$name] = $command;
@ -698,9 +738,9 @@ class Application
*/
public static function getAbbreviations($names)
{
$abbrevs = array();
$abbrevs = [];
foreach ($names as $name) {
for ($len = strlen($name); $len > 0; --$len) {
for ($len = \strlen($name); $len > 0; --$len) {
$abbrev = substr($name, 0, $len);
$abbrevs[$abbrev][] = $name;
}
@ -729,29 +769,33 @@ class Application
do {
$message = trim($e->getMessage());
if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
$title = sprintf(' [%s%s] ', get_class($e), 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '');
$class = \get_class($e);
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
$title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '');
$len = Helper::strlen($title);
} else {
$len = 0;
}
$width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX;
// HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327
if (defined('HHVM_VERSION') && $width > 1 << 31) {
$width = 1 << 31;
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
}, $message);
}
$lines = array();
foreach ('' !== $message ? preg_split('/\r?\n/', $message) : array() as $line) {
$width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX;
$lines = [];
foreach ('' !== $message ? preg_split('/\r?\n/', $message) : [] as $line) {
foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
// pre-format lines to get the right string length
$lineLength = Helper::strlen($line) + 4;
$lines[] = array($line, $lineLength);
$lines[] = [$line, $lineLength];
$len = max($lineLength, $len);
}
}
$messages = array();
$messages = [];
if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
$messages[] = sprintf('<comment>%s</comment>', OutputFormatter::escape(sprintf('In %s line %s:', basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a')));
}
@ -773,7 +817,14 @@ class Application
// exception related properties
$trace = $e->getTrace();
for ($i = 0, $count = count($trace); $i < $count; ++$i) {
array_unshift($trace, [
'function' => '',
'file' => $e->getFile() ?: 'n/a',
'line' => $e->getLine() ?: 'n/a',
'args' => [],
]);
for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
$class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
$type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
$function = $trace[$i]['function'];
@ -788,96 +839,26 @@ class Application
} while ($e = $e->getPrevious());
}
/**
* Tries to figure out the terminal width in which this application runs.
*
* @return int|null
*
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
protected function getTerminalWidth()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
return $this->terminal->getWidth();
}
/**
* Tries to figure out the terminal height in which this application runs.
*
* @return int|null
*
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
protected function getTerminalHeight()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
return $this->terminal->getHeight();
}
/**
* Tries to figure out the terminal dimensions based on the current environment.
*
* @return array Array containing width and height
*
* @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead.
*/
public function getTerminalDimensions()
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED);
return array($this->terminal->getWidth(), $this->terminal->getHeight());
}
/**
* Sets terminal dimensions.
*
* Can be useful to force terminal dimensions for functional tests.
*
* @param int $width The width
* @param int $height The height
*
* @return $this
*
* @deprecated since version 3.2, to be removed in 4.0. Set the COLUMNS and LINES env vars instead.
*/
public function setTerminalDimensions($width, $height)
{
@trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__), E_USER_DEPRECATED);
putenv('COLUMNS='.$width);
putenv('LINES='.$height);
return $this;
}
/**
* Configures the input and output instances based on the user arguments and options.
*/
protected function configureIO(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--ansi'), true)) {
if (true === $input->hasParameterOption(['--ansi'], true)) {
$output->setDecorated(true);
} elseif (true === $input->hasParameterOption(array('--no-ansi'), true)) {
} elseif (true === $input->hasParameterOption(['--no-ansi'], true)) {
$output->setDecorated(false);
}
if (true === $input->hasParameterOption(array('--no-interaction', '-n'), true)) {
if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) {
$input->setInteractive(false);
} elseif (function_exists('posix_isatty')) {
} elseif (\function_exists('posix_isatty')) {
$inputStream = null;
if ($input instanceof StreamableInputInterface) {
$inputStream = $input->getStream();
}
// This check ensures that calling QuestionHelper::setInputStream() works
// To be removed in 4.0 (in the same time as QuestionHelper::setInputStream)
if (!$inputStream && $this->getHelperSet()->has('question')) {
$inputStream = $this->getHelperSet()->get('question')->getInputStream(false);
}
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
$input->setInteractive(false);
}
@ -891,7 +872,7 @@ class Application
default: $shellVerbosity = 0; break;
}
if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) {
if (true === $input->hasParameterOption(['--quiet', '-q'], true)) {
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
$shellVerbosity = -1;
} else {
@ -955,19 +936,7 @@ class Application
} else {
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
}
} catch (\Exception $e) {
} catch (\Throwable $e) {
}
if (null !== $e) {
if ($this->dispatcher->hasListeners(ConsoleEvents::EXCEPTION)) {
$x = $e instanceof \Exception ? $e : new FatalThrowableError($e);
$event = new ConsoleExceptionEvent($command, $input, $output, $x, $x->getCode());
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
if ($x !== $event->getException()) {
$e = $event->getException();
}
}
$event = new ConsoleErrorEvent($input, $output, $e, $command);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
$e = $event->getError();
@ -1004,7 +973,7 @@ class Application
*/
protected function getDefaultInputDefinition()
{
return new InputDefinition(array(
return new InputDefinition([
new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
@ -1014,7 +983,7 @@ class Application
new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
));
]);
}
/**
@ -1024,7 +993,7 @@ class Application
*/
protected function getDefaultCommands()
{
return array(new HelpCommand(), new ListCommand());
return [new HelpCommand(), new ListCommand()];
}
/**
@ -1034,12 +1003,12 @@ class Application
*/
protected function getDefaultHelperSet()
{
return new HelperSet(array(
return new HelperSet([
new FormatterHelper(),
new DebugFormatterHelper(),
new ProcessHelper(),
new QuestionHelper(),
));
]);
}
/**
@ -1069,7 +1038,7 @@ class Application
$parts = explode(':', $name);
array_pop($parts);
return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
return implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit));
}
/**
@ -1084,9 +1053,9 @@ class Application
private function findAlternatives($name, $collection)
{
$threshold = 1e3;
$alternatives = array();
$alternatives = [];
$collectionParts = array();
$collectionParts = [];
foreach ($collection as $item) {
$collectionParts[$item] = explode(':', $item);
}
@ -1102,7 +1071,7 @@ class Application
}
$lev = levenshtein($subname, $parts[$i]);
if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
if ($lev <= \strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
$alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
} elseif ($exists) {
$alternatives[$collectionName] += $threshold;
@ -1112,7 +1081,7 @@ class Application
foreach ($collection as $item) {
$lev = levenshtein($name, $item);
if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) {
$alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
}
}
@ -1145,6 +1114,14 @@ class Application
return $this;
}
/**
* @internal
*/
public function isSingleCommand()
{
return $this->singleCommand;
}
private function splitStringByWidth($string, $width)
{
// str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
@ -1155,7 +1132,7 @@ class Application
}
$utf8String = mb_convert_encoding($string, 'utf8', $encoding);
$lines = array();
$lines = [];
$line = '';
foreach (preg_split('//u', $utf8String) as $char) {
// test if $char could be appended to current line
@ -1168,7 +1145,7 @@ class Application
$line = $char;
}
$lines[] = count($lines) ? str_pad($line, $width) : $line;
$lines[] = \count($lines) ? str_pad($line, $width) : $line;
mb_convert_variables($encoding, 'utf8', $lines);
@ -1186,10 +1163,10 @@ class Application
{
// -1 as third argument is needed to skip the command short name when exploding
$parts = explode(':', $name, -1);
$namespaces = array();
$namespaces = [];
foreach ($parts as $part) {
if (count($namespaces)) {
if (\count($namespaces)) {
$namespaces[] = end($namespaces).':'.$part;
} else {
$namespaces[] = $part;

View File

@ -1,6 +1,34 @@
CHANGELOG
=========
4.2.0
-----
* allowed passing commands as `[$process, 'ENV_VAR' => 'value']` to
`ProcessHelper::run()` to pass environment variables
* deprecated passing a command as a string to `ProcessHelper::run()`,
pass it the command as an array of its arguments instead
* made the `ProcessHelper` class final
* added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`)
* added `capture_stderr_separately` option to `CommandTester::execute()`
4.1.0
-----
* added option to run suggested command if command is not found and only 1 alternative is available
* added option to modify console output and print multiple modifiable sections
* added support for iterable messages in output `write` and `writeln` methods
4.0.0
-----
* `OutputFormatter` throws an exception when unknown options are used
* removed `QuestionHelper::setInputStream()/getInputStream()`
* removed `Application::getTerminalWidth()/getTerminalHeight()` and
`Application::setTerminalDimensions()/getTerminalDimensions()`
* removed `ConsoleExceptionEvent`
* removed `ConsoleEvents::EXCEPTION`
3.4.0
-----

View File

@ -11,16 +11,16 @@
namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Base class for all commands.
@ -37,7 +37,7 @@ class Command
private $application;
private $name;
private $processTitle;
private $aliases = array();
private $aliases = [];
private $definition;
private $hidden = false;
private $help;
@ -46,8 +46,8 @@ class Command
private $applicationDefinitionMerged = false;
private $applicationDefinitionMergedWithArgs = false;
private $code;
private $synopsis = array();
private $usages = array();
private $synopsis = [];
private $usages = [];
private $helperSet;
/**
@ -55,7 +55,7 @@ class Command
*/
public static function getDefaultName()
{
$class = get_called_class();
$class = \get_called_class();
$r = new \ReflectionProperty($class, 'defaultName');
return $class === $r->class ? static::$defaultName : null;
@ -66,7 +66,7 @@ class Command
*
* @throws LogicException When the command name is empty
*/
public function __construct($name = null)
public function __construct(string $name = null)
{
$this->definition = new InputDefinition();
@ -150,7 +150,7 @@ class Command
* execute() method, you set the code to execute by passing
* a Closure to the setCode() method.
*
* @return null|int null or 0 if everything went fine, or an error code
* @return int|null null or 0 if everything went fine, or an error code
*
* @throws LogicException When this abstract method is not implemented
*
@ -173,10 +173,14 @@ class Command
}
/**
* Initializes the command just after the input has been validated.
* Initializes the command after the input has been bound and before the input
* is validated.
*
* This is mainly useful when a lot of commands extends one main command
* where some things need to be initialized based on the input arguments and options.
*
* @see InputInterface::bind()
* @see InputInterface::validate()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
@ -217,16 +221,15 @@ class Command
$this->initialize($input, $output);
if (null !== $this->processTitle) {
if (function_exists('cli_set_process_title')) {
if (false === @cli_set_process_title($this->processTitle)) {
if (\function_exists('cli_set_process_title')) {
if (!@cli_set_process_title($this->processTitle)) {
if ('Darwin' === PHP_OS) {
$output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
$output->writeln('<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>', OutputInterface::VERBOSITY_VERY_VERBOSE);
} else {
$error = error_get_last();
trigger_error($error['message'], E_USER_WARNING);
cli_set_process_title($this->processTitle);
}
}
} elseif (function_exists('setproctitle')) {
} elseif (\function_exists('setproctitle')) {
setproctitle($this->processTitle);
} elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
$output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
@ -247,7 +250,7 @@ class Command
$input->validate();
if ($this->code) {
$statusCode = call_user_func($this->code, $input, $output);
$statusCode = ($this->code)($input, $output);
} else {
$statusCode = $this->execute($input, $output);
}
@ -274,15 +277,7 @@ class Command
if ($code instanceof \Closure) {
$r = new \ReflectionFunction($code);
if (null === $r->getClosureThis()) {
if (\PHP_VERSION_ID < 70000) {
// Bug in PHP5: https://bugs.php.net/bug.php?id=64761
// This means that we cannot bind static closures and therefore we must
// ignore any errors here. There is no way to test if the closure is
// bindable.
$code = @\Closure::bind($code, $this);
} else {
$code = \Closure::bind($code, $this);
}
$code = \Closure::bind($code, $this);
}
}
@ -306,14 +301,13 @@ class Command
$this->definition->addOptions($this->application->getDefinition()->getOptions());
$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$currentArguments = $this->definition->getArguments();
$this->definition->setArguments($this->application->getDefinition()->getArguments());
$this->definition->addArguments($currentArguments);
}
$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$this->applicationDefinitionMergedWithArgs = true;
}
}
@ -366,10 +360,12 @@ class Command
/**
* Adds an argument.
*
* @param string $name The argument name
* @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
* @param string $name The argument name
* @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param string $description A description text
* @param string|string[]|null $default The default value (for InputArgument::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*
* @return $this
*/
@ -383,11 +379,13 @@ class Command
/**
* Adds an option.
*
* @param string $name The option name
* @param string $shortcut The shortcut (can be null)
* @param int $mode The option mode: One of the InputOption::VALUE_* constants
* @param string $description A description text
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
* @param string $name The option name
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
* @param string $description A description text
* @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*
* @return $this
*/
@ -527,15 +525,16 @@ class Command
public function getProcessedHelp()
{
$name = $this->name;
$isSingleCommand = $this->application && $this->application->isSingleCommand();
$placeholders = array(
$placeholders = [
'%command.name%',
'%command.full_name%',
);
$replacements = array(
];
$replacements = [
$name,
$_SERVER['PHP_SELF'].' '.$name,
);
$isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].' '.$name,
];
return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
}
@ -551,7 +550,7 @@ class Command
*/
public function setAliases($aliases)
{
if (!is_array($aliases) && !$aliases instanceof \Traversable) {
if (!\is_array($aliases) && !$aliases instanceof \Traversable) {
throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
}
@ -644,11 +643,9 @@ class Command
*
* It must be non-empty and parts can optionally be separated by ":".
*
* @param string $name
*
* @throws InvalidArgumentException When the name is invalid
*/
private function validateName($name)
private function validateName(string $name)
{
if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));

View File

@ -13,8 +13,8 @@ namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
@ -35,11 +35,11 @@ class HelpCommand extends Command
$this
->setName('help')
->setDefinition(array(
->setDefinition([
new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
))
])
->setDescription('Displays help for a command')
->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays help for a given command:
@ -71,10 +71,10 @@ EOF
}
$helper = new DescriptorHelper();
$helper->describe($output, $this->command, array(
$helper->describe($output, $this->command, [
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
));
]);
$this->command = null;
}

View File

@ -13,10 +13,10 @@ namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* ListCommand displays the list of all available commands for the application.
@ -69,11 +69,11 @@ EOF
protected function execute(InputInterface $input, OutputInterface $output)
{
$helper = new DescriptorHelper();
$helper->describe($output, $this->getApplication(), array(
$helper->describe($output, $this->getApplication(), [
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
'namespace' => $input->getArgument('namespace'),
));
]);
}
/**
@ -81,10 +81,10 @@ EOF
*/
private function createDefinition()
{
return new InputDefinition(array(
return new InputDefinition([
new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
));
]);
}
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Lock;
use Symfony\Component\Lock\Store\FlockStore;
@ -36,14 +35,14 @@ trait LockableTrait
private function lock($name = null, $blocking = false)
{
if (!class_exists(SemaphoreStore::class)) {
throw new RuntimeException('To enable the locking feature you must install the symfony/lock component.');
throw new LogicException('To enable the locking feature you must install the symfony/lock component.');
}
if (null !== $this->lock) {
throw new LogicException('A lock is already in place.');
}
if (SemaphoreStore::isSupported($blocking)) {
if (SemaphoreStore::isSupported()) {
$store = new SemaphoreStore();
} else {
$store = new FlockStore();

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\CommandLoader;
use Symfony\Component\Console\Command\Command;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\CommandLoader;
use Psr\Container\ContainerInterface;

View File

@ -35,19 +35,6 @@ final class ConsoleEvents
*/
const TERMINATE = 'console.terminate';
/**
* The EXCEPTION event occurs when an uncaught exception appears
* while executing Command#run().
*
* This event allows you to deal with the exception or
* to modify the thrown exception.
*
* @Event("Symfony\Component\Console\Event\ConsoleExceptionEvent")
*
* @deprecated The console.exception event is deprecated since version 3.3 and will be removed in 4.0. Use the console.error event instead.
*/
const EXCEPTION = 'console.exception';
/**
* The ERROR event occurs when an uncaught exception or error appears.
*

View File

@ -29,7 +29,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
private $commandLoaderServiceId;
private $commandTag;
public function __construct($commandLoaderServiceId = 'console.command_loader', $commandTag = 'console.command')
public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command')
{
$this->commandLoaderServiceId = $commandLoaderServiceId;
$this->commandTag = $commandTag;
@ -38,17 +38,14 @@ class AddConsoleCommandPass implements CompilerPassInterface
public function process(ContainerBuilder $container)
{
$commandServices = $container->findTaggedServiceIds($this->commandTag, true);
$lazyCommandMap = array();
$lazyCommandRefs = array();
$serviceIds = array();
$lazyServiceIds = array();
$lazyCommandMap = [];
$lazyCommandRefs = [];
$serviceIds = [];
foreach ($commandServices as $id => $tags) {
$definition = $container->getDefinition($id);
$class = $container->getParameterBag()->resolveValue($definition->getClass());
$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));
if (isset($tags[0]['command'])) {
$commandName = $tags[0]['command'];
} else {
@ -62,24 +59,20 @@ class AddConsoleCommandPass implements CompilerPassInterface
}
if (null === $commandName) {
if (isset($serviceIds[$commandId]) || $container->hasAlias($commandId)) {
$commandId = $commandId.'_'.$id;
}
if (!$definition->isPublic() || $definition->isPrivate()) {
$commandId = 'console.command.public_alias.'.$id;
$container->setAlias($commandId, $id)->setPublic(true);
$id = $commandId;
}
$serviceIds[$commandId] = $id;
$serviceIds[] = $id;
continue;
}
$serviceIds[$commandId] = $id;
$lazyServiceIds[$id] = true;
unset($tags[0]);
$lazyCommandMap[$commandName] = $id;
$lazyCommandRefs[$id] = new TypedReference($id, $class);
$aliases = array();
$aliases = [];
foreach ($tags as $tag) {
if (isset($tag['command'])) {
@ -88,19 +81,18 @@ class AddConsoleCommandPass implements CompilerPassInterface
}
}
$definition->addMethodCall('setName', array($commandName));
$definition->addMethodCall('setName', [$commandName]);
if ($aliases) {
$definition->addMethodCall('setAliases', array($aliases));
$definition->addMethodCall('setAliases', [$aliases]);
}
}
$container
->register($this->commandLoaderServiceId, ContainerCommandLoader::class)
->setPublic(true)
->setArguments(array(ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap));
->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]);
$container->setParameter('console.command.ids', $serviceIds);
$container->setParameter('console.lazy_command.ids', $lazyServiceIds);
}
}

View File

@ -43,12 +43,7 @@ class ApplicationDescription
*/
private $aliases;
/**
* @param Application $application
* @param string|null $namespace
* @param bool $showHidden
*/
public function __construct(Application $application, $namespace = null, $showHidden = false)
public function __construct(Application $application, string $namespace = null, bool $showHidden = false)
{
$this->application = $application;
$this->namespace = $namespace;
@ -97,12 +92,12 @@ class ApplicationDescription
private function inspectApplication()
{
$this->commands = array();
$this->namespaces = array();
$this->commands = [];
$this->namespaces = [];
$all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
foreach ($this->sortCommands($all) as $namespace => $commands) {
$names = array();
$names = [];
/** @var Command $command */
foreach ($commands as $name => $command) {
@ -119,17 +114,14 @@ class ApplicationDescription
$names[] = $name;
}
$this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
$this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
}
}
/**
* @return array
*/
private function sortCommands(array $commands)
private function sortCommands(array $commands): array
{
$namespacedCommands = array();
$globalCommands = array();
$namespacedCommands = [];
$globalCommands = [];
foreach ($commands as $name => $command) {
$key = $this->application->extractNamespace($name, 1);
if (!$key) {

View File

@ -13,11 +13,11 @@ namespace Symfony\Component\Console\Descriptor;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
@ -34,7 +34,7 @@ abstract class Descriptor implements DescriptorInterface
/**
* {@inheritdoc}
*/
public function describe(OutputInterface $output, $object, array $options = array())
public function describe(OutputInterface $output, $object, array $options = [])
{
$this->output = $output;
@ -55,7 +55,7 @@ abstract class Descriptor implements DescriptorInterface
$this->describeApplication($object, $options);
break;
default:
throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', \get_class($object)));
}
}
@ -75,33 +75,33 @@ abstract class Descriptor implements DescriptorInterface
*
* @return string|mixed
*/
abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
abstract protected function describeInputArgument(InputArgument $argument, array $options = []);
/**
* Describes an InputOption instance.
*
* @return string|mixed
*/
abstract protected function describeInputOption(InputOption $option, array $options = array());
abstract protected function describeInputOption(InputOption $option, array $options = []);
/**
* Describes an InputDefinition instance.
*
* @return string|mixed
*/
abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []);
/**
* Describes a Command instance.
*
* @return string|mixed
*/
abstract protected function describeCommand(Command $command, array $options = array());
abstract protected function describeCommand(Command $command, array $options = []);
/**
* Describes an Application instance.
*
* @return string|mixed
*/
abstract protected function describeApplication(Application $application, array $options = array());
abstract protected function describeApplication(Application $application, array $options = []);
}

View File

@ -21,11 +21,11 @@ use Symfony\Component\Console\Output\OutputInterface;
interface DescriptorInterface
{
/**
* Describes an InputArgument instance.
* Describes an object if supported.
*
* @param OutputInterface $output
* @param object $object
* @param array $options
*/
public function describe(OutputInterface $output, $object, array $options = array());
public function describe(OutputInterface $output, $object, array $options = []);
}

View File

@ -29,7 +29,7 @@ class JsonDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputArgument(InputArgument $argument, array $options = array())
protected function describeInputArgument(InputArgument $argument, array $options = [])
{
$this->writeData($this->getInputArgumentData($argument), $options);
}
@ -37,7 +37,7 @@ class JsonDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputOption(InputOption $option, array $options = array())
protected function describeInputOption(InputOption $option, array $options = [])
{
$this->writeData($this->getInputOptionData($option), $options);
}
@ -45,7 +45,7 @@ class JsonDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputDefinition(InputDefinition $definition, array $options = array())
protected function describeInputDefinition(InputDefinition $definition, array $options = [])
{
$this->writeData($this->getInputDefinitionData($definition), $options);
}
@ -53,7 +53,7 @@ class JsonDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeCommand(Command $command, array $options = array())
protected function describeCommand(Command $command, array $options = [])
{
$this->writeData($this->getCommandData($command), $options);
}
@ -61,17 +61,17 @@ class JsonDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeApplication(Application $application, array $options = array())
protected function describeApplication(Application $application, array $options = [])
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace, true);
$commands = array();
$commands = [];
foreach ($description->getCommands() as $command) {
$commands[] = $this->getCommandData($command);
}
$data = array();
$data = [];
if ('UNKNOWN' !== $application->getName()) {
$data['application']['name'] = $application->getName();
if ('UNKNOWN' !== $application->getVersion()) {
@ -97,7 +97,9 @@ class JsonDescriptor extends Descriptor
*/
private function writeData(array $data, array $options)
{
$this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
$flags = isset($options['json_encoding']) ? $options['json_encoding'] : 0;
$this->write(json_encode($data, $flags));
}
/**
@ -105,13 +107,13 @@ class JsonDescriptor extends Descriptor
*/
private function getInputArgumentData(InputArgument $argument)
{
return array(
return [
'name' => $argument->getName(),
'is_required' => $argument->isRequired(),
'is_array' => $argument->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
);
];
}
/**
@ -119,15 +121,15 @@ class JsonDescriptor extends Descriptor
*/
private function getInputOptionData(InputOption $option)
{
return array(
return [
'name' => '--'.$option->getName(),
'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '',
'accept_value' => $option->acceptValue(),
'is_value_required' => $option->isValueRequired(),
'is_multiple' => $option->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(),
);
];
}
/**
@ -135,17 +137,17 @@ class JsonDescriptor extends Descriptor
*/
private function getInputDefinitionData(InputDefinition $definition)
{
$inputArguments = array();
$inputArguments = [];
foreach ($definition->getArguments() as $name => $argument) {
$inputArguments[$name] = $this->getInputArgumentData($argument);
}
$inputOptions = array();
$inputOptions = [];
foreach ($definition->getOptions() as $name => $option) {
$inputOptions[$name] = $this->getInputOptionData($option);
}
return array('arguments' => $inputArguments, 'options' => $inputOptions);
return ['arguments' => $inputArguments, 'options' => $inputOptions];
}
/**
@ -156,13 +158,13 @@ class JsonDescriptor extends Descriptor
$command->getSynopsis();
$command->mergeApplicationDefinition(false);
return array(
return [
'name' => $command->getName(),
'usage' => array_merge(array($command->getSynopsis()), $command->getUsages(), $command->getAliases()),
'usage' => array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()),
'description' => $command->getDescription(),
'help' => $command->getProcessedHelp(),
'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
'hidden' => $command->isHidden(),
);
];
}
}

View File

@ -31,7 +31,7 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
public function describe(OutputInterface $output, $object, array $options = array())
public function describe(OutputInterface $output, $object, array $options = [])
{
$decorated = $output->isDecorated();
$output->setDecorated(false);
@ -52,7 +52,7 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputArgument(InputArgument $argument, array $options = array())
protected function describeInputArgument(InputArgument $argument, array $options = [])
{
$this->write(
'#### `'.($argument->getName() ?: '<none>')."`\n\n"
@ -66,11 +66,11 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputOption(InputOption $option, array $options = array())
protected function describeInputOption(InputOption $option, array $options = [])
{
$name = '--'.$option->getName();
if ($option->getShortcut()) {
$name .= '|-'.implode('|-', explode('|', $option->getShortcut())).'';
$name .= '|-'.str_replace('|', '|-', $option->getShortcut()).'';
}
$this->write(
@ -86,9 +86,9 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputDefinition(InputDefinition $definition, array $options = array())
protected function describeInputDefinition(InputDefinition $definition, array $options = [])
{
if ($showArguments = count($definition->getArguments()) > 0) {
if ($showArguments = \count($definition->getArguments()) > 0) {
$this->write('### Arguments');
foreach ($definition->getArguments() as $argument) {
$this->write("\n\n");
@ -96,7 +96,7 @@ class MarkdownDescriptor extends Descriptor
}
}
if (count($definition->getOptions()) > 0) {
if (\count($definition->getOptions()) > 0) {
if ($showArguments) {
$this->write("\n\n");
}
@ -112,7 +112,7 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeCommand(Command $command, array $options = array())
protected function describeCommand(Command $command, array $options = [])
{
$command->getSynopsis();
$command->mergeApplicationDefinition(false);
@ -122,7 +122,7 @@ class MarkdownDescriptor extends Descriptor
.str_repeat('-', Helper::strlen($command->getName()) + 2)."\n\n"
.($command->getDescription() ? $command->getDescription()."\n\n" : '')
.'### Usage'."\n\n"
.array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
.array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
return $carry.'* `'.$usage.'`'."\n";
})
);
@ -141,7 +141,7 @@ class MarkdownDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeApplication(Application $application, array $options = array())
protected function describeApplication(Application $application, array $options = [])
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);

View File

@ -31,16 +31,16 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputArgument(InputArgument $argument, array $options = array())
protected function describeInputArgument(InputArgument $argument, array $options = [])
{
if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
$default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
} else {
$default = '';
}
$totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName());
$spacingWidth = $totalWidth - strlen($argument->getName());
$spacingWidth = $totalWidth - \strlen($argument->getName());
$this->writeText(sprintf(' <info>%s</info> %s%s%s',
$argument->getName(),
@ -54,9 +54,9 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputOption(InputOption $option, array $options = array())
protected function describeInputOption(InputOption $option, array $options = [])
{
if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
$default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
} else {
$default = '';
@ -71,7 +71,7 @@ class TextDescriptor extends Descriptor
}
}
$totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option));
$totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]);
$synopsis = sprintf('%s%s',
$option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ',
sprintf('--%s%s', $option->getName(), $value)
@ -92,7 +92,7 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputDefinition(InputDefinition $definition, array $options = array())
protected function describeInputDefinition(InputDefinition $definition, array $options = [])
{
$totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
foreach ($definition->getArguments() as $argument) {
@ -103,7 +103,7 @@ class TextDescriptor extends Descriptor
$this->writeText('<comment>Arguments:</comment>', $options);
$this->writeText("\n");
foreach ($definition->getArguments() as $argument) {
$this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth)));
$this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth]));
$this->writeText("\n");
}
}
@ -113,20 +113,20 @@ class TextDescriptor extends Descriptor
}
if ($definition->getOptions()) {
$laterOptions = array();
$laterOptions = [];
$this->writeText('<comment>Options:</comment>', $options);
foreach ($definition->getOptions() as $option) {
if (strlen($option->getShortcut()) > 1) {
if (\strlen($option->getShortcut()) > 1) {
$laterOptions[] = $option;
continue;
}
$this->writeText("\n");
$this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
$this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
}
foreach ($laterOptions as $option) {
$this->writeText("\n");
$this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
$this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));
}
}
}
@ -134,14 +134,21 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeCommand(Command $command, array $options = array())
protected function describeCommand(Command $command, array $options = [])
{
$command->getSynopsis(true);
$command->getSynopsis(false);
$command->mergeApplicationDefinition(false);
if ($description = $command->getDescription()) {
$this->writeText('<comment>Description:</comment>', $options);
$this->writeText("\n");
$this->writeText(' '.$description);
$this->writeText("\n\n");
}
$this->writeText('<comment>Usage:</comment>', $options);
foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) {
$this->writeText("\n");
$this->writeText(' '.OutputFormatter::escape($usage), $options);
}
@ -154,7 +161,8 @@ class TextDescriptor extends Descriptor
$this->writeText("\n");
}
if ($help = $command->getProcessedHelp()) {
$help = $command->getProcessedHelp();
if ($help && $help !== $description) {
$this->writeText("\n");
$this->writeText('<comment>Help:</comment>', $options);
$this->writeText("\n");
@ -166,7 +174,7 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeApplication(Application $application, array $options = array())
protected function describeApplication(Application $application, array $options = [])
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);
@ -202,9 +210,9 @@ class TextDescriptor extends Descriptor
}
// calculate max. width based on available commands per namespace
$width = $this->getColumnWidth(call_user_func_array('array_merge', array_map(function ($namespace) use ($commands) {
$width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) {
return array_intersect($namespace['commands'], array_keys($commands));
}, $namespaces)));
}, $namespaces))));
if ($describedNamespace) {
$this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
@ -242,7 +250,7 @@ class TextDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
private function writeText($content, array $options = array())
private function writeText($content, array $options = [])
{
$this->write(
isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
@ -252,10 +260,8 @@ class TextDescriptor extends Descriptor
/**
* Formats command aliases to show them in the command description.
*
* @return string
*/
private function getCommandAliasesText(Command $command)
private function getCommandAliasesText(Command $command): string
{
$text = '';
$aliases = $command->getAliases();
@ -271,20 +277,18 @@ class TextDescriptor extends Descriptor
* Formats input option/argument default value.
*
* @param mixed $default
*
* @return string
*/
private function formatDefaultValue($default)
private function formatDefaultValue($default): string
{
if (INF === $default) {
return 'INF';
}
if (is_string($default)) {
if (\is_string($default)) {
$default = OutputFormatter::escape($default);
} elseif (is_array($default)) {
} elseif (\is_array($default)) {
foreach ($default as $key => $value) {
if (is_string($value)) {
if (\is_string($value)) {
$default[$key] = OutputFormatter::escape($value);
}
}
@ -295,12 +299,10 @@ class TextDescriptor extends Descriptor
/**
* @param (Command|string)[] $commands
*
* @return int
*/
private function getColumnWidth(array $commands)
private function getColumnWidth(array $commands): int
{
$widths = array();
$widths = [];
foreach ($commands as $command) {
if ($command instanceof Command) {
@ -318,10 +320,8 @@ class TextDescriptor extends Descriptor
/**
* @param InputOption[] $options
*
* @return int
*/
private function calculateTotalWidthForOptions(array $options)
private function calculateTotalWidthForOptions(array $options): int
{
$totalWidth = 0;
foreach ($options as $option) {

View File

@ -64,7 +64,7 @@ class XmlDescriptor extends Descriptor
$commandXML->appendChild($usagesXML = $dom->createElement('usages'));
foreach (array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()) as $usage) {
foreach (array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) {
$usagesXML->appendChild($dom->createElement('usage', $usage));
}
@ -130,7 +130,7 @@ class XmlDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputArgument(InputArgument $argument, array $options = array())
protected function describeInputArgument(InputArgument $argument, array $options = [])
{
$this->writeDocument($this->getInputArgumentDocument($argument));
}
@ -138,7 +138,7 @@ class XmlDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputOption(InputOption $option, array $options = array())
protected function describeInputOption(InputOption $option, array $options = [])
{
$this->writeDocument($this->getInputOptionDocument($option));
}
@ -146,7 +146,7 @@ class XmlDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeInputDefinition(InputDefinition $definition, array $options = array())
protected function describeInputDefinition(InputDefinition $definition, array $options = [])
{
$this->writeDocument($this->getInputDefinitionDocument($definition));
}
@ -154,7 +154,7 @@ class XmlDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeCommand(Command $command, array $options = array())
protected function describeCommand(Command $command, array $options = [])
{
$this->writeDocument($this->getCommandDocument($command));
}
@ -162,7 +162,7 @@ class XmlDescriptor extends Descriptor
/**
* {@inheritdoc}
*/
protected function describeApplication(Application $application, array $options = array())
protected function describeApplication(Application $application, array $options = [])
{
$this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
}
@ -188,10 +188,7 @@ class XmlDescriptor extends Descriptor
$this->write($dom->saveXML());
}
/**
* @return \DOMDocument
*/
private function getInputArgumentDocument(InputArgument $argument)
private function getInputArgumentDocument(InputArgument $argument): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
@ -203,7 +200,7 @@ class XmlDescriptor extends Descriptor
$descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
$objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
$defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
$defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [var_export($argument->getDefault(), true)] : ($argument->getDefault() ? [$argument->getDefault()] : []));
foreach ($defaults as $default) {
$defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
$defaultXML->appendChild($dom->createTextNode($default));
@ -212,10 +209,7 @@ class XmlDescriptor extends Descriptor
return $dom;
}
/**
* @return \DOMDocument
*/
private function getInputOptionDocument(InputOption $option)
private function getInputOptionDocument(InputOption $option): \DOMDocument
{
$dom = new \DOMDocument('1.0', 'UTF-8');
@ -224,7 +218,7 @@ class XmlDescriptor extends Descriptor
$pos = strpos($option->getShortcut(), '|');
if (false !== $pos) {
$objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
$objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
$objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut()));
} else {
$objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
}
@ -235,7 +229,7 @@ class XmlDescriptor extends Descriptor
$descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
if ($option->acceptValue()) {
$defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
$defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [var_export($option->getDefault(), true)] : ($option->getDefault() ? [$option->getDefault()] : []));
$objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
if (!empty($defaults)) {

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Console\Event;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -26,58 +25,34 @@ final class ConsoleErrorEvent extends ConsoleEvent
private $error;
private $exitCode;
public function __construct(InputInterface $input, OutputInterface $output, $error, Command $command = null)
public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null)
{
parent::__construct($command, $input, $output);
$this->setError($error);
}
/**
* Returns the thrown error/exception.
*
* @return \Throwable
*/
public function getError()
{
return $this->error;
}
/**
* Replaces the thrown error/exception.
*
* @param \Throwable $error
*/
public function setError($error)
{
if (!$error instanceof \Throwable && !$error instanceof \Exception) {
throw new InvalidArgumentException(sprintf('The error passed to ConsoleErrorEvent must be an instance of \Throwable or \Exception, "%s" was passed instead.', is_object($error) ? get_class($error) : gettype($error)));
}
$this->error = $error;
}
/**
* Sets the exit code.
*
* @param int $exitCode The command exit code
*/
public function setExitCode($exitCode)
public function getError(): \Throwable
{
$this->exitCode = (int) $exitCode;
return $this->error;
}
public function setError(\Throwable $error): void
{
$this->error = $error;
}
public function setExitCode(int $exitCode): void
{
$this->exitCode = $exitCode;
$r = new \ReflectionProperty($this->error, 'code');
$r->setAccessible(true);
$r->setValue($this->error, $this->exitCode);
}
/**
* Gets the exit code.
*
* @return int The command exit code
*/
public function getExitCode()
public function getExitCode(): int
{
return null !== $this->exitCode ? $this->exitCode : (is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
return null !== $this->exitCode ? $this->exitCode : (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
}
}

View File

@ -1,71 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Event;
@trigger_error(sprintf('The "%s" class is deprecated since version 3.3 and will be removed in 4.0. Use the ConsoleErrorEvent instead.', ConsoleExceptionEvent::class), E_USER_DEPRECATED);
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Allows to handle exception thrown in a command.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since version 3.3, to be removed in 4.0. Use ConsoleErrorEvent instead.
*/
class ConsoleExceptionEvent extends ConsoleEvent
{
private $exception;
private $exitCode;
public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
{
parent::__construct($command, $input, $output);
$this->setException($exception);
$this->exitCode = (int) $exitCode;
}
/**
* Returns the thrown exception.
*
* @return \Exception The thrown exception
*/
public function getException()
{
return $this->exception;
}
/**
* Replaces the thrown exception.
*
* This exception will be thrown if no response is set in the event.
*
* @param \Exception $exception The thrown exception
*/
public function setException(\Exception $exception)
{
$this->exception = $exception;
}
/**
* Gets the exit code.
*
* @return int The command exit code
*/
public function getExitCode()
{
return $this->exitCode;
}
}

View File

@ -22,14 +22,9 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class ConsoleTerminateEvent extends ConsoleEvent
{
/**
* The exit code of the command.
*
* @var int
*/
private $exitCode;
public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode)
{
parent::__construct($command, $input, $output);

View File

@ -40,10 +40,10 @@ class ErrorListener implements EventSubscriberInterface
$error = $event->getError();
if (!$inputString = $this->getInputString($event)) {
return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage()));
return $this->logger->error('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]);
}
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage()));
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
}
public function onConsoleTerminate(ConsoleTerminateEvent $event)
@ -59,18 +59,18 @@ class ErrorListener implements EventSubscriberInterface
}
if (!$inputString = $this->getInputString($event)) {
return $this->logger->debug('The console exited with code "{code}"', array('code' => $exitCode));
return $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]);
}
$this->logger->debug('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode));
$this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]);
}
public static function getSubscribedEvents()
{
return array(
ConsoleEvents::ERROR => array('onConsoleError', -128),
ConsoleEvents::TERMINATE => array('onConsoleTerminate', -128),
);
return [
ConsoleEvents::ERROR => ['onConsoleError', -128],
ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128],
];
}
private static function getInputString(ConsoleEvent $event)
@ -80,7 +80,7 @@ class ErrorListener implements EventSubscriberInterface
if (method_exists($input, '__toString')) {
if ($commandName) {
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
return str_replace(["'$commandName'", "\"$commandName\""], $commandName, (string) $input);
}
return (string) $input;

View File

@ -26,7 +26,7 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
* @param int $code Exception code
* @param \Exception $previous Previous exception used for the exception chaining
*/
public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
public function __construct(string $message, array $alternatives = [], int $code = 0, \Exception $previous = null)
{
parent::__construct($message, $code, $previous);

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Console\Exception;
*
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/
interface ExceptionInterface
interface ExceptionInterface extends \Throwable
{
}

View File

@ -9,16 +9,13 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\Debug\Tests;
namespace Symfony\Component\Console\Exception;
use Symfony\Component\Debug\ExceptionHandler;
class MockExceptionHandler extends ExceptionHandler
/**
* Represents an incorrect namespace typed in the console.
*
* @author Pierre du Plessis <pdples@gmail.com>
*/
class NamespaceNotFoundException extends CommandNotFoundException
{
public $e;
public function handle(\Exception $e)
{
$this->e = $e;
}
}

View File

@ -17,11 +17,12 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
* Formatter class for console output.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
* @author Roland Franssen <franssen.roland@gmail.com>
*/
class OutputFormatter implements OutputFormatterInterface
class OutputFormatter implements WrappableOutputFormatterInterface
{
private $decorated;
private $styles = array();
private $styles = [];
private $styleStack;
/**
@ -50,10 +51,10 @@ class OutputFormatter implements OutputFormatterInterface
public static function escapeTrailingBackslash($text)
{
if ('\\' === substr($text, -1)) {
$len = strlen($text);
$len = \strlen($text);
$text = rtrim($text, '\\');
$text = str_replace("\0", '', $text);
$text .= str_repeat("\0", $len - strlen($text));
$text .= str_repeat("\0", $len - \strlen($text));
}
return $text;
@ -65,9 +66,9 @@ class OutputFormatter implements OutputFormatterInterface
* @param bool $decorated Whether this formatter should actually decorate strings
* @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
*/
public function __construct($decorated = false, array $styles = array())
public function __construct(bool $decorated = false, array $styles = [])
{
$this->decorated = (bool) $decorated;
$this->decorated = $decorated;
$this->setStyle('error', new OutputFormatterStyle('white', 'red'));
$this->setStyle('info', new OutputFormatterStyle('green'));
@ -130,10 +131,18 @@ class OutputFormatter implements OutputFormatterInterface
*/
public function format($message)
{
$message = (string) $message;
return $this->formatAndWrap((string) $message, 0);
}
/**
* {@inheritdoc}
*/
public function formatAndWrap(string $message, int $width)
{
$offset = 0;
$output = '';
$tagRegex = '[a-z][a-z0-9,_=;-]*+';
$currentLineLength = 0;
preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
foreach ($matches[0] as $i => $match) {
$pos = $match[1];
@ -144,8 +153,8 @@ class OutputFormatter implements OutputFormatterInterface
}
// add the text up to the next tag
$output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
$offset = $pos + strlen($text);
$output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength);
$offset = $pos + \strlen($text);
// opening tag?
if ($open = '/' != $text[1]) {
@ -157,8 +166,8 @@ class OutputFormatter implements OutputFormatterInterface
if (!$open && !$tag) {
// </>
$this->styleStack->pop();
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
$output .= $this->applyCurrentStyle($text);
} elseif (false === $style = $this->createStyleFromString($tag)) {
$output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength);
} elseif ($open) {
$this->styleStack->push($style);
} else {
@ -166,10 +175,10 @@ class OutputFormatter implements OutputFormatterInterface
}
}
$output .= $this->applyCurrentStyle(substr($message, $offset));
$output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength);
if (false !== strpos($output, "\0")) {
return strtr($output, array("\0" => '\\', '\\<' => '<'));
return strtr($output, ["\0" => '\\', '\\<' => '<']);
}
return str_replace('\\<', '<', $output);
@ -186,11 +195,9 @@ class OutputFormatter implements OutputFormatterInterface
/**
* Tries to create new style instance from string.
*
* @param string $string
*
* @return OutputFormatterStyle|false false if string is not format string
* @return OutputFormatterStyle|false False if string is not format string
*/
private function createStyleFromString($string)
private function createStyleFromString(string $string)
{
if (isset($this->styles[$string])) {
return $this->styles[$string];
@ -203,22 +210,17 @@ class OutputFormatter implements OutputFormatterInterface
$style = new OutputFormatterStyle();
foreach ($matches as $match) {
array_shift($match);
$match[0] = strtolower($match[0]);
if ('fg' == $match[0]) {
$style->setForeground($match[1]);
$style->setForeground(strtolower($match[1]));
} elseif ('bg' == $match[0]) {
$style->setBackground($match[1]);
$style->setBackground(strtolower($match[1]));
} elseif ('options' === $match[0]) {
preg_match_all('([^,;]+)', $match[1], $options);
preg_match_all('([^,;]+)', strtolower($match[1]), $options);
$options = array_shift($options);
foreach ($options as $option) {
try {
$style->setOption($option);
} catch (\InvalidArgumentException $e) {
@trigger_error(sprintf('Unknown style options are deprecated since version 3.2 and will be removed in 4.0. Exception "%s".', $e->getMessage()), E_USER_DEPRECATED);
return false;
}
$style->setOption($option);
}
} else {
return false;
@ -230,13 +232,51 @@ class OutputFormatter implements OutputFormatterInterface
/**
* Applies current style from stack to text, if must be applied.
*
* @param string $text Input text
*
* @return string Styled text
*/
private function applyCurrentStyle($text)
private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength): string
{
return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
if ('' === $text) {
return '';
}
if (!$width) {
return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text;
}
if (!$currentLineLength && '' !== $current) {
$text = ltrim($text);
}
if ($currentLineLength) {
$prefix = substr($text, 0, $i = $width - $currentLineLength)."\n";
$text = substr($text, $i);
} else {
$prefix = '';
}
preg_match('~(\\n)$~', $text, $matches);
$text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text);
$text = rtrim($text, "\n").($matches[1] ?? '');
if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) {
$text = "\n".$text;
}
$lines = explode("\n", $text);
foreach ($lines as $line) {
$currentLineLength += \strlen($line);
if ($width <= $currentLineLength) {
$currentLineLength = 0;
}
}
if ($this->isDecorated()) {
foreach ($lines as $i => $line) {
$lines[$i] = $this->styleStack->getCurrent()->apply($line);
}
}
return implode("\n", $lines);
}
}

View File

@ -20,39 +20,39 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
*/
class OutputFormatterStyle implements OutputFormatterStyleInterface
{
private static $availableForegroundColors = array(
'black' => array('set' => 30, 'unset' => 39),
'red' => array('set' => 31, 'unset' => 39),
'green' => array('set' => 32, 'unset' => 39),
'yellow' => array('set' => 33, 'unset' => 39),
'blue' => array('set' => 34, 'unset' => 39),
'magenta' => array('set' => 35, 'unset' => 39),
'cyan' => array('set' => 36, 'unset' => 39),
'white' => array('set' => 37, 'unset' => 39),
'default' => array('set' => 39, 'unset' => 39),
);
private static $availableBackgroundColors = array(
'black' => array('set' => 40, 'unset' => 49),
'red' => array('set' => 41, 'unset' => 49),
'green' => array('set' => 42, 'unset' => 49),
'yellow' => array('set' => 43, 'unset' => 49),
'blue' => array('set' => 44, 'unset' => 49),
'magenta' => array('set' => 45, 'unset' => 49),
'cyan' => array('set' => 46, 'unset' => 49),
'white' => array('set' => 47, 'unset' => 49),
'default' => array('set' => 49, 'unset' => 49),
);
private static $availableOptions = array(
'bold' => array('set' => 1, 'unset' => 22),
'underscore' => array('set' => 4, 'unset' => 24),
'blink' => array('set' => 5, 'unset' => 25),
'reverse' => array('set' => 7, 'unset' => 27),
'conceal' => array('set' => 8, 'unset' => 28),
);
private static $availableForegroundColors = [
'black' => ['set' => 30, 'unset' => 39],
'red' => ['set' => 31, 'unset' => 39],
'green' => ['set' => 32, 'unset' => 39],
'yellow' => ['set' => 33, 'unset' => 39],
'blue' => ['set' => 34, 'unset' => 39],
'magenta' => ['set' => 35, 'unset' => 39],
'cyan' => ['set' => 36, 'unset' => 39],
'white' => ['set' => 37, 'unset' => 39],
'default' => ['set' => 39, 'unset' => 39],
];
private static $availableBackgroundColors = [
'black' => ['set' => 40, 'unset' => 49],
'red' => ['set' => 41, 'unset' => 49],
'green' => ['set' => 42, 'unset' => 49],
'yellow' => ['set' => 43, 'unset' => 49],
'blue' => ['set' => 44, 'unset' => 49],
'magenta' => ['set' => 45, 'unset' => 49],
'cyan' => ['set' => 46, 'unset' => 49],
'white' => ['set' => 47, 'unset' => 49],
'default' => ['set' => 49, 'unset' => 49],
];
private static $availableOptions = [
'bold' => ['set' => 1, 'unset' => 22],
'underscore' => ['set' => 4, 'unset' => 24],
'blink' => ['set' => 5, 'unset' => 25],
'reverse' => ['set' => 7, 'unset' => 27],
'conceal' => ['set' => 8, 'unset' => 28],
];
private $foreground;
private $background;
private $options = array();
private $options = [];
/**
* Initializes output formatter style.
@ -61,7 +61,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
* @param string|null $background The style background color name
* @param array $options The style options
*/
public function __construct($foreground = null, $background = null, array $options = array())
public function __construct(string $foreground = null, string $background = null, array $options = [])
{
if (null !== $foreground) {
$this->setForeground($foreground);
@ -69,17 +69,13 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
if (null !== $background) {
$this->setBackground($background);
}
if (count($options)) {
if (\count($options)) {
$this->setOptions($options);
}
}
/**
* Sets style foreground color.
*
* @param string|null $color The color name
*
* @throws InvalidArgumentException When the color name isn't defined
* {@inheritdoc}
*/
public function setForeground($color = null)
{
@ -90,22 +86,14 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
}
if (!isset(static::$availableForegroundColors[$color])) {
throw new InvalidArgumentException(sprintf(
'Invalid foreground color specified: "%s". Expected one of (%s)',
$color,
implode(', ', array_keys(static::$availableForegroundColors))
));
throw new InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors))));
}
$this->foreground = static::$availableForegroundColors[$color];
}
/**
* Sets style background color.
*
* @param string|null $color The color name
*
* @throws InvalidArgumentException When the color name isn't defined
* {@inheritdoc}
*/
public function setBackground($color = null)
{
@ -116,53 +104,33 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
}
if (!isset(static::$availableBackgroundColors[$color])) {
throw new InvalidArgumentException(sprintf(
'Invalid background color specified: "%s". Expected one of (%s)',
$color,
implode(', ', array_keys(static::$availableBackgroundColors))
));
throw new InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors))));
}
$this->background = static::$availableBackgroundColors[$color];
}
/**
* Sets some specific style option.
*
* @param string $option The option name
*
* @throws InvalidArgumentException When the option name isn't defined
* {@inheritdoc}
*/
public function setOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf(
'Invalid option specified: "%s". Expected one of (%s)',
$option,
implode(', ', array_keys(static::$availableOptions))
));
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
}
if (!in_array(static::$availableOptions[$option], $this->options)) {
if (!\in_array(static::$availableOptions[$option], $this->options)) {
$this->options[] = static::$availableOptions[$option];
}
}
/**
* Unsets some specific style option.
*
* @param string $option The option name
*
* @throws InvalidArgumentException When the option name isn't defined
* {@inheritdoc}
*/
public function unsetOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf(
'Invalid option specified: "%s". Expected one of (%s)',
$option,
implode(', ', array_keys(static::$availableOptions))
));
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
}
$pos = array_search(static::$availableOptions[$option], $this->options);
@ -176,7 +144,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
*/
public function setOptions(array $options)
{
$this->options = array();
$this->options = [];
foreach ($options as $option) {
$this->setOption($option);
@ -184,16 +152,12 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
}
/**
* Applies the style to a given text.
*
* @param string $text The text to style
*
* @return string
* {@inheritdoc}
*/
public function apply($text)
{
$setCodes = array();
$unsetCodes = array();
$setCodes = [];
$unsetCodes = [];
if (null !== $this->foreground) {
$setCodes[] = $this->foreground['set'];
@ -203,14 +167,14 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
$setCodes[] = $this->background['set'];
$unsetCodes[] = $this->background['unset'];
}
if (count($this->options)) {
if (\count($this->options)) {
foreach ($this->options as $option) {
$setCodes[] = $option['set'];
$unsetCodes[] = $option['unset'];
}
}
if (0 === count($setCodes)) {
if (0 === \count($setCodes)) {
return $text;
}

View File

@ -21,7 +21,7 @@ interface OutputFormatterStyleInterface
/**
* Sets style foreground color.
*
* @param string $color The color name
* @param string|null $color The color name
*/
public function setForeground($color = null);

View File

@ -12,11 +12,12 @@
namespace Symfony\Component\Console\Formatter;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Contracts\Service\ResetInterface;
/**
* @author Jean-François Simon <contact@jfsimon.fr>
*/
class OutputFormatterStyleStack
class OutputFormatterStyleStack implements ResetInterface
{
/**
* @var OutputFormatterStyleInterface[]
@ -36,7 +37,7 @@ class OutputFormatterStyleStack
*/
public function reset()
{
$this->styles = array();
$this->styles = [];
}
/**
@ -66,7 +67,7 @@ class OutputFormatterStyleStack
foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
if ($style->apply('') === $stackedStyle->apply('')) {
$this->styles = array_slice($this->styles, 0, $index);
$this->styles = \array_slice($this->styles, 0, $index);
return $stackedStyle;
}
@ -86,7 +87,7 @@ class OutputFormatterStyleStack
return $this->emptyStyle;
}
return $this->styles[count($this->styles) - 1];
return $this->styles[\count($this->styles) - 1];
}
/**

View File

@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Formatter;
/**
* Formatter interface for console output that supports word wrapping.
*
* @author Roland Franssen <franssen.roland@gmail.com>
*/
interface WrappableOutputFormatterInterface extends OutputFormatterInterface
{
/**
* Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping).
*/
public function formatAndWrap(string $message, int $width);
}

View File

@ -20,8 +20,8 @@ namespace Symfony\Component\Console\Helper;
*/
class DebugFormatterHelper extends Helper
{
private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default');
private $started = array();
private $colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default'];
private $started = [];
private $count = -1;
/**
@ -35,7 +35,7 @@ class DebugFormatterHelper extends Helper
*/
public function start($id, $message, $prefix = 'RUN')
{
$this->started[$id] = array('border' => ++$this->count % count($this->colors));
$this->started[$id] = ['border' => ++$this->count % \count($this->colors)];
return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
}

View File

@ -16,8 +16,8 @@ use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Output\OutputInterface;
/**
* This class adds helper method to describe objects in various formats.
@ -29,7 +29,7 @@ class DescriptorHelper extends Helper
/**
* @var DescriptorInterface[]
*/
private $descriptors = array();
private $descriptors = [];
public function __construct()
{
@ -54,12 +54,12 @@ class DescriptorHelper extends Helper
*
* @throws InvalidArgumentException when the given format is not supported
*/
public function describe(OutputInterface $output, $object, array $options = array())
public function describe(OutputInterface $output, $object, array $options = [])
{
$options = array_merge(array(
$options = array_merge([
'raw_text' => false,
'format' => 'txt',
), $options);
], $options);
if (!isset($this->descriptors[$options['format']])) {
throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));

View File

@ -45,19 +45,19 @@ class FormatterHelper extends Helper
*/
public function formatBlock($messages, $style, $large = false)
{
if (!is_array($messages)) {
$messages = array($messages);
if (!\is_array($messages)) {
$messages = [$messages];
}
$len = 0;
$lines = array();
$lines = [];
foreach ($messages as $message) {
$message = OutputFormatter::escape($message);
$lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
$len = max($this->strlen($message) + ($large ? 4 : 2), $len);
}
$messages = $large ? array(str_repeat(' ', $len)) : array();
$messages = $large ? [str_repeat(' ', $len)] : [];
for ($i = 0; isset($lines[$i]); ++$i) {
$messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
}

View File

@ -48,7 +48,7 @@ abstract class Helper implements HelperInterface
public static function strlen($string)
{
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return strlen($string);
return \strlen($string);
}
return mb_strwidth($string, $encoding);
@ -74,24 +74,24 @@ abstract class Helper implements HelperInterface
public static function formatTime($secs)
{
static $timeFormats = array(
array(0, '< 1 sec'),
array(1, '1 sec'),
array(2, 'secs', 1),
array(60, '1 min'),
array(120, 'mins', 60),
array(3600, '1 hr'),
array(7200, 'hrs', 3600),
array(86400, '1 day'),
array(172800, 'days', 86400),
);
static $timeFormats = [
[0, '< 1 sec'],
[1, '1 sec'],
[2, 'secs', 1],
[60, '1 min'],
[120, 'mins', 60],
[3600, '1 hr'],
[7200, 'hrs', 3600],
[86400, '1 day'],
[172800, 'days', 86400],
];
foreach ($timeFormats as $index => $format) {
if ($secs >= $format[0]) {
if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
|| $index == count($timeFormats) - 1
|| $index == \count($timeFormats) - 1
) {
if (2 == count($format)) {
if (2 == \count($format)) {
return $format[1];
}

View File

@ -24,16 +24,16 @@ class HelperSet implements \IteratorAggregate
/**
* @var Helper[]
*/
private $helpers = array();
private $helpers = [];
private $command;
/**
* @param Helper[] $helpers An array of helper
*/
public function __construct(array $helpers = array())
public function __construct(array $helpers = [])
{
foreach ($helpers as $alias => $helper) {
$this->set($helper, is_int($alias) ? null : $alias);
$this->set($helper, \is_int($alias) ? null : $alias);
}
}

View File

@ -11,8 +11,8 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputInterface;
/**
* An implementation of InputAwareInterface for Helpers.

View File

@ -20,18 +20,20 @@ use Symfony\Component\Process\Process;
* The ProcessHelper class provides helpers to run external processes.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.2
*/
class ProcessHelper extends Helper
{
/**
* Runs an external process.
*
* @param OutputInterface $output An OutputInterface instance
* @param string|array|Process $cmd An instance of Process or an array of arguments to escape and run or a command to run
* @param string|null $error An error message that must be displayed if something went wrong
* @param callable|null $callback A PHP callback to run whenever there is some
* output available on STDOUT or STDERR
* @param int $verbosity The threshold for verbosity
* @param OutputInterface $output An OutputInterface instance
* @param array|Process $cmd An instance of Process or an array of the command and arguments
* @param string|null $error An error message that must be displayed if something went wrong
* @param callable|null $callback A PHP callback to run whenever there is some
* output available on STDOUT or STDERR
* @param int $verbosity The threshold for verbosity
*
* @return Process The process that ran
*/
@ -44,9 +46,22 @@ class ProcessHelper extends Helper
$formatter = $this->getHelperSet()->get('debug_formatter');
if ($cmd instanceof Process) {
$process = $cmd;
} else {
$cmd = [$cmd];
}
if (!\is_array($cmd)) {
@trigger_error(sprintf('Passing a command as a string to "%s()" is deprecated since Symfony 4.2, pass it the command as an array of arguments instead.', __METHOD__), E_USER_DEPRECATED);
$cmd = [method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd)];
}
if (\is_string($cmd[0] ?? null)) {
$process = new Process($cmd);
$cmd = [];
} elseif (($cmd[0] ?? null) instanceof Process) {
$process = $cmd[0];
unset($cmd[0]);
} else {
throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__));
}
if ($verbosity <= $output->getVerbosity()) {
@ -57,7 +72,7 @@ class ProcessHelper extends Helper
$callback = $this->wrapCallback($output, $process, $callback);
}
$process->run($callback);
$process->run($callback, $cmd);
if ($verbosity <= $output->getVerbosity()) {
$message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
@ -121,7 +136,7 @@ class ProcessHelper extends Helper
$output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
if (null !== $callback) {
call_user_func($callback, $type, $buffer);
$callback($type, $buffer);
}
};
}

View File

@ -11,9 +11,10 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Terminal;
/**
@ -38,7 +39,7 @@ final class ProgressBar
private $stepWidth;
private $percent = 0.0;
private $formatLineCount;
private $messages = array();
private $messages = [];
private $overwrite = true;
private $terminal;
private $firstRun = true;
@ -50,7 +51,7 @@ final class ProgressBar
* @param OutputInterface $output An OutputInterface instance
* @param int $max Maximum steps (0 if unknown)
*/
public function __construct(OutputInterface $output, $max = 0)
public function __construct(OutputInterface $output, int $max = 0)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
@ -79,7 +80,7 @@ final class ProgressBar
* @param string $name The placeholder name (including the delimiter char like %)
* @param callable $callable A PHP callable
*/
public static function setPlaceholderFormatterDefinition($name, callable $callable)
public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
@ -95,7 +96,7 @@ final class ProgressBar
*
* @return callable|null A PHP callable
*/
public static function getPlaceholderFormatterDefinition($name)
public static function getPlaceholderFormatterDefinition(string $name): ?callable
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
@ -112,7 +113,7 @@ final class ProgressBar
* @param string $name The format name
* @param string $format A format string
*/
public static function setFormatDefinition($name, $format)
public static function setFormatDefinition(string $name, string $format): void
{
if (!self::$formats) {
self::$formats = self::initFormats();
@ -128,7 +129,7 @@ final class ProgressBar
*
* @return string|null A format string
*/
public static function getFormatDefinition($name)
public static function getFormatDefinition(string $name): ?string
{
if (!self::$formats) {
self::$formats = self::initFormats();
@ -147,102 +148,57 @@ final class ProgressBar
* @param string $message The text to associate with the placeholder
* @param string $name The name of the placeholder
*/
public function setMessage($message, $name = 'message')
public function setMessage(string $message, string $name = 'message')
{
$this->messages[$name] = $message;
}
public function getMessage($name = 'message')
public function getMessage(string $name = 'message')
{
return $this->messages[$name];
}
/**
* Gets the progress bar start time.
*
* @return int The progress bar start time
*/
public function getStartTime()
public function getStartTime(): int
{
return $this->startTime;
}
/**
* Gets the progress bar maximal steps.
*
* @return int The progress bar max steps
*/
public function getMaxSteps()
public function getMaxSteps(): int
{
return $this->max;
}
/**
* Gets the current step position.
*
* @return int The progress bar step
*/
public function getProgress()
public function getProgress(): int
{
return $this->step;
}
/**
* Gets the progress bar step width.
*
* @return int The progress bar step width
*/
private function getStepWidth()
private function getStepWidth(): int
{
return $this->stepWidth;
}
/**
* Gets the current progress bar percent.
*
* @return float The current progress bar percent
*/
public function getProgressPercent()
public function getProgressPercent(): float
{
return $this->percent;
}
/**
* Sets the progress bar width.
*
* @param int $size The progress bar size
*/
public function setBarWidth($size)
public function setBarWidth(int $size)
{
$this->barWidth = max(1, (int) $size);
$this->barWidth = max(1, $size);
}
/**
* Gets the progress bar width.
*
* @return int The progress bar size
*/
public function getBarWidth()
public function getBarWidth(): int
{
return $this->barWidth;
}
/**
* Sets the bar character.
*
* @param string $char A character
*/
public function setBarCharacter($char)
public function setBarCharacter(string $char)
{
$this->barChar = $char;
}
/**
* Gets the bar character.
*
* @return string A character
*/
public function getBarCharacter()
public function getBarCharacter(): string
{
if (null === $this->barChar) {
return $this->max ? '=' : $this->emptyBarChar;
@ -251,52 +207,27 @@ final class ProgressBar
return $this->barChar;
}
/**
* Sets the empty bar character.
*
* @param string $char A character
*/
public function setEmptyBarCharacter($char)
public function setEmptyBarCharacter(string $char)
{
$this->emptyBarChar = $char;
}
/**
* Gets the empty bar character.
*
* @return string A character
*/
public function getEmptyBarCharacter()
public function getEmptyBarCharacter(): string
{
return $this->emptyBarChar;
}
/**
* Sets the progress bar character.
*
* @param string $char A character
*/
public function setProgressCharacter($char)
public function setProgressCharacter(string $char)
{
$this->progressChar = $char;
}
/**
* Gets the progress bar character.
*
* @return string A character
*/
public function getProgressCharacter()
public function getProgressCharacter(): string
{
return $this->progressChar;
}
/**
* Sets the progress bar format.
*
* @param string $format The format
*/
public function setFormat($format)
public function setFormat(string $format)
{
$this->format = null;
$this->internalFormat = $format;
@ -307,9 +238,9 @@ final class ProgressBar
*
* @param int|float $freq The frequency in steps
*/
public function setRedrawFrequency($freq)
public function setRedrawFrequency(int $freq)
{
$this->redrawFreq = max((int) $freq, 1);
$this->redrawFreq = max($freq, 1);
}
/**
@ -317,7 +248,7 @@ final class ProgressBar
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
*/
public function start($max = null)
public function start(int $max = null)
{
$this->startTime = time();
$this->step = 0;
@ -335,30 +266,21 @@ final class ProgressBar
*
* @param int $step Number of steps to advance
*/
public function advance($step = 1)
public function advance(int $step = 1)
{
$this->setProgress($this->step + $step);
}
/**
* Sets whether to overwrite the progressbar, false for new line.
*
* @param bool $overwrite
*/
public function setOverwrite($overwrite)
public function setOverwrite(bool $overwrite)
{
$this->overwrite = (bool) $overwrite;
$this->overwrite = $overwrite;
}
/**
* Sets the current progress.
*
* @param int $step The current progress
*/
public function setProgress($step)
public function setProgress(int $step)
{
$step = (int) $step;
if ($this->max && $step > $this->max) {
$this->max = $step;
} elseif ($step < 0) {
@ -374,10 +296,17 @@ final class ProgressBar
}
}
public function setMaxSteps(int $max)
{
$this->format = null;
$this->max = max(0, $max);
$this->stepWidth = $this->max ? Helper::strlen((string) $this->max) : 4;
}
/**
* Finishes the progress output.
*/
public function finish()
public function finish(): void
{
if (!$this->max) {
$this->max = $this->step;
@ -394,7 +323,7 @@ final class ProgressBar
/**
* Outputs the current progress string.
*/
public function display()
public function display(): void
{
if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
return;
@ -414,7 +343,7 @@ final class ProgressBar
* while a progress bar is running.
* Call display() to show the progress bar again.
*/
public function clear()
public function clear(): void
{
if (!$this->overwrite) {
return;
@ -427,12 +356,7 @@ final class ProgressBar
$this->overwrite('');
}
/**
* Sets the progress bar format.
*
* @param string $format The format
*/
private function setRealFormat($format)
private function setRealFormat(string $format)
{
// try to use the _nomax variant if available
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
@ -446,39 +370,28 @@ final class ProgressBar
$this->formatLineCount = substr_count($this->format, "\n");
}
/**
* Sets the progress bar maximal steps.
*
* @param int $max The progress bar max steps
*/
private function setMaxSteps($max)
{
$this->max = max(0, (int) $max);
$this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
}
/**
* Overwrites a previous message to the output.
*
* @param string $message The message
*/
private function overwrite($message)
private function overwrite(string $message): void
{
if ($this->overwrite) {
if (!$this->firstRun) {
// Move the cursor to the beginning of the line
$this->output->write("\x0D");
if ($this->output instanceof ConsoleSectionOutput) {
$lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
$this->output->clear($lines);
} else {
// Erase previous lines
if ($this->formatLineCount > 0) {
$message = str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount).$message;
}
// Erase the line
$this->output->write("\x1B[2K");
// Erase previous lines
if ($this->formatLineCount > 0) {
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
// Move the cursor to the beginning of the line and erase the line
$message = "\x0D\x1B[2K$message";
}
}
} elseif ($this->step > 0) {
$this->output->writeln('');
$message = PHP_EOL.$message;
}
$this->firstRun = false;
@ -486,7 +399,7 @@ final class ProgressBar
$this->output->write($message);
}
private function determineBestFormat()
private function determineBestFormat(): string
{
switch ($this->output->getVerbosity()) {
// OutputInterface::VERBOSITY_QUIET: display is disabled anyway
@ -501,10 +414,10 @@ final class ProgressBar
}
}
private static function initPlaceholderFormatters()
private static function initPlaceholderFormatters(): array
{
return array(
'bar' => function (ProgressBar $bar, OutputInterface $output) {
return [
'bar' => function (self $bar, OutputInterface $output) {
$completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
$display = str_repeat($bar->getBarCharacter(), $completeBars);
if ($completeBars < $bar->getBarWidth()) {
@ -514,10 +427,10 @@ final class ProgressBar
return $display;
},
'elapsed' => function (ProgressBar $bar) {
'elapsed' => function (self $bar) {
return Helper::formatTime(time() - $bar->getStartTime());
},
'remaining' => function (ProgressBar $bar) {
'remaining' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
}
@ -530,7 +443,7 @@ final class ProgressBar
return Helper::formatTime($remaining);
},
'estimated' => function (ProgressBar $bar) {
'estimated' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
}
@ -543,24 +456,24 @@ final class ProgressBar
return Helper::formatTime($estimated);
},
'memory' => function (ProgressBar $bar) {
'memory' => function (self $bar) {
return Helper::formatMemory(memory_get_usage(true));
},
'current' => function (ProgressBar $bar) {
'current' => function (self $bar) {
return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
},
'max' => function (ProgressBar $bar) {
'max' => function (self $bar) {
return $bar->getMaxSteps();
},
'percent' => function (ProgressBar $bar) {
'percent' => function (self $bar) {
return floor($bar->getProgressPercent() * 100);
},
);
];
}
private static function initFormats()
private static function initFormats(): array
{
return array(
return [
'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
'normal_nomax' => ' %current% [%bar%]',
@ -572,18 +485,15 @@ final class ProgressBar
'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
);
];
}
/**
* @return string
*/
private function buildLine()
private function buildLine(): string
{
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
$callback = function ($matches) {
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
$text = call_user_func($formatter, $this, $this->output);
$text = $formatter($this, $this->output);
} elseif (isset($this->messages[$matches[1]])) {
$text = $this->messages[$matches[1]];
} else {

View File

@ -39,7 +39,7 @@ class ProgressIndicator
* @param int $indicatorChangeInterval Change interval in milliseconds
* @param array|null $indicatorValues Animated indicator characters
*/
public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null)
{
$this->output = $output;
@ -48,12 +48,12 @@ class ProgressIndicator
}
if (null === $indicatorValues) {
$indicatorValues = array('-', '\\', '|', '/');
$indicatorValues = ['-', '\\', '|', '/'];
}
$indicatorValues = array_values($indicatorValues);
if (2 > count($indicatorValues)) {
if (2 > \count($indicatorValues)) {
throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
}
@ -196,7 +196,7 @@ class ProgressIndicator
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
return call_user_func($formatter, $self);
return $formatter($self);
}
return $matches[0];
@ -219,10 +219,8 @@ class ProgressIndicator
/**
* Overwrites a previous message to the output.
*
* @param string $message The message
*/
private function overwrite($message)
private function overwrite(string $message)
{
if ($this->output->isDecorated()) {
$this->output->write("\x0D\x1B[2K");
@ -239,25 +237,25 @@ class ProgressIndicator
private static function initPlaceholderFormatters()
{
return array(
'indicator' => function (ProgressIndicator $indicator) {
return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)];
return [
'indicator' => function (self $indicator) {
return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)];
},
'message' => function (ProgressIndicator $indicator) {
'message' => function (self $indicator) {
return $indicator->message;
},
'elapsed' => function (ProgressIndicator $indicator) {
'elapsed' => function (self $indicator) {
return Helper::formatTime(time() - $indicator->startTime);
},
'memory' => function () {
return Helper::formatMemory(memory_get_usage(true));
},
);
];
}
private static function initFormats()
{
return array(
return [
'normal' => ' %indicator% %message%',
'normal_no_ansi' => ' %message%',
@ -266,6 +264,6 @@ class ProgressIndicator
'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
);
];
}
}

View File

@ -11,16 +11,16 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
/**
* The QuestionHelper class provides helpers to interact with the user.
@ -47,7 +47,29 @@ class QuestionHelper extends Helper
}
if (!$input->isInteractive()) {
return $question->getDefault();
$default = $question->getDefault();
if (null === $default) {
return $default;
}
if ($validator = $question->getValidator()) {
return \call_user_func($question->getValidator(), $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
if (!$question->isMultiselect()) {
return isset($choices[$default]) ? $choices[$default] : $default;
}
$default = explode(',', $default);
foreach ($default as $k => $v) {
$v = trim($v);
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
}
}
return $default;
}
if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) {
@ -65,46 +87,6 @@ class QuestionHelper extends Helper
return $this->validateAttempts($interviewer, $output, $question);
}
/**
* Sets the input stream to read from when interacting with the user.
*
* This is mainly useful for testing purpose.
*
* @deprecated since version 3.2, to be removed in 4.0. Use
* StreamableInputInterface::setStream() instead.
*
* @param resource $stream The input stream
*
* @throws InvalidArgumentException In case the stream is not a resource
*/
public function setInputStream($stream)
{
@trigger_error(sprintf('The %s() method is deprecated since version 3.2 and will be removed in 4.0. Use %s::setStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED);
if (!is_resource($stream)) {
throw new InvalidArgumentException('Input stream must be a valid resource.');
}
$this->inputStream = $stream;
}
/**
* Returns the helper's input stream.
*
* @deprecated since version 3.2, to be removed in 4.0. Use
* StreamableInputInterface::getStream() instead.
*
* @return resource
*/
public function getInputStream()
{
if (0 === func_num_args() || func_get_arg(0)) {
@trigger_error(sprintf('The %s() method is deprecated since version 3.2 and will be removed in 4.0. Use %s::getStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED);
}
return $this->inputStream;
}
/**
* {@inheritdoc}
*/
@ -124,7 +106,7 @@ class QuestionHelper extends Helper
/**
* Asks the question to the user.
*
* @return bool|mixed|null|string
* @return bool|mixed|string|null
*
* @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
*/
@ -150,15 +132,19 @@ class QuestionHelper extends Helper
if (false === $ret) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new RuntimeException('Aborted');
throw new RuntimeException('Aborted.');
}
$ret = trim($ret);
}
} else {
$ret = trim($this->autocomplete($output, $question, $inputStream, is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
$ret = trim($this->autocomplete($output, $question, $inputStream, \is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
}
$ret = strlen($ret) > 0 ? $ret : $question->getDefault();
if ($output instanceof ConsoleSectionOutput) {
$output->addContent($ret);
}
$ret = \strlen($ret) > 0 ? $ret : $question->getDefault();
if ($normalizer = $question->getNormalizer()) {
return $normalizer($ret);
@ -175,7 +161,7 @@ class QuestionHelper extends Helper
$message = $question->getQuestion();
if ($question instanceof ChoiceQuestion) {
$maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
$maxWidth = max(array_map([$this, 'strlen'], array_keys($question->getChoices())));
$messages = (array) $question->getQuestion();
foreach ($question->getChoices() as $key => $value) {
@ -211,18 +197,16 @@ class QuestionHelper extends Helper
* @param OutputInterface $output
* @param Question $question
* @param resource $inputStream
* @param array $autocomplete
*
* @return string
*/
private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete)
private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete): string
{
$fullChoice = '';
$ret = '';
$i = 0;
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);
$numMatches = \count($matches);
$sttyMode = shell_exec('stty -g');
@ -236,10 +220,14 @@ class QuestionHelper extends Helper
while (!feof($inputStream)) {
$c = fread($inputStream, 1);
// Backspace Character
if ("\177" === $c) {
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
shell_exec(sprintf('stty %s', $sttyMode));
throw new RuntimeException('Aborted.');
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) {
--$i;
$fullChoice = substr($fullChoice, 0, -1);
// Move cursor backwards
$output->write("\033[1D");
}
@ -247,7 +235,7 @@ class QuestionHelper extends Helper
if (0 === $i) {
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);
$numMatches = \count($matches);
} else {
$numMatches = 0;
}
@ -271,13 +259,15 @@ class QuestionHelper extends Helper
$ofs += ('A' === $c[2]) ? -1 : 1;
$ofs = ($numMatches + $ofs) % $numMatches;
}
} elseif (ord($c) < 32) {
} elseif (\ord($c) < 32) {
if ("\t" === $c || "\n" === $c) {
if ($numMatches > 0 && -1 !== $ofs) {
$ret = $matches[$ofs];
// Echo out remaining chars for current match
$output->write(substr($ret, $i));
$i = strlen($ret);
$remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))));
$output->write($remainingCharacters);
$fullChoice .= $remainingCharacters;
$i = \strlen($fullChoice);
}
if ("\n" === $c) {
@ -290,16 +280,27 @@ class QuestionHelper extends Helper
continue;
} else {
if ("\x80" <= $c) {
$c .= fread($inputStream, ["\xC0" => 1, "\xD0" => 1, "\xE0" => 2, "\xF0" => 3][$c & "\xF0"]);
}
$output->write($c);
$ret .= $c;
$fullChoice .= $c;
++$i;
$tempRet = $ret;
if ($question instanceof ChoiceQuestion && $question->isMultiselect()) {
$tempRet = $this->mostRecentlyEnteredValue($fullChoice);
}
$numMatches = 0;
$ofs = 0;
foreach ($autocomplete as $value) {
// If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
if (0 === strpos($value, $ret) && $i !== strlen($value)) {
if (0 === strpos($value, $tempRet)) {
$matches[$numMatches++] = $value;
}
}
@ -311,8 +312,9 @@ class QuestionHelper extends Helper
if ($numMatches > 0 && -1 !== $ofs) {
// Save cursor position
$output->write("\0337");
// Write highlighted text
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
// Write highlighted text, complete the partially entered response
$charactersEntered = \strlen(trim($this->mostRecentlyEnteredValue($fullChoice)));
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $charactersEntered)).'</hl>');
// Restore cursor position
$output->write("\0338");
}
@ -321,7 +323,22 @@ class QuestionHelper extends Helper
// Reset stty so it behaves normally again
shell_exec(sprintf('stty %s', $sttyMode));
return $ret;
return $fullChoice;
}
private function mostRecentlyEnteredValue($entered)
{
// Determine the most recent value that the user entered
if (false === strpos($entered, ',')) {
return $entered;
}
$choices = explode(',', $entered);
if (\strlen($lastChoice = trim($choices[\count($choices) - 1])) > 0) {
return $lastChoice;
}
return $entered;
}
/**
@ -330,13 +347,11 @@ class QuestionHelper extends Helper
* @param OutputInterface $output An Output instance
* @param resource $inputStream The handler resource
*
* @return string The answer
*
* @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
*/
private function getHiddenResponse(OutputInterface $output, $inputStream)
private function getHiddenResponse(OutputInterface $output, $inputStream): string
{
if ('\\' === DIRECTORY_SEPARATOR) {
if ('\\' === \DIRECTORY_SEPARATOR) {
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
// handle code running from a phar
@ -364,7 +379,7 @@ class QuestionHelper extends Helper
shell_exec(sprintf('stty %s', $sttyMode));
if (false === $value) {
throw new RuntimeException('Aborted');
throw new RuntimeException('Aborted.');
}
$value = trim($value);
@ -406,7 +421,7 @@ class QuestionHelper extends Helper
}
try {
return call_user_func($question->getValidator(), $interviewer());
return $question->getValidator()($interviewer());
} catch (RuntimeException $e) {
throw $e;
} catch (\Exception $error) {
@ -432,7 +447,7 @@ class QuestionHelper extends Helper
if (file_exists('/usr/bin/env')) {
// handle other OSs with bash/zsh/ksh/csh if available to hide the answer
$test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) {
if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
self::$shell = $sh;
break;
@ -445,10 +460,8 @@ class QuestionHelper extends Helper
/**
* Returns whether Stty is available or not.
*
* @return bool
*/
private function hasSttyAvailable()
private function hasSttyAvailable(): bool
{
if (null !== self::$stty) {
return self::$stty;

View File

@ -11,14 +11,12 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Formatter\OutputFormatter;
/**
* Symfony Style Guide compliant question helper.
@ -27,32 +25,6 @@ use Symfony\Component\Console\Formatter\OutputFormatter;
*/
class SymfonyQuestionHelper extends QuestionHelper
{
/**
* {@inheritdoc}
*
* To be removed in 4.0
*/
public function ask(InputInterface $input, OutputInterface $output, Question $question)
{
$validator = $question->getValidator();
$question->setValidator(function ($value) use ($validator) {
if (null !== $validator) {
$value = $validator($value);
} else {
// make required
if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
@trigger_error('The default question validator is deprecated since Symfony 3.3 and will not be used anymore in version 4.0. Set a custom question validator if needed.', E_USER_DEPRECATED);
throw new LogicException('A value is required.');
}
}
return $value;
});
return parent::ask($input, $output, $question);
}
/**
* {@inheritdoc}
*/
@ -86,7 +58,7 @@ class SymfonyQuestionHelper extends QuestionHelper
case $question instanceof ChoiceQuestion:
$choices = $question->getChoices();
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default]));
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(isset($choices[$default]) ? $choices[$default] : $default));
break;

View File

@ -11,8 +11,12 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Provides helpers to display a table.
@ -21,23 +25,34 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
* @author Саша Стаменковић <umpirsky@gmail.com>
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
* @author Max Grigorian <maxakawizard@gmail.com>
* @author Dany Maillard <danymaillard93b@gmail.com>
*/
class Table
{
private const SEPARATOR_TOP = 0;
private const SEPARATOR_TOP_BOTTOM = 1;
private const SEPARATOR_MID = 2;
private const SEPARATOR_BOTTOM = 3;
private const BORDER_OUTSIDE = 0;
private const BORDER_INSIDE = 1;
private $headerTitle;
private $footerTitle;
/**
* Table headers.
*/
private $headers = array();
private $headers = [];
/**
* Table rows.
*/
private $rows = array();
private $rows = [];
/**
* Column widths cache.
*/
private $effectiveColumnWidths = array();
private $effectiveColumnWidths = [];
/**
* Number of columns cache.
@ -59,17 +74,20 @@ class Table
/**
* @var array
*/
private $columnStyles = array();
private $columnStyles = [];
/**
* User set column widths.
*
* @var array
*/
private $columnWidths = array();
private $columnWidths = [];
private $columnMaxWidths = [];
private static $styles;
private $rendered = false;
public function __construct(OutputInterface $output)
{
$this->output = $output;
@ -168,11 +186,7 @@ class Table
*/
public function getColumnStyle($columnIndex)
{
if (isset($this->columnStyles[$columnIndex])) {
return $this->columnStyles[$columnIndex];
}
return $this->getStyle();
return $this->columnStyles[$columnIndex] ?? $this->getStyle();
}
/**
@ -199,7 +213,7 @@ class Table
*/
public function setColumnWidths(array $widths)
{
$this->columnWidths = array();
$this->columnWidths = [];
foreach ($widths as $index => $width) {
$this->setColumnWidth($index, $width);
}
@ -207,11 +221,30 @@ class Table
return $this;
}
/**
* Sets the maximum width of a column.
*
* Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while
* formatted strings are preserved.
*
* @return $this
*/
public function setColumnMaxWidth(int $columnIndex, int $width): self
{
if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_class($this->output->getFormatter())));
}
$this->columnMaxWidths[$columnIndex] = $width;
return $this;
}
public function setHeaders(array $headers)
{
$headers = array_values($headers);
if (!empty($headers) && !is_array($headers[0])) {
$headers = array($headers);
if (!empty($headers) && !\is_array($headers[0])) {
$headers = [$headers];
}
$this->headers = $headers;
@ -221,7 +254,7 @@ class Table
public function setRows(array $rows)
{
$this->rows = array();
$this->rows = [];
return $this->addRows($rows);
}
@ -243,7 +276,7 @@ class Table
return $this;
}
if (!is_array($row)) {
if (!\is_array($row)) {
throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
}
@ -252,6 +285,25 @@ class Table
return $this;
}
/**
* Adds a row to the table, and re-renders the table.
*/
public function appendRow($row): self
{
if (!$this->output instanceof ConsoleSectionOutput) {
throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
}
if ($this->rendered) {
$this->output->clear($this->calculateRowCount());
}
$this->addRow($row);
$this->render();
return $this;
}
public function setRow($column, array $row)
{
$this->rows[$column] = $row;
@ -259,67 +311,126 @@ class Table
return $this;
}
public function setHeaderTitle(?string $title): self
{
$this->headerTitle = $title;
return $this;
}
public function setFooterTitle(?string $title): self
{
$this->footerTitle = $title;
return $this;
}
/**
* Renders table to output.
*
* Example:
* <code>
* +---------------+-----------------------+------------------+
* | ISBN | Title | Author |
* +---------------+-----------------------+------------------+
* | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
* +---------------+-----------------------+------------------+
* </code>
*
* +---------------+-----------------------+------------------+
* | ISBN | Title | Author |
* +---------------+-----------------------+------------------+
* | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
* +---------------+-----------------------+------------------+
*/
public function render()
{
$this->calculateNumberOfColumns();
$rows = $this->buildTableRows($this->rows);
$headers = $this->buildTableRows($this->headers);
$rows = array_merge($this->headers, [$divider = new TableSeparator()], $this->rows);
$this->calculateNumberOfColumns($rows);
$this->calculateColumnsWidth(array_merge($headers, $rows));
$rows = $this->buildTableRows($rows);
$this->calculateColumnsWidth($rows);
$this->renderRowSeparator();
if (!empty($headers)) {
foreach ($headers as $header) {
$this->renderRow($header, $this->style->getCellHeaderFormat());
$this->renderRowSeparator();
}
}
$isHeader = true;
$isFirstRow = false;
foreach ($rows as $row) {
if ($divider === $row) {
$isHeader = false;
$isFirstRow = true;
continue;
}
if ($row instanceof TableSeparator) {
$this->renderRowSeparator();
} else {
$this->renderRow($row, $this->style->getCellRowFormat());
continue;
}
if (!$row) {
continue;
}
if ($isHeader || $isFirstRow) {
if ($isFirstRow) {
$this->renderRowSeparator(self::SEPARATOR_TOP_BOTTOM);
$isFirstRow = false;
} else {
$this->renderRowSeparator(self::SEPARATOR_TOP, $this->headerTitle, $this->style->getHeaderTitleFormat());
}
}
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
}
if (!empty($rows)) {
$this->renderRowSeparator();
}
$this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
$this->cleanup();
$this->rendered = true;
}
/**
* Renders horizontal header separator.
*
* Example: <code>+-----+-----------+-------+</code>
* Example:
*
* +-----+-----------+-------+
*/
private function renderRowSeparator()
private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
{
if (0 === $count = $this->numberOfColumns) {
return;
}
if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
$borders = $this->style->getBorderChars();
if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) {
return;
}
$markup = $this->style->getCrossingChar();
$crossings = $this->style->getCrossingChars();
if (self::SEPARATOR_MID === $type) {
list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
} elseif (self::SEPARATOR_TOP === $type) {
list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
} elseif (self::SEPARATOR_TOP_BOTTOM === $type) {
list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
} else {
list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
}
$markup = $leftChar;
for ($column = 0; $column < $count; ++$column) {
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar();
$markup .= str_repeat($horizontal, $this->effectiveColumnWidths[$column]);
$markup .= $column === $count - 1 ? $rightChar : $midChar;
}
if (null !== $title) {
$titleLength = Helper::strlenWithoutDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title));
$markupLength = Helper::strlen($markup);
if ($titleLength > $limit = $markupLength - 4) {
$titleLength = $limit;
$formatLength = Helper::strlenWithoutDecoration($formatter, sprintf($titleFormat, ''));
$formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...');
}
$titleStart = ($markupLength - $titleLength) / 2;
if (false === mb_detect_encoding($markup, null, true)) {
$markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength);
} else {
$markup = mb_substr($markup, 0, $titleStart).$formattedTitle.mb_substr($markup, $titleStart + $titleLength);
}
}
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
@ -328,41 +439,36 @@ class Table
/**
* Renders vertical column separator.
*/
private function renderColumnSeparator()
private function renderColumnSeparator($type = self::BORDER_OUTSIDE)
{
return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
$borders = $this->style->getBorderChars();
return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
}
/**
* Renders table row.
*
* Example: <code>| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |</code>
* Example:
*
* @param array $row
* @param string $cellFormat
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
*/
private function renderRow(array $row, $cellFormat)
private function renderRow(array $row, string $cellFormat)
{
if (empty($row)) {
return;
}
$rowContent = $this->renderColumnSeparator();
foreach ($this->getRowColumns($row) as $column) {
$rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
$columns = $this->getRowColumns($row);
$last = \count($columns) - 1;
foreach ($columns as $i => $column) {
$rowContent .= $this->renderCell($row, $column, $cellFormat);
$rowContent .= $this->renderColumnSeparator();
$rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE);
}
$this->output->writeln($rowContent);
}
/**
* Renders table cell with padding.
*
* @param array $row
* @param int $column
* @param string $cellFormat
*/
private function renderCell(array $row, $column, $cellFormat)
private function renderCell(array $row, int $column, string $cellFormat)
{
$cell = isset($row[$column]) ? $row[$column] : '';
$width = $this->effectiveColumnWidths[$column];
@ -375,13 +481,13 @@ class Table
// str_pad won't work properly with multi-byte strings, we need to fix the padding
if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
$width += strlen($cell) - mb_strwidth($cell, $encoding);
$width += \strlen($cell) - mb_strwidth($cell, $encoding);
}
$style = $this->getColumnStyle($column);
if ($cell instanceof TableSeparator) {
return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width));
}
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
@ -393,14 +499,10 @@ class Table
/**
* Calculate number of columns for this table.
*/
private function calculateNumberOfColumns()
private function calculateNumberOfColumns($rows)
{
if (null !== $this->numberOfColumns) {
return;
}
$columns = array(0);
foreach (array_merge($this->headers, $this->rows) as $row) {
$columns = [0];
foreach ($rows as $row) {
if ($row instanceof TableSeparator) {
continue;
}
@ -413,19 +515,28 @@ class Table
private function buildTableRows($rows)
{
$unmergedRows = array();
for ($rowKey = 0; $rowKey < count($rows); ++$rowKey) {
/** @var WrappableOutputFormatterInterface $formatter */
$formatter = $this->output->getFormatter();
$unmergedRows = [];
for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) {
$rows = $this->fillNextRows($rows, $rowKey);
// Remove any new line breaks and replace it with a new line
foreach ($rows[$rowKey] as $column => $cell) {
$colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
if (isset($this->columnMaxWidths[$column]) && Helper::strlenWithoutDecoration($formatter, $cell) > $this->columnMaxWidths[$column]) {
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
}
if (!strstr($cell, "\n")) {
continue;
}
$escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
foreach ($lines as $lineKey => $line) {
if ($cell instanceof TableCell) {
$line = new TableCell($line, array('colspan' => $cell->getColspan()));
if ($colspan > 1) {
$line = new TableCell($line, ['colspan' => $colspan]);
}
if (0 === $lineKey) {
$rows[$rowKey][$column] = $line;
@ -436,45 +547,60 @@ class Table
}
}
$tableRows = array();
foreach ($rows as $rowKey => $row) {
$tableRows[] = $this->fillCells($row);
if (isset($unmergedRows[$rowKey])) {
$tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
return new TableRows(function () use ($rows, $unmergedRows) {
foreach ($rows as $rowKey => $row) {
yield $this->fillCells($row);
if (isset($unmergedRows[$rowKey])) {
foreach ($unmergedRows[$rowKey] as $row) {
yield $row;
}
}
}
});
}
private function calculateRowCount(): int
{
$numberOfRows = \count(iterator_to_array($this->buildTableRows(array_merge($this->headers, [new TableSeparator()], $this->rows))));
if ($this->headers) {
++$numberOfRows; // Add row for header separator
}
return $tableRows;
++$numberOfRows; // Add row for footer separator
return $numberOfRows;
}
/**
* fill rows that contains rowspan > 1.
*
* @param array $rows
* @param int $line
*
* @return array
* @throws InvalidArgumentException
*/
private function fillNextRows(array $rows, $line)
private function fillNextRows(array $rows, int $line): array
{
$unmergedRows = array();
$unmergedRows = [];
foreach ($rows[$line] as $column => $cell) {
if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', \gettype($cell)));
}
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;
$lines = array($cell);
$lines = [$cell];
if (strstr($cell, "\n")) {
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
$nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
$nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
$rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
$rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan()]);
unset($lines[0]);
}
// create a two dimensional array (rowspan x colspan)
$unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
$unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows);
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
$value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan()]);
if ($nbLines === $unmergedRowKey - $line) {
break;
}
@ -484,10 +610,10 @@ class Table
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
// we need to know if $unmergedRow will be merged or inserted into $rows
if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
foreach ($unmergedRow as $cellKey => $cell) {
// insert cell into row at cellKey position
array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]);
}
} else {
$row = $this->copyRow($rows, $unmergedRowKey - 1);
@ -496,7 +622,7 @@ class Table
$row[$column] = $unmergedRow[$column];
}
}
array_splice($rows, $unmergedRowKey, 0, array($row));
array_splice($rows, $unmergedRowKey, 0, [$row]);
}
}
@ -505,12 +631,10 @@ class Table
/**
* fill cells for a row that contains colspan > 1.
*
* @return array
*/
private function fillCells($row)
{
$newRow = array();
$newRow = [];
foreach ($row as $column => $cell) {
$newRow[] = $cell;
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
@ -524,19 +648,13 @@ class Table
return $newRow ?: $row;
}
/**
* @param array $rows
* @param int $line
*
* @return array
*/
private function copyRow(array $rows, $line)
private function copyRow(array $rows, int $line): array
{
$row = $rows[$line];
foreach ($row as $cellKey => $cellValue) {
$row[$cellKey] = '';
if ($cellValue instanceof TableCell) {
$row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
$row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]);
}
}
@ -545,12 +663,10 @@ class Table
/**
* Gets number of columns by row.
*
* @return int
*/
private function getNumberOfColumns(array $row)
private function getNumberOfColumns(array $row): int
{
$columns = count($row);
$columns = \count($row);
foreach ($row as $column) {
$columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
}
@ -560,10 +676,8 @@ class Table
/**
* Gets list of columns for the given row.
*
* @return array
*/
private function getRowColumns(array $row)
private function getRowColumns(array $row): array
{
$columns = range(0, $this->numberOfColumns - 1);
foreach ($row as $cellKey => $cell) {
@ -579,10 +693,10 @@ class Table
/**
* Calculates columns widths.
*/
private function calculateColumnsWidth(array $rows)
private function calculateColumnsWidth(iterable $rows)
{
for ($column = 0; $column < $this->numberOfColumns; ++$column) {
$lengths = array();
$lengths = [];
foreach ($rows as $row) {
if ($row instanceof TableSeparator) {
continue;
@ -604,29 +718,16 @@ class Table
$lengths[] = $this->getCellWidth($row, $column);
}
$this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
$this->effectiveColumnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2;
}
}
/**
* Gets column width.
*
* @return int
*/
private function getColumnSeparatorWidth()
private function getColumnSeparatorWidth(): int
{
return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
return Helper::strlen(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
}
/**
* Gets cell width.
*
* @param array $row
* @param int $column
*
* @return int
*/
private function getCellWidth(array $row, $column)
private function getCellWidth(array $row, int $column): int
{
$cellWidth = 0;
@ -636,8 +737,9 @@ class Table
}
$columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0;
$cellWidth = max($cellWidth, $columnWidth);
return max($cellWidth, $columnWidth);
return isset($this->columnMaxWidths[$column]) ? min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth;
}
/**
@ -645,7 +747,7 @@ class Table
*/
private function cleanup()
{
$this->effectiveColumnWidths = array();
$this->effectiveColumnWidths = [];
$this->numberOfColumns = null;
}
@ -653,33 +755,47 @@ class Table
{
$borderless = new TableStyle();
$borderless
->setHorizontalBorderChar('=')
->setVerticalBorderChar(' ')
->setCrossingChar(' ')
->setHorizontalBorderChars('=')
->setVerticalBorderChars(' ')
->setDefaultCrossingChar(' ')
;
$compact = new TableStyle();
$compact
->setHorizontalBorderChar('')
->setVerticalBorderChar(' ')
->setCrossingChar('')
->setHorizontalBorderChars('')
->setVerticalBorderChars(' ')
->setDefaultCrossingChar('')
->setCellRowContentFormat('%s')
;
$styleGuide = new TableStyle();
$styleGuide
->setHorizontalBorderChar('-')
->setVerticalBorderChar(' ')
->setCrossingChar(' ')
->setHorizontalBorderChars('-')
->setVerticalBorderChars(' ')
->setDefaultCrossingChar(' ')
->setCellHeaderFormat('%s')
;
return array(
$box = (new TableStyle())
->setHorizontalBorderChars('─')
->setVerticalBorderChars('│')
->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├')
;
$boxDouble = (new TableStyle())
->setHorizontalBorderChars('═', '─')
->setVerticalBorderChars('║', '│')
->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣')
;
return [
'default' => new TableStyle(),
'borderless' => $borderless,
'compact' => $compact,
'symfony-style-guide' => $styleGuide,
);
'box' => $box,
'box-double' => $boxDouble,
];
}
private function resolveStyle($name)

View File

@ -19,21 +19,13 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
class TableCell
{
private $value;
private $options = array(
private $options = [
'rowspan' => 1,
'colspan' => 1,
);
];
/**
* @param string $value
* @param array $options
*/
public function __construct($value = '', array $options = array())
public function __construct(string $value = '', array $options = [])
{
if (is_numeric($value) && !is_string($value)) {
$value = (string) $value;
}
$this->value = $value;
// check option names

View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Helper;
/**
* @internal
*/
class TableRows implements \IteratorAggregate
{
private $generator;
public function __construct(callable $generator)
{
$this->generator = $generator;
}
public function getIterator()
{
$g = $this->generator;
return $g();
}
}

View File

@ -18,7 +18,7 @@ namespace Symfony\Component\Console\Helper;
*/
class TableSeparator extends TableCell
{
public function __construct(array $options = array())
public function __construct(array $options = [])
{
parent::__construct('', $options);
}

View File

@ -19,13 +19,29 @@ use Symfony\Component\Console\Exception\LogicException;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Саша Стаменковић <umpirsky@gmail.com>
* @author Dany Maillard <danymaillard93b@gmail.com>
*/
class TableStyle
{
private $paddingChar = ' ';
private $horizontalBorderChar = '-';
private $verticalBorderChar = '|';
private $horizontalOutsideBorderChar = '-';
private $horizontalInsideBorderChar = '-';
private $verticalOutsideBorderChar = '|';
private $verticalInsideBorderChar = '|';
private $crossingChar = '+';
private $crossingTopRightChar = '+';
private $crossingTopMidChar = '+';
private $crossingTopLeftChar = '+';
private $crossingMidRightChar = '+';
private $crossingBottomRightChar = '+';
private $crossingBottomMidChar = '+';
private $crossingBottomLeftChar = '+';
private $crossingMidLeftChar = '+';
private $crossingTopLeftBottomChar = '+';
private $crossingTopMidBottomChar = '+';
private $crossingTopRightBottomChar = '+';
private $headerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
private $footerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
private $cellHeaderFormat = '<info>%s</info>';
private $cellRowFormat = '%s';
private $cellRowContentFormat = ' %s ';
@ -60,28 +76,85 @@ class TableStyle
return $this->paddingChar;
}
/**
* Sets horizontal border characters.
*
* <code>
* ╔═══════════════╤══════════════════════════╤══════════════════╗
* 1 ISBN 2 Title Author
* ╠═══════════════╪══════════════════════════╪══════════════════╣
* 99921-58-10-7 Divine Comedy Dante Alighieri
* 9971-5-0210-0 A Tale of Two Cities Charles Dickens
* 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
* 80-902734-1-6 And Then There Were None Agatha Christie
* ╚═══════════════╧══════════════════════════╧══════════════════╝
* </code>
*
* @param string $outside Outside border char (see #1 of example)
* @param string|null $inside Inside border char (see #2 of example), equals $outside if null
*/
public function setHorizontalBorderChars(string $outside, string $inside = null): self
{
$this->horizontalOutsideBorderChar = $outside;
$this->horizontalInsideBorderChar = $inside ?? $outside;
return $this;
}
/**
* Sets horizontal border character.
*
* @param string $horizontalBorderChar
*
* @return $this
*
* @deprecated since Symfony 4.1, use {@link setHorizontalBorderChars()} instead.
*/
public function setHorizontalBorderChar($horizontalBorderChar)
{
$this->horizontalBorderChar = $horizontalBorderChar;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setHorizontalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED);
return $this;
return $this->setHorizontalBorderChars($horizontalBorderChar, $horizontalBorderChar);
}
/**
* Gets horizontal border character.
*
* @return string
*
* @deprecated since Symfony 4.1, use {@link getBorderChars()} instead.
*/
public function getHorizontalBorderChar()
{
return $this->horizontalBorderChar;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED);
return $this->horizontalOutsideBorderChar;
}
/**
* Sets vertical border characters.
*
* <code>
* ╔═══════════════╤══════════════════════════╤══════════════════╗
* ISBN Title Author
* ╠═══════1═══════╪══════════════════════════╪══════════════════╣
* 99921-58-10-7 Divine Comedy Dante Alighieri
* 9971-5-0210-0 A Tale of Two Cities Charles Dickens
* ╟───────2───────┼──────────────────────────┼──────────────────╢
* 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
* 80-902734-1-6 And Then There Were None Agatha Christie
* ╚═══════════════╧══════════════════════════╧══════════════════╝
* </code>
*
* @param string $outside Outside border char (see #1 of example)
* @param string|null $inside Inside border char (see #2 of example), equals $outside if null
*/
public function setVerticalBorderChars(string $outside, string $inside = null): self
{
$this->verticalOutsideBorderChar = $outside;
$this->verticalInsideBorderChar = $inside ?? $outside;
return $this;
}
/**
@ -90,22 +163,100 @@ class TableStyle
* @param string $verticalBorderChar
*
* @return $this
*
* @deprecated since Symfony 4.1, use {@link setVerticalBorderChars()} instead.
*/
public function setVerticalBorderChar($verticalBorderChar)
{
$this->verticalBorderChar = $verticalBorderChar;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setVerticalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED);
return $this;
return $this->setVerticalBorderChars($verticalBorderChar, $verticalBorderChar);
}
/**
* Gets vertical border character.
*
* @return string
*
* @deprecated since Symfony 4.1, use {@link getBorderChars()} instead.
*/
public function getVerticalBorderChar()
{
return $this->verticalBorderChar;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED);
return $this->verticalOutsideBorderChar;
}
/**
* Gets border characters.
*
* @internal
*/
public function getBorderChars()
{
return [
$this->horizontalOutsideBorderChar,
$this->verticalOutsideBorderChar,
$this->horizontalInsideBorderChar,
$this->verticalInsideBorderChar,
];
}
/**
* Sets crossing characters.
*
* Example:
* <code>
* 1═══════════════2══════════════════════════2══════════════════3
* ISBN Title Author
* 8'══════════════0'═════════════════════════0'═════════════════4'
* 99921-58-10-7 Divine Comedy Dante Alighieri
* 9971-5-0210-0 A Tale of Two Cities Charles Dickens
* 8───────────────0──────────────────────────0──────────────────4
* 960-425-059-0 The Lord of the Rings J. R. R. Tolkien
* 80-902734-1-6 And Then There Were None Agatha Christie
* 7═══════════════6══════════════════════════6══════════════════5
* </code>
*
* @param string $cross Crossing char (see #0 of example)
* @param string $topLeft Top left char (see #1 of example)
* @param string $topMid Top mid char (see #2 of example)
* @param string $topRight Top right char (see #3 of example)
* @param string $midRight Mid right char (see #4 of example)
* @param string $bottomRight Bottom right char (see #5 of example)
* @param string $bottomMid Bottom mid char (see #6 of example)
* @param string $bottomLeft Bottom left char (see #7 of example)
* @param string $midLeft Mid left char (see #8 of example)
* @param string|null $topLeftBottom Top left bottom char (see #8' of example), equals to $midLeft if null
* @param string|null $topMidBottom Top mid bottom char (see #0' of example), equals to $cross if null
* @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null
*/
public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self
{
$this->crossingChar = $cross;
$this->crossingTopLeftChar = $topLeft;
$this->crossingTopMidChar = $topMid;
$this->crossingTopRightChar = $topRight;
$this->crossingMidRightChar = $midRight;
$this->crossingBottomRightChar = $bottomRight;
$this->crossingBottomMidChar = $bottomMid;
$this->crossingBottomLeftChar = $bottomLeft;
$this->crossingMidLeftChar = $midLeft;
$this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft;
$this->crossingTopMidBottomChar = $topMidBottom ?? $cross;
$this->crossingTopRightBottomChar = $topRightBottom ?? $midRight;
return $this;
}
/**
* Sets default crossing character used for each cross.
*
* @see {@link setCrossingChars()} for setting each crossing individually.
*/
public function setDefaultCrossingChar(string $char): self
{
return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char);
}
/**
@ -114,24 +265,49 @@ class TableStyle
* @param string $crossingChar
*
* @return $this
*
* @deprecated since Symfony 4.1. Use {@link setDefaultCrossingChar()} instead.
*/
public function setCrossingChar($crossingChar)
{
$this->crossingChar = $crossingChar;
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED);
return $this;
return $this->setDefaultCrossingChar($crossingChar);
}
/**
* Gets crossing character.
*
* @return string $crossingChar
* @return string
*/
public function getCrossingChar()
{
return $this->crossingChar;
}
/**
* Gets crossing characters.
*
* @internal
*/
public function getCrossingChars(): array
{
return [
$this->crossingChar,
$this->crossingTopLeftChar,
$this->crossingTopMidChar,
$this->crossingTopRightChar,
$this->crossingMidRightChar,
$this->crossingBottomRightChar,
$this->crossingBottomMidChar,
$this->crossingBottomLeftChar,
$this->crossingMidLeftChar,
$this->crossingTopLeftBottomChar,
$this->crossingTopMidBottomChar,
$this->crossingTopRightBottomChar,
];
}
/**
* Sets header cell format.
*
@ -237,7 +413,7 @@ class TableStyle
*/
public function setPadType($padType)
{
if (!in_array($padType, array(STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH), true)) {
if (!\in_array($padType, [STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH], true)) {
throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
}
@ -255,4 +431,28 @@ class TableStyle
{
return $this->padType;
}
public function getHeaderTitleFormat(): string
{
return $this->headerTitleFormat;
}
public function setHeaderTitleFormat(string $format): self
{
$this->headerTitleFormat = $format;
return $this;
}
public function getFooterTitleFormat(): string
{
return $this->footerTitleFormat;
}
public function setFooterTitleFormat(string $format): self
{
$this->footerTitleFormat = $format;
return $this;
}
}

View File

@ -97,7 +97,7 @@ class ArgvInput extends Input
{
$name = substr($token, 1);
if (strlen($name) > 1) {
if (\strlen($name) > 1) {
if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
// an option with a value (with no space)
$this->addShortOption($name[0], substr($name, 1));
@ -118,10 +118,11 @@ class ArgvInput extends Input
*/
private function parseShortOptionSet($name)
{
$len = strlen($name);
$len = \strlen($name);
for ($i = 0; $i < $len; ++$i) {
if (!$this->definition->hasShortcut($name[$i])) {
throw new RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
$encoding = mb_detect_encoding($name, null, true);
throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding)));
}
$option = $this->definition->getOptionForShortcut($name[$i]);
@ -145,12 +146,7 @@ class ArgvInput extends Input
$name = substr($token, 2);
if (false !== $pos = strpos($name, '=')) {
if (0 === strlen($value = substr($name, $pos + 1))) {
// if no value after "=" then substr() returns "" since php7 only, false before
// see http://php.net/manual/fr/migration70.incompatible.php#119151
if (\PHP_VERSION_ID < 70000 && false === $value) {
$value = '';
}
if (0 === \strlen($value = substr($name, $pos + 1))) {
array_unshift($this->parsed, $value);
}
$this->addLongOption(substr($name, 0, $pos), $value);
@ -168,12 +164,12 @@ class ArgvInput extends Input
*/
private function parseArgument($token)
{
$c = count($this->arguments);
$c = \count($this->arguments);
// if input is expecting another argument, add it
if ($this->definition->hasArgument($c)) {
$arg = $this->definition->getArgument($c);
$this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
$this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
// if last argument isArray(), append token to last argument
} elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
@ -183,7 +179,7 @@ class ArgvInput extends Input
// unexpected argument
} else {
$all = $this->definition->getArguments();
if (count($all)) {
if (\count($all)) {
throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
}
@ -228,11 +224,11 @@ class ArgvInput extends Input
throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
}
if (in_array($value, array('', null), true) && $option->acceptValue() && count($this->parsed)) {
if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) {
// if option accepts an optional or mandatory argument
// let's see if there is one provided
$next = array_shift($this->parsed);
if ((isset($next[0]) && '-' !== $next[0]) || in_array($next, array('', null), true)) {
if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) {
$value = $next;
} else {
array_unshift($this->parsed, $next);
@ -261,8 +257,27 @@ class ArgvInput extends Input
*/
public function getFirstArgument()
{
foreach ($this->tokens as $token) {
$isOption = false;
foreach ($this->tokens as $i => $token) {
if ($token && '-' === $token[0]) {
if (false !== strpos($token, '=') || !isset($this->tokens[$i + 1])) {
continue;
}
// If it's a long option, consider that everything after "--" is the option name.
// Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
$name = '-' === $token[1] ? substr($token, 2) : substr($token, -1);
if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
// noop
} elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
$isOption = true;
}
continue;
}
if ($isOption) {
$isOption = false;
continue;
}
@ -282,19 +297,13 @@ class ArgvInput extends Input
return false;
}
foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
// Options with values:
// For long options, test for '--option=' at beginning
// For short options, test for '-o' at beginning
$leading = 0 === strpos($value, '--') ? $value.'=' : $value;
if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) {
return true;
}
if (0 === strpos($token, '-') && 0 !== strpos($token, '--')) {
$noValue = explode('=', $token);
$token = $noValue[0];
$searchableToken = str_replace('-', '', $token);
$searchableValue = str_replace('-', '', $value);
if ('' !== $searchableToken && '' !== $searchableValue && false !== strpos($searchableToken, $searchableValue)) {
return true;
}
}
}
}
@ -309,20 +318,23 @@ class ArgvInput extends Input
$values = (array) $values;
$tokens = $this->tokens;
while (0 < count($tokens)) {
while (0 < \count($tokens)) {
$token = array_shift($tokens);
if ($onlyParams && '--' === $token) {
return false;
return $default;
}
foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
if (false !== $pos = strpos($token, '=')) {
return substr($token, $pos + 1);
}
if ($token === $value) {
return array_shift($tokens);
}
// Options with values:
// For long options, test for '--option=' at beginning
// For short options, test for '-o' at beginning
$leading = 0 === strpos($value, '--') ? $value.'=' : $value;
if ('' !== $leading && 0 === strpos($token, $leading)) {
return substr($token, \strlen($leading));
}
}
}

View File

@ -19,7 +19,7 @@ use Symfony\Component\Console\Exception\InvalidOptionException;
*
* Usage:
*
* $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
* $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']);
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@ -56,7 +56,7 @@ class ArrayInput extends Input
$values = (array) $values;
foreach ($this->parameters as $k => $v) {
if (!is_int($k)) {
if (!\is_int($k)) {
$v = $k;
}
@ -64,7 +64,7 @@ class ArrayInput extends Input
return false;
}
if (in_array($v, $values)) {
if (\in_array($v, $values)) {
return true;
}
}
@ -80,15 +80,15 @@ class ArrayInput extends Input
$values = (array) $values;
foreach ($this->parameters as $k => $v) {
if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) {
return false;
if ($onlyParams && ('--' === $k || (\is_int($k) && '--' === $v))) {
return $default;
}
if (is_int($k)) {
if (in_array($v, $values)) {
if (\is_int($k)) {
if (\in_array($v, $values)) {
return true;
}
} elseif (in_array($k, $values)) {
} elseif (\in_array($k, $values)) {
return $v;
}
}
@ -103,10 +103,10 @@ class ArrayInput extends Input
*/
public function __toString()
{
$params = array();
$params = [];
foreach ($this->parameters as $param => $val) {
if ($param && '-' === $param[0]) {
if (is_array($val)) {
if (\is_array($val)) {
foreach ($val as $v) {
$params[] = $param.('' != $v ? '='.$this->escapeToken($v) : '');
}
@ -114,7 +114,7 @@ class ArrayInput extends Input
$params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
}
} else {
$params[] = is_array($val) ? array_map(array($this, 'escapeToken'), $val) : $this->escapeToken($val);
$params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val);
}
}

View File

@ -29,8 +29,8 @@ abstract class Input implements InputInterface, StreamableInputInterface
{
protected $definition;
protected $stream;
protected $options = array();
protected $arguments = array();
protected $options = [];
protected $arguments = [];
protected $interactive = true;
public function __construct(InputDefinition $definition = null)
@ -48,8 +48,8 @@ abstract class Input implements InputInterface, StreamableInputInterface
*/
public function bind(InputDefinition $definition)
{
$this->arguments = array();
$this->options = array();
$this->arguments = [];
$this->options = [];
$this->definition = $definition;
$this->parse();
@ -69,10 +69,10 @@ abstract class Input implements InputInterface, StreamableInputInterface
$givenArguments = $this->arguments;
$missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
});
if (count($missingArguments) > 0) {
if (\count($missingArguments) > 0) {
throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
}
}
@ -150,7 +150,7 @@ abstract class Input implements InputInterface, StreamableInputInterface
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}
return array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
}
/**

View File

@ -31,18 +31,18 @@ class InputArgument
private $description;
/**
* @param string $name The argument name
* @param int $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (for self::OPTIONAL mode only)
* @param string $name The argument name
* @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param string $description A description text
* @param string|string[]|null $default The default value (for self::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*/
public function __construct($name, $mode = null, $description = '', $default = null)
public function __construct(string $name, int $mode = null, string $description = '', $default = null)
{
if (null === $mode) {
$mode = self::OPTIONAL;
} elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
} elseif ($mode > 7 || $mode < 1) {
throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
}
@ -86,7 +86,7 @@ class InputArgument
/**
* Sets the default value.
*
* @param mixed $default The default value
* @param string|string[]|null $default The default value
*
* @throws LogicException When incorrect default value is given
*/
@ -98,8 +98,8 @@ class InputArgument
if ($this->isArray()) {
if (null === $default) {
$default = array();
} elseif (!is_array($default)) {
$default = [];
} elseif (!\is_array($default)) {
throw new LogicException('A default value for an array argument must be an array.');
}
}
@ -110,7 +110,7 @@ class InputArgument
/**
* Returns the default value.
*
* @return mixed The default value
* @return string|string[]|null The default value
*/
public function getDefault()
{

View File

@ -21,8 +21,6 @@ interface InputAwareInterface
{
/**
* Sets the Console Input.
*
* @param InputInterface
*/
public function setInput(InputInterface $input);
}

View File

@ -19,10 +19,10 @@ use Symfony\Component\Console\Exception\LogicException;
*
* Usage:
*
* $definition = new InputDefinition(array(
* new InputArgument('name', InputArgument::REQUIRED),
* new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
* ));
* $definition = new InputDefinition([
* new InputArgument('name', InputArgument::REQUIRED),
* new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
* ]);
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@ -38,7 +38,7 @@ class InputDefinition
/**
* @param array $definition An array of InputArgument and InputOption instance
*/
public function __construct(array $definition = array())
public function __construct(array $definition = [])
{
$this->setDefinition($definition);
}
@ -48,8 +48,8 @@ class InputDefinition
*/
public function setDefinition(array $definition)
{
$arguments = array();
$options = array();
$arguments = [];
$options = [];
foreach ($definition as $item) {
if ($item instanceof InputOption) {
$options[] = $item;
@ -67,9 +67,9 @@ class InputDefinition
*
* @param InputArgument[] $arguments An array of InputArgument objects
*/
public function setArguments($arguments = array())
public function setArguments($arguments = [])
{
$this->arguments = array();
$this->arguments = [];
$this->requiredCount = 0;
$this->hasOptional = false;
$this->hasAnArrayArgument = false;
@ -81,7 +81,7 @@ class InputDefinition
*
* @param InputArgument[] $arguments An array of InputArgument objects
*/
public function addArguments($arguments = array())
public function addArguments($arguments = [])
{
if (null !== $arguments) {
foreach ($arguments as $argument) {
@ -135,7 +135,7 @@ class InputDefinition
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}
$arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
$arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
return $arguments[$name];
}
@ -149,7 +149,7 @@ class InputDefinition
*/
public function hasArgument($name)
{
$arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
$arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
return isset($arguments[$name]);
}
@ -171,7 +171,7 @@ class InputDefinition
*/
public function getArgumentCount()
{
return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
return $this->hasAnArrayArgument ? PHP_INT_MAX : \count($this->arguments);
}
/**
@ -191,7 +191,7 @@ class InputDefinition
*/
public function getArgumentDefaults()
{
$values = array();
$values = [];
foreach ($this->arguments as $argument) {
$values[$argument->getName()] = $argument->getDefault();
}
@ -204,10 +204,10 @@ class InputDefinition
*
* @param InputOption[] $options An array of InputOption objects
*/
public function setOptions($options = array())
public function setOptions($options = [])
{
$this->options = array();
$this->shortcuts = array();
$this->options = [];
$this->shortcuts = [];
$this->addOptions($options);
}
@ -216,7 +216,7 @@ class InputDefinition
*
* @param InputOption[] $options An array of InputOption objects
*/
public function addOptions($options = array())
public function addOptions($options = [])
{
foreach ($options as $option) {
$this->addOption($option);
@ -322,7 +322,7 @@ class InputDefinition
*/
public function getOptionDefaults()
{
$values = array();
$values = [];
foreach ($this->options as $option) {
$values[$option->getName()] = $option->getDefault();
}
@ -338,8 +338,10 @@ class InputDefinition
* @return string The InputOption name
*
* @throws InvalidArgumentException When option given does not exist
*
* @internal
*/
private function shortcutToName($shortcut)
public function shortcutToName($shortcut)
{
if (!isset($this->shortcuts[$shortcut])) {
throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
@ -357,7 +359,7 @@ class InputDefinition
*/
public function getSynopsis($short = false)
{
$elements = array();
$elements = [];
if ($short && $this->getOptions()) {
$elements[] = '[options]';
@ -378,25 +380,25 @@ class InputDefinition
}
}
if (count($elements) && $this->getArguments()) {
if (\count($elements) && $this->getArguments()) {
$elements[] = '[--]';
}
$tail = '';
foreach ($this->getArguments() as $argument) {
$element = '<'.$argument->getName().'>';
if (!$argument->isRequired()) {
$element = '['.$element.']';
} elseif ($argument->isArray()) {
$element = $element.' ('.$element.')';
}
if ($argument->isArray()) {
$element .= '...';
}
if (!$argument->isRequired()) {
$element = '['.$element;
$tail .= ']';
}
$elements[] = $element;
}
return implode(' ', $elements);
return implode(' ', $elements).$tail;
}
}

View File

@ -24,7 +24,7 @@ interface InputInterface
/**
* Returns the first argument from the raw parameters (not parsed).
*
* @return string The value of the first argument or null otherwise
* @return string|null The value of the first argument or null otherwise
*/
public function getFirstArgument();
@ -33,6 +33,8 @@ interface InputInterface
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
* Does not necessarily return the correct result for short options
* when multiple flags are combined in the same option.
*
* @param string|array $values The values to look for in the raw parameters (can be an array)
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
@ -46,6 +48,8 @@ interface InputInterface
*
* This method is to be used to introspect the input parameters
* before they have been validated. It must be used carefully.
* Does not necessarily return the correct result for short options
* when multiple flags are combined in the same option.
*
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param mixed $default The default value to return if no result is found
@ -57,6 +61,8 @@ interface InputInterface
/**
* Binds the current Input instance with the given arguments and options.
*
* @throws RuntimeException
*/
public function bind(InputDefinition $definition);
@ -79,7 +85,7 @@ interface InputInterface
*
* @param string $name The argument name
*
* @return mixed The argument value
* @return string|string[]|null The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/
@ -88,8 +94,8 @@ interface InputInterface
/**
* Sets an argument value by name.
*
* @param string $name The argument name
* @param string $value The argument value
* @param string $name The argument name
* @param string|string[]|null $value The argument value
*
* @throws InvalidArgumentException When argument given doesn't exist
*/
@ -116,7 +122,7 @@ interface InputInterface
*
* @param string $name The option name
*
* @return mixed The option value
* @return string|string[]|bool|null The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/
@ -125,8 +131,8 @@ interface InputInterface
/**
* Sets an option value by name.
*
* @param string $name The option name
* @param string|bool $value The option value
* @param string $name The option name
* @param string|string[]|bool|null $value The option value
*
* @throws InvalidArgumentException When option given doesn't exist
*/

View File

@ -33,15 +33,15 @@ class InputOption
private $description;
/**
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param mixed $default The default value (must be null for self::VALUE_NONE)
* @param string $name The option name
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
{
if (0 === strpos($name, '--')) {
$name = substr($name, 2);
@ -56,7 +56,7 @@ class InputOption
}
if (null !== $shortcut) {
if (is_array($shortcut)) {
if (\is_array($shortcut)) {
$shortcut = implode('|', $shortcut);
}
$shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
@ -70,7 +70,7 @@ class InputOption
if (null === $mode) {
$mode = self::VALUE_NONE;
} elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
} elseif ($mode > 15 || $mode < 1) {
throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
}
@ -89,7 +89,7 @@ class InputOption
/**
* Returns the option shortcut.
*
* @return string The shortcut
* @return string|null The shortcut
*/
public function getShortcut()
{
@ -149,7 +149,7 @@ class InputOption
/**
* Sets the default value.
*
* @param mixed $default The default value
* @param string|string[]|int|bool|null $default The default value
*
* @throws LogicException When incorrect default value is given
*/
@ -161,8 +161,8 @@ class InputOption
if ($this->isArray()) {
if (null === $default) {
$default = array();
} elseif (!is_array($default)) {
$default = [];
} elseif (!\is_array($default)) {
throw new LogicException('A default value for an array option must be an array.');
}
}
@ -173,7 +173,7 @@ class InputOption
/**
* Returns the default value.
*
* @return mixed The default value
* @return string|string[]|int|bool|null The default value
*/
public function getDefault()
{
@ -195,7 +195,7 @@ class InputOption
*
* @return bool
*/
public function equals(InputOption $option)
public function equals(self $option)
{
return $option->getName() === $this->getName()
&& $option->getShortcut() === $this->getShortcut()

View File

@ -28,11 +28,11 @@ class StringInput extends ArgvInput
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
/**
* @param string $input An array of parameters from the CLI (in the argv format)
* @param string $input A string representing the parameters from the CLI
*/
public function __construct($input)
public function __construct(string $input)
{
parent::__construct(array());
parent::__construct([]);
$this->setTokens($this->tokenize($input));
}
@ -48,15 +48,15 @@ class StringInput extends ArgvInput
*/
private function tokenize($input)
{
$tokens = array();
$length = strlen($input);
$tokens = [];
$length = \strlen($input);
$cursor = 0;
while ($cursor < $length) {
if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
} elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, \strlen($match[3]) - 2)));
} elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
$tokens[] = stripcslashes(substr($match[0], 1, \strlen($match[0]) - 2));
} elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes($match[1]);
} else {
@ -64,7 +64,7 @@ class StringInput extends ArgvInput
throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
}
$cursor += strlen($match[0]);
$cursor += \strlen($match[0]);
}
return $tokens;

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2017 Fabien Potencier
Copyright (c) 2004-2019 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

View File

@ -14,8 +14,8 @@ namespace Symfony\Component\Console\Logger;
use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* PSR-3 compliant console logger.
@ -30,7 +30,7 @@ class ConsoleLogger extends AbstractLogger
const ERROR = 'error';
private $output;
private $verbosityLevelMap = array(
private $verbosityLevelMap = [
LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
@ -39,8 +39,8 @@ class ConsoleLogger extends AbstractLogger
LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
);
private $formatLevelMap = array(
];
private $formatLevelMap = [
LogLevel::EMERGENCY => self::ERROR,
LogLevel::ALERT => self::ERROR,
LogLevel::CRITICAL => self::ERROR,
@ -49,10 +49,10 @@ class ConsoleLogger extends AbstractLogger
LogLevel::NOTICE => self::INFO,
LogLevel::INFO => self::INFO,
LogLevel::DEBUG => self::INFO,
);
];
private $errored = false;
public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = [])
{
$this->output = $output;
$this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
@ -62,7 +62,7 @@ class ConsoleLogger extends AbstractLogger
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = array())
public function log($level, $message, array $context = [])
{
if (!isset($this->verbosityLevelMap[$level])) {
throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
@ -99,19 +99,14 @@ class ConsoleLogger extends AbstractLogger
* Interpolates context values into the message placeholders.
*
* @author PHP Framework Interoperability Group
*
* @param string $message
* @param array $context
*
* @return string
*/
private function interpolate($message, array $context)
private function interpolate(string $message, array $context): string
{
if (false === strpos($message, '{')) {
return $message;
}
$replacements = array();
$replacements = [];
foreach ($context as $key => $val) {
if (null === $val || is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) {
$replacements["{{$key}}"] = $val;

View File

@ -30,13 +30,14 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
private $stderr;
private $consoleSectionOutputs = [];
/**
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
{
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
@ -48,6 +49,14 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
}
}
/**
* Creates a new output section.
*/
public function section(): ConsoleSectionOutput
{
return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
}
/**
* {@inheritdoc}
*/
@ -121,11 +130,11 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
*/
private function isRunningOS400()
{
$checks = array(
function_exists('php_uname') ? php_uname('s') : '',
$checks = [
\function_exists('php_uname') ? php_uname('s') : '',
getenv('OSTYPE'),
PHP_OS,
);
];
return false !== stripos(implode(';', $checks), 'OS400');
}

View File

@ -13,9 +13,11 @@ namespace Symfony\Component\Console\Output;
/**
* ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
* This adds information about stderr output stream.
* This adds information about stderr and section output stream.
*
* @author Dariusz Górecki <darek.krk@gmail.com>
*
* @method ConsoleSectionOutput section() Creates a new output section
*/
interface ConsoleOutputInterface extends OutputInterface
{

View File

@ -0,0 +1,141 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Terminal;
/**
* @author Pierre du Plessis <pdples@gmail.com>
* @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
*/
class ConsoleSectionOutput extends StreamOutput
{
private $content = [];
private $lines = 0;
private $sections;
private $terminal;
/**
* @param resource $stream
* @param ConsoleSectionOutput[] $sections
*/
public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
{
parent::__construct($stream, $verbosity, $decorated, $formatter);
array_unshift($sections, $this);
$this->sections = &$sections;
$this->terminal = new Terminal();
}
/**
* Clears previous output for this section.
*
* @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
*/
public function clear(int $lines = null)
{
if (empty($this->content) || !$this->isDecorated()) {
return;
}
if ($lines) {
array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content
} else {
$lines = $this->lines;
$this->content = [];
}
$this->lines -= $lines;
parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false);
}
/**
* Overwrites the previous output with a new message.
*
* @param array|string $message
*/
public function overwrite($message)
{
$this->clear();
$this->writeln($message);
}
public function getContent(): string
{
return implode('', $this->content);
}
/**
* @internal
*/
public function addContent(string $input)
{
foreach (explode(PHP_EOL, $input) as $lineContent) {
$this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
$this->content[] = $lineContent;
$this->content[] = PHP_EOL;
}
}
/**
* {@inheritdoc}
*/
protected function doWrite($message, $newline)
{
if (!$this->isDecorated()) {
return parent::doWrite($message, $newline);
}
$erasedContent = $this->popStreamContentUntilCurrentSection();
$this->addContent($message);
parent::doWrite($message, true);
parent::doWrite($erasedContent, false);
}
/**
* At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
* current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
*/
private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string
{
$numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
$erasedContent = [];
foreach ($this->sections as $section) {
if ($section === $this) {
break;
}
$numberOfLinesToClear += $section->lines;
$erasedContent[] = $section->getContent();
}
if ($numberOfLinesToClear > 0) {
// move cursor up n lines
parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false);
// erase to end of screen
parent::doWrite("\x1b[0J", false);
}
return implode('', array_reverse($erasedContent));
}
private function getDisplayLength(string $text): string
{
return Helper::strlenWithoutDecoration($this->getFormatter(), str_replace("\t", ' ', $text));
}
}

View File

@ -11,8 +11,8 @@
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
* Base class for output classes.
@ -37,7 +37,7 @@ abstract class Output implements OutputInterface
* @param bool $decorated Whether to decorate messages
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
*/
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null)
{
$this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
$this->formatter = $formatter ?: new OutputFormatter();
@ -137,7 +137,9 @@ abstract class Output implements OutputInterface
*/
public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
{
$messages = (array) $messages;
if (!is_iterable($messages)) {
$messages = [$messages];
}
$types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
$type = $types & $options ?: self::OUTPUT_NORMAL;

View File

@ -33,17 +33,17 @@ interface OutputInterface
/**
* Writes a message to the output.
*
* @param string|array $messages The message as an array of lines or a single string
* @param bool $newline Whether to add a newline
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
* @param string|iterable $messages The message as an iterable of strings or a single string
* @param bool $newline Whether to add a newline
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
*/
public function write($messages, $newline = false, $options = 0);
/**
* Writes a message to the output and adds a newline at the end.
*
* @param string|array $messages The message as an array of lines of a single string
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
* @param string|iterable $messages The message as an iterable of strings or a single string
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
*/
public function writeln($messages, $options = 0);

View File

@ -20,11 +20,11 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*
* Usage:
*
* $output = new StreamOutput(fopen('php://stdout', 'w'));
* $output = new StreamOutput(fopen('php://stdout', 'w'));
*
* As `StreamOutput` can use any stream, you can also use a file:
*
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@ -40,9 +40,9 @@ class StreamOutput extends Output
*
* @throws InvalidArgumentException When first argument is not a real stream
*/
public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
{
if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
}
@ -70,7 +70,11 @@ class StreamOutput extends Output
*/
protected function doWrite($message, $newline)
{
if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
if ($newline) {
$message .= PHP_EOL;
}
if (false === @fwrite($this->stream, $message)) {
// should never happen
throw new RuntimeException('Unable to write output.');
}
@ -83,21 +87,38 @@ class StreamOutput extends Output
*
* Colorization is disabled if not supported by the stream:
*
* - Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
* - non tty consoles
* This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
* terminals via named pipes, so we can only check the environment.
*
* Reference: Composer\XdebugHandler\Process::supportsColor
* https://github.com/composer/xdebug-handler
*
* @return bool true if the stream supports colorization, false otherwise
*/
protected function hasColorSupport()
{
if (DIRECTORY_SEPARATOR === '\\') {
return
'10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
if ('Hyper' === getenv('TERM_PROGRAM')) {
return true;
}
if (\DIRECTORY_SEPARATOR === '\\') {
return (\function_exists('sapi_windows_vt100_support')
&& @sapi_windows_vt100_support($this->stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}
return function_exists('posix_isatty') && @posix_isatty($this->stream);
if (\function_exists('stream_isatty')) {
return @stream_isatty($this->stream);
}
if (\function_exists('posix_isatty')) {
return @posix_isatty($this->stream);
}
$stat = @fstat($this->stream);
// Check if formatted mode is S_IFCHR
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
}
}

View File

@ -30,7 +30,7 @@ class ChoiceQuestion extends Question
* @param array $choices The list of available choices
* @param mixed $default The default answer to return
*/
public function __construct($question, array $choices, $default = null)
public function __construct(string $question, array $choices, $default = null)
{
if (!$choices) {
throw new \LogicException('Choice question must have at least 1 choice available.');
@ -121,12 +121,7 @@ class ChoiceQuestion extends Question
return $this;
}
/**
* Returns the default answer validator.
*
* @return callable
*/
private function getDefaultValidator()
private function getDefaultValidator(): callable
{
$choices = $this->choices;
$errorMessage = $this->errorMessage;
@ -134,29 +129,27 @@ class ChoiceQuestion extends Question
$isAssoc = $this->isAssoc($choices);
return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
// Collapse all spaces.
$selectedChoices = str_replace(' ', '', $selected);
if ($multiselect) {
// Check for a separated comma values
if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selectedChoices, $matches)) {
if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selected, $matches)) {
throw new InvalidArgumentException(sprintf($errorMessage, $selected));
}
$selectedChoices = explode(',', $selectedChoices);
$selectedChoices = array_map('trim', explode(',', $selected));
} else {
$selectedChoices = array($selected);
$selectedChoices = [trim($selected)];
}
$multiselectChoices = array();
$multiselectChoices = [];
foreach ($selectedChoices as $value) {
$results = array();
$results = [];
foreach ($choices as $key => $choice) {
if ($choice === $value) {
$results[] = $key;
}
}
if (count($results) > 1) {
if (\count($results) > 1) {
throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
}

View File

@ -25,9 +25,9 @@ class ConfirmationQuestion extends Question
* @param bool $default The default answer to return, true or false
* @param string $trueAnswerRegex A regex to match the "yes" answer
*/
public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i')
{
parent::__construct($question, (bool) $default);
parent::__construct($question, $default);
$this->trueAnswerRegex = $trueAnswerRegex;
$this->setNormalizer($this->getDefaultNormalizer());
@ -44,7 +44,7 @@ class ConfirmationQuestion extends Question
$regex = $this->trueAnswerRegex;
return function ($answer) use ($default, $regex) {
if (is_bool($answer)) {
if (\is_bool($answer)) {
return $answer;
}
@ -53,7 +53,7 @@ class ConfirmationQuestion extends Question
return $answer && $answerIsTrue;
}
return !$answer || $answerIsTrue;
return '' === $answer || $answerIsTrue;
};
}
}

View File

@ -34,7 +34,7 @@ class Question
* @param string $question The question to ask to the user
* @param mixed $default The default answer to return if the user enters nothing
*/
public function __construct($question, $default = null)
public function __construct(string $question, $default = null)
{
$this->question = $question;
$this->default = $default;
@ -117,7 +117,7 @@ class Question
/**
* Gets values for the autocompleter.
*
* @return null|iterable
* @return iterable|null
*/
public function getAutocompleterValues()
{
@ -127,7 +127,7 @@ class Question
/**
* Sets values for the autocompleter.
*
* @param null|iterable $values
* @param iterable|null $values
*
* @return $this
*
@ -136,12 +136,12 @@ class Question
*/
public function setAutocompleterValues($values)
{
if (is_array($values)) {
if (\is_array($values)) {
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
}
if (null !== $values && !is_array($values) && !$values instanceof \Traversable) {
throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or a `Traversable` object.');
if (null !== $values && !\is_array($values) && !$values instanceof \Traversable) {
throw new InvalidArgumentException('Autocompleter values can be either an array, "null" or a "Traversable" object.');
}
if ($this->hidden) {
@ -156,7 +156,7 @@ class Question
/**
* Sets a validator for the question.
*
* @param null|callable $validator
* @param callable|null $validator
*
* @return $this
*/
@ -170,7 +170,7 @@ class Question
/**
* Gets the validator for the question.
*
* @return null|callable
* @return callable|null
*/
public function getValidator()
{
@ -182,7 +182,7 @@ class Question
*
* Null means an unlimited number of attempts.
*
* @param null|int $attempts
* @param int|null $attempts
*
* @return $this
*
@ -204,7 +204,7 @@ class Question
*
* Null means an unlimited number of attempts.
*
* @return null|int
* @return int|null
*/
public function getMaxAttempts()
{
@ -241,6 +241,6 @@ class Question
protected function isAssoc($array)
{
return (bool) count(array_filter(array_keys($array), 'is_string'));
return (bool) \count(array_filter(array_keys($array), 'is_string'));
}
}

View File

@ -13,8 +13,8 @@ namespace Symfony\Component\Console\Style;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Decorates output to add console style guide helpers.

View File

@ -91,7 +91,7 @@ interface StyleInterface
* @param string|null $default
* @param callable|null $validator
*
* @return string
* @return mixed
*/
public function ask($question, $default = null, $validator = null);
@ -101,7 +101,7 @@ interface StyleInterface
* @param string $question
* @param callable|null $validator
*
* @return string
* @return mixed
*/
public function askHidden($question, $validator = null);
@ -122,7 +122,7 @@ interface StyleInterface
* @param array $choices
* @param string|int|null $default
*
* @return string
* @return mixed
*/
public function choice($question, array $choices, $default = null);

View File

@ -46,7 +46,7 @@ class SymfonyStyle extends OutputStyle
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
// Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
$this->lineLength = min($width - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
$this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
parent::__construct($output);
}
@ -63,7 +63,7 @@ class SymfonyStyle extends OutputStyle
*/
public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true)
{
$messages = is_array($messages) ? array_values($messages) : array($messages);
$messages = \is_array($messages) ? array_values($messages) : [$messages];
$this->autoPrependBlock();
$this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape));
@ -76,10 +76,10 @@ class SymfonyStyle extends OutputStyle
public function title($message)
{
$this->autoPrependBlock();
$this->writeln(array(
$this->writeln([
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
]);
$this->newLine();
}
@ -89,10 +89,10 @@ class SymfonyStyle extends OutputStyle
public function section($message)
{
$this->autoPrependBlock();
$this->writeln(array(
$this->writeln([
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
]);
$this->newLine();
}
@ -117,7 +117,7 @@ class SymfonyStyle extends OutputStyle
{
$this->autoPrependText();
$messages = is_array($message) ? array_values($message) : array($message);
$messages = \is_array($message) ? array_values($message) : [$message];
foreach ($messages as $message) {
$this->writeln(sprintf(' %s', $message));
}
@ -269,7 +269,7 @@ class SymfonyStyle extends OutputStyle
{
$progressBar = parent::createProgressBar($max);
if ('\\' !== DIRECTORY_SEPARATOR) {
if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) {
$progressBar->setEmptyBarCharacter('░'); // light shade character \u2591
$progressBar->setProgressCharacter('');
$progressBar->setBarCharacter('▓'); // dark shade character \u2593
@ -279,7 +279,7 @@ class SymfonyStyle extends OutputStyle
}
/**
* @return string
* @return mixed
*/
public function askQuestion(Question $question)
{
@ -306,8 +306,14 @@ class SymfonyStyle extends OutputStyle
*/
public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
parent::writeln($messages, $type);
$this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
if (!is_iterable($messages)) {
$messages = [$messages];
}
foreach ($messages as $message) {
parent::writeln($message, $type);
$this->writeBuffer($message, true, $type);
}
}
/**
@ -315,8 +321,14 @@ class SymfonyStyle extends OutputStyle
*/
public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
parent::write($messages, $newline, $type);
$this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
if (!is_iterable($messages)) {
$messages = [$messages];
}
foreach ($messages as $message) {
parent::write($message, $newline, $type);
$this->writeBuffer($message, $newline, $type);
}
}
/**
@ -338,10 +350,7 @@ class SymfonyStyle extends OutputStyle
return new self($this->input, $this->getErrorOutput());
}
/**
* @return ProgressBar
*/
private function getProgressBar()
private function getProgressBar(): ProgressBar
{
if (!$this->progressBar) {
throw new RuntimeException('The ProgressBar is not started.');
@ -350,18 +359,20 @@ class SymfonyStyle extends OutputStyle
return $this->progressBar;
}
private function autoPrependBlock()
private function autoPrependBlock(): void
{
$chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
if (!isset($chars[0])) {
return $this->newLine(); //empty history, so we should start with a new line.
$this->newLine(); //empty history, so we should start with a new line.
return;
}
//Prepend new line for each non LF chars (This means no blank line was output before)
$this->newLine(2 - substr_count($chars, "\n"));
}
private function autoPrependText()
private function autoPrependText(): void
{
$fetched = $this->bufferedOutput->fetch();
//Prepend new line if last char isn't EOL:
@ -370,24 +381,22 @@ class SymfonyStyle extends OutputStyle
}
}
private function reduceBuffer($messages)
private function writeBuffer(string $message, bool $newLine, int $type): void
{
// We need to know if the two last chars are PHP_EOL
// Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
return array_map(function ($value) {
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
$this->bufferedOutput->write(substr($message, -4), $newLine, $type);
}
private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false)
{
$indentLength = 0;
$prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
$lines = array();
$lines = [];
if (null !== $type) {
$type = sprintf('[%s] ', $type);
$indentLength = strlen($type);
$indentLength = \strlen($type);
$lineIndentation = str_repeat(' ', $indentLength);
}
@ -399,7 +408,7 @@ class SymfonyStyle extends OutputStyle
$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));
if (count($messages) > 1 && $key < count($messages) - 1) {
if (\count($messages) > 1 && $key < \count($messages) - 1) {
$lines[] = '';
}
}

View File

@ -56,7 +56,7 @@ class Terminal
private static function initDimensions()
{
if ('\\' === DIRECTORY_SEPARATOR) {
if ('\\' === \DIRECTORY_SEPARATOR) {
if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
// extract [w, H] from "wxh (WxH)"
// or [w, h] from "wxh"
@ -87,23 +87,23 @@ class Terminal
*/
private static function getConsoleMode()
{
if (!function_exists('proc_open')) {
if (!\function_exists('proc_open')) {
return;
}
$descriptorspec = array(
1 => array('pipe', 'w'),
2 => array('pipe', 'w'),
);
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
if (is_resource($process)) {
$descriptorspec = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
if (\is_resource($process)) {
$info = stream_get_contents($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
return array((int) $matches[2], (int) $matches[1]);
return [(int) $matches[2], (int) $matches[1]];
}
}
}
@ -115,17 +115,17 @@ class Terminal
*/
private static function getSttyColumns()
{
if (!function_exists('proc_open')) {
if (!\function_exists('proc_open')) {
return;
}
$descriptorspec = array(
1 => array('pipe', 'w'),
2 => array('pipe', 'w'),
);
$descriptorspec = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
if (is_resource($process)) {
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
if (\is_resource($process)) {
$info = stream_get_contents($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);

View File

@ -13,10 +13,6 @@ namespace Symfony\Component\Console\Tester;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
/**
* Eases the testing of console applications.
@ -30,14 +26,11 @@ use Symfony\Component\Console\Output\StreamOutput;
*/
class ApplicationTester
{
use TesterTrait;
private $application;
private $input;
private $statusCode;
/**
* @var OutputInterface
*/
private $output;
private $captureStreamsIndependently = false;
public function __construct(Application $application)
{
@ -59,118 +52,26 @@ class ApplicationTester
*
* @return int The command exit code
*/
public function run(array $input, $options = array())
public function run(array $input, $options = [])
{
$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
$this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
if (!$this->captureStreamsIndependently) {
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}
} else {
$this->output = new ConsoleOutput(
isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL,
isset($options['decorated']) ? $options['decorated'] : null
);
$shellInteractive = getenv('SHELL_INTERACTIVE');
$errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
$errorOutput->setFormatter($this->output->getFormatter());
$errorOutput->setVerbosity($this->output->getVerbosity());
$errorOutput->setDecorated($this->output->isDecorated());
$reflectedOutput = new \ReflectionObject($this->output);
$strErrProperty = $reflectedOutput->getProperty('stderr');
$strErrProperty->setAccessible(true);
$strErrProperty->setValue($this->output, $errorOutput);
$reflectedParent = $reflectedOutput->getParentClass();
$streamProperty = $reflectedParent->getProperty('stream');
$streamProperty->setAccessible(true);
$streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
putenv('SHELL_INTERACTIVE=1');
}
return $this->statusCode = $this->application->run($this->input, $this->output);
}
$this->initOutput($options);
/**
* Gets the display returned by the last execution of the application.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string The display
*/
public function getDisplay($normalize = false)
{
rewind($this->output->getStream());
$this->statusCode = $this->application->run($this->input, $this->output);
$display = stream_get_contents($this->output->getStream());
putenv($shellInteractive ? "SHELL_INTERACTIVE=$shellInteractive" : 'SHELL_INTERACTIVE');
if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}
return $display;
}
/**
* Gets the output written to STDERR by the application.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string
*/
public function getErrorOutput($normalize = false)
{
if (!$this->captureStreamsIndependently) {
throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
}
rewind($this->output->getErrorOutput()->getStream());
$display = stream_get_contents($this->output->getErrorOutput()->getStream());
if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}
return $display;
}
/**
* Gets the input instance used by the last execution of the application.
*
* @return InputInterface The current input instance
*/
public function getInput()
{
return $this->input;
}
/**
* Gets the output instance used by the last execution of the application.
*
* @return OutputInterface The current output instance
*/
public function getOutput()
{
return $this->output;
}
/**
* Gets the status code returned by the last execution of the application.
*
* @return int The status code
*/
public function getStatusCode()
{
return $this->statusCode;
}
}

View File

@ -13,9 +13,6 @@ namespace Symfony\Component\Console\Tester;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Eases the testing of console commands.
@ -25,10 +22,10 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class CommandTester
{
use TesterTrait;
private $command;
private $input;
private $output;
private $inputs = array();
private $statusCode;
public function __construct(Command $command)
@ -41,16 +38,17 @@ class CommandTester
*
* Available execution options:
*
* * interactive: Sets the input interactive flag
* * decorated: Sets the output decorated flag
* * verbosity: Sets the output verbosity flag
* * interactive: Sets the input interactive flag
* * decorated: Sets the output decorated flag
* * verbosity: Sets the output verbosity flag
* * capture_stderr_separately: Make output of stdOut and stdErr separately available
*
* @param array $input An array of command arguments and options
* @param array $options An array of execution options
*
* @return int The command exit code
*/
public function execute(array $input, array $options = array())
public function execute(array $input, array $options = [])
{
// set the command name automatically if the application requires
// this argument and no command name was passed
@ -58,99 +56,23 @@ class CommandTester
&& (null !== $application = $this->command->getApplication())
&& $application->getDefinition()->hasArgument('command')
) {
$input = array_merge(array('command' => $this->command->getName()), $input);
$input = array_merge(['command' => $this->command->getName()], $input);
}
$this->input = new ArrayInput($input);
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}
// Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN.
$this->input->setStream(self::createStream($this->inputs));
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
$this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false);
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
if (!isset($options['decorated'])) {
$options['decorated'] = false;
}
$this->initOutput($options);
return $this->statusCode = $this->command->run($this->input, $this->output);
}
/**
* Gets the display returned by the last execution of the command.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string The display
*/
public function getDisplay($normalize = false)
{
rewind($this->output->getStream());
$display = stream_get_contents($this->output->getStream());
if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}
return $display;
}
/**
* Gets the input instance used by the last execution of the command.
*
* @return InputInterface The current input instance
*/
public function getInput()
{
return $this->input;
}
/**
* Gets the output instance used by the last execution of the command.
*
* @return OutputInterface The current output instance
*/
public function getOutput()
{
return $this->output;
}
/**
* Gets the status code returned by the last execution of the application.
*
* @return int The status code
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* Sets the user inputs.
*
* @param array $inputs An array of strings representing each input
* passed to the command input stream
*
* @return CommandTester
*/
public function setInputs(array $inputs)
{
$this->inputs = $inputs;
return $this;
}
private static function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);
fwrite($stream, implode(PHP_EOL, $inputs));
rewind($stream);
return $stream;
}
}

View File

@ -0,0 +1,177 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Tester;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
/**
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
*/
trait TesterTrait
{
/** @var StreamOutput */
private $output;
private $inputs = [];
private $captureStreamsIndependently = false;
/**
* Gets the display returned by the last execution of the command or application.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string The display
*/
public function getDisplay($normalize = false)
{
if (null === $this->output) {
throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
}
rewind($this->output->getStream());
$display = stream_get_contents($this->output->getStream());
if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}
return $display;
}
/**
* Gets the output written to STDERR by the application.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string
*/
public function getErrorOutput($normalize = false)
{
if (!$this->captureStreamsIndependently) {
throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
}
rewind($this->output->getErrorOutput()->getStream());
$display = stream_get_contents($this->output->getErrorOutput()->getStream());
if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}
return $display;
}
/**
* Gets the input instance used by the last execution of the command or application.
*
* @return InputInterface The current input instance
*/
public function getInput()
{
return $this->input;
}
/**
* Gets the output instance used by the last execution of the command or application.
*
* @return OutputInterface The current output instance
*/
public function getOutput()
{
return $this->output;
}
/**
* Gets the status code returned by the last execution of the command or application.
*
* @return int The status code
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* Sets the user inputs.
*
* @param array $inputs An array of strings representing each input
* passed to the command input stream
*
* @return self
*/
public function setInputs(array $inputs)
{
$this->inputs = $inputs;
return $this;
}
/**
* Initializes the output property.
*
* Available options:
*
* * decorated: Sets the output decorated flag
* * verbosity: Sets the output verbosity flag
* * capture_stderr_separately: Make output of stdOut and stdErr separately available
*/
private function initOutput(array $options)
{
$this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
if (!$this->captureStreamsIndependently) {
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}
} else {
$this->output = new ConsoleOutput(
isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL,
isset($options['decorated']) ? $options['decorated'] : null
);
$errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
$errorOutput->setFormatter($this->output->getFormatter());
$errorOutput->setVerbosity($this->output->getVerbosity());
$errorOutput->setDecorated($this->output->isDecorated());
$reflectedOutput = new \ReflectionObject($this->output);
$strErrProperty = $reflectedOutput->getProperty('stderr');
$strErrProperty->setAccessible(true);
$strErrProperty->setValue($this->output, $errorOutput);
$reflectedParent = $reflectedOutput->getParentClass();
$streamProperty = $reflectedParent->getProperty('stream');
$streamProperty->setAccessible(true);
$streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
}
}
private static function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);
foreach ($inputs as $input) {
fwrite($stream, $input.PHP_EOL);
}
rewind($stream);
return $stream;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -12,16 +12,16 @@
namespace Symfony\Component\Console\Tests\Command;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tester\CommandTester;
class CommandTest extends TestCase
@ -71,7 +71,7 @@ class CommandTest extends TestCase
$ret = $command->setDefinition($definition = new InputDefinition());
$this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
$this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
$command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
$command->setDefinition([new InputArgument('foo'), new InputOption('bar')]);
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
$this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
$command->setDefinition(new InputDefinition());
@ -130,10 +130,10 @@ class CommandTest extends TestCase
public function provideInvalidCommandNames()
{
return array(
array(''),
array('foo:'),
);
return [
[''],
['foo:'],
];
}
public function testGetSetDescription()
@ -166,15 +166,23 @@ class CommandTest extends TestCase
$command = new \TestCommand();
$command->setHelp('');
$this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description');
$command = new \TestCommand();
$command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
$application = new Application();
$application->add($command);
$application->setDefaultCommand('namespace:name', true);
$this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly in single command applications');
$this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name% in single command applications');
}
public function testGetSetAliases()
{
$command = new \TestCommand();
$this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
$ret = $command->setAliases(array('name1'));
$this->assertEquals(['name'], $command->getAliases(), '->getAliases() returns the aliases');
$ret = $command->setAliases(['name1']);
$this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
$this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
$this->assertEquals(['name1'], $command->getAliases(), '->setAliases() sets the aliases');
}
public function testSetAliasesNull()
@ -223,11 +231,11 @@ class CommandTest extends TestCase
public function testMergeApplicationDefinition()
{
$application1 = new Application();
$application1->getDefinition()->addArguments(array(new InputArgument('foo')));
$application1->getDefinition()->addOptions(array(new InputOption('bar')));
$application1->getDefinition()->addArguments([new InputArgument('foo')]);
$application1->getDefinition()->addOptions([new InputOption('bar')]);
$command = new \TestCommand();
$command->setApplication($application1);
$command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));
$command->setDefinition($definition = new InputDefinition([new InputArgument('bar'), new InputOption('foo')]));
$r = new \ReflectionObject($command);
$m = $r->getMethod('mergeApplicationDefinition');
@ -245,11 +253,11 @@ class CommandTest extends TestCase
public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
{
$application1 = new Application();
$application1->getDefinition()->addArguments(array(new InputArgument('foo')));
$application1->getDefinition()->addOptions(array(new InputOption('bar')));
$application1->getDefinition()->addArguments([new InputArgument('foo')]);
$application1->getDefinition()->addOptions([new InputOption('bar')]);
$command = new \TestCommand();
$command->setApplication($application1);
$command->setDefinition($definition = new InputDefinition(array()));
$command->setDefinition($definition = new InputDefinition([]));
$r = new \ReflectionObject($command);
$m = $r->getMethod('mergeApplicationDefinition');
@ -269,7 +277,7 @@ class CommandTest extends TestCase
{
$tester = new CommandTester(new \TestCommand());
$tester->execute(array(), array('interactive' => true));
$tester->execute([], ['interactive' => true]);
$this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
}
@ -278,7 +286,7 @@ class CommandTest extends TestCase
{
$tester = new CommandTester(new \TestCommand());
$tester->execute(array(), array('interactive' => false));
$tester->execute([], ['interactive' => false]);
$this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
}
@ -301,7 +309,7 @@ class CommandTest extends TestCase
{
$command = new \TestCommand();
$tester = new CommandTester($command);
$tester->execute(array('--bar' => true));
$tester->execute(['--bar' => true]);
}
public function testRunReturnsIntegerExitCode()
@ -310,10 +318,10 @@ class CommandTest extends TestCase
$exitCode = $command->run(new StringInput(''), new NullOutput());
$this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');
$command = $this->getMockBuilder('TestCommand')->setMethods(array('execute'))->getMock();
$command = $this->getMockBuilder('TestCommand')->setMethods(['execute'])->getMock();
$command->expects($this->once())
->method('execute')
->will($this->returnValue('2.3'));
->willReturn('2.3');
$exitCode = $command->run(new StringInput(''), new NullOutput());
$this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
}
@ -340,7 +348,7 @@ class CommandTest extends TestCase
$command->setApplication(new Application());
$command->setProcessTitle('foo');
$this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
if (function_exists('cli_set_process_title')) {
if (\function_exists('cli_set_process_title')) {
if (null === @cli_get_process_title() && 'Darwin' === PHP_OS) {
$this->markTestSkipped('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.');
}
@ -356,16 +364,16 @@ class CommandTest extends TestCase
});
$this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
$tester = new CommandTester($command);
$tester->execute(array());
$tester->execute([]);
$this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
}
public function getSetCodeBindToClosureTests()
{
return array(
array(true, 'not bound to the command'),
array(false, 'bound to the command'),
);
return [
[true, 'not bound to the command'],
[false, 'bound to the command'],
];
}
/**
@ -381,7 +389,7 @@ class CommandTest extends TestCase
$command = new \TestCommand();
$command->setCode($code);
$tester = new CommandTester($command);
$tester->execute(array());
$tester->execute([]);
$this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay());
}
@ -390,15 +398,9 @@ class CommandTest extends TestCase
$command = new \TestCommand();
$command->setCode(self::createClosure());
$tester = new CommandTester($command);
$tester->execute(array());
$tester->execute([]);
if (\PHP_VERSION_ID < 70000) {
// Cannot bind static closures in PHP 5
$this->assertEquals('interact called'.PHP_EOL.'not bound'.PHP_EOL, $tester->getDisplay());
} else {
// Can bind static closures in PHP 7
$this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay());
}
$this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay());
}
private static function createClosure()
@ -411,10 +413,10 @@ class CommandTest extends TestCase
public function testSetCodeWithNonClosureCallable()
{
$command = new \TestCommand();
$ret = $command->setCode(array($this, 'callableMethodCommand'));
$ret = $command->setCode([$this, 'callableMethodCommand']);
$this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
$tester = new CommandTester($command);
$tester->execute(array());
$tester->execute([]);
$this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
}

View File

@ -12,10 +12,10 @@
namespace Symfony\Component\Console\Tests\Command;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
class HelpCommandTest extends TestCase
{
@ -24,7 +24,7 @@ class HelpCommandTest extends TestCase
$command = new HelpCommand();
$command->setApplication(new Application());
$commandTester = new CommandTester($command);
$commandTester->execute(array('command_name' => 'li'), array('decorated' => false));
$commandTester->execute(['command_name' => 'li'], ['decorated' => false]);
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
@ -35,7 +35,7 @@ class HelpCommandTest extends TestCase
$command = new HelpCommand();
$commandTester = new CommandTester($command);
$command->setCommand(new ListCommand());
$commandTester->execute(array(), array('decorated' => false));
$commandTester->execute([], ['decorated' => false]);
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
@ -46,7 +46,7 @@ class HelpCommandTest extends TestCase
$command = new HelpCommand();
$commandTester = new CommandTester($command);
$command->setCommand(new ListCommand());
$commandTester->execute(array('--format' => 'xml'));
$commandTester->execute(['--format' => 'xml']);
$this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --xml is passed');
}
@ -54,7 +54,7 @@ class HelpCommandTest extends TestCase
{
$application = new Application();
$commandTester = new CommandTester($application->get('help'));
$commandTester->execute(array('command_name' => 'list'));
$commandTester->execute(['command_name' => 'list']);
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
@ -64,7 +64,7 @@ class HelpCommandTest extends TestCase
{
$application = new Application();
$commandTester = new CommandTester($application->get('help'));
$commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
$commandTester->execute(['command_name' => 'list', '--format' => 'xml']);
$this->assertContains('list [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
}

Some files were not shown because too many files have changed in this diff Show More