From 45d0e0a7ddbf0bbc075a5aacff3894f49ed4e5d8 Mon Sep 17 00:00:00 2001
From: "venkatesh.r"
\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+})
-)';
-
-const PARAMS = '\[(?[^[\]]*+(?:\[(?¶ms)\][^[\]]*+)*+)\]';
-const ARGS = '\((?[^()]*+(?:\((?&args)\)[^()]*+)*+)\)';
-
-///////////////////////////////
-/// Preprocessing functions ///
-///////////////////////////////
-
-function preprocessGrammar($code) {
- $code = resolveNodes($code);
- $code = resolveMacros($code);
- $code = resolveStackAccess($code);
-
- return $code;
-}
-
-function resolveNodes($code) {
- return preg_replace_callback(
- '~\b(?[A-Z][a-zA-Z_\\\\]++)\s*' . PARAMS . '~',
- function($matches) {
- // recurse
- $matches['params'] = resolveNodes($matches['params']);
-
- $params = magicSplit(
- '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,',
- $matches['params']
- );
-
- $paramCode = '';
- foreach ($params as $param) {
- $paramCode .= $param . ', ';
- }
-
- return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())';
- },
- $code
- );
-}
-
-function resolveMacros($code) {
- return preg_replace_callback(
- '~\b(?)(?!array\()(?[a-z][A-Za-z]++)' . ARGS . '~',
- function($matches) {
- // recurse
- $matches['args'] = resolveMacros($matches['args']);
-
- $name = $matches['name'];
- $args = magicSplit(
- '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,',
- $matches['args']
- );
-
- if ('attributes' === $name) {
- assertArgs(0, $args, $name);
- return '$this->startAttributeStack[#1] + $this->endAttributes';
- }
-
- if ('stackAttributes' === $name) {
- assertArgs(1, $args, $name);
- return '$this->startAttributeStack[' . $args[0] . ']'
- . ' + $this->endAttributeStack[' . $args[0] . ']';
- }
-
- if ('init' === $name) {
- return '$$ = array(' . implode(', ', $args) . ')';
- }
-
- if ('push' === $name) {
- assertArgs(2, $args, $name);
-
- return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0];
- }
-
- if ('pushNormalizing' === $name) {
- assertArgs(2, $args, $name);
-
- return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }'
- . ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }';
- }
-
- if ('toArray' == $name) {
- assertArgs(1, $args, $name);
-
- return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')';
- }
-
- if ('parseVar' === $name) {
- assertArgs(1, $args, $name);
-
- return 'substr(' . $args[0] . ', 1)';
- }
-
- if ('parseEncapsed' === $name) {
- assertArgs(3, $args, $name);
-
- return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {'
- . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }';
- }
-
- if ('makeNop' === $name) {
- assertArgs(3, $args, $name);
-
- return '$startAttributes = ' . $args[1] . ';'
- . ' if (isset($startAttributes[\'comments\']))'
- . ' { ' . $args[0] . ' = new Stmt\Nop($startAttributes + ' . $args[2] . '); }'
- . ' else { ' . $args[0] . ' = null; }';
- }
-
- if ('makeZeroLengthNop' == $name) {
- assertArgs(2, $args, $name);
-
- return '$startAttributes = ' . $args[1] . ';'
- . ' if (isset($startAttributes[\'comments\']))'
- . ' { ' . $args[0] . ' = new Stmt\Nop($this->createCommentNopAttributes($startAttributes[\'comments\'])); }'
- . ' else { ' . $args[0] . ' = null; }';
- }
-
- if ('prependLeadingComments' === $name) {
- assertArgs(1, $args, $name);
-
- return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; '
- . 'if (!empty($attrs[\'comments\'])) {'
- . '$stmts[0]->setAttribute(\'comments\', '
- . 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }';
- }
-
- return $matches[0];
- },
- $code
- );
-}
-
-function assertArgs($num, $args, $name) {
- if ($num != count($args)) {
- die('Wrong argument count for ' . $name . '().');
- }
-}
-
-function resolveStackAccess($code) {
- $code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code);
- $code = preg_replace('/#(\d+)/', '$$1', $code);
- return $code;
-}
-
-function removeTrailingWhitespace($code) {
- $lines = explode("\n", $code);
- $lines = array_map('rtrim', $lines);
- return implode("\n", $lines);
-}
-
-//////////////////////////////
-/// Regex helper functions ///
-//////////////////////////////
-
-function regex($regex) {
- return '~' . LIB . '(?:' . str_replace('~', '\~', $regex) . ')~';
-}
-
-function magicSplit($regex, $string) {
- $pieces = preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string);
-
- foreach ($pieces as &$piece) {
- $piece = trim($piece);
- }
-
- if ($pieces === ['']) {
- return [];
- }
-
- return $pieces;
-}
diff --git a/vendor/nikic/php-parser/grammar/rebuildParsers.php b/vendor/nikic/php-parser/grammar/rebuildParsers.php
deleted file mode 100644
index 2d0c6b1..0000000
--- a/vendor/nikic/php-parser/grammar/rebuildParsers.php
+++ /dev/null
@@ -1,81 +0,0 @@
- 'Php5',
- __DIR__ . '/php7.y' => 'Php7',
-];
-
-$tokensFile = __DIR__ . '/tokens.y';
-$tokensTemplate = __DIR__ . '/tokens.template';
-$skeletonFile = __DIR__ . '/parser.template';
-$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy';
-$tmpResultFile = __DIR__ . '/tmp_parser.php';
-$resultDir = __DIR__ . '/../lib/PhpParser/Parser';
-$tokensResultsFile = $resultDir . '/Tokens.php';
-
-$kmyacc = getenv('KMYACC');
-if (!$kmyacc) {
- // Use phpyacc from dev dependencies by default.
- $kmyacc = __DIR__ . '/../vendor/bin/phpyacc';
-}
-
-$options = array_flip($argv);
-$optionDebug = isset($options['--debug']);
-$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']);
-
-///////////////////
-/// Main script ///
-///////////////////
-
-$tokens = file_get_contents($tokensFile);
-
-foreach ($grammarFileToName as $grammarFile => $name) {
- echo "Building temporary $name grammar file.\n";
-
- $grammarCode = file_get_contents($grammarFile);
- $grammarCode = str_replace('%tokens', $tokens, $grammarCode);
- $grammarCode = preprocessGrammar($grammarCode);
-
- file_put_contents($tmpGrammarFile, $grammarCode);
-
- $additionalArgs = $optionDebug ? '-t -v' : '';
-
- echo "Building $name parser.\n";
- $output = execCmd("$kmyacc $additionalArgs -m $skeletonFile -p $name $tmpGrammarFile");
-
- $resultCode = file_get_contents($tmpResultFile);
- $resultCode = removeTrailingWhitespace($resultCode);
-
- ensureDirExists($resultDir);
- file_put_contents("$resultDir/$name.php", $resultCode);
- unlink($tmpResultFile);
-
- echo "Building token definition.\n";
- $output = execCmd("$kmyacc -m $tokensTemplate $tmpGrammarFile");
- rename($tmpResultFile, $tokensResultsFile);
-
- if (!$optionKeepTmpGrammar) {
- unlink($tmpGrammarFile);
- }
-}
-
-////////////////////////////////
-/// Utility helper functions ///
-////////////////////////////////
-
-function ensureDirExists($dir) {
- if (!is_dir($dir)) {
- mkdir($dir, 0777, true);
- }
-}
-
-function execCmd($cmd) {
- $output = trim(shell_exec("$cmd 2>&1"));
- if ($output !== "") {
- echo "> " . $cmd . "\n";
- echo $output;
- }
- return $output;
-}
diff --git a/vendor/nikic/php-parser/grammar/tokens.template b/vendor/nikic/php-parser/grammar/tokens.template
deleted file mode 100644
index ba4e490..0000000
--- a/vendor/nikic/php-parser/grammar/tokens.template
+++ /dev/null
@@ -1,17 +0,0 @@
-semValue
-#semval($,%t) $this->semValue
-#semval(%n) $this->stackPos-(%l-%n)
-#semval(%n,%t) $this->stackPos-(%l-%n)
-
-namespace PhpParser\Parser;
-#include;
-
-/* GENERATED file based on grammar/tokens.y */
-final class Tokens
-{
-#tokenval
- const %s = %n;
-#endtokenval
-}
diff --git a/vendor/nikic/php-parser/grammar/tokens.y b/vendor/nikic/php-parser/grammar/tokens.y
deleted file mode 100644
index 8f0b217..0000000
--- a/vendor/nikic/php-parser/grammar/tokens.y
+++ /dev/null
@@ -1,115 +0,0 @@
-/* We currently rely on the token ID mapping to be the same between PHP 5 and PHP 7 - so the same lexer can be used for
- * both. This is enforced by sharing this token file. */
-
-%right T_THROW
-%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
-%left ','
-%left T_LOGICAL_OR
-%left T_LOGICAL_XOR
-%left T_LOGICAL_AND
-%right T_PRINT
-%right T_YIELD
-%right T_DOUBLE_ARROW
-%right T_YIELD_FROM
-%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL
-%left '?' ':'
-%right T_COALESCE
-%left T_BOOLEAN_OR
-%left T_BOOLEAN_AND
-%left '|'
-%left '^'
-%left T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
-%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
-%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
-%left T_SL T_SR
-%left '+' '-' '.'
-%left '*' '/' '%'
-%right '!'
-%nonassoc T_INSTANCEOF
-%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
-%right T_POW
-%right '['
-%nonassoc T_NEW T_CLONE
-%token T_EXIT
-%token T_IF
-%left T_ELSEIF
-%left T_ELSE
-%left T_ENDIF
-%token T_LNUMBER
-%token T_DNUMBER
-%token T_STRING
-%token T_STRING_VARNAME
-%token T_VARIABLE
-%token T_NUM_STRING
-%token T_INLINE_HTML
-%token T_ENCAPSED_AND_WHITESPACE
-%token T_CONSTANT_ENCAPSED_STRING
-%token T_ECHO
-%token T_DO
-%token T_WHILE
-%token T_ENDWHILE
-%token T_FOR
-%token T_ENDFOR
-%token T_FOREACH
-%token T_ENDFOREACH
-%token T_DECLARE
-%token T_ENDDECLARE
-%token T_AS
-%token T_SWITCH
-%token T_MATCH
-%token T_ENDSWITCH
-%token T_CASE
-%token T_DEFAULT
-%token T_BREAK
-%token T_CONTINUE
-%token T_GOTO
-%token T_FUNCTION
-%token T_FN
-%token T_CONST
-%token T_RETURN
-%token T_TRY
-%token T_CATCH
-%token T_FINALLY
-%token T_THROW
-%token T_USE
-%token T_INSTEADOF
-%token T_GLOBAL
-%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC T_READONLY
-%token T_VAR
-%token T_UNSET
-%token T_ISSET
-%token T_EMPTY
-%token T_HALT_COMPILER
-%token T_CLASS
-%token T_TRAIT
-%token T_INTERFACE
-%token T_ENUM
-%token T_EXTENDS
-%token T_IMPLEMENTS
-%token T_OBJECT_OPERATOR
-%token T_NULLSAFE_OBJECT_OPERATOR
-%token T_DOUBLE_ARROW
-%token T_LIST
-%token T_ARRAY
-%token T_CALLABLE
-%token T_CLASS_C
-%token T_TRAIT_C
-%token T_METHOD_C
-%token T_FUNC_C
-%token T_LINE
-%token T_FILE
-%token T_START_HEREDOC
-%token T_END_HEREDOC
-%token T_DOLLAR_OPEN_CURLY_BRACES
-%token T_CURLY_OPEN
-%token T_PAAMAYIM_NEKUDOTAYIM
-%token T_NAMESPACE
-%token T_NS_C
-%token T_DIR
-%token T_NS_SEPARATOR
-%token T_ELLIPSIS
-%token T_NAME_FULLY_QUALIFIED
-%token T_NAME_QUALIFIED
-%token T_NAME_RELATIVE
-%token T_ATTRIBUTE
-%token T_ENUM
diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php
index d0e7de0..83f3ea8 100644
--- a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php
+++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php
@@ -118,6 +118,9 @@ class NameResolver extends NodeVisitorAbstract
$this->addNamespacedName($const);
}
} else if ($node instanceof Stmt\ClassConst) {
+ if (null !== $node->type) {
+ $node->type = $this->resolveType($node->type);
+ }
$this->resolveAttrGroups($node);
} else if ($node instanceof Stmt\EnumCase) {
$this->resolveAttrGroups($node);
diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php
index a430671..59bd1e8 100644
--- a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php
+++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php
@@ -1738,7 +1738,7 @@ class Php5 extends \PhpParser\ParserAbstract
$this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes);
},
259 => function ($stackPos) {
- if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }
+ if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } else { $this->semValue = $this->semStack[$stackPos-(2-1)]; }
},
260 => function ($stackPos) {
$this->semValue = array();
diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php
index fc895cb..6d2b4b0 100644
--- a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php
+++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php
@@ -2056,7 +2056,7 @@ class Php7 extends \PhpParser\ParserAbstract
$this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes);
},
340 => function ($stackPos) {
- if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }
+ if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } else { $this->semValue = $this->semStack[$stackPos-(2-1)]; }
},
341 => function ($stackPos) {
$this->semValue = array();
diff --git a/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php
index f041e7f..baba23b 100644
--- a/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php
+++ b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php
@@ -2,6 +2,9 @@
namespace PhpParser;
+use PhpParser\Lexer\Emulative;
+use PhpParser\Parser\Php7;
+
class ParserFactory
{
const PREFER_PHP7 = 1;
@@ -41,4 +44,33 @@ class ParserFactory
);
}
}
+
+ /**
+ * Create a parser targeting the newest version supported by this library. Code for older
+ * versions will be accepted if there have been no relevant backwards-compatibility breaks in
+ * PHP.
+ *
+ * All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos,
+ * startFilePos, endFilePos) will be enabled.
+ */
+ public function createForNewestSupportedVersion(): Parser {
+ return new Php7(new Emulative($this->getLexerOptions()));
+ }
+
+ /**
+ * Create a parser targeting the host PHP version, that is the PHP version we're currently
+ * running on. This parser will not use any token emulation.
+ *
+ * All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos,
+ * startFilePos, endFilePos) will be enabled.
+ */
+ public function createForHostVersion(): Parser {
+ return new Php7(new Lexer($this->getLexerOptions()));
+ }
+
+ private function getLexerOptions(): array {
+ return ['usedAttributes' => [
+ 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos',
+ ]];
+ }
}
diff --git a/vendor/phpunit/phpunit/ChangeLog-9.6.md b/vendor/phpunit/phpunit/ChangeLog-9.6.md
index 8fb7ed9..ef54f17 100644
--- a/vendor/phpunit/phpunit/ChangeLog-9.6.md
+++ b/vendor/phpunit/phpunit/ChangeLog-9.6.md
@@ -2,6 +2,18 @@
All notable changes of the PHPUnit 9.6 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+## [9.6.15] - 2023-12-01
+
+### Fixed
+
+* [#5596](https://github.com/sebastianbergmann/phpunit/issues/5596): `PHPUnit\Framework\TestCase` has `@internal` annotation in PHAR
+
+## [9.6.14] - 2023-12-01
+
+### Added
+
+* [#5577](https://github.com/sebastianbergmann/phpunit/issues/5577): `--composer-lock` CLI option for PHAR binary that displays the `composer.lock` used to build the PHAR
+
## [9.6.13] - 2023-09-19
### Changed
@@ -95,6 +107,8 @@ All notable changes of the PHPUnit 9.6 release series are documented in this fil
* [#5064](https://github.com/sebastianbergmann/phpunit/issues/5064): Deprecate `PHPUnit\Framework\TestCase::getMockClass()`
* [#5132](https://github.com/sebastianbergmann/phpunit/issues/5132): Deprecate `Test` suffix for abstract test case classes
+[9.6.15]: https://github.com/sebastianbergmann/phpunit/compare/9.6.14...9.6.15
+[9.6.14]: https://github.com/sebastianbergmann/phpunit/compare/9.6.13...9.6.14
[9.6.13]: https://github.com/sebastianbergmann/phpunit/compare/9.6.12...9.6.13
[9.6.12]: https://github.com/sebastianbergmann/phpunit/compare/9.6.11...9.6.12
[9.6.11]: https://github.com/sebastianbergmann/phpunit/compare/9.6.10...9.6.11
diff --git a/vendor/phpunit/phpunit/README.md b/vendor/phpunit/phpunit/README.md
index c561c59..9fae13d 100644
--- a/vendor/phpunit/phpunit/README.md
+++ b/vendor/phpunit/phpunit/README.md
@@ -1,5 +1,3 @@
-🇺🇦 UKRAINE NEEDS YOUR HELP NOW!
-
# PHPUnit
[](https://packagist.org/packages/phpunit/phpunit)
diff --git a/vendor/phpunit/phpunit/phpunit b/vendor/phpunit/phpunit/phpunit
old mode 100644
new mode 100755
diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php
index 962eec7..e35af52 100644
--- a/vendor/phpunit/phpunit/src/Runner/Version.php
+++ b/vendor/phpunit/phpunit/src/Runner/Version.php
@@ -41,7 +41,7 @@ public static function id(): string
}
if (self::$version === '') {
- self::$version = (new VersionId('9.6.13', dirname(__DIR__, 2)))->getVersion();
+ self::$version = (new VersionId('9.6.15', dirname(__DIR__, 2)))->getVersion();
}
return self::$version;
diff --git a/vendor/setasign/fpdi/README.md b/vendor/setasign/fpdi/README.md
index c503b7d..e27d205 100644
--- a/vendor/setasign/fpdi/README.md
+++ b/vendor/setasign/fpdi/README.md
@@ -27,7 +27,7 @@ To use FPDI with FPDF include following in your composer.json file:
{
"require": {
"setasign/fpdf": "1.8.*",
- "setasign/fpdi": "^2.0"
+ "setasign/fpdi": "^2.5"
}
}
```
@@ -37,8 +37,8 @@ If you want to use TCPDF, you have to update your composer.json to:
```json
{
"require": {
- "tecnickcom/tcpdf": "6.3.*",
- "setasign/fpdi": "^2.0"
+ "tecnickcom/tcpdf": "6.6.*",
+ "setasign/fpdi": "^2.5"
}
}
```
@@ -48,7 +48,7 @@ If you want to use tFPDF, you have to update your composer.json to:
```json
{
"require": {
- "setasign/tfpdf": "1.31.*",
+ "setasign/tfpdf": "1.33.*",
"setasign/fpdi": "^2.3"
}
}
diff --git a/vendor/setasign/fpdi/composer.json b/vendor/setasign/fpdi/composer.json
index b947748..c0eb4df 100644
--- a/vendor/setasign/fpdi/composer.json
+++ b/vendor/setasign/fpdi/composer.json
@@ -38,9 +38,9 @@
},
"require-dev": {
"phpunit/phpunit": "~5.7",
- "setasign/fpdf": "~1.8",
+ "setasign/fpdf": "~1.8.6",
"tecnickcom/tcpdf": "~6.2",
- "setasign/tfpdf": "~1.31",
+ "setasign/tfpdf": "~1.33",
"squizlabs/php_codesniffer": "^3.5"
},
"autoload-dev": {
diff --git a/vendor/setasign/fpdi/src/FpdfTrait.php b/vendor/setasign/fpdi/src/FpdfTrait.php
index 0b56288..67fa561 100644
--- a/vendor/setasign/fpdi/src/FpdfTrait.php
+++ b/vendor/setasign/fpdi/src/FpdfTrait.php
@@ -14,6 +14,7 @@ use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
use setasign\Fpdi\PdfParser\PdfParserException;
use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
use setasign\Fpdi\PdfParser\Type\PdfNull;
+use setasign\Fpdi\PdfParser\Type\PdfType;
/**
* This trait is used for the implementation of FPDI in FPDF and tFPDF.
@@ -142,20 +143,6 @@ trait FpdfTrait
$this->_put('/A <_textstring($pl[4]) . '>>');
if (isset($pl['importedLink'])) {
$values = $pl['importedLink']['pdfObject']->value;
- unset(
- $values['P'],
- $values['NM'],
- $values['AP'],
- $values['AS'],
- $values['Type'],
- $values['Subtype'],
- $values['Rect'],
- $values['A'],
- $values['QuadPoints'],
- $values['Rotate'],
- $values['M'],
- $values['StructParent']
- );
foreach ($values as $name => $entry) {
$this->_put('/' . $name . ' ', false);
diff --git a/vendor/setasign/fpdi/src/Fpdi.php b/vendor/setasign/fpdi/src/Fpdi.php
index 6e910df..fd158a6 100644
--- a/vendor/setasign/fpdi/src/Fpdi.php
+++ b/vendor/setasign/fpdi/src/Fpdi.php
@@ -30,9 +30,5 @@ class Fpdi extends FpdfTpl
*
* @string
*/
-<<<<<<< HEAD
- const VERSION = '2.4.1';
-=======
- const VERSION = '2.5.0';
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
+ const VERSION = '2.6.0';
}
diff --git a/vendor/setasign/fpdi/src/FpdiTrait.php b/vendor/setasign/fpdi/src/FpdiTrait.php
index 8387528..6d57b99 100644
--- a/vendor/setasign/fpdi/src/FpdiTrait.php
+++ b/vendor/setasign/fpdi/src/FpdiTrait.php
@@ -129,7 +129,7 @@ trait FpdiTrait
*/
protected function getPdfParserInstance(StreamReader $streamReader, array $parserParams = [])
{
- // note: if you get an exception here - turn off errors/warnings on not found for your autoloader.
+ // note: if you get an exception here - turn off errors/warnings on not found classes for your autoloader.
// psr-4 (https://www.php-fig.org/psr/psr-4/) says: Autoloader implementations MUST NOT throw
// exceptions, MUST NOT raise errors of any level, and SHOULD NOT return a value.
/** @noinspection PhpUndefinedClassInspection */
@@ -596,7 +596,7 @@ trait FpdiTrait
} elseif ($value instanceof PdfString) {
$this->_put('(' . $value->value . ')', false);
} elseif ($value instanceof PdfHexString) {
- $this->_put('<' . $value->value . '>');
+ $this->_put('<' . $value->value . '>', false);
} elseif ($value instanceof PdfBoolean) {
$this->_put($value->value ? 'true ' : 'false ', false);
} elseif ($value instanceof PdfArray) {
@@ -615,11 +615,8 @@ trait FpdiTrait
} elseif ($value instanceof PdfToken) {
$this->_put($value->value);
} elseif ($value instanceof PdfNull) {
- $this->_put('null ');
+ $this->_put('null ', false);
} elseif ($value instanceof PdfStream) {
- /**
- * @var $value PdfStream
- */
$this->writePdfType($value->value);
$this->_put('stream');
$this->_put($value->getStream());
@@ -636,12 +633,22 @@ trait FpdiTrait
$this->_put($this->objectMap[$this->currentReaderId][$value->value] . ' 0 R ', false);
} elseif ($value instanceof PdfIndirectObject) {
- /**
- * @var PdfIndirectObject $value
- */
$n = $this->objectMap[$this->currentReaderId][$value->objectNumber];
$this->_newobj($n);
$this->writePdfType($value->value);
+
+ // add newline before "endobj" for all objects in view to PDF/A conformance
+ if (
+ !(
+ ($value->value instanceof PdfArray) ||
+ ($value->value instanceof PdfDictionary) ||
+ ($value->value instanceof PdfToken) ||
+ ($value->value instanceof PdfStream)
+ )
+ ) {
+ $this->_put("\n", false);
+ }
+
$this->_put('endobj');
}
}
diff --git a/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php b/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php
index c9d19b9..7fa146d 100644
--- a/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php
+++ b/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php
@@ -69,7 +69,7 @@ class CrossReference
// sometimes the file header offset is part of the byte offsets, so let's retry by resetting it to zero.
if ($e->getCode() === CrossReferenceException::INVALID_DATA && $this->fileHeaderOffset !== 0) {
$this->fileHeaderOffset = 0;
- $reader = $this->readXref($offset + $this->fileHeaderOffset);
+ $reader = $this->readXref($offset);
} else {
throw $e;
}
diff --git a/vendor/setasign/fpdi/src/PdfParser/Filter/Flate.php b/vendor/setasign/fpdi/src/PdfParser/Filter/Flate.php
index 1cefa15..29f0799 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Filter/Flate.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Filter/Flate.php
@@ -55,21 +55,10 @@ class Flate implements FilterInterface
return $data;
}
- // Try this fallback
- $tries = 0;
+ // Try this fallback (remove the zlib stream header)
+ $data = @(gzinflate(substr($oData, 2)));
- $oDataLen = strlen($oData);
- while ($tries < 6 && ($data === false || (strlen($data) < ($oDataLen - $tries - 1)))) {
- $data = @(gzinflate(substr($oData, $tries)));
- $tries++;
- }
-
- // let's use this fallback only if the $data is longer than the original data
- if (strlen($data) > ($oDataLen - $tries - 1)) {
- return $data;
- }
-
- if (!$data) {
+ if ($data === false) {
throw new FlateException(
'Error while decompressing stream.',
FlateException::DECOMPRESS_ERROR
diff --git a/vendor/setasign/fpdi/src/PdfParser/PdfParser.php b/vendor/setasign/fpdi/src/PdfParser/PdfParser.php
index e76c7f2..22a72e6 100644
--- a/vendor/setasign/fpdi/src/PdfParser/PdfParser.php
+++ b/vendor/setasign/fpdi/src/PdfParser/PdfParser.php
@@ -25,10 +25,7 @@ use setasign\Fpdi\PdfParser\Type\PdfStream;
use setasign\Fpdi\PdfParser\Type\PdfString;
use setasign\Fpdi\PdfParser\Type\PdfToken;
use setasign\Fpdi\PdfParser\Type\PdfType;
-<<<<<<< HEAD
-=======
use setasign\Fpdi\PdfParser\Type\PdfTypeException;
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
/**
* A PDF parser class
@@ -262,31 +259,12 @@ class PdfParser
switch ($token) {
case '(':
$this->ensureExpectedType($token, $expectedType);
-<<<<<<< HEAD
- return PdfString::parse($this->streamReader);
-=======
return $this->parsePdfString();
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
case '<':
if ($this->streamReader->getByte() === '<') {
$this->ensureExpectedType('<<', $expectedType);
$this->streamReader->addOffset(1);
-<<<<<<< HEAD
- return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
- }
-
- $this->ensureExpectedType($token, $expectedType);
- return PdfHexString::parse($this->streamReader);
-
- case '/':
- $this->ensureExpectedType($token, $expectedType);
- return PdfName::parse($this->tokenizer, $this->streamReader);
-
- case '[':
- $this->ensureExpectedType($token, $expectedType);
- return PdfArray::parse($this->tokenizer, $this);
-=======
return $this->parsePdfDictionary();
}
@@ -300,7 +278,6 @@ class PdfParser
case '[':
$this->ensureExpectedType($token, $expectedType);
return $this->parsePdfArray();
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
default:
if (\is_numeric($token)) {
@@ -315,17 +292,7 @@ class PdfParser
);
}
-<<<<<<< HEAD
- return PdfIndirectObject::parse(
- (int) $token,
- (int) $token2,
- $this,
- $this->tokenizer,
- $this->streamReader
- );
-=======
return $this->parsePdfIndirectObject((int)$token, (int)$token2);
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
case 'R':
if (
$expectedType !== null &&
@@ -337,11 +304,7 @@ class PdfParser
);
}
-<<<<<<< HEAD
- return PdfIndirectObjectReference::create((int) $token, (int) $token2);
-=======
return PdfIndirectObjectReference::create((int)$token, (int)$token2);
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
}
$this->tokenizer->pushStack($token3);
@@ -384,8 +347,6 @@ class PdfParser
}
/**
-<<<<<<< HEAD
-=======
* @return PdfString
*/
protected function parsePdfString()
@@ -445,7 +406,6 @@ class PdfParser
}
/**
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Ensures that the token will evaluate to an expected object type (or not).
*
* @param string $token
@@ -453,11 +413,7 @@ class PdfParser
* @return bool
* @throws Type\PdfTypeException
*/
-<<<<<<< HEAD
- private function ensureExpectedType($token, $expectedType)
-=======
protected function ensureExpectedType($token, $expectedType)
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
{
static $mapping = [
'(' => PdfString::class,
diff --git a/vendor/setasign/fpdi/src/PdfParser/StreamReader.php b/vendor/setasign/fpdi/src/PdfParser/StreamReader.php
index cd032c3..a493a85 100644
--- a/vendor/setasign/fpdi/src/PdfParser/StreamReader.php
+++ b/vendor/setasign/fpdi/src/PdfParser/StreamReader.php
@@ -113,15 +113,12 @@ class StreamReader
);
}
-<<<<<<< HEAD
-=======
if (fseek($stream, 0) === -1) {
throw new \InvalidArgumentException(
'Given stream is not seekable!'
);
}
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$this->stream = $stream;
$this->closeStream = $closeStream;
$this->reset();
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php
index 37a7e6c..c7981b6 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php
@@ -25,11 +25,7 @@ class PdfArray extends PdfType
*
* @param Tokenizer $tokenizer
* @param PdfParser $parser
-<<<<<<< HEAD
- * @return bool|self
-=======
* @return false|self
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* @throws PdfTypeException
*/
public static function parse(Tokenizer $tokenizer, PdfParser $parser)
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php
index 35ba3af..cd9d2b6 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php
@@ -21,11 +21,7 @@ class PdfHexString extends PdfType
* Parses a hexadecimal string object from the stream reader.
*
* @param StreamReader $streamReader
-<<<<<<< HEAD
- * @return bool|self
-=======
* @return false|self
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
*/
public static function parse(StreamReader $streamReader)
{
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php
index 0ae560e..72a80e1 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php
@@ -22,19 +22,6 @@ class PdfIndirectObject extends PdfType
/**
* Parses an indirect object from a tokenizer, parser and stream-reader.
*
-<<<<<<< HEAD
- * @param int $objectNumberToken
- * @param int $objectGenerationNumberToken
- * @param PdfParser $parser
- * @param Tokenizer $tokenizer
- * @param StreamReader $reader
- * @return bool|self
- * @throws PdfTypeException
- */
- public static function parse(
- $objectNumberToken,
- $objectGenerationNumberToken,
-=======
* @param int $objectNumber
* @param int $objectGenerationNumber
* @param PdfParser $parser
@@ -46,7 +33,6 @@ class PdfIndirectObject extends PdfType
public static function parse(
$objectNumber,
$objectGenerationNumber,
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
PdfParser $parser,
Tokenizer $tokenizer,
StreamReader $reader
@@ -64,13 +50,8 @@ class PdfIndirectObject extends PdfType
}
$v = new self();
-<<<<<<< HEAD
- $v->objectNumber = (int) $objectNumberToken;
- $v->generationNumber = (int) $objectGenerationNumberToken;
-=======
$v->objectNumber = (int) $objectNumber;
$v->generationNumber = (int) $objectGenerationNumber;
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$v->value = $value;
return $v;
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php
index 1fda3e0..cfa2cdb 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php
@@ -213,8 +213,6 @@ class PdfStream extends PdfType
}
/**
-<<<<<<< HEAD
-=======
* Get all filters defined for this stream.
*
* @return PdfType[]
@@ -237,7 +235,6 @@ class PdfStream extends PdfType
}
/**
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Get the unfiltered stream data.
*
* @return string
@@ -247,25 +244,11 @@ class PdfStream extends PdfType
public function getUnfilteredStream()
{
$stream = $this->getStream();
-<<<<<<< HEAD
- $filters = PdfDictionary::get($this->value, 'Filter');
- if ($filters instanceof PdfNull) {
- return $stream;
- }
-
- if ($filters instanceof PdfArray) {
- $filters = $filters->value;
- } else {
- $filters = [$filters];
- }
-
-=======
$filters = $this->getFilters();
if ($filters === []) {
return $stream;
}
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
$decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
if ($decodeParams instanceof PdfArray) {
$decodeParams = $decodeParams->value;
@@ -341,8 +324,6 @@ class PdfStream extends PdfType
$stream = $filterObject->decode($stream);
break;
-<<<<<<< HEAD
-=======
case 'Crypt':
if (!$decodeParam instanceof PdfDictionary) {
break;
@@ -358,7 +339,6 @@ class PdfStream extends PdfType
FilterException::UNSUPPORTED_FILTER
);
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
default:
throw new FilterException(
\sprintf('Unsupported filter "%s".', $filter->value),
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php
index 3aee867..dc4ce33 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php
@@ -79,8 +79,6 @@ class PdfString extends PdfType
}
/**
-<<<<<<< HEAD
-=======
* Escapes sequences in a string according to the PDF specification.
*
* @param string $s
@@ -111,7 +109,6 @@ class PdfString extends PdfType
}
/**
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
* Unescapes escaped sequences in a PDF string according to the PDF specification.
*
* @param string $s
diff --git a/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php b/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php
index 065ad38..ecd18b3 100644
--- a/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php
+++ b/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php
@@ -69,6 +69,34 @@ class PdfType
return $value;
}
+ /**
+ * Flatten indirect object references to direct objects.
+ *
+ * @param PdfType $value
+ * @param PdfParser $parser
+ * @return PdfType
+ * @throws CrossReferenceException
+ * @throws PdfParserException
+ */
+ public static function flatten(PdfType $value, PdfParser $parser)
+ {
+ if ($value instanceof PdfIndirectObjectReference) {
+ return self::flatten(self::resolve($value, $parser), $parser);
+ }
+
+ if ($value instanceof PdfDictionary || $value instanceof PdfArray) {
+ foreach ($value->value as $key => $_value) {
+ $value->value[$key] = self::flatten($_value, $parser);
+ }
+ }
+
+ if ($value instanceof PdfStream) {
+ throw new PdfTypeException('There is a stream object found which cannot be flattened to a direct object.');
+ }
+
+ return $value;
+ }
+
/**
* The value of the PDF type.
*
diff --git a/vendor/setasign/fpdi/src/PdfReader/Page.php b/vendor/setasign/fpdi/src/PdfReader/Page.php
index 8d08c95..ad3c0c2 100644
--- a/vendor/setasign/fpdi/src/PdfReader/Page.php
+++ b/vendor/setasign/fpdi/src/PdfReader/Page.php
@@ -10,6 +10,7 @@
namespace setasign\Fpdi\PdfReader;
+use setasign\Fpdi\FpdiException;
use setasign\Fpdi\GraphicsState;
use setasign\Fpdi\Math\Vector;
use setasign\Fpdi\PdfParser\Filter\FilterException;
@@ -281,14 +282,15 @@ class Page
* origin is lower-left.
*
* @return array
- * @throws CrossReferenceException
- * @throws PdfParserException
- * @throws PdfTypeException
*/
public function getExternalLinks($box = PageBoundaries::CROP_BOX)
{
- $dict = $this->getPageDictionary();
- $annotations = PdfType::resolve(PdfDictionary::get($dict, 'Annots'), $this->parser);
+ try {
+ $dict = $this->getPageDictionary();
+ $annotations = PdfType::resolve(PdfDictionary::get($dict, 'Annots'), $this->parser);
+ } catch (FpdiException $e) {
+ return [];
+ }
if (!$annotations instanceof PdfArray) {
return [];
@@ -297,93 +299,120 @@ class Page
$links = [];
foreach ($annotations->value as $entry) {
- $annotation = PdfType::resolve($entry, $this->parser);
+ try {
+ $annotation = PdfType::resolve($entry, $this->parser);
- $value = PdfType::resolve(PdfDictionary::get($annotation, 'Subtype'), $this->parser);
- if (!$value instanceof PdfName || $value->value !== 'Link') {
- continue;
- }
+ $value = PdfType::resolve(PdfDictionary::get($annotation, 'Subtype'), $this->parser);
+ if (!$value instanceof PdfName || $value->value !== 'Link') {
+ continue;
+ }
- $dest = PdfType::resolve(PdfDictionary::get($annotation, 'Dest'), $this->parser);
- if (!$dest instanceof PdfNull) {
- continue;
- }
+ $dest = PdfType::resolve(PdfDictionary::get($annotation, 'Dest'), $this->parser);
+ if (!$dest instanceof PdfNull) {
+ continue;
+ }
- $action = PdfType::resolve(PdfDictionary::get($annotation, 'A'), $this->parser);
- if (!$action instanceof PdfDictionary) {
- continue;
- }
+ $action = PdfType::resolve(PdfDictionary::get($annotation, 'A'), $this->parser);
+ if (!$action instanceof PdfDictionary) {
+ continue;
+ }
- $actionType = PdfType::resolve(PdfDictionary::get($action, 'S'), $this->parser);
- if (!$actionType instanceof PdfName || $actionType->value !== 'URI') {
- continue;
- }
+ $actionType = PdfType::resolve(PdfDictionary::get($action, 'S'), $this->parser);
+ if (!$actionType instanceof PdfName || $actionType->value !== 'URI') {
+ continue;
+ }
- $uri = PdfType::resolve(PdfDictionary::get($action, 'URI'), $this->parser);
- if ($uri instanceof PdfString) {
- $uriValue = PdfString::unescape($uri->value);
- } elseif ($uri instanceof PdfHexString) {
- $uriValue = \hex2bin($uri->value);
- } else {
- continue;
- }
+ $uri = PdfType::resolve(PdfDictionary::get($action, 'URI'), $this->parser);
+ if ($uri instanceof PdfString) {
+ $uriValue = PdfString::unescape($uri->value);
+ } elseif ($uri instanceof PdfHexString) {
+ $uriValue = \hex2bin($uri->value);
+ } else {
+ continue;
+ }
- $rect = PdfType::resolve(PdfDictionary::get($annotation, 'Rect'), $this->parser);
- if (!$rect instanceof PdfArray || count($rect->value) !== 4) {
- continue;
- }
+ $rect = PdfType::resolve(PdfDictionary::get($annotation, 'Rect'), $this->parser);
+ if (!$rect instanceof PdfArray || count($rect->value) !== 4) {
+ continue;
+ }
- $rect = Rectangle::byPdfArray($rect, $this->parser);
- if ($rect->getWidth() === 0 || $rect->getHeight() === 0) {
- continue;
- }
+ $rect = Rectangle::byPdfArray($rect, $this->parser);
+ if ($rect->getWidth() === 0 || $rect->getHeight() === 0) {
+ continue;
+ }
- $bbox = $this->getBoundary($box);
- $rotation = $this->getRotation();
+ $bbox = $this->getBoundary($box);
+ $rotation = $this->getRotation();
- $gs = new GraphicsState();
- $gs->translate(-$bbox->getLlx(), -$bbox->getLly());
- $gs->rotate($bbox->getLlx(), $bbox->getLly(), -$rotation);
+ $gs = new GraphicsState();
+ $gs->translate(-$bbox->getLlx(), -$bbox->getLly());
+ $gs->rotate($bbox->getLlx(), $bbox->getLly(), -$rotation);
- switch ($rotation) {
- case 90:
- $gs->translate(-$bbox->getWidth(), 0);
- break;
- case 180:
- $gs->translate(-$bbox->getWidth(), -$bbox->getHeight());
- break;
- case 270:
- $gs->translate(0, -$bbox->getHeight());
- break;
- }
+ switch ($rotation) {
+ case 90:
+ $gs->translate(-$bbox->getWidth(), 0);
+ break;
+ case 180:
+ $gs->translate(-$bbox->getWidth(), -$bbox->getHeight());
+ break;
+ case 270:
+ $gs->translate(0, -$bbox->getHeight());
+ break;
+ }
- $normalizedRect = Rectangle::byVectors(
- $gs->toUserSpace(new Vector($rect->getLlx(), $rect->getLly())),
- $gs->toUserSpace(new Vector($rect->getUrx(), $rect->getUry()))
- );
+ $normalizedRect = Rectangle::byVectors(
+ $gs->toUserSpace(new Vector($rect->getLlx(), $rect->getLly())),
+ $gs->toUserSpace(new Vector($rect->getUrx(), $rect->getUry()))
+ );
- $quadPoints = PdfType::resolve(PdfDictionary::get($annotation, 'QuadPoints'), $this->parser);
- $normalizedQuadPoints = [];
- if ($quadPoints instanceof PdfArray) {
- $quadPointsCount = count($quadPoints->value);
- if ($quadPointsCount % 8 === 0) {
- for ($i = 0; ($i + 1) < $quadPointsCount; $i += 2) {
- $x = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i], $this->parser));
- $y = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i + 1], $this->parser));
+ $quadPoints = PdfType::resolve(PdfDictionary::get($annotation, 'QuadPoints'), $this->parser);
+ $normalizedQuadPoints = [];
+ if ($quadPoints instanceof PdfArray) {
+ $quadPointsCount = count($quadPoints->value);
+ if ($quadPointsCount % 8 === 0) {
+ for ($i = 0; ($i + 1) < $quadPointsCount; $i += 2) {
+ $x = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i], $this->parser));
+ $y = PdfNumeric::ensure(PdfType::resolve($quadPoints->value[$i + 1], $this->parser));
- $v = $gs->toUserSpace(new Vector($x->value, $y->value));
- $normalizedQuadPoints[] = $v->getX();
- $normalizedQuadPoints[] = $v->getY();
+ $v = $gs->toUserSpace(new Vector($x->value, $y->value));
+ $normalizedQuadPoints[] = $v->getX();
+ $normalizedQuadPoints[] = $v->getY();
+ }
}
}
- }
- $links[] = [
- 'rect' => $normalizedRect,
- 'quadPoints' => $normalizedQuadPoints,
- 'uri' => $uriValue,
- 'pdfObject' => $annotation
- ];
+ // we remove unsupported/unneeded values here
+ unset(
+ $annotation->value['P'],
+ $annotation->value['NM'],
+ $annotation->value['AP'],
+ $annotation->value['AS'],
+ $annotation->value['Type'],
+ $annotation->value['Subtype'],
+ $annotation->value['Rect'],
+ $annotation->value['A'],
+ $annotation->value['QuadPoints'],
+ $annotation->value['Rotate'],
+ $annotation->value['M'],
+ $annotation->value['StructParent'],
+ $annotation->value['OC']
+ );
+
+ // ...and flatten the PDF object to eliminate any indirect references.
+ // Indirect references are a problem when writing the output in FPDF
+ // because FPDF uses pre-calculated object numbers while FPDI creates
+ // them at runtime.
+ $annotation = PdfType::flatten($annotation, $this->parser);
+
+ $links[] = [
+ 'rect' => $normalizedRect,
+ 'quadPoints' => $normalizedQuadPoints,
+ 'uri' => $uriValue,
+ 'pdfObject' => $annotation
+ ];
+ } catch (FpdiException $e) {
+ continue;
+ }
}
return $links;
diff --git a/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php b/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php
index ad5fc23..ad794d0 100644
--- a/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php
+++ b/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php
@@ -46,11 +46,7 @@ class Fpdi extends \TCPDF
*
* @string
*/
-<<<<<<< HEAD
- const VERSION = '2.4.1';
-=======
- const VERSION = '2.5.0';
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
+ const VERSION = '2.6.0';
/**
* A counter for template ids.
@@ -255,11 +251,7 @@ class Fpdi extends \TCPDF
if ($value instanceof PdfString) {
$string = PdfString::unescape($value->value);
$string = $this->_encrypt_data($this->currentObjectNumber, $string);
-<<<<<<< HEAD
- $value->value = \TCPDF_STATIC::_escape($string);
-=======
$value->value = PdfString::escape($string);
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
} elseif ($value instanceof PdfHexString) {
$filter = new AsciiHex();
$string = $filter->decode($value->value);
@@ -311,21 +303,8 @@ class Fpdi extends \TCPDF
// ensure we have a default value - otherwise TCPDF will set it to 4 throughout
$lastAnnotationOpt['f'] = 0;
+ // values in this dictonary are all direct objects and we don't need to resolve them here again.
$values = $externalLink['pdfObject']->value;
- unset(
- $values['P'],
- $values['NM'],
- $values['AP'],
- $values['AS'],
- $values['Type'],
- $values['Subtype'],
- $values['Rect'],
- $values['A'],
- $values['QuadPoints'],
- $values['Rotate'],
- $values['M'],
- $values['StructParent']
- );
foreach ($values as $key => $value) {
try {
@@ -334,17 +313,17 @@ class Fpdi extends \TCPDF
$value = PdfDictionary::ensure($value);
$bs = [];
if (isset($value->value['W'])) {
- $bs['w'] = PdfNumeric::ensure(PdfType::resolve($value->value['W'], $parser))->value;
+ $bs['w'] = PdfNumeric::ensure($value->value['W'])->value;
}
if (isset($value->value['S'])) {
- $bs['s'] = PdfName::ensure(PdfType::resolve($value->value['S'], $parser))->value;
+ $bs['s'] = PdfName::ensure($value->value['S'])->value;
}
if (isset($value->value['D'])) {
$d = [];
- foreach (PdfArray::ensure(PdfType::resolve($value->value['D'], $parser))->value as $item) {
- $d[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value;
+ foreach (PdfArray::ensure($value->value['D'])->value as $item) {
+ $d[] = PdfNumeric::ensure($item)->value;
}
$bs['d'] = $d;
}
@@ -353,20 +332,20 @@ class Fpdi extends \TCPDF
break;
case 'Border':
- $borderArray = PdfArray::ensure(PdfType::resolve($value, $parser))->value;
+ $borderArray = PdfArray::ensure($value)->value;
if (count($borderArray) < 3) {
continue 2;
}
$border = [
- PdfNumeric::ensure(PdfType::resolve($borderArray[0], $parser))->value,
- PdfNumeric::ensure(PdfType::resolve($borderArray[1], $parser))->value,
- PdfNumeric::ensure(PdfType::resolve($borderArray[2], $parser))->value,
+ PdfNumeric::ensure($borderArray[0])->value,
+ PdfNumeric::ensure($borderArray[1])->value,
+ PdfNumeric::ensure($borderArray[2])->value,
];
if (isset($borderArray[3])) {
$dashArray = [];
- foreach (PdfArray::ensure(PdfType::resolve($borderArray[3], $parser))->value as $item) {
- $dashArray[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value;
+ foreach (PdfArray::ensure($borderArray[3])->value as $item) {
+ $dashArray[] = PdfNumeric::ensure($item)->value;
}
$border[] = $dashArray;
}
@@ -379,7 +358,7 @@ class Fpdi extends \TCPDF
$colors = PdfArray::ensure(PdfType::resolve($value, $parser))->value;
$m = count($colors) === 4 ? 100 : 255;
foreach ($colors as $item) {
- $c[] = PdfNumeric::ensure(PdfType::resolve($item, $parser))->value * $m;
+ $c[] = PdfNumeric::ensure($item)->value * $m;
}
$lastAnnotationOpt['c'] = $c;
break;
diff --git a/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php b/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php
index 7ce46a4..bcf4472 100644
--- a/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php
+++ b/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php
@@ -28,9 +28,5 @@ class Fpdi extends FpdfTpl
*
* @string
*/
-<<<<<<< HEAD
- const VERSION = '2.4.1';
-=======
- const VERSION = '2.5.0';
->>>>>>> 097faaa6cdcfaa51b2861ff317b6deb027bec7bf
+ const VERSION = '2.6.0';
}
diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php
index b01efff..07cc6d6 100644
--- a/vendor/symfony/console/Application.php
+++ b/vendor/symfony/console/Application.php
@@ -21,6 +21,7 @@ use Symfony\Component\Console\Command\SignalableCommandInterface;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleSignalEvent;
@@ -32,6 +33,7 @@ use Symfony\Component\Console\Exception\NamespaceNotFoundException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
+use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\HelperSet;
@@ -72,20 +74,21 @@ class Application implements ResetInterface
{
private array $commands = [];
private bool $wantHelps = false;
- private $runningCommand = null;
+ private ?Command $runningCommand = null;
private string $name;
private string $version;
- private $commandLoader = null;
+ private ?CommandLoaderInterface $commandLoader = null;
private bool $catchExceptions = true;
+ private bool $catchErrors = false;
private bool $autoExit = true;
- private $definition;
- private $helperSet;
- private $dispatcher = null;
- private $terminal;
+ private InputDefinition $definition;
+ private HelperSet $helperSet;
+ private ?EventDispatcherInterface $dispatcher = null;
+ private Terminal $terminal;
private string $defaultCommand;
private bool $singleCommand = false;
private bool $initialized = false;
- private $signalRegistry;
+ private ?SignalRegistry $signalRegistry = null;
private array $signalsToDispatchEvent = [];
public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN')
@@ -103,12 +106,12 @@ class Application implements ResetInterface
/**
* @final
*/
- public function setDispatcher(EventDispatcherInterface $dispatcher)
+ public function setDispatcher(EventDispatcherInterface $dispatcher): void
{
$this->dispatcher = $dispatcher;
}
- public function setCommandLoader(CommandLoaderInterface $commandLoader)
+ public function setCommandLoader(CommandLoaderInterface $commandLoader): void
{
$this->commandLoader = $commandLoader;
}
@@ -116,13 +119,13 @@ class Application implements ResetInterface
public function getSignalRegistry(): SignalRegistry
{
if (!$this->signalRegistry) {
- throw new RuntimeException('Signals are not supported. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
+ throw new RuntimeException('Signals are not supported. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
}
return $this->signalRegistry;
}
- public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent)
+ public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent): void
{
$this->signalsToDispatchEvent = $signalsToDispatchEvent;
}
@@ -141,13 +144,8 @@ class Application implements ResetInterface
@putenv('COLUMNS='.$this->terminal->getWidth());
}
- if (null === $input) {
- $input = new ArgvInput();
- }
-
- if (null === $output) {
- $output = new ConsoleOutput();
- }
+ $input ??= new ArgvInput();
+ $output ??= new ConsoleOutput();
$renderException = function (\Throwable $e) use ($output) {
if ($output instanceof ConsoleOutputInterface) {
@@ -169,8 +167,11 @@ class Application implements ResetInterface
try {
$exitCode = $this->doRun($input, $output);
- } catch (\Exception $e) {
- if (!$this->catchExceptions) {
+ } catch (\Throwable $e) {
+ if ($e instanceof \Exception && !$this->catchExceptions) {
+ throw $e;
+ }
+ if (!$e instanceof \Exception && !$this->catchErrors) {
throw $e;
}
@@ -217,7 +218,7 @@ class Application implements ResetInterface
*
* @return int 0 if everything went fine, or an error code
*/
- public function doRun(InputInterface $input, OutputInterface $output)
+ public function doRun(InputInterface $input, OutputInterface $output): int
{
if (true === $input->hasParameterOption(['--version', '-V'], true)) {
$output->writeln($this->getLongVersion());
@@ -228,7 +229,7 @@ class Application implements ResetInterface
try {
// Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument.
$input->bind($this->getDefinition());
- } catch (ExceptionInterface $e) {
+ } catch (ExceptionInterface) {
// Errors must be ignored, full binding/validation happens later when the command is known.
}
@@ -258,7 +259,26 @@ class Application implements ResetInterface
// the command name MUST be the first element of the input
$command = $this->find($name);
} catch (\Throwable $e) {
- if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) {
+ if (($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) && 1 === \count($alternatives = $e->getAlternatives()) && $input->isInteractive()) {
+ $alternative = $alternatives[0];
+
+ $style = new SymfonyStyle($input, $output);
+ $output->writeln('');
+ $formattedBlock = (new FormatterHelper())->formatBlock(sprintf('Command "%s" is not defined.', $name), 'error', true);
+ $output->writeln($formattedBlock);
+ 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($event, ConsoleEvents::ERROR);
+
+ return $event->getExitCode();
+ }
+
+ return 1;
+ }
+
+ $command = $this->find($alternative);
+ } else {
if (null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e);
$this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
@@ -270,27 +290,24 @@ class Application implements ResetInterface
$e = $event->getError();
}
- throw $e;
- }
+ try {
+ if ($e instanceof CommandNotFoundException && $namespace = $this->findNamespace($name)) {
+ $helper = new DescriptorHelper();
+ $helper->describe($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output, $this, [
+ 'format' => 'txt',
+ 'raw_text' => false,
+ 'namespace' => $namespace,
+ 'short' => false,
+ ]);
- $alternative = $alternatives[0];
+ return isset($event) ? $event->getExitCode() : 1;
+ }
- $style = new SymfonyStyle($input, $output);
- $output->writeln('');
- $formattedBlock = (new FormatterHelper())->formatBlock(sprintf('Command "%s" is not defined.', $name), 'error', true);
- $output->writeln($formattedBlock);
- 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($event, ConsoleEvents::ERROR);
-
- return $event->getExitCode();
+ throw $e;
+ } catch (NamespaceNotFoundException) {
+ throw $e;
}
-
- return 1;
}
-
- $command = $this->find($alternative);
}
if ($command instanceof LazyCommand) {
@@ -304,14 +321,11 @@ class Application implements ResetInterface
return $exitCode;
}
- /**
- * {@inheritdoc}
- */
- public function reset()
+ public function reset(): void
{
}
- public function setHelperSet(HelperSet $helperSet)
+ public function setHelperSet(HelperSet $helperSet): void
{
$this->helperSet = $helperSet;
}
@@ -324,7 +338,7 @@ class Application implements ResetInterface
return $this->helperSet ??= $this->getDefaultHelperSet();
}
- public function setDefinition(InputDefinition $definition)
+ public function setDefinition(InputDefinition $definition): void
{
$this->definition = $definition;
}
@@ -355,18 +369,16 @@ class Application implements ResetInterface
CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType()
&& 'command' === $input->getCompletionName()
) {
- $commandNames = [];
foreach ($this->all() as $name => $command) {
// skip hidden commands and aliased commands as they already get added below
if ($command->isHidden() || $command->getName() !== $name) {
continue;
}
- $commandNames[] = $command->getName();
+ $suggestions->suggestValue(new Suggestion($command->getName(), $command->getDescription()));
foreach ($command->getAliases() as $name) {
- $commandNames[] = $name;
+ $suggestions->suggestValue(new Suggestion($name, $command->getDescription()));
}
}
- $suggestions->suggestValues(array_filter($commandNames));
return;
}
@@ -397,11 +409,19 @@ class Application implements ResetInterface
/**
* Sets whether to catch exceptions or not during commands execution.
*/
- public function setCatchExceptions(bool $boolean)
+ public function setCatchExceptions(bool $boolean): void
{
$this->catchExceptions = $boolean;
}
+ /**
+ * Sets whether to catch errors or not during commands execution.
+ */
+ public function setCatchErrors(bool $catchErrors = true): void
+ {
+ $this->catchErrors = $catchErrors;
+ }
+
/**
* Gets whether to automatically exit after a command execution or not.
*/
@@ -413,7 +433,7 @@ class Application implements ResetInterface
/**
* Sets whether to automatically exit after a command execution or not.
*/
- public function setAutoExit(bool $boolean)
+ public function setAutoExit(bool $boolean): void
{
$this->autoExit = $boolean;
}
@@ -428,8 +448,8 @@ class Application implements ResetInterface
/**
* Sets the application name.
- **/
- public function setName(string $name)
+ */
+ public function setName(string $name): void
{
$this->name = $name;
}
@@ -445,17 +465,15 @@ class Application implements ResetInterface
/**
* Sets the application version.
*/
- public function setVersion(string $version)
+ public function setVersion(string $version): void
{
$this->version = $version;
}
/**
* Returns the long version of the application.
- *
- * @return string
*/
- public function getLongVersion()
+ public function getLongVersion(): string
{
if ('UNKNOWN' !== $this->getName()) {
if ('UNKNOWN' !== $this->getVersion()) {
@@ -483,7 +501,7 @@ class Application implements ResetInterface
*
* @param Command[] $commands An array of commands
*/
- public function addCommands(array $commands)
+ public function addCommands(array $commands): void
{
foreach ($commands as $command) {
$this->add($command);
@@ -495,10 +513,8 @@ class Application implements ResetInterface
*
* If a command with the same name already exists, it will be overridden.
* If the command is not enabled it will not be added.
- *
- * @return Command|null
*/
- public function add(Command $command)
+ public function add(Command $command): ?Command
{
$this->init();
@@ -531,11 +547,9 @@ class Application implements ResetInterface
/**
* Returns a registered command by name or alias.
*
- * @return Command
- *
* @throws CommandNotFoundException When given command name does not exist
*/
- public function get(string $name)
+ public function get(string $name): Command
{
$this->init();
@@ -569,7 +583,7 @@ class Application implements ResetInterface
{
$this->init();
- return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name)));
+ return isset($this->commands[$name]) || ($this->commandLoader?->has($name) && $this->add($this->commandLoader->get($name)));
}
/**
@@ -638,11 +652,9 @@ class Application implements ResetInterface
* Contrary to get, this command tries to find the best
* match if you give it an abbreviation of a name or alias.
*
- * @return Command
- *
* @throws CommandNotFoundException When command name is incorrect or ambiguous
*/
- public function find(string $name)
+ public function find(string $name): Command
{
$this->init();
@@ -679,9 +691,7 @@ class Application implements ResetInterface
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
// remove hidden commands
- $alternatives = array_filter($alternatives, function ($name) {
- return !$this->get($name)->isHidden();
- });
+ $alternatives = array_filter($alternatives, fn ($name) => !$this->get($name)->isHidden());
if (1 == \count($alternatives)) {
$message .= "\n\nDid you mean this?\n ";
@@ -752,7 +762,7 @@ class Application implements ResetInterface
*
* @return Command[]
*/
- public function all(string $namespace = null)
+ public function all(string $namespace = null): array
{
$this->init();
@@ -832,9 +842,7 @@ class Application implements ResetInterface
}
if (str_contains($message, "@anonymous\0")) {
- $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
- return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
- }, $message);
+ $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $message);
}
$width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : \PHP_INT_MAX;
@@ -896,7 +904,7 @@ class Application implements ResetInterface
/**
* Configures the input and output instances based on the user arguments and options.
*/
- protected function configureIO(InputInterface $input, OutputInterface $output)
+ protected function configureIO(InputInterface $input, OutputInterface $output): void
{
if (true === $input->hasParameterOption(['--ansi'], true)) {
$output->setDecorated(true);
@@ -961,7 +969,7 @@ class Application implements ResetInterface
*
* @return int 0 if everything went fine, or an error code
*/
- protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
+ protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output): int
{
foreach ($command->getHelperSet() as $helper) {
if ($helper instanceof InputAwareInterface) {
@@ -969,44 +977,53 @@ class Application implements ResetInterface
}
}
- if ($this->signalsToDispatchEvent) {
- $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : [];
+ $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : [];
+ if ($commandSignals || $this->dispatcher && $this->signalsToDispatchEvent) {
+ if (!$this->signalRegistry) {
+ throw new RuntimeException('Unable to subscribe to signal events. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
+ }
- if ($commandSignals || null !== $this->dispatcher) {
- if (!$this->signalRegistry) {
- throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
- }
+ if (Terminal::hasSttyAvailable()) {
+ $sttyMode = shell_exec('stty -g');
- if (Terminal::hasSttyAvailable()) {
- $sttyMode = shell_exec('stty -g');
-
- foreach ([\SIGINT, \SIGTERM] as $signal) {
- $this->signalRegistry->register($signal, static function () use ($sttyMode) {
- shell_exec('stty '.$sttyMode);
- });
- }
+ foreach ([\SIGINT, \SIGTERM] as $signal) {
+ $this->signalRegistry->register($signal, static fn () => shell_exec('stty '.$sttyMode));
}
}
- if (null !== $this->dispatcher) {
+ if ($this->dispatcher) {
+ // We register application signals, so that we can dispatch the event
foreach ($this->signalsToDispatchEvent as $signal) {
$event = new ConsoleSignalEvent($command, $input, $output, $signal);
- $this->signalRegistry->register($signal, function ($signal, $hasNext) use ($event) {
+ $this->signalRegistry->register($signal, function ($signal) use ($event, $command, $commandSignals) {
$this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL);
+ $exitCode = $event->getExitCode();
- // No more handlers, we try to simulate PHP default behavior
- if (!$hasNext) {
- if (!\in_array($signal, [\SIGUSR1, \SIGUSR2], true)) {
- exit(0);
- }
+ // If the command is signalable, we call the handleSignal() method
+ if (\in_array($signal, $commandSignals, true)) {
+ $exitCode = $command->handleSignal($signal, $exitCode);
+ }
+
+ if (false !== $exitCode) {
+ $event = new ConsoleTerminateEvent($command, $event->getInput(), $event->getOutput(), $exitCode, $signal);
+ $this->dispatcher->dispatch($event, ConsoleEvents::TERMINATE);
+
+ exit($event->getExitCode());
}
});
}
+
+ // then we register command signals, but not if already handled after the dispatcher
+ $commandSignals = array_diff($commandSignals, $this->signalsToDispatchEvent);
}
foreach ($commandSignals as $signal) {
- $this->signalRegistry->register($signal, [$command, 'handleSignal']);
+ $this->signalRegistry->register($signal, function (int $signal) use ($command): void {
+ if (false !== $exitCode = $command->handleSignal($signal)) {
+ exit($exitCode);
+ }
+ });
}
}
@@ -1018,7 +1035,7 @@ class Application implements ResetInterface
try {
$command->mergeApplicationDefinition();
$input->bind($command->getDefinition());
- } catch (ExceptionInterface $e) {
+ } catch (ExceptionInterface) {
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
}
@@ -1162,7 +1179,7 @@ class Application implements ResetInterface
}
}
- $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
+ $alternatives = array_filter($alternatives, fn ($lev) => $lev < 2 * $threshold);
ksort($alternatives, \SORT_NATURAL | \SORT_FLAG_CASE);
return array_keys($alternatives);
@@ -1253,7 +1270,7 @@ class Application implements ResetInterface
return $namespaces;
}
- private function init()
+ private function init(): void
{
if ($this->initialized) {
return;
diff --git a/vendor/symfony/console/CHANGELOG.md b/vendor/symfony/console/CHANGELOG.md
index 9a93c79..0ff71d2 100644
--- a/vendor/symfony/console/CHANGELOG.md
+++ b/vendor/symfony/console/CHANGELOG.md
@@ -1,6 +1,49 @@
CHANGELOG
=========
+7.0
+---
+
+ * Add method `__toString()` to `InputInterface`
+ * Remove `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead
+ * Require explicit argument when calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()` and `Question::setAutocompleterCallback/setValidator()`
+ * Remove `StringInput::REGEX_STRING`
+
+6.4
+---
+
+ * Add `SignalMap` to map signal value to its name
+ * Multi-line text in vertical tables is aligned properly
+ * The application can also catch errors with `Application::setCatchErrors(true)`
+ * Add `RunCommandMessage` and `RunCommandMessageHandler`
+ * Dispatch `ConsoleTerminateEvent` after an exit on signal handling and add `ConsoleTerminateEvent::getInterruptingSignal()`
+
+6.3
+---
+
+ * Add support for choosing exit code while handling signal, or to not exit at all
+ * Add `ProgressBar::setPlaceholderFormatter` to set a placeholder attached to a instance, instead of being global.
+ * Add `ReStructuredTextDescriptor`
+
+6.2
+---
+
+ * Improve truecolor terminal detection in some cases
+ * Add support for 256 color terminals (conversion from Ansi24 to Ansi8 if terminal is capable of it)
+ * Deprecate calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()`, `Question::setAutocompleterCallback/setValidator()`without any arguments
+ * Change the signature of `OutputFormatterStyleInterface::setForeground/setBackground()` to `setForeground/setBackground(?string)`
+ * Change the signature of `HelperInterface::setHelperSet()` to `setHelperSet(?HelperSet)`
+
+6.1
+---
+
+ * Add support to display table vertically when calling setVertical()
+ * Add method `__toString()` to `InputInterface`
+ * Added `OutputWrapper` to prevent truncated URL in `SymfonyStyle::createBlock`.
+ * Deprecate `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead
+ * Add suggested values for arguments and options in input definition, for input completion
+ * Add `$resumeAt` parameter to `ProgressBar#start()`, so that one can easily 'resume' progress on longer tasks, and still get accurate `getEstimate()` and `getRemaining()` results.
+
6.0
---
diff --git a/vendor/symfony/console/CI/GithubActionReporter.php b/vendor/symfony/console/CI/GithubActionReporter.php
index a15c1ff..7e55654 100644
--- a/vendor/symfony/console/CI/GithubActionReporter.php
+++ b/vendor/symfony/console/CI/GithubActionReporter.php
@@ -20,7 +20,7 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class GithubActionReporter
{
- private $output;
+ private OutputInterface $output;
/**
* @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85
diff --git a/vendor/symfony/console/Color.php b/vendor/symfony/console/Color.php
index 7fcc507..60ed046 100644
--- a/vendor/symfony/console/Color.php
+++ b/vendor/symfony/console/Color.php
@@ -117,17 +117,7 @@ final class Color
}
if ('#' === $color[0]) {
- $color = substr($color, 1);
-
- if (3 === \strlen($color)) {
- $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2];
- }
-
- if (6 !== \strlen($color)) {
- throw new InvalidArgumentException(sprintf('Invalid "%s" color.', $color));
- }
-
- return ($background ? '4' : '3').$this->convertHexColorToAnsi(hexdec($color));
+ return ($background ? '4' : '3').Terminal::getColorMode()->convertFromHexToAnsiColorCode($color);
}
if (isset(self::COLORS[$color])) {
@@ -140,41 +130,4 @@ final class Color
throw new InvalidArgumentException(sprintf('Invalid "%s" color; expected one of (%s).', $color, implode(', ', array_merge(array_keys(self::COLORS), array_keys(self::BRIGHT_COLORS)))));
}
-
- private function convertHexColorToAnsi(int $color): string
- {
- $r = ($color >> 16) & 255;
- $g = ($color >> 8) & 255;
- $b = $color & 255;
-
- // see https://github.com/termstandard/colors/ for more information about true color support
- if ('truecolor' !== getenv('COLORTERM')) {
- return (string) $this->degradeHexColorToAnsi($r, $g, $b);
- }
-
- return sprintf('8;2;%d;%d;%d', $r, $g, $b);
- }
-
- private function degradeHexColorToAnsi(int $r, int $g, int $b): int
- {
- if (0 === round($this->getSaturation($r, $g, $b) / 50)) {
- return 0;
- }
-
- return (round($b / 255) << 2) | (round($g / 255) << 1) | round($r / 255);
- }
-
- private function getSaturation(int $r, int $g, int $b): int
- {
- $r = $r / 255;
- $g = $g / 255;
- $b = $b / 255;
- $v = max($r, $g, $b);
-
- if (0 === $diff = $v - min($r, $g, $b)) {
- return 0;
- }
-
- return (int) $diff * 100 / $v;
- }
}
diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php
index 986d4bd..c498917 100644
--- a/vendor/symfony/console/Command/Command.php
+++ b/vendor/symfony/console/Command/Command.php
@@ -15,9 +15,11 @@ use Symfony\Component\Console\Application;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\Console\Helper\HelperInterface;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
@@ -37,55 +39,37 @@ class Command
public const FAILURE = 1;
public const INVALID = 2;
- /**
- * @var string|null The default command name
- */
- protected static $defaultName;
-
- /**
- * @var string|null The default command description
- */
- protected static $defaultDescription;
-
- private $application = null;
+ private ?Application $application = null;
private ?string $name = null;
private ?string $processTitle = null;
private array $aliases = [];
- private $definition;
+ private InputDefinition $definition;
private bool $hidden = false;
private string $help = '';
private string $description = '';
- private $fullDefinition = null;
+ private ?InputDefinition $fullDefinition = null;
private bool $ignoreValidationErrors = false;
private ?\Closure $code = null;
private array $synopsis = [];
private array $usages = [];
- private $helperSet = null;
+ private ?HelperSet $helperSet = null;
public static function getDefaultName(): ?string
{
- $class = static::class;
-
- if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
+ if ($attribute = (new \ReflectionClass(static::class))->getAttributes(AsCommand::class)) {
return $attribute[0]->newInstance()->name;
}
- $r = new \ReflectionProperty($class, 'defaultName');
-
- return $class === $r->class ? static::$defaultName : null;
+ return null;
}
public static function getDefaultDescription(): ?string
{
- $class = static::class;
-
- if ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class)) {
+ if ($attribute = (new \ReflectionClass(static::class))->getAttributes(AsCommand::class)) {
return $attribute[0]->newInstance()->description;
}
- $r = new \ReflectionProperty($class, 'defaultDescription');
-
- return $class === $r->class ? static::$defaultDescription : null;
+ return null;
}
/**
@@ -124,12 +108,12 @@ class Command
*
* This is mainly useful for the help command.
*/
- public function ignoreValidationErrors()
+ public function ignoreValidationErrors(): void
{
$this->ignoreValidationErrors = true;
}
- public function setApplication(Application $application = null)
+ public function setApplication(?Application $application): void
{
$this->application = $application;
if ($application) {
@@ -141,7 +125,7 @@ class Command
$this->fullDefinition = null;
}
- public function setHelperSet(HelperSet $helperSet)
+ public function setHelperSet(HelperSet $helperSet): void
{
$this->helperSet = $helperSet;
}
@@ -167,16 +151,16 @@ class Command
*
* Override this to check for x or y and return false if the command cannot
* run properly under the current conditions.
- *
- * @return bool
*/
- public function isEnabled()
+ public function isEnabled(): bool
{
return true;
}
/**
* Configures the current command.
+ *
+ * @return void
*/
protected function configure()
{
@@ -196,7 +180,7 @@ class Command
*
* @see setCode()
*/
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
throw new LogicException('You must override the execute() method in the concrete command class.');
}
@@ -207,6 +191,8 @@ class Command
* This method is executed before the InputDefinition is validated.
* This means that this is the only place where the command can
* interactively ask for values of missing required arguments.
+ *
+ * @return void
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
@@ -221,6 +207,8 @@ class Command
*
* @see InputInterface::bind()
* @see InputInterface::validate()
+ *
+ * @return void
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
@@ -303,6 +291,12 @@ class Command
*/
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
+ $definition = $this->getDefinition();
+ if (CompletionInput::TYPE_OPTION_VALUE === $input->getCompletionType() && $definition->hasOption($input->getCompletionName())) {
+ $definition->getOption($input->getCompletionName())->complete($input, $suggestions);
+ } elseif (CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType() && $definition->hasArgument($input->getCompletionName())) {
+ $definition->getArgument($input->getCompletionName())->complete($input, $suggestions);
+ }
}
/**
@@ -334,7 +328,7 @@ class Command
}
}
} else {
- $code = \Closure::fromCallable($code);
+ $code = $code(...);
}
$this->code = $code;
@@ -351,7 +345,7 @@ class Command
*
* @internal
*/
- public function mergeApplicationDefinition(bool $mergeArgs = true)
+ public function mergeApplicationDefinition(bool $mergeArgs = true): void
{
if (null === $this->application) {
return;
@@ -411,19 +405,18 @@ class Command
/**
* Adds an argument.
*
- * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
- * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
- *
- * @throws InvalidArgumentException When argument mode is not valid
+ * @param $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+ * @param $default The default value (for InputArgument::OPTIONAL mode only)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
*
* @return $this
+ *
+ * @throws InvalidArgumentException When argument mode is not valid
*/
- public function addArgument(string $name, int $mode = null, string $description = '', mixed $default = null): static
+ public function addArgument(string $name, int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static
{
- $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
- if (null !== $this->fullDefinition) {
- $this->fullDefinition->addArgument(new InputArgument($name, $mode, $description, $default));
- }
+ $this->definition->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues));
+ $this->fullDefinition?->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues));
return $this;
}
@@ -434,17 +427,16 @@ class Command
* @param $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param $mode The option mode: One of the InputOption::VALUE_* constants
* @param $default The default value (must be null for InputOption::VALUE_NONE)
- *
- * @throws InvalidArgumentException If option mode is invalid or incompatible
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
*
* @return $this
+ *
+ * @throws InvalidArgumentException If option mode is invalid or incompatible
*/
- public function addOption(string $name, string|array $shortcut = null, int $mode = null, string $description = '', mixed $default = null): static
+ public function addOption(string $name, string|array $shortcut = null, int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static
{
- $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
- if (null !== $this->fullDefinition) {
- $this->fullDefinition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
- }
+ $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues));
+ $this->fullDefinition?->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues));
return $this;
}
@@ -560,7 +552,7 @@ class Command
public function getProcessedHelp(): string
{
$name = $this->name;
- $isSingleCommand = $this->application && $this->application->isSingleCommand();
+ $isSingleCommand = $this->application?->isSingleCommand();
$placeholders = [
'%command.name%',
@@ -651,7 +643,7 @@ class Command
* @throws LogicException if no HelperSet is defined
* @throws InvalidArgumentException if the helper is not defined
*/
- public function getHelper(string $name): mixed
+ public function getHelper(string $name): HelperInterface
{
if (null === $this->helperSet) {
throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
@@ -667,7 +659,7 @@ class Command
*
* @throws InvalidArgumentException When the name is invalid
*/
- private function validateName(string $name)
+ private function validateName(string $name): void
{
if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
diff --git a/vendor/symfony/console/Command/CompleteCommand.php b/vendor/symfony/console/Command/CompleteCommand.php
index 11ada4e..38aa737 100644
--- a/vendor/symfony/console/Command/CompleteCommand.php
+++ b/vendor/symfony/console/Command/CompleteCommand.php
@@ -11,10 +11,13 @@
namespace Symfony\Component\Console\Command;
+use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Completion\Output\BashCompletionOutput;
use Symfony\Component\Console\Completion\Output\CompletionOutputInterface;
+use Symfony\Component\Console\Completion\Output\FishCompletionOutput;
+use Symfony\Component\Console\Completion\Output\ZshCompletionOutput;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Input\InputInterface;
@@ -26,14 +29,13 @@ use Symfony\Component\Console\Output\OutputInterface;
*
* @author Wouter de Jong
*/
+#[AsCommand(name: '|_complete', description: 'Internal command to provide shell completion suggestions')]
final class CompleteCommand extends Command
{
- protected static $defaultName = '|_complete';
- protected static $defaultDescription = 'Internal command to provide shell completion suggestions';
+ public const COMPLETION_API_VERSION = '1';
- private $completionOutputs;
-
- private $isDebug = false;
+ private array $completionOutputs;
+ private bool $isDebug = false;
/**
* @param array> $completionOutputs A list of additional completion outputs, with shell name as key and FQCN as value
@@ -41,7 +43,11 @@ final class CompleteCommand extends Command
public function __construct(array $completionOutputs = [])
{
// must be set before the parent constructor, as the property value is used in configure()
- $this->completionOutputs = $completionOutputs + ['bash' => BashCompletionOutput::class];
+ $this->completionOutputs = $completionOutputs + [
+ 'bash' => BashCompletionOutput::class,
+ 'fish' => FishCompletionOutput::class,
+ 'zsh' => ZshCompletionOutput::class,
+ ];
parent::__construct();
}
@@ -52,28 +58,29 @@ final class CompleteCommand extends Command
->addOption('shell', 's', InputOption::VALUE_REQUIRED, 'The shell type ("'.implode('", "', array_keys($this->completionOutputs)).'")')
->addOption('input', 'i', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'An array of input tokens (e.g. COMP_WORDS or argv)')
->addOption('current', 'c', InputOption::VALUE_REQUIRED, 'The index of the "input" array that the cursor is in (e.g. COMP_CWORD)')
- ->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'The version of the completion script')
+ ->addOption('api-version', 'a', InputOption::VALUE_REQUIRED, 'The API version of the completion script')
+ ->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'deprecated')
;
}
- protected function initialize(InputInterface $input, OutputInterface $output)
+ protected function initialize(InputInterface $input, OutputInterface $output): void
{
- $this->isDebug = filter_var(getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOLEAN);
+ $this->isDebug = filter_var(getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOL);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
try {
- // uncomment when a bugfix or BC break has been introduced in the shell completion scripts
- // $version = $input->getOption('symfony');
- // if ($version && version_compare($version, 'x.y', '>=')) {
- // $message = sprintf('Completion script version is not supported ("%s" given, ">=x.y" required).', $version);
- // $this->log($message);
+ // "symfony" must be kept for compat with the shell scripts generated by Symfony Console 5.4 - 6.1
+ $version = $input->getOption('symfony') ? '1' : $input->getOption('api-version');
+ if ($version && version_compare($version, self::COMPLETION_API_VERSION, '<')) {
+ $message = sprintf('Completion script version is not supported ("%s" given, ">=%s" required).', $version, self::COMPLETION_API_VERSION);
+ $this->log($message);
- // $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.');
+ $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.');
- // return 126;
- // }
+ return 126;
+ }
$shell = $input->getOption('shell');
if (!$shell) {
@@ -116,12 +123,12 @@ final class CompleteCommand extends Command
$completionInput->bind($command->getDefinition());
if (CompletionInput::TYPE_OPTION_NAME === $completionInput->getCompletionType()) {
- $this->log(' Completing option names for the '.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).'> command.');
+ $this->log(' Completing option names for the '.($command instanceof LazyCommand ? $command->getCommand() : $command)::class.'> command.');
$suggestions->suggestOptions($command->getDefinition()->getOptions());
} else {
$this->log([
- ' Completing using the '.\get_class($command instanceof LazyCommand ? $command->getCommand() : $command).'> class.',
+ ' Completing using the '.($command instanceof LazyCommand ? $command->getCommand() : $command)::class.'> class.',
' Completing '.$completionInput->getCompletionType().'> for '.$completionInput->getCompletionName().'>',
]);
if (null !== $compval = $completionInput->getCompletionValue()) {
@@ -137,7 +144,7 @@ final class CompleteCommand extends Command
$this->log('Suggestions:>');
if ($options = $suggestions->getOptionSuggestions()) {
- $this->log(' --'.implode(' --', array_map(function ($o) { return $o->getName(); }, $options)));
+ $this->log(' --'.implode(' --', array_map(fn ($o) => $o->getName(), $options)));
} elseif ($values = $suggestions->getValueSuggestions()) {
$this->log(' '.implode(' ', $values));
} else {
@@ -155,10 +162,10 @@ final class CompleteCommand extends Command
throw $e;
}
- return self::FAILURE;
+ return 2;
}
- return self::SUCCESS;
+ return 0;
}
private function createCompletionInput(InputInterface $input): CompletionInput
@@ -172,7 +179,7 @@ final class CompleteCommand extends Command
try {
$completionInput->bind($this->getApplication()->getDefinition());
- } catch (ExceptionInterface $e) {
+ } catch (ExceptionInterface) {
}
return $completionInput;
@@ -187,7 +194,7 @@ final class CompleteCommand extends Command
}
return $this->getApplication()->find($inputName);
- } catch (CommandNotFoundException $e) {
+ } catch (CommandNotFoundException) {
}
return null;
diff --git a/vendor/symfony/console/Command/DumpCompletionCommand.php b/vendor/symfony/console/Command/DumpCompletionCommand.php
index 518d606..be6f545 100644
--- a/vendor/symfony/console/Command/DumpCompletionCommand.php
+++ b/vendor/symfony/console/Command/DumpCompletionCommand.php
@@ -11,8 +11,7 @@
namespace Symfony\Component\Console\Command;
-use Symfony\Component\Console\Completion\CompletionInput;
-use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -25,55 +24,57 @@ use Symfony\Component\Process\Process;
*
* @author Wouter de Jong
*/
+#[AsCommand(name: 'completion', description: 'Dump the shell completion script')]
final class DumpCompletionCommand extends Command
{
- protected static $defaultName = 'completion';
- protected static $defaultDescription = 'Dump the shell completion script';
+ private array $supportedShells;
- public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
- {
- if ($input->mustSuggestArgumentValuesFor('shell')) {
- $suggestions->suggestValues($this->getSupportedShells());
- }
- }
-
- protected function configure()
+ protected function configure(): void
{
$fullCommand = $_SERVER['PHP_SELF'];
$commandName = basename($fullCommand);
$fullCommand = @realpath($fullCommand) ?: $fullCommand;
+ $shell = $this->guessShell();
+ [$rcFile, $completionFile] = match ($shell) {
+ 'fish' => ['~/.config/fish/config.fish', "/etc/fish/completions/$commandName.fish"],
+ 'zsh' => ['~/.zshrc', '$fpath[1]/_'.$commandName],
+ default => ['~/.bashrc', "/etc/bash_completion.d/$commandName"],
+ };
+
+ $supportedShells = implode(', ', $this->getSupportedShells());
+
$this
->setHelp(<<%command.name%> command dumps the shell completion script required
-to use shell autocompletion (currently only bash completion is supported).
+to use shell autocompletion (currently, {$supportedShells} completion are supported).
Static installation
------------------->
Dump the script to a global completion file and restart your shell:
- %command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName}>
+ %command.full_name% {$shell} | sudo tee {$completionFile}>
Or dump the script to a local file and source it:
- %command.full_name% bash > completion.sh>
+ %command.full_name% {$shell} > completion.sh>
# source the file whenever you use the project>
source completion.sh>
- # or add this line at the end of your "~/.bashrc" file:>
+ # or add this line at the end of your "{$rcFile}" file:>
source /path/to/completion.sh>
Dynamic installation
-------------------->
-Add this to the end of your shell configuration file (e.g. "~/.bashrc">):
+Add this to the end of your shell configuration file (e.g. "{$rcFile}">):
- eval "$({$fullCommand} completion bash)">
+ eval "$({$fullCommand} completion {$shell})">
EOH
)
- ->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given')
+ ->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given', null, $this->getSupportedShells(...))
->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log')
;
}
@@ -85,7 +86,7 @@ EOH
if ($input->getOption('debug')) {
$this->tailDebugLog($commandName, $output);
- return self::SUCCESS;
+ return 0;
}
$shell = $input->getArgument('shell') ?? self::guessShell();
@@ -102,12 +103,12 @@ EOH
$output->writeln(sprintf('Shell not detected, Symfony shell completion only supports "%s").>', implode('", "', $supportedShells)));
}
- return self::INVALID;
+ return 2;
}
- $output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], file_get_contents($completionFile)));
+ $output->write(str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, CompleteCommand::COMPLETION_API_VERSION], file_get_contents($completionFile)));
- return self::SUCCESS;
+ return 0;
}
private static function guessShell(): string
@@ -132,8 +133,19 @@ EOH
*/
private function getSupportedShells(): array
{
- return array_map(function ($f) {
- return pathinfo($f, \PATHINFO_EXTENSION);
- }, glob(__DIR__.'/../Resources/completion.*'));
+ if (isset($this->supportedShells)) {
+ return $this->supportedShells;
+ }
+
+ $shells = [];
+
+ foreach (new \DirectoryIterator(__DIR__.'/../Resources/') as $file) {
+ if (str_starts_with($file->getBasename(), 'completion.') && $file->isFile()) {
+ $shells[] = $file->getExtension();
+ }
+ }
+ sort($shells);
+
+ return $this->supportedShells = $shells;
}
}
diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php
index 66f8593..a2a72da 100644
--- a/vendor/symfony/console/Command/HelpCommand.php
+++ b/vendor/symfony/console/Command/HelpCommand.php
@@ -11,8 +11,6 @@
namespace Symfony\Component\Console\Command;
-use Symfony\Component\Console\Completion\CompletionInput;
-use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Descriptor\ApplicationDescription;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
@@ -27,20 +25,17 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class HelpCommand extends Command
{
- private $command;
+ private Command $command;
- /**
- * {@inheritdoc}
- */
- protected function configure()
+ protected function configure(): void
{
$this->ignoreValidationErrors();
$this
->setName('help')
->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 InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help', fn () => array_keys((new ApplicationDescription($this->getApplication()))->getCommands())),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', fn () => (new DescriptorHelper())->getFormats()),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
])
->setDescription('Display help for a command')
@@ -59,14 +54,11 @@ EOF
;
}
- public function setCommand(Command $command)
+ public function setCommand(Command $command): void
{
$this->command = $command;
}
- /**
- * {@inheritdoc}
- */
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->command ??= $this->getApplication()->find($input->getArgument('command_name'));
@@ -81,19 +73,4 @@ EOF
return 0;
}
-
- public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
- {
- if ($input->mustSuggestArgumentValuesFor('command_name')) {
- $descriptor = new ApplicationDescription($this->getApplication());
- $suggestions->suggestValues(array_keys($descriptor->getCommands()));
-
- return;
- }
-
- if ($input->mustSuggestOptionValuesFor('format')) {
- $helper = new DescriptorHelper();
- $suggestions->suggestValues($helper->getFormats());
- }
- }
}
diff --git a/vendor/symfony/console/Command/LazyCommand.php b/vendor/symfony/console/Command/LazyCommand.php
index aec4126..7279724 100644
--- a/vendor/symfony/console/Command/LazyCommand.php
+++ b/vendor/symfony/console/Command/LazyCommand.php
@@ -14,6 +14,8 @@ namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
+use Symfony\Component\Console\Helper\HelperInterface;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
@@ -24,7 +26,7 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
final class LazyCommand extends Command
{
- private $command;
+ private \Closure|Command $command;
private ?bool $isEnabled;
public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = true)
@@ -43,7 +45,7 @@ final class LazyCommand extends Command
$this->getCommand()->ignoreValidationErrors();
}
- public function setApplication(Application $application = null): void
+ public function setApplication(?Application $application): void
{
if ($this->command instanceof parent) {
$this->command->setApplication($application);
@@ -108,16 +110,22 @@ final class LazyCommand extends Command
return $this->getCommand()->getNativeDefinition();
}
- public function addArgument(string $name, int $mode = null, string $description = '', mixed $default = null): static
+ /**
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ */
+ public function addArgument(string $name, int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static
{
- $this->getCommand()->addArgument($name, $mode, $description, $default);
+ $this->getCommand()->addArgument($name, $mode, $description, $default, $suggestedValues);
return $this;
}
- public function addOption(string $name, string|array $shortcut = null, int $mode = null, string $description = '', mixed $default = null): static
+ /**
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ */
+ public function addOption(string $name, string|array $shortcut = null, int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static
{
- $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default);
+ $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues);
return $this;
}
@@ -163,7 +171,7 @@ final class LazyCommand extends Command
return $this->getCommand()->getUsages();
}
- public function getHelper(string $name): mixed
+ public function getHelper(string $name): HelperInterface
{
return $this->getCommand()->getHelper($name);
}
diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php
index 5c7260f..61b4b1b 100644
--- a/vendor/symfony/console/Command/ListCommand.php
+++ b/vendor/symfony/console/Command/ListCommand.php
@@ -11,8 +11,6 @@
namespace Symfony\Component\Console\Command;
-use Symfony\Component\Console\Completion\CompletionInput;
-use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Descriptor\ApplicationDescription;
use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
@@ -27,17 +25,14 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class ListCommand extends Command
{
- /**
- * {@inheritdoc}
- */
- protected function configure()
+ protected function configure(): void
{
$this
->setName('list')
->setDefinition([
- new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
+ new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name', null, fn () => array_keys((new ApplicationDescription($this->getApplication()))->getNamespaces())),
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'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', fn () => (new DescriptorHelper())->getFormats()),
new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments'),
])
->setDescription('List commands')
@@ -62,9 +57,6 @@ EOF
;
}
- /**
- * {@inheritdoc}
- */
protected function execute(InputInterface $input, OutputInterface $output): int
{
$helper = new DescriptorHelper();
@@ -77,19 +69,4 @@ EOF
return 0;
}
-
- public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
- {
- if ($input->mustSuggestArgumentValuesFor('namespace')) {
- $descriptor = new ApplicationDescription($this->getApplication());
- $suggestions->suggestValues(array_keys($descriptor->getNamespaces()));
-
- return;
- }
-
- if ($input->mustSuggestOptionValuesFor('format')) {
- $helper = new DescriptorHelper();
- $suggestions->suggestValues($helper->getFormats());
- }
- }
}
diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php
index 7969551..c1006a6 100644
--- a/vendor/symfony/console/Command/LockableTrait.php
+++ b/vendor/symfony/console/Command/LockableTrait.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Console\Command;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Lock\LockFactory;
+use Symfony\Component\Lock\LockInterface;
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;
@@ -23,7 +24,7 @@ use Symfony\Component\Lock\Store\SemaphoreStore;
*/
trait LockableTrait
{
- private $lock = null;
+ private ?LockInterface $lock = null;
/**
* Locks a command.
@@ -31,7 +32,7 @@ trait LockableTrait
private function lock(string $name = null, bool $blocking = false): bool
{
if (!class_exists(SemaphoreStore::class)) {
- throw new LogicException('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. Try running "composer require symfony/lock".');
}
if (null !== $this->lock) {
@@ -57,7 +58,7 @@ trait LockableTrait
/**
* Releases the command lock if there is one.
*/
- private function release()
+ private function release(): void
{
if ($this->lock) {
$this->lock->release();
diff --git a/vendor/symfony/console/Command/SignalableCommandInterface.php b/vendor/symfony/console/Command/SignalableCommandInterface.php
index d439728..40b301d 100644
--- a/vendor/symfony/console/Command/SignalableCommandInterface.php
+++ b/vendor/symfony/console/Command/SignalableCommandInterface.php
@@ -25,6 +25,8 @@ interface SignalableCommandInterface
/**
* The method will be called when the application is signaled.
+ *
+ * @return int|false The exit code to return or false to continue the normal execution
*/
- public function handleSignal(int $signal): void;
+ public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false;
}
diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
index 9b26577..bfa0ac4 100644
--- a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
+++ b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
@@ -22,7 +22,7 @@ use Symfony\Component\Console\Exception\CommandNotFoundException;
*/
class ContainerCommandLoader implements CommandLoaderInterface
{
- private $container;
+ private ContainerInterface $container;
private array $commandMap;
/**
@@ -34,9 +34,6 @@ class ContainerCommandLoader implements CommandLoaderInterface
$this->commandMap = $commandMap;
}
- /**
- * {@inheritdoc}
- */
public function get(string $name): Command
{
if (!$this->has($name)) {
@@ -46,17 +43,11 @@ class ContainerCommandLoader implements CommandLoaderInterface
return $this->container->get($this->commandMap[$name]);
}
- /**
- * {@inheritdoc}
- */
public function has(string $name): bool
{
return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]);
}
- /**
- * {@inheritdoc}
- */
public function getNames(): array
{
return array_keys($this->commandMap);
diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
index c55dc1d..9ced75a 100644
--- a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
+++ b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
@@ -31,17 +31,11 @@ class FactoryCommandLoader implements CommandLoaderInterface
$this->factories = $factories;
}
- /**
- * {@inheritdoc}
- */
public function has(string $name): bool
{
return isset($this->factories[$name]);
}
- /**
- * {@inheritdoc}
- */
public function get(string $name): Command
{
if (!isset($this->factories[$name])) {
@@ -53,9 +47,6 @@ class FactoryCommandLoader implements CommandLoaderInterface
return $factory();
}
- /**
- * {@inheritdoc}
- */
public function getNames(): array
{
return array_keys($this->factories);
diff --git a/vendor/symfony/console/Completion/CompletionInput.php b/vendor/symfony/console/Completion/CompletionInput.php
index 368b945..7ba41c0 100644
--- a/vendor/symfony/console/Completion/CompletionInput.php
+++ b/vendor/symfony/console/Completion/CompletionInput.php
@@ -31,11 +31,11 @@ final class CompletionInput extends ArgvInput
public const TYPE_OPTION_NAME = 'option_name';
public const TYPE_NONE = 'none';
- private $tokens;
- private $currentIndex;
- private $completionType;
- private $completionName = null;
- private $completionValue = '';
+ private array $tokens;
+ private int $currentIndex;
+ private string $completionType;
+ private ?string $completionName = null;
+ private string $completionValue = '';
/**
* Converts a terminal string into tokens.
@@ -64,9 +64,6 @@ final class CompletionInput extends ArgvInput
return $input;
}
- /**
- * {@inheritdoc}
- */
public function bind(InputDefinition $definition): void
{
parent::bind($definition);
@@ -84,7 +81,7 @@ final class CompletionInput extends ArgvInput
return;
}
- if (null !== $option && $option->acceptValue()) {
+ if ($option?->acceptValue()) {
$this->completionType = self::TYPE_OPTION_VALUE;
$this->completionName = $option->getName();
$this->completionValue = $optionValue ?: (!str_starts_with($optionToken, '--') ? substr($optionToken, 2) : '');
@@ -97,7 +94,7 @@ final class CompletionInput extends ArgvInput
if ('-' === $previousToken[0] && '' !== trim($previousToken, '-')) {
// check if previous option accepted a value
$previousOption = $this->getOptionFromToken($previousToken);
- if (null !== $previousOption && $previousOption->acceptValue()) {
+ if ($previousOption?->acceptValue()) {
$this->completionType = self::TYPE_OPTION_VALUE;
$this->completionName = $previousOption->getName();
$this->completionValue = $relevantToken;
@@ -144,7 +141,9 @@ final class CompletionInput extends ArgvInput
* TYPE_OPTION_NAME when completing the name of an input option
* TYPE_NONE when nothing should be completed
*
- * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component
+ * TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component.
+ *
+ * @return self::TYPE_*
*/
public function getCompletionType(): string
{
@@ -183,7 +182,7 @@ final class CompletionInput extends ArgvInput
{
try {
return parent::parseToken($token, $parseOptions);
- } catch (RuntimeException $e) {
+ } catch (RuntimeException) {
// suppress errors, completed input is almost never valid
}
diff --git a/vendor/symfony/console/Completion/CompletionSuggestions.php b/vendor/symfony/console/Completion/CompletionSuggestions.php
index 7191181..549bbaf 100644
--- a/vendor/symfony/console/Completion/CompletionSuggestions.php
+++ b/vendor/symfony/console/Completion/CompletionSuggestions.php
@@ -20,8 +20,8 @@ use Symfony\Component\Console\Input\InputOption;
*/
final class CompletionSuggestions
{
- private $valueSuggestions = [];
- private $optionSuggestions = [];
+ private array $valueSuggestions = [];
+ private array $optionSuggestions = [];
/**
* Add a suggested value for an input option or argument.
diff --git a/vendor/symfony/console/Completion/Suggestion.php b/vendor/symfony/console/Completion/Suggestion.php
index ff156f8..7392965 100644
--- a/vendor/symfony/console/Completion/Suggestion.php
+++ b/vendor/symfony/console/Completion/Suggestion.php
@@ -16,13 +16,12 @@ namespace Symfony\Component\Console\Completion;
*
* @author Wouter de Jong
*/
-class Suggestion
+class Suggestion implements \Stringable
{
- private string $value;
-
- public function __construct(string $value)
- {
- $this->value = $value;
+ public function __construct(
+ private readonly string $value,
+ private readonly string $description = ''
+ ) {
}
public function getValue(): string
@@ -30,6 +29,11 @@ class Suggestion
return $this->value;
}
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+
public function __toString(): string
{
return $this->getValue();
diff --git a/vendor/symfony/console/Cursor.php b/vendor/symfony/console/Cursor.php
index 995e3d7..69fd382 100644
--- a/vendor/symfony/console/Cursor.php
+++ b/vendor/symfony/console/Cursor.php
@@ -18,7 +18,8 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
final class Cursor
{
- private $output;
+ private OutputInterface $output;
+ /** @var resource */
private $input;
/**
@@ -183,11 +184,7 @@ final class Cursor
{
static $isTtySupported;
- if (null === $isTtySupported && \function_exists('proc_open')) {
- $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
- }
-
- if (!$isTtySupported) {
+ if (!$isTtySupported ??= '/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT)) {
return [1, 1];
}
diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
index cfb2049..f712c61 100644
--- a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
+++ b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
@@ -29,7 +29,7 @@ use Symfony\Component\DependencyInjection\TypedReference;
*/
class AddConsoleCommandPass implements CompilerPassInterface
{
- public function process(ContainerBuilder $container)
+ public function process(ContainerBuilder $container): void
{
$commandServices = $container->findTaggedServiceIds('console.command', true);
$lazyCommandMap = [];
@@ -87,7 +87,7 @@ class AddConsoleCommandPass implements CompilerPassInterface
$lazyCommandMap[$tag['command']] = $id;
}
- $description = $description ?? $tag['description'] ?? null;
+ $description ??= $tag['description'] ?? null;
}
$definition->addMethodCall('setName', [$commandName]);
diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php
index 2fd311a..f8ed180 100644
--- a/vendor/symfony/console/Descriptor/ApplicationDescription.php
+++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php
@@ -24,7 +24,7 @@ class ApplicationDescription
{
public const GLOBAL_NAMESPACE = '_global';
- private $application;
+ private Application $application;
private ?string $namespace;
private bool $showHidden;
private array $namespaces;
@@ -79,7 +79,7 @@ class ApplicationDescription
return $this->commands[$name] ?? $this->aliases[$name];
}
- private function inspectApplication()
+ private function inspectApplication(): void
{
$this->commands = [];
$this->namespaces = [];
diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php
index a364830..7b2509c 100644
--- a/vendor/symfony/console/Descriptor/Descriptor.php
+++ b/vendor/symfony/console/Descriptor/Descriptor.php
@@ -26,43 +26,23 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
abstract class Descriptor implements DescriptorInterface
{
- /**
- * @var OutputInterface
- */
- protected $output;
+ protected OutputInterface $output;
- /**
- * {@inheritdoc}
- */
- public function describe(OutputInterface $output, object $object, array $options = [])
+ public function describe(OutputInterface $output, object $object, array $options = []): void
{
$this->output = $output;
- switch (true) {
- case $object instanceof InputArgument:
- $this->describeInputArgument($object, $options);
- break;
- case $object instanceof InputOption:
- $this->describeInputOption($object, $options);
- break;
- case $object instanceof InputDefinition:
- $this->describeInputDefinition($object, $options);
- break;
- case $object instanceof Command:
- $this->describeCommand($object, $options);
- break;
- case $object instanceof Application:
- $this->describeApplication($object, $options);
- break;
- default:
- throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_debug_type($object)));
- }
+ match (true) {
+ $object instanceof InputArgument => $this->describeInputArgument($object, $options),
+ $object instanceof InputOption => $this->describeInputOption($object, $options),
+ $object instanceof InputDefinition => $this->describeInputDefinition($object, $options),
+ $object instanceof Command => $this->describeCommand($object, $options),
+ $object instanceof Application => $this->describeApplication($object, $options),
+ default => throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_debug_type($object))),
+ };
}
- /**
- * Writes content to output.
- */
- protected function write(string $content, bool $decorated = false)
+ protected function write(string $content, bool $decorated = false): void
{
$this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
}
@@ -70,25 +50,25 @@ abstract class Descriptor implements DescriptorInterface
/**
* Describes an InputArgument instance.
*/
- abstract protected function describeInputArgument(InputArgument $argument, array $options = []);
+ abstract protected function describeInputArgument(InputArgument $argument, array $options = []): void;
/**
* Describes an InputOption instance.
*/
- abstract protected function describeInputOption(InputOption $option, array $options = []);
+ abstract protected function describeInputOption(InputOption $option, array $options = []): void;
/**
* Describes an InputDefinition instance.
*/
- abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []);
+ abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []): void;
/**
* Describes a Command instance.
*/
- abstract protected function describeCommand(Command $command, array $options = []);
+ abstract protected function describeCommand(Command $command, array $options = []): void;
/**
* Describes an Application instance.
*/
- abstract protected function describeApplication(Application $application, array $options = []);
+ abstract protected function describeApplication(Application $application, array $options = []): void;
}
diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php
index ebea303..04e5a7c 100644
--- a/vendor/symfony/console/Descriptor/DescriptorInterface.php
+++ b/vendor/symfony/console/Descriptor/DescriptorInterface.php
@@ -20,5 +20,5 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
interface DescriptorInterface
{
- public function describe(OutputInterface $output, object $object, array $options = []);
+ public function describe(OutputInterface $output, object $object, array $options = []): void;
}
diff --git a/vendor/symfony/console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Descriptor/JsonDescriptor.php
index 1d28659..9563037 100644
--- a/vendor/symfony/console/Descriptor/JsonDescriptor.php
+++ b/vendor/symfony/console/Descriptor/JsonDescriptor.php
@@ -26,18 +26,12 @@ use Symfony\Component\Console\Input\InputOption;
*/
class JsonDescriptor extends Descriptor
{
- /**
- * {@inheritdoc}
- */
- protected function describeInputArgument(InputArgument $argument, array $options = [])
+ protected function describeInputArgument(InputArgument $argument, array $options = []): void
{
$this->writeData($this->getInputArgumentData($argument), $options);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputOption(InputOption $option, array $options = [])
+ protected function describeInputOption(InputOption $option, array $options = []): void
{
$this->writeData($this->getInputOptionData($option), $options);
if ($option->isNegatable()) {
@@ -45,26 +39,17 @@ class JsonDescriptor extends Descriptor
}
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputDefinition(InputDefinition $definition, array $options = [])
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []): void
{
$this->writeData($this->getInputDefinitionData($definition), $options);
}
- /**
- * {@inheritdoc}
- */
- protected function describeCommand(Command $command, array $options = [])
+ protected function describeCommand(Command $command, array $options = []): void
{
$this->writeData($this->getCommandData($command, $options['short'] ?? false), $options);
}
- /**
- * {@inheritdoc}
- */
- protected function describeApplication(Application $application, array $options = [])
+ protected function describeApplication(Application $application, array $options = []): void
{
$describedNamespace = $options['namespace'] ?? null;
$description = new ApplicationDescription($application, $describedNamespace, true);
@@ -96,7 +81,7 @@ class JsonDescriptor extends Descriptor
/**
* Writes data as json.
*/
- private function writeData(array $data, array $options)
+ private function writeData(array $data, array $options): void
{
$flags = $options['json_encoding'] ?? 0;
diff --git a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
index 21ceca6..b3f16ee 100644
--- a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
+++ b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
@@ -28,10 +28,7 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class MarkdownDescriptor extends Descriptor
{
- /**
- * {@inheritdoc}
- */
- public function describe(OutputInterface $output, object $object, array $options = [])
+ public function describe(OutputInterface $output, object $object, array $options = []): void
{
$decorated = $output->isDecorated();
$output->setDecorated(false);
@@ -41,18 +38,12 @@ class MarkdownDescriptor extends Descriptor
$output->setDecorated($decorated);
}
- /**
- * {@inheritdoc}
- */
- protected function write(string $content, bool $decorated = true)
+ protected function write(string $content, bool $decorated = true): void
{
parent::write($content, $decorated);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputArgument(InputArgument $argument, array $options = [])
+ protected function describeInputArgument(InputArgument $argument, array $options = []): void
{
$this->write(
'#### `'.($argument->getName() ?: '')."`\n\n"
@@ -63,10 +54,7 @@ class MarkdownDescriptor extends Descriptor
);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputOption(InputOption $option, array $options = [])
+ protected function describeInputOption(InputOption $option, array $options = []): void
{
$name = '--'.$option->getName();
if ($option->isNegatable()) {
@@ -87,18 +75,13 @@ class MarkdownDescriptor extends Descriptor
);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputDefinition(InputDefinition $definition, array $options = [])
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []): void
{
if ($showArguments = \count($definition->getArguments()) > 0) {
$this->write('### Arguments');
foreach ($definition->getArguments() as $argument) {
$this->write("\n\n");
- if (null !== $describeInputArgument = $this->describeInputArgument($argument)) {
- $this->write($describeInputArgument);
- }
+ $this->describeInputArgument($argument);
}
}
@@ -110,17 +93,12 @@ class MarkdownDescriptor extends Descriptor
$this->write('### Options');
foreach ($definition->getOptions() as $option) {
$this->write("\n\n");
- if (null !== $describeInputOption = $this->describeInputOption($option)) {
- $this->write($describeInputOption);
- }
+ $this->describeInputOption($option);
}
}
}
- /**
- * {@inheritdoc}
- */
- protected function describeCommand(Command $command, array $options = [])
+ protected function describeCommand(Command $command, array $options = []): void
{
if ($options['short'] ?? false) {
$this->write(
@@ -128,9 +106,7 @@ class MarkdownDescriptor extends Descriptor
.str_repeat('-', Helper::width($command->getName()) + 2)."\n\n"
.($command->getDescription() ? $command->getDescription()."\n\n" : '')
.'### Usage'."\n\n"
- .array_reduce($command->getAliases(), function ($carry, $usage) {
- return $carry.'* `'.$usage.'`'."\n";
- })
+ .array_reduce($command->getAliases(), fn ($carry, $usage) => $carry.'* `'.$usage.'`'."\n")
);
return;
@@ -143,9 +119,7 @@ class MarkdownDescriptor extends Descriptor
.str_repeat('-', Helper::width($command->getName()) + 2)."\n\n"
.($command->getDescription() ? $command->getDescription()."\n\n" : '')
.'### Usage'."\n\n"
- .array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
- return $carry.'* `'.$usage.'`'."\n";
- })
+ .array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), fn ($carry, $usage) => $carry.'* `'.$usage.'`'."\n")
);
if ($help = $command->getProcessedHelp()) {
@@ -160,10 +134,7 @@ class MarkdownDescriptor extends Descriptor
}
}
- /**
- * {@inheritdoc}
- */
- protected function describeApplication(Application $application, array $options = [])
+ protected function describeApplication(Application $application, array $options = []): void
{
$describedNamespace = $options['namespace'] ?? null;
$description = new ApplicationDescription($application, $describedNamespace);
@@ -178,16 +149,12 @@ class MarkdownDescriptor extends Descriptor
}
$this->write("\n\n");
- $this->write(implode("\n", array_map(function ($commandName) use ($description) {
- return sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName()));
- }, $namespace['commands'])));
+ $this->write(implode("\n", array_map(fn ($commandName) => sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName())), $namespace['commands'])));
}
foreach ($description->getCommands() as $command) {
$this->write("\n\n");
- if (null !== $describeCommand = $this->describeCommand($command, $options)) {
- $this->write($describeCommand);
- }
+ $this->describeCommand($command, $options);
}
}
diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php
index 3f309f5..d04d102 100644
--- a/vendor/symfony/console/Descriptor/TextDescriptor.php
+++ b/vendor/symfony/console/Descriptor/TextDescriptor.php
@@ -28,10 +28,7 @@ use Symfony\Component\Console\Input\InputOption;
*/
class TextDescriptor extends Descriptor
{
- /**
- * {@inheritdoc}
- */
- protected function describeInputArgument(InputArgument $argument, array $options = [])
+ protected function describeInputArgument(InputArgument $argument, array $options = []): void
{
if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
$default = sprintf(' [default: %s] ', $this->formatDefaultValue($argument->getDefault()));
@@ -51,10 +48,7 @@ class TextDescriptor extends Descriptor
), $options);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputOption(InputOption $option, array $options = [])
+ protected function describeInputOption(InputOption $option, array $options = []): void
{
if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
$default = sprintf(' [default: %s] ', $this->formatDefaultValue($option->getDefault()));
@@ -89,10 +83,7 @@ class TextDescriptor extends Descriptor
), $options);
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputDefinition(InputDefinition $definition, array $options = [])
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []): void
{
$totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
foreach ($definition->getArguments() as $argument) {
@@ -131,10 +122,7 @@ class TextDescriptor extends Descriptor
}
}
- /**
- * {@inheritdoc}
- */
- protected function describeCommand(Command $command, array $options = [])
+ protected function describeCommand(Command $command, array $options = []): void
{
$command->mergeApplicationDefinition(false);
@@ -169,10 +157,7 @@ class TextDescriptor extends Descriptor
}
}
- /**
- * {@inheritdoc}
- */
- protected function describeApplication(Application $application, array $options = [])
+ protected function describeApplication(Application $application, array $options = []): void
{
$describedNamespace = $options['namespace'] ?? null;
$description = new ApplicationDescription($application, $describedNamespace);
@@ -208,9 +193,7 @@ class TextDescriptor extends Descriptor
}
// calculate max. width based on available commands per namespace
- $width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) {
- return array_intersect($namespace['commands'], array_keys($commands));
- }, array_values($namespaces)))));
+ $width = $this->getColumnWidth(array_merge(...array_values(array_map(fn ($namespace) => array_intersect($namespace['commands'], array_keys($commands)), array_values($namespaces)))));
if ($describedNamespace) {
$this->writeText(sprintf('Available commands for the "%s" namespace: ', $describedNamespace), $options);
@@ -219,9 +202,7 @@ class TextDescriptor extends Descriptor
}
foreach ($namespaces as $namespace) {
- $namespace['commands'] = array_filter($namespace['commands'], function ($name) use ($commands) {
- return isset($commands[$name]);
- });
+ $namespace['commands'] = array_filter($namespace['commands'], fn ($name) => isset($commands[$name]));
if (!$namespace['commands']) {
continue;
@@ -245,10 +226,7 @@ class TextDescriptor extends Descriptor
}
}
- /**
- * {@inheritdoc}
- */
- private function writeText(string $content, array $options = [])
+ private function writeText(string $content, array $options = []): void
{
$this->write(
isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php
index 4f7cd8b..72580fd 100644
--- a/vendor/symfony/console/Descriptor/XmlDescriptor.php
+++ b/vendor/symfony/console/Descriptor/XmlDescriptor.php
@@ -120,42 +120,27 @@ class XmlDescriptor extends Descriptor
return $dom;
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputArgument(InputArgument $argument, array $options = [])
+ protected function describeInputArgument(InputArgument $argument, array $options = []): void
{
$this->writeDocument($this->getInputArgumentDocument($argument));
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputOption(InputOption $option, array $options = [])
+ protected function describeInputOption(InputOption $option, array $options = []): void
{
$this->writeDocument($this->getInputOptionDocument($option));
}
- /**
- * {@inheritdoc}
- */
- protected function describeInputDefinition(InputDefinition $definition, array $options = [])
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []): void
{
$this->writeDocument($this->getInputDefinitionDocument($definition));
}
- /**
- * {@inheritdoc}
- */
- protected function describeCommand(Command $command, array $options = [])
+ protected function describeCommand(Command $command, array $options = []): void
{
$this->writeDocument($this->getCommandDocument($command, $options['short'] ?? false));
}
- /**
- * {@inheritdoc}
- */
- protected function describeApplication(Application $application, array $options = [])
+ protected function describeApplication(Application $application, array $options = []): void
{
$this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? false));
}
@@ -163,7 +148,7 @@ class XmlDescriptor extends Descriptor
/**
* Appends document children to parent node.
*/
- private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
+ private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent): void
{
foreach ($importedParent->childNodes as $childNode) {
$parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
@@ -173,7 +158,7 @@ class XmlDescriptor extends Descriptor
/**
* Writes DOM document.
*/
- private function writeDocument(\DOMDocument $dom)
+ private function writeDocument(\DOMDocument $dom): void
{
$dom->formatOutput = true;
$this->write($dom->saveXML());
diff --git a/vendor/symfony/console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Event/ConsoleCommandEvent.php
index 31c9ee9..0757a23 100644
--- a/vendor/symfony/console/Event/ConsoleCommandEvent.php
+++ b/vendor/symfony/console/Event/ConsoleCommandEvent.php
@@ -12,7 +12,10 @@
namespace Symfony\Component\Console\Event;
/**
- * Allows to do things before the command is executed, like skipping the command or changing the input.
+ * Allows to do things before the command is executed, like skipping the command or executing code before the command is
+ * going to be executed.
+ *
+ * Changing the input arguments will have no effect.
*
* @author Fabien Potencier
*/
diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php
index 19bd4bf..d4a6912 100644
--- a/vendor/symfony/console/Event/ConsoleErrorEvent.php
+++ b/vendor/symfony/console/Event/ConsoleErrorEvent.php
@@ -47,7 +47,6 @@ final class ConsoleErrorEvent extends ConsoleEvent
$this->exitCode = $exitCode;
$r = new \ReflectionProperty($this->error, 'code');
- $r->setAccessible(true);
$r->setValue($this->error, $this->exitCode);
}
diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php
index 56b8a9a..437a58e 100644
--- a/vendor/symfony/console/Event/ConsoleEvent.php
+++ b/vendor/symfony/console/Event/ConsoleEvent.php
@@ -23,10 +23,10 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
class ConsoleEvent extends Event
{
- protected $command;
+ protected ?Command $command;
- private $input;
- private $output;
+ private InputInterface $input;
+ private OutputInterface $output;
public function __construct(?Command $command, InputInterface $input, OutputInterface $output)
{
diff --git a/vendor/symfony/console/Event/ConsoleSignalEvent.php b/vendor/symfony/console/Event/ConsoleSignalEvent.php
index 766af69..95af1f9 100644
--- a/vendor/symfony/console/Event/ConsoleSignalEvent.php
+++ b/vendor/symfony/console/Event/ConsoleSignalEvent.php
@@ -21,15 +21,36 @@ use Symfony\Component\Console\Output\OutputInterface;
final class ConsoleSignalEvent extends ConsoleEvent
{
private int $handlingSignal;
+ private int|false $exitCode;
- public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal)
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal, int|false $exitCode = 0)
{
parent::__construct($command, $input, $output);
$this->handlingSignal = $handlingSignal;
+ $this->exitCode = $exitCode;
}
public function getHandlingSignal(): int
{
return $this->handlingSignal;
}
+
+ public function setExitCode(int $exitCode): void
+ {
+ if ($exitCode < 0 || $exitCode > 255) {
+ throw new \InvalidArgumentException('Exit code must be between 0 and 255.');
+ }
+
+ $this->exitCode = $exitCode;
+ }
+
+ public function abortExit(): void
+ {
+ $this->exitCode = false;
+ }
+
+ public function getExitCode(): int|false
+ {
+ return $this->exitCode;
+ }
}
diff --git a/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Event/ConsoleTerminateEvent.php
index de63c8f..38f7253 100644
--- a/vendor/symfony/console/Event/ConsoleTerminateEvent.php
+++ b/vendor/symfony/console/Event/ConsoleTerminateEvent.php
@@ -19,16 +19,18 @@ use Symfony\Component\Console\Output\OutputInterface;
* Allows to manipulate the exit code of a command after its execution.
*
* @author Francesco Levorato
+ * @author Jules Pietri
*/
final class ConsoleTerminateEvent extends ConsoleEvent
{
- private int $exitCode;
-
- public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode)
- {
+ public function __construct(
+ Command $command,
+ InputInterface $input,
+ OutputInterface $output,
+ private int $exitCode,
+ private readonly ?int $interruptingSignal = null,
+ ) {
parent::__construct($command, $input, $output);
-
- $this->setExitCode($exitCode);
}
public function setExitCode(int $exitCode): void
@@ -40,4 +42,9 @@ final class ConsoleTerminateEvent extends ConsoleEvent
{
return $this->exitCode;
}
+
+ public function getInterruptingSignal(): ?int
+ {
+ return $this->interruptingSignal;
+ }
}
diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php
index 61bd9d3..5c38e8e 100644
--- a/vendor/symfony/console/EventListener/ErrorListener.php
+++ b/vendor/symfony/console/EventListener/ErrorListener.php
@@ -24,14 +24,14 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*/
class ErrorListener implements EventSubscriberInterface
{
- private $logger;
+ private ?LoggerInterface $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
- public function onConsoleError(ConsoleErrorEvent $event)
+ public function onConsoleError(ConsoleErrorEvent $event): void
{
if (null === $this->logger) {
return;
@@ -48,7 +48,7 @@ class ErrorListener implements EventSubscriberInterface
$this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
}
- public function onConsoleTerminate(ConsoleTerminateEvent $event)
+ public function onConsoleTerminate(ConsoleTerminateEvent $event): void
{
if (null === $this->logger) {
return;
@@ -79,7 +79,7 @@ class ErrorListener implements EventSubscriberInterface
private static function getInputString(ConsoleEvent $event): ?string
{
- $commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
+ $commandName = $event->getCommand()?->getName();
$input = $event->getInput();
if ($input instanceof \Stringable) {
diff --git a/vendor/symfony/console/Formatter/NullOutputFormatter.php b/vendor/symfony/console/Formatter/NullOutputFormatter.php
index d770e14..5c11c76 100644
--- a/vendor/symfony/console/Formatter/NullOutputFormatter.php
+++ b/vendor/symfony/console/Formatter/NullOutputFormatter.php
@@ -16,52 +16,34 @@ namespace Symfony\Component\Console\Formatter;
*/
final class NullOutputFormatter implements OutputFormatterInterface
{
- private $style;
+ private NullOutputFormatterStyle $style;
- /**
- * {@inheritdoc}
- */
public function format(?string $message): ?string
{
return null;
}
- /**
- * {@inheritdoc}
- */
public function getStyle(string $name): OutputFormatterStyleInterface
{
// to comply with the interface we must return a OutputFormatterStyleInterface
- return $this->style ?? $this->style = new NullOutputFormatterStyle();
+ return $this->style ??= new NullOutputFormatterStyle();
}
- /**
- * {@inheritdoc}
- */
public function hasStyle(string $name): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
public function isDecorated(): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
public function setDecorated(bool $decorated): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function setStyle(string $name, OutputFormatterStyleInterface $style): void
{
// do nothing
diff --git a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
index 9232510..06fa6e4 100644
--- a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
+++ b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
@@ -16,49 +16,31 @@ namespace Symfony\Component\Console\Formatter;
*/
final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
{
- /**
- * {@inheritdoc}
- */
public function apply(string $text): string
{
return $text;
}
- /**
- * {@inheritdoc}
- */
- public function setBackground(string $color = null): void
+ public function setBackground(?string $color): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
- public function setForeground(string $color = null): void
+ public function setForeground(?string $color): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function setOption(string $option): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function setOptions(array $options): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function unsetOption(string $option): void
{
// do nothing
diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php
index 4a6ae91..8e81e59 100644
--- a/vendor/symfony/console/Formatter/OutputFormatter.php
+++ b/vendor/symfony/console/Formatter/OutputFormatter.php
@@ -13,6 +13,8 @@ namespace Symfony\Component\Console\Formatter;
use Symfony\Component\Console\Exception\InvalidArgumentException;
+use function Symfony\Component\String\b;
+
/**
* Formatter class for console output.
*
@@ -23,7 +25,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface
{
private bool $decorated;
private array $styles = [];
- private $styleStack;
+ private OutputFormatterStyleStack $styleStack;
public function __clone()
{
@@ -81,41 +83,26 @@ class OutputFormatter implements WrappableOutputFormatterInterface
$this->styleStack = new OutputFormatterStyleStack();
}
- /**
- * {@inheritdoc}
- */
- public function setDecorated(bool $decorated)
+ public function setDecorated(bool $decorated): void
{
$this->decorated = $decorated;
}
- /**
- * {@inheritdoc}
- */
public function isDecorated(): bool
{
return $this->decorated;
}
- /**
- * {@inheritdoc}
- */
- public function setStyle(string $name, OutputFormatterStyleInterface $style)
+ public function setStyle(string $name, OutputFormatterStyleInterface $style): void
{
$this->styles[strtolower($name)] = $style;
}
- /**
- * {@inheritdoc}
- */
public function hasStyle(string $name): bool
{
return isset($this->styles[strtolower($name)]);
}
- /**
- * {@inheritdoc}
- */
public function getStyle(string $name): OutputFormatterStyleInterface
{
if (!$this->hasStyle($name)) {
@@ -125,18 +112,12 @@ class OutputFormatter implements WrappableOutputFormatterInterface
return $this->styles[strtolower($name)];
}
- /**
- * {@inheritdoc}
- */
public function format(?string $message): ?string
{
return $this->formatAndWrap($message, 0);
}
- /**
- * {@inheritdoc}
- */
- public function formatAndWrap(?string $message, int $width)
+ public function formatAndWrap(?string $message, int $width): string
{
if (null === $message) {
return '';
@@ -161,7 +142,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface
$offset = $pos + \strlen($text);
// opening tag?
- if ($open = '/' != $text[1]) {
+ if ($open = '/' !== $text[1]) {
$tag = $matches[1][$i][0];
} else {
$tag = $matches[3][$i][0] ?? '';
@@ -253,10 +234,10 @@ class OutputFormatter implements WrappableOutputFormatterInterface
}
preg_match('~(\\n)$~', $text, $matches);
- $text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text);
+ $text = $prefix.$this->addLineBreaks($text, $width);
$text = rtrim($text, "\n").($matches[1] ?? '');
- if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) {
+ if (!$currentLineLength && '' !== $current && !str_ends_with($current, "\n")) {
$text = "\n".$text;
}
@@ -277,4 +258,11 @@ class OutputFormatter implements WrappableOutputFormatterInterface
return implode("\n", $lines);
}
+
+ private function addLineBreaks(string $text, int $width): string
+ {
+ $encoding = mb_detect_encoding($text, null, true) ?: 'UTF-8';
+
+ return b($text)->toCodePointString($encoding)->wordwrap($width, "\n", true)->toByteString($encoding);
+ }
}
diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php
index b94e51d..947347f 100644
--- a/vendor/symfony/console/Formatter/OutputFormatterInterface.php
+++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php
@@ -21,7 +21,7 @@ interface OutputFormatterInterface
/**
* Sets the decorated flag.
*/
- public function setDecorated(bool $decorated);
+ public function setDecorated(bool $decorated): void;
/**
* Whether the output will decorate messages.
@@ -31,7 +31,7 @@ interface OutputFormatterInterface
/**
* Sets a new style.
*/
- public function setStyle(string $name, OutputFormatterStyleInterface $style);
+ public function setStyle(string $name, OutputFormatterStyleInterface $style): void;
/**
* Checks if output formatter has style with specified name.
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php
index 0a009e9..4582ccd 100644
--- a/vendor/symfony/console/Formatter/OutputFormatterStyle.php
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyle.php
@@ -20,7 +20,7 @@ use Symfony\Component\Console\Color;
*/
class OutputFormatterStyle implements OutputFormatterStyleInterface
{
- private $color;
+ private Color $color;
private string $foreground;
private string $background;
private array $options;
@@ -38,18 +38,12 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
$this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options);
}
- /**
- * {@inheritdoc}
- */
- public function setForeground(string $color = null)
+ public function setForeground(?string $color): void
{
$this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options);
}
- /**
- * {@inheritdoc}
- */
- public function setBackground(string $color = null)
+ public function setBackground(?string $color): void
{
$this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options);
}
@@ -59,19 +53,13 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
$this->href = $url;
}
- /**
- * {@inheritdoc}
- */
- public function setOption(string $option)
+ public function setOption(string $option): void
{
$this->options[] = $option;
$this->color = new Color($this->foreground, $this->background, $this->options);
}
- /**
- * {@inheritdoc}
- */
- public function unsetOption(string $option)
+ public function unsetOption(string $option): void
{
$pos = array_search($option, $this->options);
if (false !== $pos) {
@@ -81,21 +69,16 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
$this->color = new Color($this->foreground, $this->background, $this->options);
}
- /**
- * {@inheritdoc}
- */
- public function setOptions(array $options)
+ public function setOptions(array $options): void
{
$this->color = new Color($this->foreground, $this->background, $this->options = $options);
}
- /**
- * {@inheritdoc}
- */
public function apply(string $text): string
{
$this->handlesHrefGracefully ??= 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
- && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
+ && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100)
+ && !isset($_SERVER['IDEA_INITIAL_DIRECTORY']);
if (null !== $this->href && $this->handlesHrefGracefully) {
$text = "\033]8;;$this->href\033\\$text\033]8;;\033\\";
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
index 91d50aa..0374192 100644
--- a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
@@ -21,27 +21,27 @@ interface OutputFormatterStyleInterface
/**
* Sets style foreground color.
*/
- public function setForeground(string $color = null);
+ public function setForeground(?string $color): void;
/**
* Sets style background color.
*/
- public function setBackground(string $color = null);
+ public function setBackground(?string $color): void;
/**
* Sets some specific style option.
*/
- public function setOption(string $option);
+ public function setOption(string $option): void;
/**
* Unsets some specific style option.
*/
- public function unsetOption(string $option);
+ public function unsetOption(string $option): void;
/**
* Sets multiple style options at once.
*/
- public function setOptions(array $options);
+ public function setOptions(array $options): void;
/**
* Applies the style to a given text.
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
index 66f86a5..c3726a3 100644
--- a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
@@ -24,7 +24,7 @@ class OutputFormatterStyleStack implements ResetInterface
*/
private array $styles = [];
- private $emptyStyle;
+ private OutputFormatterStyleInterface $emptyStyle;
public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
{
@@ -35,7 +35,7 @@ class OutputFormatterStyleStack implements ResetInterface
/**
* Resets stack (ie. empty internal arrays).
*/
- public function reset()
+ public function reset(): void
{
$this->styles = [];
}
@@ -43,7 +43,7 @@ class OutputFormatterStyleStack implements ResetInterface
/**
* Pushes a style in the stack.
*/
- public function push(OutputFormatterStyleInterface $style)
+ public function push(OutputFormatterStyleInterface $style): void
{
$this->styles[] = $style;
}
@@ -55,7 +55,7 @@ class OutputFormatterStyleStack implements ResetInterface
*/
public function pop(OutputFormatterStyleInterface $style = null): OutputFormatterStyleInterface
{
- if (empty($this->styles)) {
+ if (!$this->styles) {
return $this->emptyStyle;
}
@@ -79,7 +79,7 @@ class OutputFormatterStyleStack implements ResetInterface
*/
public function getCurrent(): OutputFormatterStyleInterface
{
- if (empty($this->styles)) {
+ if (!$this->styles) {
return $this->emptyStyle;
}
diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
index 42319ee..412d997 100644
--- a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
+++ b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
@@ -21,5 +21,5 @@ 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);
+ public function formatAndWrap(?string $message, int $width): string;
}
diff --git a/vendor/symfony/console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Helper/DebugFormatterHelper.php
index 64c7cff..9ea7fb9 100644
--- a/vendor/symfony/console/Helper/DebugFormatterHelper.php
+++ b/vendor/symfony/console/Helper/DebugFormatterHelper.php
@@ -91,9 +91,6 @@ class DebugFormatterHelper extends Helper
return sprintf(' >', self::COLORS[$this->started[$id]['border']]);
}
- /**
- * {@inheritdoc}
- */
public function getName(): string
{
return 'debug_formatter';
diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php
index 63597c6..300c7b1 100644
--- a/vendor/symfony/console/Helper/DescriptorHelper.php
+++ b/vendor/symfony/console/Helper/DescriptorHelper.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Descriptor\DescriptorInterface;
use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+use Symfony\Component\Console\Descriptor\ReStructuredTextDescriptor;
use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\InvalidArgumentException;
@@ -38,6 +39,7 @@ class DescriptorHelper extends Helper
->register('xml', new XmlDescriptor())
->register('json', new JsonDescriptor())
->register('md', new MarkdownDescriptor())
+ ->register('rst', new ReStructuredTextDescriptor())
;
}
@@ -50,7 +52,7 @@ class DescriptorHelper extends Helper
*
* @throws InvalidArgumentException when the given format is not supported
*/
- public function describe(OutputInterface $output, ?object $object, array $options = [])
+ public function describe(OutputInterface $output, ?object $object, array $options = []): void
{
$options = array_merge([
'raw_text' => false,
@@ -77,9 +79,6 @@ class DescriptorHelper extends Helper
return $this;
}
- /**
- * {@inheritdoc}
- */
public function getName(): string
{
return 'descriptor';
diff --git a/vendor/symfony/console/Helper/Dumper.php b/vendor/symfony/console/Helper/Dumper.php
index 5019095..8c6a94d 100644
--- a/vendor/symfony/console/Helper/Dumper.php
+++ b/vendor/symfony/console/Helper/Dumper.php
@@ -21,9 +21,9 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
*/
final class Dumper
{
- private $output;
- private $dumper;
- private $cloner;
+ private OutputInterface $output;
+ private ?CliDumper $dumper;
+ private ?ClonerInterface $cloner;
private \Closure $handler;
public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
@@ -34,25 +34,18 @@ final class Dumper
if (class_exists(CliDumper::class)) {
$this->handler = function ($var): string {
- $dumper = $this->dumper ?? $this->dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
+ $dumper = $this->dumper ??= new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
$dumper->setColors($this->output->isDecorated());
- return rtrim($dumper->dump(($this->cloner ?? $this->cloner = new VarCloner())->cloneVar($var)->withRefHandles(false), true));
+ return rtrim($dumper->dump(($this->cloner ??= new VarCloner())->cloneVar($var)->withRefHandles(false), true));
};
} else {
- $this->handler = function ($var): string {
- switch (true) {
- case null === $var:
- return 'null';
- case true === $var:
- return 'true';
- case false === $var:
- return 'false';
- case \is_string($var):
- return '"'.$var.'"';
- default:
- return rtrim(print_r($var, true));
- }
+ $this->handler = fn ($var): string => match (true) {
+ null === $var => 'null',
+ true === $var => 'true',
+ false === $var => 'false',
+ \is_string($var) => '"'.$var.'"',
+ default => rtrim(print_r($var, true)),
};
}
}
diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php
index 2d7d1fa..279e4c7 100644
--- a/vendor/symfony/console/Helper/FormatterHelper.php
+++ b/vendor/symfony/console/Helper/FormatterHelper.php
@@ -74,9 +74,6 @@ class FormatterHelper extends Helper
return self::substr($message, 0, $length).$suffix;
}
- /**
- * {@inheritdoc}
- */
public function getName(): string
{
return 'formatter';
diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php
index c626729..afb20ad 100644
--- a/vendor/symfony/console/Helper/Helper.php
+++ b/vendor/symfony/console/Helper/Helper.php
@@ -21,19 +21,13 @@ use Symfony\Component\String\UnicodeString;
*/
abstract class Helper implements HelperInterface
{
- protected $helperSet = null;
+ protected ?HelperSet $helperSet = null;
- /**
- * {@inheritdoc}
- */
- public function setHelperSet(HelperSet $helperSet = null)
+ public function setHelperSet(?HelperSet $helperSet): void
{
$this->helperSet = $helperSet;
}
- /**
- * {@inheritdoc}
- */
public function getHelperSet(): ?HelperSet
{
return $this->helperSet;
@@ -45,7 +39,7 @@ abstract class Helper implements HelperInterface
*/
public static function width(?string $string): int
{
- $string ?? $string = '';
+ $string ??= '';
if (preg_match('//u', $string)) {
return (new UnicodeString($string))->width(false);
@@ -64,7 +58,7 @@ abstract class Helper implements HelperInterface
*/
public static function length(?string $string): int
{
- $string ?? $string = '';
+ $string ??= '';
if (preg_match('//u', $string)) {
return (new UnicodeString($string))->length();
@@ -82,7 +76,7 @@ abstract class Helper implements HelperInterface
*/
public static function substr(?string $string, int $from, int $length = null): string
{
- $string ?? $string = '';
+ $string ??= '';
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return substr($string, $from, $length);
@@ -91,36 +85,47 @@ abstract class Helper implements HelperInterface
return mb_substr($string, $from, $length, $encoding);
}
- public static function formatTime(int|float $secs)
+ public static function formatTime(int|float $secs, int $precision = 1): string
{
+ $secs = (int) floor($secs);
+
+ if (0 === $secs) {
+ return '< 1 sec';
+ }
+
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],
+ [1, '1 sec', 'secs'],
+ [60, '1 min', 'mins'],
+ [3600, '1 hr', 'hrs'],
+ [86400, '1 day', 'days'],
];
+ $times = [];
foreach ($timeFormats as $index => $format) {
- if ($secs >= $format[0]) {
- if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
- || $index == \count($timeFormats) - 1
- ) {
- if (2 == \count($format)) {
- return $format[1];
- }
+ $seconds = isset($timeFormats[$index + 1]) ? $secs % $timeFormats[$index + 1][0] : $secs;
- return floor($secs / $format[2]).' '.$format[1];
- }
+ if (isset($times[$index - $precision])) {
+ unset($times[$index - $precision]);
}
+
+ if (0 === $seconds) {
+ continue;
+ }
+
+ $unitCount = ($seconds / $format[0]);
+ $times[$index] = 1 === $unitCount ? $format[1] : $unitCount.' '.$format[2];
+
+ if ($secs === $seconds) {
+ break;
+ }
+
+ $secs -= $seconds;
}
+
+ return implode(', ', array_reverse($times));
}
- public static function formatMemory(int $memory)
+ public static function formatMemory(int $memory): string
{
if ($memory >= 1024 * 1024 * 1024) {
return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
@@ -137,7 +142,7 @@ abstract class Helper implements HelperInterface
return sprintf('%d B', $memory);
}
- public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string)
+ public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string): string
{
$isDecorated = $formatter->isDecorated();
$formatter->setDecorated(false);
diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php
index 1d2b7bf..8c4da3c 100644
--- a/vendor/symfony/console/Helper/HelperInterface.php
+++ b/vendor/symfony/console/Helper/HelperInterface.php
@@ -21,7 +21,7 @@ interface HelperInterface
/**
* Sets the helper set associated with this helper.
*/
- public function setHelperSet(HelperSet $helperSet = null);
+ public function setHelperSet(?HelperSet $helperSet): void;
/**
* Gets the helper set associated with this helper.
@@ -30,8 +30,6 @@ interface HelperInterface
/**
* Returns the canonical name of this helper.
- *
- * @return string
*/
- public function getName();
+ public function getName(): string;
}
diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php
index be0beca..42153b6 100644
--- a/vendor/symfony/console/Helper/HelperSet.php
+++ b/vendor/symfony/console/Helper/HelperSet.php
@@ -18,15 +18,15 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
*
* @author Fabien Potencier
*
- * @implements \IteratorAggregate
+ * @implements \IteratorAggregate
*/
class HelperSet implements \IteratorAggregate
{
- /** @var array */
+ /** @var array */
private array $helpers = [];
/**
- * @param Helper[] $helpers An array of helper
+ * @param HelperInterface[] $helpers
*/
public function __construct(array $helpers = [])
{
@@ -35,7 +35,7 @@ class HelperSet implements \IteratorAggregate
}
}
- public function set(HelperInterface $helper, string $alias = null)
+ public function set(HelperInterface $helper, string $alias = null): void
{
$this->helpers[$helper->getName()] = $helper;
if (null !== $alias) {
diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php
index 0d0dba2..47126bd 100644
--- a/vendor/symfony/console/Helper/InputAwareHelper.php
+++ b/vendor/symfony/console/Helper/InputAwareHelper.php
@@ -21,12 +21,9 @@ use Symfony\Component\Console\Input\InputInterface;
*/
abstract class InputAwareHelper extends Helper implements InputAwareInterface
{
- protected $input;
+ protected InputInterface $input;
- /**
- * {@inheritdoc}
- */
- public function setInput(InputInterface $input)
+ public function setInput(InputInterface $input): void
{
$this->input = $input;
}
diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php
index e5ba4db..26d35a1 100644
--- a/vendor/symfony/console/Helper/ProcessHelper.php
+++ b/vendor/symfony/console/Helper/ProcessHelper.php
@@ -130,9 +130,6 @@ class ProcessHelper extends Helper
return str_replace('<', '\\<', $str);
}
- /**
- * {@inheritdoc}
- */
public function getName(): string
{
return 'process';
diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php
index 2b4a45f..64389c4 100644
--- a/vendor/symfony/console/Helper/ProgressBar.php
+++ b/vendor/symfony/console/Helper/ProgressBar.php
@@ -47,17 +47,19 @@ final class ProgressBar
private float $lastWriteTime = 0;
private float $minSecondsBetweenRedraws = 0;
private float $maxSecondsBetweenRedraws = 1;
- private $output;
+ private OutputInterface $output;
private int $step = 0;
+ private int $startingStep = 0;
private ?int $max = null;
private int $startTime;
private int $stepWidth;
private float $percent = 0.0;
private array $messages = [];
private bool $overwrite = true;
- private $terminal;
+ private Terminal $terminal;
private ?string $previousMessage = null;
- private $cursor;
+ private Cursor $cursor;
+ private array $placeholders = [];
private static array $formatters;
private static array $formats;
@@ -93,12 +95,12 @@ final class ProgressBar
}
/**
- * Sets a placeholder formatter for a given name.
+ * Sets a placeholder formatter for a given name, globally for all instances of ProgressBar.
*
* This method also allow you to override an existing placeholder.
*
- * @param string $name The placeholder name (including the delimiter char like %)
- * @param callable $callable A PHP callable
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable(ProgressBar):string $callable A PHP callable
*/
public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void
{
@@ -119,6 +121,26 @@ final class ProgressBar
return self::$formatters[$name] ?? null;
}
+ /**
+ * Sets a placeholder formatter for a given name, for this instance only.
+ *
+ * @param callable(ProgressBar):string $callable A PHP callable
+ */
+ public function setPlaceholderFormatter(string $name, callable $callable): void
+ {
+ $this->placeholders[$name] = $callable;
+ }
+
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ */
+ public function getPlaceholderFormatter(string $name): ?callable
+ {
+ return $this->placeholders[$name] ?? $this::getPlaceholderFormatterDefinition($name);
+ }
+
/**
* Sets a format for a given name.
*
@@ -156,12 +178,12 @@ final class ProgressBar
* @param string $message The text to associate with the placeholder
* @param string $name The name of the placeholder
*/
- public function setMessage(string $message, string $name = 'message')
+ public function setMessage(string $message, string $name = 'message'): void
{
$this->messages[$name] = $message;
}
- public function getMessage(string $name = 'message')
+ public function getMessage(string $name = 'message'): string
{
return $this->messages[$name];
}
@@ -198,11 +220,11 @@ final class ProgressBar
public function getEstimated(): float
{
- if (!$this->step) {
+ if (0 === $this->step || $this->step === $this->startingStep) {
return 0;
}
- return round((time() - $this->startTime) / $this->step * $this->max);
+ return round((time() - $this->startTime) / ($this->step - $this->startingStep) * $this->max);
}
public function getRemaining(): float
@@ -211,10 +233,10 @@ final class ProgressBar
return 0;
}
- return round((time() - $this->startTime) / $this->step * ($this->max - $this->step));
+ return round((time() - $this->startTime) / ($this->step - $this->startingStep) * ($this->max - $this->step));
}
- public function setBarWidth(int $size)
+ public function setBarWidth(int $size): void
{
$this->barWidth = max(1, $size);
}
@@ -224,7 +246,7 @@ final class ProgressBar
return $this->barWidth;
}
- public function setBarCharacter(string $char)
+ public function setBarCharacter(string $char): void
{
$this->barChar = $char;
}
@@ -234,7 +256,7 @@ final class ProgressBar
return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar);
}
- public function setEmptyBarCharacter(string $char)
+ public function setEmptyBarCharacter(string $char): void
{
$this->emptyBarChar = $char;
}
@@ -244,7 +266,7 @@ final class ProgressBar
return $this->emptyBarChar;
}
- public function setProgressCharacter(string $char)
+ public function setProgressCharacter(string $char): void
{
$this->progressChar = $char;
}
@@ -254,7 +276,7 @@ final class ProgressBar
return $this->progressChar;
}
- public function setFormat(string $format)
+ public function setFormat(string $format): void
{
$this->format = null;
$this->internalFormat = $format;
@@ -265,7 +287,7 @@ final class ProgressBar
*
* @param int|null $freq The frequency in steps
*/
- public function setRedrawFrequency(?int $freq)
+ public function setRedrawFrequency(?int $freq): void
{
$this->redrawFreq = null !== $freq ? max(1, $freq) : null;
}
@@ -283,7 +305,13 @@ final class ProgressBar
/**
* Returns an iterator that will automatically update the progress bar when iterated.
*
- * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
+ * @template TKey
+ * @template TValue
+ *
+ * @param iterable $iterable
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
+ *
+ * @return iterable
*/
public function iterate(iterable $iterable, int $max = null): iterable
{
@@ -301,13 +329,16 @@ final class ProgressBar
/**
* Starts the progress output.
*
- * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ * @param int $startAt The starting point of the bar (useful e.g. when resuming a previously started bar)
*/
- public function start(int $max = null)
+ public function start(int $max = null, int $startAt = 0): void
{
$this->startTime = time();
- $this->step = 0;
- $this->percent = 0.0;
+ $this->step = $startAt;
+ $this->startingStep = $startAt;
+
+ $startAt > 0 ? $this->setProgress($startAt) : $this->percent = 0.0;
if (null !== $max) {
$this->setMaxSteps($max);
@@ -321,7 +352,7 @@ final class ProgressBar
*
* @param int $step Number of steps to advance
*/
- public function advance(int $step = 1)
+ public function advance(int $step = 1): void
{
$this->setProgress($this->step + $step);
}
@@ -329,12 +360,12 @@ final class ProgressBar
/**
* Sets whether to overwrite the progressbar, false for new line.
*/
- public function setOverwrite(bool $overwrite)
+ public function setOverwrite(bool $overwrite): void
{
$this->overwrite = $overwrite;
}
- public function setProgress(int $step)
+ public function setProgress(int $step): void
{
if ($this->max && $step > $this->max) {
$this->max = $step;
@@ -367,7 +398,7 @@ final class ProgressBar
}
}
- public function setMaxSteps(int $max)
+ public function setMaxSteps(int $max): void
{
$this->format = null;
$this->max = max(0, $max);
@@ -427,7 +458,7 @@ final class ProgressBar
$this->overwrite('');
}
- private function setRealFormat(string $format)
+ private function setRealFormat(string $format): void
{
// try to use the _nomax variant if available
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
@@ -487,17 +518,13 @@ final class ProgressBar
private function determineBestFormat(): string
{
- switch ($this->output->getVerbosity()) {
+ return match ($this->output->getVerbosity()) {
// OutputInterface::VERBOSITY_QUIET: display is disabled anyway
- case OutputInterface::VERBOSITY_VERBOSE:
- return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
- case OutputInterface::VERBOSITY_VERY_VERBOSE:
- return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
- case OutputInterface::VERBOSITY_DEBUG:
- return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
- default:
- return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
- }
+ OutputInterface::VERBOSITY_VERBOSE => $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX,
+ OutputInterface::VERBOSITY_VERY_VERBOSE => $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX,
+ OutputInterface::VERBOSITY_DEBUG => $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX,
+ default => $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX,
+ };
}
private static function initPlaceholderFormatters(): array
@@ -513,35 +540,25 @@ final class ProgressBar
return $display;
},
- 'elapsed' => function (self $bar) {
- return Helper::formatTime(time() - $bar->getStartTime());
- },
+ 'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime(), 2),
'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.');
}
- return Helper::formatTime($bar->getRemaining());
+ return Helper::formatTime($bar->getRemaining(), 2);
},
'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.');
}
- return Helper::formatTime($bar->getEstimated());
- },
- 'memory' => function (self $bar) {
- return Helper::formatMemory(memory_get_usage(true));
- },
- 'current' => function (self $bar) {
- return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT);
- },
- 'max' => function (self $bar) {
- return $bar->getMaxSteps();
- },
- 'percent' => function (self $bar) {
- return floor($bar->getProgressPercent() * 100);
+ return Helper::formatTime($bar->getEstimated(), 2);
},
+ 'memory' => fn (self $bar) => Helper::formatMemory(memory_get_usage(true)),
+ 'current' => fn (self $bar) => str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT),
+ 'max' => fn (self $bar) => $bar->getMaxSteps(),
+ 'percent' => fn (self $bar) => floor($bar->getProgressPercent() * 100),
];
}
@@ -568,7 +585,7 @@ final class ProgressBar
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
$callback = function ($matches) {
- if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
+ if ($formatter = $this->getPlaceholderFormatter($matches[1])) {
$text = $formatter($this, $this->output);
} elseif (isset($this->messages[$matches[1]])) {
$text = $this->messages[$matches[1]];
@@ -585,9 +602,7 @@ final class ProgressBar
$line = preg_replace_callback($regex, $callback, $this->format);
// gets string length for each sub line with multiline format
- $linesLength = array_map(function ($subLine) {
- return Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r")));
- }, explode("\n", $line));
+ $linesLength = array_map(fn ($subLine) => Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r"))), explode("\n", $line));
$linesWidth = max($linesLength);
diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php
index c746f9b..8865ecc 100644
--- a/vendor/symfony/console/Helper/ProgressIndicator.php
+++ b/vendor/symfony/console/Helper/ProgressIndicator.php
@@ -31,7 +31,7 @@ class ProgressIndicator
'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
];
- private $output;
+ private OutputInterface $output;
private int $startTime;
private ?string $format = null;
private ?string $message = null;
@@ -54,14 +54,8 @@ class ProgressIndicator
{
$this->output = $output;
- if (null === $format) {
- $format = $this->determineBestFormat();
- }
-
- if (null === $indicatorValues) {
- $indicatorValues = ['-', '\\', '|', '/'];
- }
-
+ $format ??= $this->determineBestFormat();
+ $indicatorValues ??= ['-', '\\', '|', '/'];
$indicatorValues = array_values($indicatorValues);
if (2 > \count($indicatorValues)) {
@@ -77,7 +71,7 @@ class ProgressIndicator
/**
* Sets the current indicator message.
*/
- public function setMessage(?string $message)
+ public function setMessage(?string $message): void
{
$this->message = $message;
@@ -87,7 +81,7 @@ class ProgressIndicator
/**
* Starts the indicator output.
*/
- public function start(string $message)
+ public function start(string $message): void
{
if ($this->started) {
throw new LogicException('Progress indicator already started.');
@@ -105,7 +99,7 @@ class ProgressIndicator
/**
* Advances the indicator.
*/
- public function advance()
+ public function advance(): void
{
if (!$this->started) {
throw new LogicException('Progress indicator has not yet been started.');
@@ -129,10 +123,8 @@ class ProgressIndicator
/**
* Finish the indicator with message.
- *
- * @param $message
*/
- public function finish(string $message)
+ public function finish(string $message): void
{
if (!$this->started) {
throw new LogicException('Progress indicator has not yet been started.');
@@ -157,7 +149,7 @@ class ProgressIndicator
*
* This method also allow you to override an existing placeholder.
*/
- public static function setPlaceholderFormatterDefinition(string $name, callable $callable)
+ public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void
{
self::$formatters ??= self::initPlaceholderFormatters();
@@ -174,7 +166,7 @@ class ProgressIndicator
return self::$formatters[$name] ?? null;
}
- private function display()
+ private function display(): void
{
if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
return;
@@ -191,22 +183,19 @@ class ProgressIndicator
private function determineBestFormat(): string
{
- switch ($this->output->getVerbosity()) {
+ return match ($this->output->getVerbosity()) {
// OutputInterface::VERBOSITY_QUIET: display is disabled anyway
- case OutputInterface::VERBOSITY_VERBOSE:
- return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
- case OutputInterface::VERBOSITY_VERY_VERBOSE:
- case OutputInterface::VERBOSITY_DEBUG:
- return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
- default:
- return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
- }
+ OutputInterface::VERBOSITY_VERBOSE => $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi',
+ OutputInterface::VERBOSITY_VERY_VERBOSE,
+ OutputInterface::VERBOSITY_DEBUG => $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi',
+ default => $this->output->isDecorated() ? 'normal' : 'normal_no_ansi',
+ };
}
/**
* Overwrites a previous message to the output.
*/
- private function overwrite(string $message)
+ private function overwrite(string $message): void
{
if ($this->output->isDecorated()) {
$this->output->write("\x0D\x1B[2K");
@@ -227,18 +216,10 @@ class ProgressIndicator
private static function initPlaceholderFormatters(): array
{
return [
- 'indicator' => function (self $indicator) {
- return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)];
- },
- 'message' => function (self $indicator) {
- return $indicator->message;
- },
- 'elapsed' => function (self $indicator) {
- return Helper::formatTime(time() - $indicator->startTime);
- },
- 'memory' => function () {
- return Helper::formatMemory(memory_get_usage(true));
- },
+ 'indicator' => fn (self $indicator) => $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)],
+ 'message' => fn (self $indicator) => $indicator->message,
+ 'elapsed' => fn (self $indicator) => Helper::formatTime(time() - $indicator->startTime, 2),
+ 'memory' => fn () => Helper::formatMemory(memory_get_usage(true)),
];
}
}
diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php
index d53420b..cb75ac9 100644
--- a/vendor/symfony/console/Helper/QuestionHelper.php
+++ b/vendor/symfony/console/Helper/QuestionHelper.php
@@ -68,9 +68,7 @@ class QuestionHelper extends Helper
return $this->doAsk($output, $question);
}
- $interviewer = function () use ($output, $question) {
- return $this->doAsk($output, $question);
- };
+ $interviewer = fn () => $this->doAsk($output, $question);
return $this->validateAttempts($interviewer, $output, $question);
} catch (MissingInputException $exception) {
@@ -84,9 +82,6 @@ class QuestionHelper extends Helper
}
}
- /**
- * {@inheritdoc}
- */
public function getName(): string
{
return 'question';
@@ -95,7 +90,7 @@ class QuestionHelper extends Helper
/**
* Prevents usage of stty.
*/
- public static function disableStty()
+ public static function disableStty(): void
{
self::$stty = false;
}
@@ -126,7 +121,18 @@ class QuestionHelper extends Helper
}
if (false === $ret) {
+ $isBlocked = stream_get_meta_data($inputStream)['blocked'] ?? true;
+
+ if (!$isBlocked) {
+ stream_set_blocking($inputStream, true);
+ }
+
$ret = $this->readInput($inputStream, $question);
+
+ if (!$isBlocked) {
+ stream_set_blocking($inputStream, false);
+ }
+
if (false === $ret) {
throw new MissingInputException('Aborted.');
}
@@ -140,6 +146,7 @@ class QuestionHelper extends Helper
}
if ($output instanceof ConsoleSectionOutput) {
+ $output->addContent(''); // add EOL to the question
$output->addContent($ret);
}
@@ -161,7 +168,7 @@ class QuestionHelper extends Helper
}
if ($validator = $question->getValidator()) {
- return \call_user_func($question->getValidator(), $default);
+ return \call_user_func($validator, $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
@@ -182,7 +189,7 @@ class QuestionHelper extends Helper
/**
* Outputs the question prompt.
*/
- protected function writePrompt(OutputInterface $output, Question $question)
+ protected function writePrompt(OutputInterface $output, Question $question): void
{
$message = $question->getQuestion();
@@ -218,7 +225,7 @@ class QuestionHelper extends Helper
/**
* Outputs an error message.
*/
- protected function writeError(OutputInterface $output, \Exception $error)
+ protected function writeError(OutputInterface $output, \Exception $error): void
{
if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
$message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
@@ -316,9 +323,7 @@ class QuestionHelper extends Helper
$matches = array_filter(
$autocomplete($ret),
- function ($match) use ($ret) {
- return '' === $ret || str_starts_with($match, $ret);
- }
+ fn ($match) => '' === $ret || str_starts_with($match, $ret)
);
$numMatches = \count($matches);
$ofs = -1;
@@ -406,7 +411,7 @@ class QuestionHelper extends Helper
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
// handle code running from a phar
- if ('phar:' === substr(__FILE__, 0, 5)) {
+ if (str_starts_with(__FILE__, 'phar:')) {
$tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
copy($exe, $tmpExe);
$exe = $tmpExe;
@@ -432,6 +437,11 @@ class QuestionHelper extends Helper
$value = fgets($inputStream, 4096);
+ if (4095 === \strlen($value)) {
+ $errOutput = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output;
+ $errOutput->warning('The value was possibly truncated by your shell or terminal emulator');
+ }
+
if (self::$stty && Terminal::hasSttyAvailable()) {
shell_exec('stty '.$sttyMode);
}
@@ -493,13 +503,11 @@ class QuestionHelper extends Helper
return self::$stdinIsInteractive = @posix_isatty(fopen('php://stdin', 'r'));
}
- if (!\function_exists('exec')) {
+ if (!\function_exists('shell_exec')) {
return self::$stdinIsInteractive = true;
}
- exec('stty 2> /dev/null', $output, $status);
-
- return self::$stdinIsInteractive = 1 !== $status;
+ return self::$stdinIsInteractive = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
}
/**
diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
index 01f94ab..48d947b 100644
--- a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
+++ b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
@@ -25,10 +25,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
*/
class SymfonyQuestionHelper extends QuestionHelper
{
- /**
- * {@inheritdoc}
- */
- protected function writePrompt(OutputInterface $output, Question $question)
+ protected function writePrompt(OutputInterface $output, Question $question): void
{
$text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
$default = $question->getDefault();
@@ -83,10 +80,7 @@ class SymfonyQuestionHelper extends QuestionHelper
$output->write($prompt);
}
- /**
- * {@inheritdoc}
- */
- protected function writeError(OutputInterface $output, \Exception $error)
+ protected function writeError(OutputInterface $output, \Exception $error): void
{
if ($output instanceof SymfonyStyle) {
$output->newLine();
diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php
index 0d8da6c..fe2ac87 100644
--- a/vendor/symfony/console/Helper/Table.php
+++ b/vendor/symfony/console/Helper/Table.php
@@ -35,20 +35,23 @@ class Table
private const SEPARATOR_BOTTOM = 3;
private const BORDER_OUTSIDE = 0;
private const BORDER_INSIDE = 1;
+ private const DISPLAY_ORIENTATION_DEFAULT = 'default';
+ private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal';
+ private const DISPLAY_ORIENTATION_VERTICAL = 'vertical';
private ?string $headerTitle = null;
private ?string $footerTitle = null;
private array $headers = [];
private array $rows = [];
- private bool $horizontal = false;
private array $effectiveColumnWidths = [];
private int $numberOfColumns;
- private $output;
- private $style;
+ private OutputInterface $output;
+ private TableStyle $style;
private array $columnStyles = [];
private array $columnWidths = [];
private array $columnMaxWidths = [];
private bool $rendered = false;
+ private string $displayOrientation = self::DISPLAY_ORIENTATION_DEFAULT;
private static array $styles;
@@ -64,7 +67,7 @@ class Table
/**
* Sets a style definition.
*/
- public static function setStyleDefinition(string $name, TableStyle $style)
+ public static function setStyleDefinition(string $name, TableStyle $style): void
{
self::$styles ??= self::initStyles();
@@ -177,7 +180,7 @@ class Table
public function setHeaders(array $headers): static
{
$headers = array_values($headers);
- if (!empty($headers) && !\is_array($headers[0])) {
+ if ($headers && !\is_array($headers[0])) {
$headers = [$headers];
}
@@ -186,7 +189,10 @@ class Table
return $this;
}
- public function setRows(array $rows)
+ /**
+ * @return $this
+ */
+ public function setRows(array $rows): static
{
$this->rows = [];
@@ -277,7 +283,17 @@ class Table
*/
public function setHorizontal(bool $horizontal = true): static
{
- $this->horizontal = $horizontal;
+ $this->displayOrientation = $horizontal ? self::DISPLAY_ORIENTATION_HORIZONTAL : self::DISPLAY_ORIENTATION_DEFAULT;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function setVertical(bool $vertical = true): static
+ {
+ $this->displayOrientation = $vertical ? self::DISPLAY_ORIENTATION_VERTICAL : self::DISPLAY_ORIENTATION_DEFAULT;
return $this;
}
@@ -295,11 +311,16 @@ class Table
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
* +---------------+-----------------------+------------------+
*/
- public function render()
+ public function render(): void
{
$divider = new TableSeparator();
- if ($this->horizontal) {
- $rows = [];
+ $isCellWithColspan = static fn ($cell) => $cell instanceof TableCell && $cell->getColspan() >= 2;
+
+ $horizontal = self::DISPLAY_ORIENTATION_HORIZONTAL === $this->displayOrientation;
+ $vertical = self::DISPLAY_ORIENTATION_VERTICAL === $this->displayOrientation;
+
+ $rows = [];
+ if ($horizontal) {
foreach ($this->headers[0] ?? [] as $i => $header) {
$rows[$i] = [$header];
foreach ($this->rows as $row) {
@@ -308,13 +329,60 @@ class Table
}
if (isset($row[$i])) {
$rows[$i][] = $row[$i];
- } elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
+ } elseif ($isCellWithColspan($rows[$i][0])) {
// Noop, there is a "title"
} else {
$rows[$i][] = null;
}
}
}
+ } elseif ($vertical) {
+ $formatter = $this->output->getFormatter();
+ $maxHeaderLength = array_reduce($this->headers[0] ?? [], static fn ($max, $header) => max($max, Helper::width(Helper::removeDecoration($formatter, $header))), 0);
+
+ foreach ($this->rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+
+ if ($rows) {
+ $rows[] = [$divider];
+ }
+
+ $containsColspan = false;
+ foreach ($row as $cell) {
+ if ($containsColspan = $isCellWithColspan($cell)) {
+ break;
+ }
+ }
+
+ $headers = $this->headers[0] ?? [];
+ $maxRows = max(\count($headers), \count($row));
+ for ($i = 0; $i < $maxRows; ++$i) {
+ $cell = (string) ($row[$i] ?? '');
+
+ $parts = explode("\n", $cell);
+ foreach ($parts as $idx => $part) {
+ if ($headers && !$containsColspan) {
+ if (0 === $idx) {
+ $rows[] = [sprintf(
+ '%s>: %s',
+ str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT),
+ $part
+ )];
+ } else {
+ $rows[] = [sprintf(
+ '%s %s',
+ str_pad('', $maxHeaderLength, ' ', \STR_PAD_LEFT),
+ $part
+ )];
+ }
+ } elseif ('' !== $cell) {
+ $rows[] = [$part];
+ }
+ }
+ }
+ }
} else {
$rows = array_merge($this->headers, [$divider], $this->rows);
}
@@ -324,8 +392,8 @@ class Table
$rowGroups = $this->buildTableRows($rows);
$this->calculateColumnsWidth($rowGroups);
- $isHeader = !$this->horizontal;
- $isFirstRow = $this->horizontal;
+ $isHeader = !$horizontal;
+ $isFirstRow = $horizontal;
$hasTitle = (bool) $this->headerTitle;
foreach ($rowGroups as $rowGroup) {
@@ -351,7 +419,7 @@ class Table
if ($isHeader && !$isHeaderSeparatorRendered) {
$this->renderRowSeparator(
- $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM,
+ self::SEPARATOR_TOP,
$hasTitle ? $this->headerTitle : null,
$hasTitle ? $this->style->getHeaderTitleFormat() : null
);
@@ -361,7 +429,7 @@ class Table
if ($isFirstRow) {
$this->renderRowSeparator(
- $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM,
+ $horizontal ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM,
$hasTitle ? $this->headerTitle : null,
$hasTitle ? $this->style->getHeaderTitleFormat() : null
);
@@ -369,7 +437,12 @@ class Table
$hasTitle = false;
}
- if ($this->horizontal) {
+ if ($vertical) {
+ $isHeader = false;
+ $isFirstRow = false;
+ }
+
+ if ($horizontal) {
$this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
} else {
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
@@ -389,9 +462,9 @@ class Table
*
* +-----+-----------+-------+
*/
- private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
+ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null): void
{
- if (0 === $count = $this->numberOfColumns) {
+ if (!$count = $this->numberOfColumns) {
return;
}
@@ -454,7 +527,7 @@ class Table
*
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
*/
- private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null)
+ private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null): void
{
$rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
$columns = $this->getRowColumns($row);
@@ -508,11 +581,11 @@ class Table
$cellFormat = '<'.$tag.'>%s>';
}
- if (strstr($content, '>')) {
+ if (str_contains($content, '>')) {
$content = str_replace('>', '', $content);
$width -= 3;
}
- if (strstr($content, '')) {
+ if (str_contains($content, '')) {
$content = str_replace('', '', $content);
$width -= \strlen('');
}
@@ -527,7 +600,7 @@ class Table
/**
* Calculate number of columns for this table.
*/
- private function calculateNumberOfColumns(array $rows)
+ private function calculateNumberOfColumns(array $rows): void
{
$columns = [0];
foreach ($rows as $row) {
@@ -556,10 +629,10 @@ class Table
if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
}
- if (!strstr($cell ?? '', "\n")) {
+ if (!str_contains($cell ?? '', "\n")) {
continue;
}
- $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
+ $escaped = implode("\n", array_map(OutputFormatter::escapeTrailingBackslash(...), explode("\n", $cell)));
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
$lines = explode("\n", str_replace("\n", ">\n", $cell));
foreach ($lines as $lineKey => $line) {
@@ -600,7 +673,7 @@ class Table
++$numberOfRows; // Add row for header separator
}
- if (\count($this->rows) > 0) {
+ if ($this->rows) {
++$numberOfRows; // Add row for footer separator
}
@@ -622,7 +695,7 @@ class Table
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;
$lines = [$cell];
- if (strstr($cell, "\n")) {
+ if (str_contains($cell, "\n")) {
$lines = explode("\n", str_replace("\n", "\n>", $cell));
$nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
@@ -666,7 +739,7 @@ class Table
/**
* fill cells for a row that contains colspan > 1.
*/
- private function fillCells(iterable $row)
+ private function fillCells(iterable $row): iterable
{
$newRow = [];
@@ -728,7 +801,7 @@ class Table
/**
* Calculates columns widths.
*/
- private function calculateColumnsWidth(iterable $groups)
+ private function calculateColumnsWidth(iterable $groups): void
{
for ($column = 0; $column < $this->numberOfColumns; ++$column) {
$lengths = [];
@@ -743,7 +816,7 @@ class Table
$textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
$textLength = Helper::width($textContent);
if ($textLength > 0) {
- $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan()));
+ $contentColumns = mb_str_split($textContent, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
$row[$i + $position] = $content;
}
@@ -782,7 +855,7 @@ class Table
/**
* Called after rendering to cleanup cache data.
*/
- private function cleanup()
+ private function cleanup(): void
{
$this->effectiveColumnWidths = [];
unset($this->numberOfColumns);
diff --git a/vendor/symfony/console/Helper/TableCellStyle.php b/vendor/symfony/console/Helper/TableCellStyle.php
index 65ae9e7..9419dcb 100644
--- a/vendor/symfony/console/Helper/TableCellStyle.php
+++ b/vendor/symfony/console/Helper/TableCellStyle.php
@@ -67,9 +67,7 @@ class TableCellStyle
{
return array_filter(
$this->getOptions(),
- function ($key) {
- return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]);
- },
+ fn ($key) => \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]),
\ARRAY_FILTER_USE_KEY
);
}
diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php
index 4e90c81..9ae2f54 100644
--- a/vendor/symfony/console/Input/ArgvInput.php
+++ b/vendor/symfony/console/Input/ArgvInput.php
@@ -45,7 +45,7 @@ class ArgvInput extends Input
public function __construct(array $argv = null, InputDefinition $definition = null)
{
- $argv = $argv ?? $_SERVER['argv'] ?? [];
+ $argv ??= $_SERVER['argv'] ?? [];
// strip the application name
array_shift($argv);
@@ -55,15 +55,12 @@ class ArgvInput extends Input
parent::__construct($definition);
}
- protected function setTokens(array $tokens)
+ protected function setTokens(array $tokens): void
{
$this->tokens = $tokens;
}
- /**
- * {@inheritdoc}
- */
- protected function parse()
+ protected function parse(): void
{
$parseOptions = true;
$this->parsed = $this->tokens;
@@ -92,7 +89,7 @@ class ArgvInput extends Input
/**
* Parses a short option.
*/
- private function parseShortOption(string $token)
+ private function parseShortOption(string $token): void
{
$name = substr($token, 1);
@@ -113,7 +110,7 @@ class ArgvInput extends Input
*
* @throws RuntimeException When option given doesn't exist
*/
- private function parseShortOptionSet(string $name)
+ private function parseShortOptionSet(string $name): void
{
$len = \strlen($name);
for ($i = 0; $i < $len; ++$i) {
@@ -136,7 +133,7 @@ class ArgvInput extends Input
/**
* Parses a long option.
*/
- private function parseLongOption(string $token)
+ private function parseLongOption(string $token): void
{
$name = substr($token, 2);
@@ -155,7 +152,7 @@ class ArgvInput extends Input
*
* @throws RuntimeException When too many arguments are given
*/
- private function parseArgument(string $token)
+ private function parseArgument(string $token): void
{
$c = \count($this->arguments);
@@ -199,7 +196,7 @@ class ArgvInput extends Input
*
* @throws RuntimeException When option given doesn't exist
*/
- private function addShortOption(string $shortcut, mixed $value)
+ private function addShortOption(string $shortcut, mixed $value): void
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
@@ -213,7 +210,7 @@ class ArgvInput extends Input
*
* @throws RuntimeException When option given doesn't exist
*/
- private function addLongOption(string $name, mixed $value)
+ private function addLongOption(string $name, mixed $value): void
{
if (!$this->definition->hasOption($name)) {
if (!$this->definition->hasNegation($name)) {
@@ -263,9 +260,6 @@ class ArgvInput extends Input
}
}
- /**
- * {@inheritdoc}
- */
public function getFirstArgument(): ?string
{
$isOption = false;
@@ -298,9 +292,6 @@ class ArgvInput extends Input
return null;
}
- /**
- * {@inheritdoc}
- */
public function hasParameterOption(string|array $values, bool $onlyParams = false): bool
{
$values = (array) $values;
@@ -323,9 +314,6 @@ class ArgvInput extends Input
return false;
}
- /**
- * {@inheritdoc}
- */
public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed
{
$values = (array) $values;
diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php
index fdb47df..03b200b 100644
--- a/vendor/symfony/console/Input/ArrayInput.php
+++ b/vendor/symfony/console/Input/ArrayInput.php
@@ -34,9 +34,6 @@ class ArrayInput extends Input
parent::__construct($definition);
}
- /**
- * {@inheritdoc}
- */
public function getFirstArgument(): ?string
{
foreach ($this->parameters as $param => $value) {
@@ -50,9 +47,6 @@ class ArrayInput extends Input
return null;
}
- /**
- * {@inheritdoc}
- */
public function hasParameterOption(string|array $values, bool $onlyParams = false): bool
{
$values = (array) $values;
@@ -74,9 +68,6 @@ class ArrayInput extends Input
return false;
}
- /**
- * {@inheritdoc}
- */
public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed
{
$values = (array) $values;
@@ -115,17 +106,14 @@ class ArrayInput extends Input
$params[] = $param.('' != $val ? $glue.$this->escapeToken($val) : '');
}
} else {
- $params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val);
+ $params[] = \is_array($val) ? implode(' ', array_map($this->escapeToken(...), $val)) : $this->escapeToken($val);
}
}
return implode(' ', $params);
}
- /**
- * {@inheritdoc}
- */
- protected function parse()
+ protected function parse(): void
{
foreach ($this->parameters as $key => $value) {
if ('--' === $key) {
@@ -146,7 +134,7 @@ class ArrayInput extends Input
*
* @throws InvalidOptionException When option given doesn't exist
*/
- private function addShortOption(string $shortcut, mixed $value)
+ private function addShortOption(string $shortcut, mixed $value): void
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
@@ -161,7 +149,7 @@ class ArrayInput extends Input
* @throws InvalidOptionException When option given doesn't exist
* @throws InvalidOptionException When a required value is missing
*/
- private function addLongOption(string $name, mixed $value)
+ private function addLongOption(string $name, mixed $value): void
{
if (!$this->definition->hasOption($name)) {
if (!$this->definition->hasNegation($name)) {
@@ -194,7 +182,7 @@ class ArrayInput extends Input
*
* @throws InvalidArgumentException When argument given doesn't exist
*/
- private function addArgument(string|int $name, mixed $value)
+ private function addArgument(string|int $name, mixed $value): void
{
if (!$this->definition->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php
index 1db503c..6a9248b 100644
--- a/vendor/symfony/console/Input/Input.php
+++ b/vendor/symfony/console/Input/Input.php
@@ -27,11 +27,12 @@ use Symfony\Component\Console\Exception\RuntimeException;
*/
abstract class Input implements InputInterface, StreamableInputInterface
{
- protected $definition;
+ protected InputDefinition $definition;
+ /** @var resource */
protected $stream;
- protected $options = [];
- protected $arguments = [];
- protected $interactive = true;
+ protected array $options = [];
+ protected array $arguments = [];
+ protected bool $interactive = true;
public function __construct(InputDefinition $definition = null)
{
@@ -43,10 +44,7 @@ abstract class Input implements InputInterface, StreamableInputInterface
}
}
- /**
- * {@inheritdoc}
- */
- public function bind(InputDefinition $definition)
+ public function bind(InputDefinition $definition): void
{
$this->arguments = [];
$this->options = [];
@@ -58,52 +56,35 @@ abstract class Input implements InputInterface, StreamableInputInterface
/**
* Processes command line arguments.
*/
- abstract protected function parse();
+ abstract protected function parse(): void;
- /**
- * {@inheritdoc}
- */
- public function validate()
+ public function validate(): void
{
$definition = $this->definition;
$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();
- });
+ $missingArguments = array_filter(array_keys($definition->getArguments()), fn ($argument) => !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired());
if (\count($missingArguments) > 0) {
throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
}
}
- /**
- * {@inheritdoc}
- */
public function isInteractive(): bool
{
return $this->interactive;
}
- /**
- * {@inheritdoc}
- */
- public function setInteractive(bool $interactive)
+ public function setInteractive(bool $interactive): void
{
$this->interactive = $interactive;
}
- /**
- * {@inheritdoc}
- */
public function getArguments(): array
{
return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
}
- /**
- * {@inheritdoc}
- */
public function getArgument(string $name): mixed
{
if (!$this->definition->hasArgument($name)) {
@@ -113,10 +94,7 @@ abstract class Input implements InputInterface, StreamableInputInterface
return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();
}
- /**
- * {@inheritdoc}
- */
- public function setArgument(string $name, mixed $value)
+ public function setArgument(string $name, mixed $value): void
{
if (!$this->definition->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
@@ -125,25 +103,16 @@ abstract class Input implements InputInterface, StreamableInputInterface
$this->arguments[$name] = $value;
}
- /**
- * {@inheritdoc}
- */
public function hasArgument(string $name): bool
{
return $this->definition->hasArgument($name);
}
- /**
- * {@inheritdoc}
- */
public function getOptions(): array
{
return array_merge($this->definition->getOptionDefaults(), $this->options);
}
- /**
- * {@inheritdoc}
- */
public function getOption(string $name): mixed
{
if ($this->definition->hasNegation($name)) {
@@ -161,10 +130,7 @@ abstract class Input implements InputInterface, StreamableInputInterface
return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
}
- /**
- * {@inheritdoc}
- */
- public function setOption(string $name, mixed $value)
+ public function setOption(string $name, mixed $value): void
{
if ($this->definition->hasNegation($name)) {
$this->options[$this->definition->negationToName($name)] = !$value;
@@ -177,9 +143,6 @@ abstract class Input implements InputInterface, StreamableInputInterface
$this->options[$name] = $value;
}
- /**
- * {@inheritdoc}
- */
public function hasOption(string $name): bool
{
return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
@@ -194,15 +157,15 @@ abstract class Input implements InputInterface, StreamableInputInterface
}
/**
- * {@inheritdoc}
+ * @param resource $stream
*/
- public function setStream($stream)
+ public function setStream($stream): void
{
$this->stream = $stream;
}
/**
- * {@inheritdoc}
+ * @return resource
*/
public function getStream()
{
diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php
index 1e666ee..642ae66 100644
--- a/vendor/symfony/console/Input/InputArgument.php
+++ b/vendor/symfony/console/Input/InputArgument.php
@@ -11,6 +11,10 @@
namespace Symfony\Component\Console\Input;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Completion\CompletionInput;
+use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
@@ -28,17 +32,19 @@ class InputArgument
private string $name;
private int $mode;
private string|int|bool|array|null|float $default;
+ private array|\Closure $suggestedValues;
private string $description;
/**
- * @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|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
+ * @param string $name The argument name
+ * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
+ * @param string $description A description text
+ * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
*
* @throws InvalidArgumentException When argument mode is not valid
*/
- public function __construct(string $name, int $mode = null, string $description = '', string|bool|int|float|array $default = null)
+ public function __construct(string $name, int $mode = null, string $description = '', string|bool|int|float|array $default = null, \Closure|array $suggestedValues = [])
{
if (null === $mode) {
$mode = self::OPTIONAL;
@@ -49,6 +55,7 @@ class InputArgument
$this->name = $name;
$this->mode = $mode;
$this->description = $description;
+ $this->suggestedValues = $suggestedValues;
$this->setDefault($default);
}
@@ -86,7 +93,7 @@ class InputArgument
*
* @throws LogicException When incorrect default value is given
*/
- public function setDefault(string|bool|int|float|array $default = null)
+ public function setDefault(string|bool|int|float|array|null $default): void
{
if ($this->isRequired() && null !== $default) {
throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
@@ -111,6 +118,27 @@ class InputArgument
return $this->default;
}
+ public function hasCompletion(): bool
+ {
+ return [] !== $this->suggestedValues;
+ }
+
+ /**
+ * Adds suggestions to $suggestions for the current completion input.
+ *
+ * @see Command::complete()
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
+ {
+ $values = $this->suggestedValues;
+ if ($values instanceof \Closure && !\is_array($values = $values($input))) {
+ throw new LogicException(sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->name, get_debug_type($values)));
+ }
+ if ($values) {
+ $suggestions->suggestValues($values);
+ }
+ }
+
/**
* Returns the description text.
*/
diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php
index 5a288de..ba4664c 100644
--- a/vendor/symfony/console/Input/InputAwareInterface.php
+++ b/vendor/symfony/console/Input/InputAwareInterface.php
@@ -22,5 +22,5 @@ interface InputAwareInterface
/**
* Sets the Console Input.
*/
- public function setInput(InputInterface $input);
+ public function setInput(InputInterface $input): void;
}
diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php
index cb270d8..f27e297 100644
--- a/vendor/symfony/console/Input/InputDefinition.php
+++ b/vendor/symfony/console/Input/InputDefinition.php
@@ -30,8 +30,8 @@ class InputDefinition
{
private array $arguments = [];
private int $requiredCount = 0;
- private $lastArrayArgument = null;
- private $lastOptionalArgument = null;
+ private ?InputArgument $lastArrayArgument = null;
+ private ?InputArgument $lastOptionalArgument = null;
private array $options = [];
private array $negations = [];
private array $shortcuts = [];
@@ -47,7 +47,7 @@ class InputDefinition
/**
* Sets the definition of the input.
*/
- public function setDefinition(array $definition)
+ public function setDefinition(array $definition): void
{
$arguments = [];
$options = [];
@@ -68,7 +68,7 @@ class InputDefinition
*
* @param InputArgument[] $arguments An array of InputArgument objects
*/
- public function setArguments(array $arguments = [])
+ public function setArguments(array $arguments = []): void
{
$this->arguments = [];
$this->requiredCount = 0;
@@ -82,7 +82,7 @@ class InputDefinition
*
* @param InputArgument[] $arguments An array of InputArgument objects
*/
- public function addArguments(?array $arguments = [])
+ public function addArguments(?array $arguments = []): void
{
if (null !== $arguments) {
foreach ($arguments as $argument) {
@@ -94,7 +94,7 @@ class InputDefinition
/**
* @throws LogicException When incorrect argument is given
*/
- public function addArgument(InputArgument $argument)
+ public function addArgument(InputArgument $argument): void
{
if (isset($this->arguments[$argument->getName()])) {
throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
@@ -191,7 +191,7 @@ class InputDefinition
*
* @param InputOption[] $options An array of InputOption objects
*/
- public function setOptions(array $options = [])
+ public function setOptions(array $options = []): void
{
$this->options = [];
$this->shortcuts = [];
@@ -204,7 +204,7 @@ class InputDefinition
*
* @param InputOption[] $options An array of InputOption objects
*/
- public function addOptions(array $options = [])
+ public function addOptions(array $options = []): void
{
foreach ($options as $option) {
$this->addOption($option);
@@ -214,7 +214,7 @@ class InputDefinition
/**
* @throws LogicException When option given already exist
*/
- public function addOption(InputOption $option)
+ public function addOption(InputOption $option): void
{
if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php
index 024da18..c177d96 100644
--- a/vendor/symfony/console/Input/InputInterface.php
+++ b/vendor/symfony/console/Input/InputInterface.php
@@ -50,24 +50,22 @@ interface InputInterface
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
* @param string|bool|int|float|array|null $default The default value to return if no result is found
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
- *
- * @return mixed
*/
- public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false);
+ public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed;
/**
* Binds the current Input instance with the given arguments and options.
*
* @throws RuntimeException
*/
- public function bind(InputDefinition $definition);
+ public function bind(InputDefinition $definition): void;
/**
* Validates the input.
*
* @throws RuntimeException When not enough arguments are given
*/
- public function validate();
+ public function validate(): void;
/**
* Returns all the given arguments merged with the default values.
@@ -79,18 +77,16 @@ interface InputInterface
/**
* Returns the argument value for a given argument name.
*
- * @return mixed
- *
* @throws InvalidArgumentException When argument given doesn't exist
*/
- public function getArgument(string $name);
+ public function getArgument(string $name): mixed;
/**
* Sets an argument value by name.
*
* @throws InvalidArgumentException When argument given doesn't exist
*/
- public function setArgument(string $name, mixed $value);
+ public function setArgument(string $name, mixed $value): void;
/**
* Returns true if an InputArgument object exists by name or position.
@@ -107,18 +103,16 @@ interface InputInterface
/**
* Returns the option value for a given option name.
*
- * @return mixed
- *
* @throws InvalidArgumentException When option given doesn't exist
*/
- public function getOption(string $name);
+ public function getOption(string $name): mixed;
/**
* Sets an option value by name.
*
* @throws InvalidArgumentException When option given doesn't exist
*/
- public function setOption(string $name, mixed $value);
+ public function setOption(string $name, mixed $value): void;
/**
* Returns true if an InputOption object exists by name.
@@ -133,5 +127,12 @@ interface InputInterface
/**
* Sets the input interactivity.
*/
- public function setInteractive(bool $interactive);
+ public function setInteractive(bool $interactive): void;
+
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ *
+ * InputArguments MUST be escaped as well as the InputOption values passed to the command.
+ */
+ public function __toString(): string;
}
diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php
index f9d74a8..f8e9b0d 100644
--- a/vendor/symfony/console/Input/InputOption.php
+++ b/vendor/symfony/console/Input/InputOption.php
@@ -11,6 +11,10 @@
namespace Symfony\Component\Console\Input;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Completion\CompletionInput;
+use Symfony\Component\Console\Completion\CompletionSuggestions;
+use Symfony\Component\Console\Completion\Suggestion;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
@@ -50,16 +54,18 @@ class InputOption
private string|array|null $shortcut;
private int $mode;
private string|int|bool|array|null|float $default;
+ private array|\Closure $suggestedValues;
private string $description;
/**
- * @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|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE)
+ * @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|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
- public function __construct(string $name, string|array $shortcut = null, int $mode = null, string $description = '', string|bool|int|float|array $default = null)
+ public function __construct(string $name, string|array $shortcut = null, int $mode = null, string $description = '', string|bool|int|float|array $default = null, array|\Closure $suggestedValues = [])
{
if (str_starts_with($name, '--')) {
$name = substr($name, 2);
@@ -96,7 +102,11 @@ class InputOption
$this->shortcut = $shortcut;
$this->mode = $mode;
$this->description = $description;
+ $this->suggestedValues = $suggestedValues;
+ if ($suggestedValues && !$this->acceptValue()) {
+ throw new LogicException('Cannot set suggested values if the option does not accept a value.');
+ }
if ($this->isArray() && !$this->acceptValue()) {
throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
}
@@ -168,7 +178,7 @@ class InputOption
return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode);
}
- public function setDefault(string|bool|int|float|array $default = null)
+ public function setDefault(string|bool|int|float|array|null $default): void
{
if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
@@ -201,6 +211,27 @@ class InputOption
return $this->description;
}
+ public function hasCompletion(): bool
+ {
+ return [] !== $this->suggestedValues;
+ }
+
+ /**
+ * Adds suggestions to $suggestions for the current completion input.
+ *
+ * @see Command::complete()
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
+ {
+ $values = $this->suggestedValues;
+ if ($values instanceof \Closure && !\is_array($values = $values($input))) {
+ throw new LogicException(sprintf('Closure for option "%s" must return an array. Got "%s".', $this->name, get_debug_type($values)));
+ }
+ if ($values) {
+ $suggestions->suggestValues($values);
+ }
+ }
+
/**
* Checks whether the given option equals this one.
*/
diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php
index d7e462f..4a0dc01 100644
--- a/vendor/symfony/console/Input/StreamableInputInterface.php
+++ b/vendor/symfony/console/Input/StreamableInputInterface.php
@@ -26,7 +26,7 @@ interface StreamableInputInterface extends InputInterface
*
* @param resource $stream The input stream
*/
- public function setStream($stream);
+ public function setStream($stream): void;
/**
* Returns the input stream.
diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php
index 56bb66c..33f0f4b 100644
--- a/vendor/symfony/console/Input/StringInput.php
+++ b/vendor/symfony/console/Input/StringInput.php
@@ -24,7 +24,6 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
*/
class StringInput extends ArgvInput
{
- public const REGEX_STRING = '([^\s]+?)(?:\s|(? OutputInterface::VERBOSITY_NORMAL,
LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
@@ -59,9 +59,6 @@ class ConsoleLogger extends AbstractLogger
$this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
}
- /**
- * {@inheritdoc}
- */
public function log($level, $message, array $context = []): void
{
if (!isset($this->verbosityLevelMap[$level])) {
@@ -109,9 +106,9 @@ class ConsoleLogger extends AbstractLogger
if (null === $val || \is_scalar($val) || $val instanceof \Stringable) {
$replacements["{{$key}}"] = $val;
} elseif ($val instanceof \DateTimeInterface) {
- $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339);
+ $replacements["{{$key}}"] = $val->format(\DateTimeInterface::RFC3339);
} elseif (\is_object($val)) {
- $replacements["{{$key}}"] = '[object '.\get_class($val).']';
+ $replacements["{{$key}}"] = '[object '.$val::class.']';
} else {
$replacements["{{$key}}"] = '['.\gettype($val).']';
}
diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php
index 784e309..3c8d390 100644
--- a/vendor/symfony/console/Output/BufferedOutput.php
+++ b/vendor/symfony/console/Output/BufferedOutput.php
@@ -29,10 +29,7 @@ class BufferedOutput extends Output
return $content;
}
- /**
- * {@inheritdoc}
- */
- protected function doWrite(string $message, bool $newline)
+ protected function doWrite(string $message, bool $newline): void
{
$this->buffer .= $message;
diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php
index c6ba068..f9e6c77 100644
--- a/vendor/symfony/console/Output/ConsoleOutput.php
+++ b/vendor/symfony/console/Output/ConsoleOutput.php
@@ -29,7 +29,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
- private $stderr;
+ private OutputInterface $stderr;
private array $consoleSectionOutputs = [];
/**
@@ -64,45 +64,30 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
}
- /**
- * {@inheritdoc}
- */
- public function setDecorated(bool $decorated)
+ public function setDecorated(bool $decorated): void
{
parent::setDecorated($decorated);
$this->stderr->setDecorated($decorated);
}
- /**
- * {@inheritdoc}
- */
- public function setFormatter(OutputFormatterInterface $formatter)
+ public function setFormatter(OutputFormatterInterface $formatter): void
{
parent::setFormatter($formatter);
$this->stderr->setFormatter($formatter);
}
- /**
- * {@inheritdoc}
- */
- public function setVerbosity(int $level)
+ public function setVerbosity(int $level): void
{
parent::setVerbosity($level);
$this->stderr->setVerbosity($level);
}
- /**
- * {@inheritdoc}
- */
public function getErrorOutput(): OutputInterface
{
return $this->stderr;
}
- /**
- * {@inheritdoc}
- */
- public function setErrorOutput(OutputInterface $error)
+ public function setErrorOutput(OutputInterface $error): void
{
$this->stderr = $error;
}
diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php
index 6b4babc..1f8f147 100644
--- a/vendor/symfony/console/Output/ConsoleOutputInterface.php
+++ b/vendor/symfony/console/Output/ConsoleOutputInterface.php
@@ -24,7 +24,7 @@ interface ConsoleOutputInterface extends OutputInterface
*/
public function getErrorOutput(): OutputInterface;
- public function setErrorOutput(OutputInterface $error);
+ public function setErrorOutput(OutputInterface $error): void;
public function section(): ConsoleSectionOutput;
}
diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php
index 92dca79..d5b5aff 100644
--- a/vendor/symfony/console/Output/ConsoleSectionOutput.php
+++ b/vendor/symfony/console/Output/ConsoleSectionOutput.php
@@ -24,7 +24,8 @@ class ConsoleSectionOutput extends StreamOutput
private array $content = [];
private int $lines = 0;
private array $sections;
- private $terminal;
+ private Terminal $terminal;
+ private int $maxHeight = 0;
/**
* @param resource $stream
@@ -38,19 +39,36 @@ class ConsoleSectionOutput extends StreamOutput
$this->terminal = new Terminal();
}
+ /**
+ * Defines a maximum number of lines for this section.
+ *
+ * When more lines are added, the section will automatically scroll to the
+ * end (i.e. remove the first lines to comply with the max height).
+ */
+ public function setMaxHeight(int $maxHeight): void
+ {
+ // when changing max height, clear output of current section and redraw again with the new height
+ $previousMaxHeight = $this->maxHeight;
+ $this->maxHeight = $maxHeight;
+ $existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? min($previousMaxHeight, $this->lines) : $this->lines);
+
+ parent::doWrite($this->getVisibleContent(), false);
+ parent::doWrite($existingContent, false);
+ }
+
/**
* 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)
+ public function clear(int $lines = null): void
{
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
+ array_splice($this->content, -$lines);
} else {
$lines = $this->lines;
$this->content = [];
@@ -58,13 +76,13 @@ class ConsoleSectionOutput extends StreamOutput
$this->lines -= $lines;
- parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false);
+ parent::doWrite($this->popStreamContentUntilCurrentSection($this->maxHeight ? min($this->maxHeight, $lines) : $lines), false);
}
/**
* Overwrites the previous output with a new message.
*/
- public function overwrite(string|iterable $message)
+ public function overwrite(string|iterable $message): void
{
$this->clear();
$this->writeln($message);
@@ -75,34 +93,107 @@ class ConsoleSectionOutput extends StreamOutput
return implode('', $this->content);
}
- /**
- * @internal
- */
- public function addContent(string $input)
+ public function getVisibleContent(): string
{
- foreach (explode(\PHP_EOL, $input) as $lineContent) {
- $this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
- $this->content[] = $lineContent;
- $this->content[] = \PHP_EOL;
+ if (0 === $this->maxHeight) {
+ return $this->getContent();
}
+
+ return implode('', \array_slice($this->content, -$this->maxHeight));
}
/**
- * {@inheritdoc}
+ * @internal
*/
- protected function doWrite(string $message, bool $newline)
+ public function addContent(string $input, bool $newline = true): int
{
+ $width = $this->terminal->getWidth();
+ $lines = explode(\PHP_EOL, $input);
+ $linesAdded = 0;
+ $count = \count($lines) - 1;
+ foreach ($lines as $i => $lineContent) {
+ // re-add the line break (that has been removed in the above `explode()` for
+ // - every line that is not the last line
+ // - if $newline is required, also add it to the last line
+ if ($i < $count || $newline) {
+ $lineContent .= \PHP_EOL;
+ }
+
+ // skip line if there is no text (or newline for that matter)
+ if ('' === $lineContent) {
+ continue;
+ }
+
+ // For the first line, check if the previous line (last entry of `$this->content`)
+ // needs to be continued (i.e. does not end with a line break).
+ if (0 === $i
+ && (false !== $lastLine = end($this->content))
+ && !str_ends_with($lastLine, \PHP_EOL)
+ ) {
+ // deduct the line count of the previous line
+ $this->lines -= (int) ceil($this->getDisplayLength($lastLine) / $width) ?: 1;
+ // concatenate previous and new line
+ $lineContent = $lastLine.$lineContent;
+ // replace last entry of `$this->content` with the new expanded line
+ array_splice($this->content, -1, 1, $lineContent);
+ } else {
+ // otherwise just add the new content
+ $this->content[] = $lineContent;
+ }
+
+ $linesAdded += (int) ceil($this->getDisplayLength($lineContent) / $width) ?: 1;
+ }
+
+ $this->lines += $linesAdded;
+
+ return $linesAdded;
+ }
+
+ /**
+ * @internal
+ */
+ public function addNewLineOfInputSubmit(): void
+ {
+ $this->content[] = \PHP_EOL;
+ ++$this->lines;
+ }
+
+ protected function doWrite(string $message, bool $newline): void
+ {
+ // Simulate newline behavior for consistent output formatting, avoiding extra logic
+ if (!$newline && str_ends_with($message, \PHP_EOL)) {
+ $message = substr($message, 0, -\strlen(\PHP_EOL));
+ $newline = true;
+ }
+
if (!$this->isDecorated()) {
parent::doWrite($message, $newline);
return;
}
- $erasedContent = $this->popStreamContentUntilCurrentSection();
+ // Check if the previous line (last entry of `$this->content`) needs to be continued
+ // (i.e. does not end with a line break). In which case, it needs to be erased first.
+ $linesToClear = $deleteLastLine = ($lastLine = end($this->content) ?: '') && !str_ends_with($lastLine, \PHP_EOL) ? 1 : 0;
- $this->addContent($message);
+ $linesAdded = $this->addContent($message, $newline);
- parent::doWrite($message, true);
+ if ($lineOverflow = $this->maxHeight > 0 && $this->lines > $this->maxHeight) {
+ // on overflow, clear the whole section and redraw again (to remove the first lines)
+ $linesToClear = $this->maxHeight;
+ }
+
+ $erasedContent = $this->popStreamContentUntilCurrentSection($linesToClear);
+
+ if ($lineOverflow) {
+ // redraw existing lines of the section
+ $previousLinesOfSection = \array_slice($this->content, $this->lines - $this->maxHeight, $this->maxHeight - $linesAdded);
+ parent::doWrite(implode('', $previousLinesOfSection), false);
+ }
+
+ // if the last line was removed, re-print its content together with the new content.
+ // otherwise, just print the new content.
+ parent::doWrite($deleteLastLine ? $lastLine.$message : $message, true);
parent::doWrite($erasedContent, false);
}
@@ -120,8 +211,13 @@ class ConsoleSectionOutput extends StreamOutput
break;
}
- $numberOfLinesToClear += $section->lines;
- $erasedContent[] = $section->getContent();
+ $numberOfLinesToClear += $section->maxHeight ? min($section->lines, $section->maxHeight) : $section->lines;
+ if ('' !== $sectionContent = $section->getVisibleContent()) {
+ if (!str_ends_with($sectionContent, \PHP_EOL)) {
+ $sectionContent .= \PHP_EOL;
+ }
+ $erasedContent[] = $sectionContent;
+ }
}
if ($numberOfLinesToClear > 0) {
diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php
index 87214ec..40ae332 100644
--- a/vendor/symfony/console/Output/NullOutput.php
+++ b/vendor/symfony/console/Output/NullOutput.php
@@ -24,101 +24,65 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class NullOutput implements OutputInterface
{
- private $formatter;
+ private NullOutputFormatter $formatter;
- /**
- * {@inheritdoc}
- */
- public function setFormatter(OutputFormatterInterface $formatter)
+ public function setFormatter(OutputFormatterInterface $formatter): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function getFormatter(): OutputFormatterInterface
{
// to comply with the interface we must return a OutputFormatterInterface
return $this->formatter ??= new NullOutputFormatter();
}
- /**
- * {@inheritdoc}
- */
- public function setDecorated(bool $decorated)
+ public function setDecorated(bool $decorated): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function isDecorated(): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
- public function setVerbosity(int $level)
+ public function setVerbosity(int $level): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
public function getVerbosity(): int
{
return self::VERBOSITY_QUIET;
}
- /**
- * {@inheritdoc}
- */
public function isQuiet(): bool
{
return true;
}
- /**
- * {@inheritdoc}
- */
public function isVerbose(): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
public function isVeryVerbose(): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
public function isDebug(): bool
{
return false;
}
- /**
- * {@inheritdoc}
- */
- public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
+ public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void
{
// do nothing
}
- /**
- * {@inheritdoc}
- */
- public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
+ public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void
{
// do nothing
}
diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php
index 58c1837..fe8564b 100644
--- a/vendor/symfony/console/Output/Output.php
+++ b/vendor/symfony/console/Output/Output.php
@@ -30,7 +30,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
abstract class Output implements OutputInterface
{
private int $verbosity;
- private $formatter;
+ private OutputFormatterInterface $formatter;
/**
* @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
@@ -44,98 +44,62 @@ abstract class Output implements OutputInterface
$this->formatter->setDecorated($decorated);
}
- /**
- * {@inheritdoc}
- */
- public function setFormatter(OutputFormatterInterface $formatter)
+ public function setFormatter(OutputFormatterInterface $formatter): void
{
$this->formatter = $formatter;
}
- /**
- * {@inheritdoc}
- */
public function getFormatter(): OutputFormatterInterface
{
return $this->formatter;
}
- /**
- * {@inheritdoc}
- */
- public function setDecorated(bool $decorated)
+ public function setDecorated(bool $decorated): void
{
$this->formatter->setDecorated($decorated);
}
- /**
- * {@inheritdoc}
- */
public function isDecorated(): bool
{
return $this->formatter->isDecorated();
}
- /**
- * {@inheritdoc}
- */
- public function setVerbosity(int $level)
+ public function setVerbosity(int $level): void
{
$this->verbosity = $level;
}
- /**
- * {@inheritdoc}
- */
public function getVerbosity(): int
{
return $this->verbosity;
}
- /**
- * {@inheritdoc}
- */
public function isQuiet(): bool
{
return self::VERBOSITY_QUIET === $this->verbosity;
}
- /**
- * {@inheritdoc}
- */
public function isVerbose(): bool
{
return self::VERBOSITY_VERBOSE <= $this->verbosity;
}
- /**
- * {@inheritdoc}
- */
public function isVeryVerbose(): bool
{
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
}
- /**
- * {@inheritdoc}
- */
public function isDebug(): bool
{
return self::VERBOSITY_DEBUG <= $this->verbosity;
}
- /**
- * {@inheritdoc}
- */
- public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
+ public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL): void
{
$this->write($messages, true, $options);
}
- /**
- * {@inheritdoc}
- */
- public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
+ public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL): void
{
if (!is_iterable($messages)) {
$messages = [$messages];
@@ -170,5 +134,5 @@ abstract class Output implements OutputInterface
/**
* Writes a message to the output.
*/
- abstract protected function doWrite(string $message, bool $newline);
+ abstract protected function doWrite(string $message, bool $newline): void;
}
diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php
index beb9218..41315fb 100644
--- a/vendor/symfony/console/Output/OutputInterface.php
+++ b/vendor/symfony/console/Output/OutputInterface.php
@@ -33,25 +33,31 @@ interface OutputInterface
/**
* Writes a message to the output.
*
- * @param $newline Whether to add a newline
- * @param $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 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(string|iterable $messages, bool $newline = false, int $options = 0);
+ public function write(string|iterable $messages, bool $newline = false, int $options = 0): void;
/**
* Writes a message to the output and adds a newline at the end.
*
- * @param $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 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(string|iterable $messages, int $options = 0);
+ public function writeln(string|iterable $messages, int $options = 0): void;
/**
* Sets the verbosity of the output.
+ *
+ * @param self::VERBOSITY_* $level
*/
- public function setVerbosity(int $level);
+ public function setVerbosity(int $level): void;
/**
* Gets the current verbosity of the output.
+ *
+ * @return self::VERBOSITY_*
*/
public function getVerbosity(): int;
@@ -78,14 +84,14 @@ interface OutputInterface
/**
* Sets the decorated flag.
*/
- public function setDecorated(bool $decorated);
+ public function setDecorated(bool $decorated): void;
/**
* Gets the decorated flag.
*/
public function isDecorated(): bool;
- public function setFormatter(OutputFormatterInterface $formatter);
+ public function setFormatter(OutputFormatterInterface $formatter): void;
/**
* Returns current output formatter instance.
diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php
index ac58e41..f5119ea 100644
--- a/vendor/symfony/console/Output/StreamOutput.php
+++ b/vendor/symfony/console/Output/StreamOutput.php
@@ -29,6 +29,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class StreamOutput extends Output
{
+ /** @var resource */
private $stream;
/**
@@ -47,9 +48,7 @@ class StreamOutput extends Output
$this->stream = $stream;
- if (null === $decorated) {
- $decorated = $this->hasColorSupport();
- }
+ $decorated ??= $this->hasColorSupport();
parent::__construct($verbosity, $decorated, $formatter);
}
@@ -64,10 +63,7 @@ class StreamOutput extends Output
return $this->stream;
}
- /**
- * {@inheritdoc}
- */
- protected function doWrite(string $message, bool $newline)
+ protected function doWrite(string $message, bool $newline): void
{
if ($newline) {
$message .= \PHP_EOL;
diff --git a/vendor/symfony/console/Output/TrimmedBufferOutput.php b/vendor/symfony/console/Output/TrimmedBufferOutput.php
index 0d375e0..5655e7b 100644
--- a/vendor/symfony/console/Output/TrimmedBufferOutput.php
+++ b/vendor/symfony/console/Output/TrimmedBufferOutput.php
@@ -45,10 +45,7 @@ class TrimmedBufferOutput extends Output
return $content;
}
- /**
- * {@inheritdoc}
- */
- protected function doWrite(string $message, bool $newline)
+ protected function doWrite(string $message, bool $newline): void
{
$this->buffer .= $message;
diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php
index f99e685..c79683c 100644
--- a/vendor/symfony/console/Question/Question.php
+++ b/vendor/symfony/console/Question/Question.php
@@ -146,13 +146,12 @@ class Question
if (\is_array($values)) {
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
- $callback = static function () use ($values) {
- return $values;
- };
+ $callback = static fn () => $values;
} elseif ($values instanceof \Traversable) {
- $valueCache = null;
- $callback = static function () use ($values, &$valueCache) {
- return $valueCache ?? $valueCache = iterator_to_array($values, false);
+ $callback = static function () use ($values) {
+ static $valueCache;
+
+ return $valueCache ??= iterator_to_array($values, false);
};
} else {
$callback = null;
@@ -176,13 +175,13 @@ class Question
*
* @return $this
*/
- public function setAutocompleterCallback(callable $callback = null): static
+ public function setAutocompleterCallback(?callable $callback): static
{
if ($this->hidden && null !== $callback) {
throw new LogicException('A hidden question cannot use the autocompleter.');
}
- $this->autocompleterCallback = null === $callback || $callback instanceof \Closure ? $callback : \Closure::fromCallable($callback);
+ $this->autocompleterCallback = null === $callback ? null : $callback(...);
return $this;
}
@@ -192,9 +191,9 @@ class Question
*
* @return $this
*/
- public function setValidator(callable $validator = null): static
+ public function setValidator(?callable $validator): static
{
- $this->validator = null === $validator || $validator instanceof \Closure ? $validator : \Closure::fromCallable($validator);
+ $this->validator = null === $validator ? null : $validator(...);
return $this;
}
@@ -246,7 +245,7 @@ class Question
*/
public function setNormalizer(callable $normalizer): static
{
- $this->normalizer = $normalizer instanceof \Closure ? $normalizer : \Closure::fromCallable($normalizer);
+ $this->normalizer = $normalizer(...);
return $this;
}
@@ -261,7 +260,7 @@ class Question
return $this->normalizer;
}
- protected function isAssoc(array $array)
+ protected function isAssoc(array $array): bool
{
return (bool) \count(array_filter(array_keys($array), 'is_string'));
}
diff --git a/vendor/symfony/console/README.md b/vendor/symfony/console/README.md
index c4c1299..ded2bc1 100644
--- a/vendor/symfony/console/README.md
+++ b/vendor/symfony/console/README.md
@@ -7,12 +7,12 @@ interfaces.
Sponsor
-------
-The Console component for Symfony 5.4/6.0 is [backed][1] by [Les-Tilleuls.coop][2].
+The Console component for Symfony 7.0 is [backed][1] by [Les-Tilleuls.coop][2].
-Les-Tilleuls.coop is a team of 50+ Symfony experts who can help you design, develop and
-fix your projects. We provide a wide range of professional services including development,
-consulting, coaching, training and audits. We also are highly skilled in JS, Go and DevOps.
-We are a worker cooperative!
+Les-Tilleuls.coop is a team of 70+ Symfony experts who can help you design, develop and
+fix your projects. They provide a wide range of professional services including development,
+consulting, coaching, training and audits. They also are highly skilled in JS, Go and DevOps.
+They are a worker cooperative!
Help Symfony by [sponsoring][3] its development!
diff --git a/vendor/symfony/console/Resources/completion.bash b/vendor/symfony/console/Resources/completion.bash
index 64b87cc..0d76eac 100644
--- a/vendor/symfony/console/Resources/completion.bash
+++ b/vendor/symfony/console/Resources/completion.bash
@@ -6,6 +6,16 @@
# https://symfony.com/doc/current/contributing/code/license.html
_sf_{{ COMMAND_NAME }}() {
+
+ # Use the default completion for shell redirect operators.
+ for w in '>' '>>' '&>' '<'; do
+ if [[ $w = "${COMP_WORDS[COMP_CWORD-1]}" ]]; then
+ compopt -o filenames
+ COMPREPLY=($(compgen -f -- "${COMP_WORDS[COMP_CWORD]}"))
+ return 0
+ fi
+ done
+
# Use newline as only separator to allow space in completion values
IFS=$'\n'
local sf_cmd="${COMP_WORDS[0]}"
@@ -25,7 +35,7 @@ _sf_{{ COMMAND_NAME }}() {
local cur prev words cword
_get_comp_words_by_ref -n := cur prev words cword
- local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-S{{ VERSION }}")
+ local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-a{{ VERSION }}")
for w in ${words[@]}; do
w=$(printf -- '%b' "$w")
# remove quotes from typed values
diff --git a/vendor/symfony/console/SignalRegistry/SignalRegistry.php b/vendor/symfony/console/SignalRegistry/SignalRegistry.php
index f51c0c3..ef2e5f0 100644
--- a/vendor/symfony/console/SignalRegistry/SignalRegistry.php
+++ b/vendor/symfony/console/SignalRegistry/SignalRegistry.php
@@ -34,20 +34,12 @@ final class SignalRegistry
$this->signalHandlers[$signal][] = $signalHandler;
- pcntl_signal($signal, [$this, 'handle']);
+ pcntl_signal($signal, $this->handle(...));
}
public static function isSupported(): bool
{
- if (!\function_exists('pcntl_signal')) {
- return false;
- }
-
- if (\in_array('pcntl_signal', explode(',', \ini_get('disable_functions')))) {
- return false;
- }
-
- return true;
+ return \function_exists('pcntl_signal');
}
/**
diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php
index 0b2ded3..05076c0 100644
--- a/vendor/symfony/console/Style/OutputStyle.php
+++ b/vendor/symfony/console/Style/OutputStyle.php
@@ -23,17 +23,14 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
abstract class OutputStyle implements OutputInterface, StyleInterface
{
- private $output;
+ private OutputInterface $output;
public function __construct(OutputInterface $output)
{
$this->output = $output;
}
- /**
- * {@inheritdoc}
- */
- public function newLine(int $count = 1)
+ public function newLine(int $count = 1): void
{
$this->output->write(str_repeat(\PHP_EOL, $count));
}
@@ -43,103 +40,67 @@ abstract class OutputStyle implements OutputInterface, StyleInterface
return new ProgressBar($this->output, $max);
}
- /**
- * {@inheritdoc}
- */
- public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL)
+ public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL): void
{
$this->output->write($messages, $newline, $type);
}
- /**
- * {@inheritdoc}
- */
- public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL)
+ public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void
{
$this->output->writeln($messages, $type);
}
- /**
- * {@inheritdoc}
- */
- public function setVerbosity(int $level)
+ public function setVerbosity(int $level): void
{
$this->output->setVerbosity($level);
}
- /**
- * {@inheritdoc}
- */
public function getVerbosity(): int
{
return $this->output->getVerbosity();
}
- /**
- * {@inheritdoc}
- */
- public function setDecorated(bool $decorated)
+ public function setDecorated(bool $decorated): void
{
$this->output->setDecorated($decorated);
}
- /**
- * {@inheritdoc}
- */
public function isDecorated(): bool
{
return $this->output->isDecorated();
}
- /**
- * {@inheritdoc}
- */
- public function setFormatter(OutputFormatterInterface $formatter)
+ public function setFormatter(OutputFormatterInterface $formatter): void
{
$this->output->setFormatter($formatter);
}
- /**
- * {@inheritdoc}
- */
public function getFormatter(): OutputFormatterInterface
{
return $this->output->getFormatter();
}
- /**
- * {@inheritdoc}
- */
public function isQuiet(): bool
{
return $this->output->isQuiet();
}
- /**
- * {@inheritdoc}
- */
public function isVerbose(): bool
{
return $this->output->isVerbose();
}
- /**
- * {@inheritdoc}
- */
public function isVeryVerbose(): bool
{
return $this->output->isVeryVerbose();
}
- /**
- * {@inheritdoc}
- */
public function isDebug(): bool
{
return $this->output->isDebug();
}
- protected function getErrorOutput()
+ protected function getErrorOutput(): OutputInterface
{
if (!$this->output instanceof ConsoleOutputInterface) {
return $this->output;
diff --git a/vendor/symfony/console/Style/StyleInterface.php b/vendor/symfony/console/Style/StyleInterface.php
index 0bb1233..869b160 100644
--- a/vendor/symfony/console/Style/StyleInterface.php
+++ b/vendor/symfony/console/Style/StyleInterface.php
@@ -21,52 +21,52 @@ interface StyleInterface
/**
* Formats a command title.
*/
- public function title(string $message);
+ public function title(string $message): void;
/**
* Formats a section title.
*/
- public function section(string $message);
+ public function section(string $message): void;
/**
* Formats a list.
*/
- public function listing(array $elements);
+ public function listing(array $elements): void;
/**
* Formats informational text.
*/
- public function text(string|array $message);
+ public function text(string|array $message): void;
/**
* Formats a success result bar.
*/
- public function success(string|array $message);
+ public function success(string|array $message): void;
/**
* Formats an error result bar.
*/
- public function error(string|array $message);
+ public function error(string|array $message): void;
/**
* Formats an warning result bar.
*/
- public function warning(string|array $message);
+ public function warning(string|array $message): void;
/**
* Formats a note admonition.
*/
- public function note(string|array $message);
+ public function note(string|array $message): void;
/**
* Formats a caution admonition.
*/
- public function caution(string|array $message);
+ public function caution(string|array $message): void;
/**
* Formats a table.
*/
- public function table(array $headers, array $rows);
+ public function table(array $headers, array $rows): void;
/**
* Asks a question.
@@ -91,20 +91,20 @@ interface StyleInterface
/**
* Add newline(s).
*/
- public function newLine(int $count = 1);
+ public function newLine(int $count = 1): void;
/**
* Starts the progress output.
*/
- public function progressStart(int $max = 0);
+ public function progressStart(int $max = 0): void;
/**
* Advances the progress output X steps.
*/
- public function progressAdvance(int $step = 1);
+ public function progressAdvance(int $step = 1): void;
/**
* Finishes the progress output.
*/
- public function progressFinish();
+ public function progressFinish(): void;
}
diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php
index 2730242..0da5d69 100644
--- a/vendor/symfony/console/Style/SymfonyStyle.php
+++ b/vendor/symfony/console/Style/SymfonyStyle.php
@@ -15,6 +15,7 @@ use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
+use Symfony\Component\Console\Helper\OutputWrapper;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Helper\Table;
@@ -22,6 +23,7 @@ use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\TrimmedBufferOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
@@ -38,12 +40,12 @@ class SymfonyStyle extends OutputStyle
{
public const MAX_LINE_LENGTH = 120;
- private $input;
- private $output;
- private $questionHelper;
- private $progressBar;
+ private InputInterface $input;
+ private OutputInterface $output;
+ private SymfonyQuestionHelper $questionHelper;
+ private ProgressBar $progressBar;
private int $lineLength;
- private $bufferedOutput;
+ private TrimmedBufferOutput $bufferedOutput;
public function __construct(InputInterface $input, OutputInterface $output)
{
@@ -59,7 +61,7 @@ class SymfonyStyle extends OutputStyle
/**
* Formats a message as a block of text.
*/
- public function block(string|array $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true)
+ public function block(string|array $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true): void
{
$messages = \is_array($messages) ? array_values($messages) : [$messages];
@@ -68,10 +70,7 @@ class SymfonyStyle extends OutputStyle
$this->newLine();
}
- /**
- * {@inheritdoc}
- */
- public function title(string $message)
+ public function title(string $message): void
{
$this->autoPrependBlock();
$this->writeln([
@@ -81,10 +80,7 @@ class SymfonyStyle extends OutputStyle
$this->newLine();
}
- /**
- * {@inheritdoc}
- */
- public function section(string $message)
+ public function section(string $message): void
{
$this->autoPrependBlock();
$this->writeln([
@@ -94,24 +90,16 @@ class SymfonyStyle extends OutputStyle
$this->newLine();
}
- /**
- * {@inheritdoc}
- */
- public function listing(array $elements)
+ public function listing(array $elements): void
{
$this->autoPrependText();
- $elements = array_map(function ($element) {
- return sprintf(' * %s', $element);
- }, $elements);
+ $elements = array_map(fn ($element) => sprintf(' * %s', $element), $elements);
$this->writeln($elements);
$this->newLine();
}
- /**
- * {@inheritdoc}
- */
- public function text(string|array $message)
+ public function text(string|array $message): void
{
$this->autoPrependText();
@@ -124,39 +112,27 @@ class SymfonyStyle extends OutputStyle
/**
* Formats a command comment.
*/
- public function comment(string|array $message)
+ public function comment(string|array $message): void
{
$this->block($message, null, null, ' // >', false, false);
}
- /**
- * {@inheritdoc}
- */
- public function success(string|array $message)
+ public function success(string|array $message): void
{
$this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
}
- /**
- * {@inheritdoc}
- */
- public function error(string|array $message)
+ public function error(string|array $message): void
{
$this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
}
- /**
- * {@inheritdoc}
- */
- public function warning(string|array $message)
+ public function warning(string|array $message): void
{
$this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', true);
}
- /**
- * {@inheritdoc}
- */
- public function note(string|array $message)
+ public function note(string|array $message): void
{
$this->block($message, 'NOTE', 'fg=yellow', ' ! ');
}
@@ -164,23 +140,17 @@ class SymfonyStyle extends OutputStyle
/**
* Formats an info message.
*/
- public function info(string|array $message)
+ public function info(string|array $message): void
{
$this->block($message, 'INFO', 'fg=green', ' ', true);
}
- /**
- * {@inheritdoc}
- */
- public function caution(string|array $message)
+ public function caution(string|array $message): void
{
$this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
}
- /**
- * {@inheritdoc}
- */
- public function table(array $headers, array $rows)
+ public function table(array $headers, array $rows): void
{
$this->createTable()
->setHeaders($headers)
@@ -194,7 +164,7 @@ class SymfonyStyle extends OutputStyle
/**
* Formats a horizontal table.
*/
- public function horizontalTable(array $headers, array $rows)
+ public function horizontalTable(array $headers, array $rows): void
{
$this->createTable()
->setHorizontal(true)
@@ -214,7 +184,7 @@ class SymfonyStyle extends OutputStyle
* * ['key' => 'value']
* * new TableSeparator()
*/
- public function definitionList(string|array|TableSeparator ...$list)
+ public function definitionList(string|array|TableSeparator ...$list): void
{
$headers = [];
$row = [];
@@ -239,9 +209,6 @@ class SymfonyStyle extends OutputStyle
$this->horizontalTable($headers, [$row]);
}
- /**
- * {@inheritdoc}
- */
public function ask(string $question, string $default = null, callable $validator = null): mixed
{
$question = new Question($question, $default);
@@ -250,9 +217,6 @@ class SymfonyStyle extends OutputStyle
return $this->askQuestion($question);
}
- /**
- * {@inheritdoc}
- */
public function askHidden(string $question, callable $validator = null): mixed
{
$question = new Question($question);
@@ -263,57 +227,42 @@ class SymfonyStyle extends OutputStyle
return $this->askQuestion($question);
}
- /**
- * {@inheritdoc}
- */
public function confirm(string $question, bool $default = true): bool
{
return $this->askQuestion(new ConfirmationQuestion($question, $default));
}
- /**
- * {@inheritdoc}
- */
- public function choice(string $question, array $choices, mixed $default = null): mixed
+ public function choice(string $question, array $choices, mixed $default = null, bool $multiSelect = false): mixed
{
if (null !== $default) {
$values = array_flip($choices);
$default = $values[$default] ?? $default;
}
- return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
+ $questionChoice = new ChoiceQuestion($question, $choices, $default);
+ $questionChoice->setMultiselect($multiSelect);
+
+ return $this->askQuestion($questionChoice);
}
- /**
- * {@inheritdoc}
- */
- public function progressStart(int $max = 0)
+ public function progressStart(int $max = 0): void
{
$this->progressBar = $this->createProgressBar($max);
$this->progressBar->start();
}
- /**
- * {@inheritdoc}
- */
- public function progressAdvance(int $step = 1)
+ public function progressAdvance(int $step = 1): void
{
$this->getProgressBar()->advance($step);
}
- /**
- * {@inheritdoc}
- */
- public function progressFinish()
+ public function progressFinish(): void
{
$this->getProgressBar()->finish();
$this->newLine(2);
unset($this->progressBar);
}
- /**
- * {@inheritdoc}
- */
public function createProgressBar(int $max = 0): ProgressBar
{
$progressBar = parent::createProgressBar($max);
@@ -329,6 +278,14 @@ class SymfonyStyle extends OutputStyle
/**
* @see ProgressBar::iterate()
+ *
+ * @template TKey
+ * @template TValue
+ *
+ * @param iterable $iterable
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
+ *
+ * @return iterable
*/
public function progressIterate(iterable $iterable, int $max = null): iterable
{
@@ -348,6 +305,11 @@ class SymfonyStyle extends OutputStyle
$answer = $this->questionHelper->ask($this->input, $this, $question);
if ($this->input->isInteractive()) {
+ if ($this->output instanceof ConsoleSectionOutput) {
+ // add the new line of the `return` to submit the input to ConsoleSectionOutput, because ConsoleSectionOutput is holding all it's lines.
+ // this is relevant when a `ConsoleSectionOutput::clear` is called.
+ $this->output->addNewLineOfInputSubmit();
+ }
$this->newLine();
$this->bufferedOutput->write("\n");
}
@@ -355,10 +317,7 @@ class SymfonyStyle extends OutputStyle
return $answer;
}
- /**
- * {@inheritdoc}
- */
- public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL)
+ public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void
{
if (!is_iterable($messages)) {
$messages = [$messages];
@@ -370,10 +329,7 @@ class SymfonyStyle extends OutputStyle
}
}
- /**
- * {@inheritdoc}
- */
- public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL)
+ public function write(string|iterable $messages, bool $newline = false, int $type = self::OUTPUT_NORMAL): void
{
if (!is_iterable($messages)) {
$messages = [$messages];
@@ -385,10 +341,7 @@ class SymfonyStyle extends OutputStyle
}
}
- /**
- * {@inheritdoc}
- */
- public function newLine(int $count = 1)
+ public function newLine(int $count = 1): void
{
parent::newLine($count);
$this->bufferedOutput->write(str_repeat("\n", $count));
@@ -434,7 +387,7 @@ class SymfonyStyle extends OutputStyle
{
$fetched = $this->bufferedOutput->fetch();
// Prepend new line if last char isn't EOL:
- if (!str_ends_with($fetched, "\n")) {
+ if ($fetched && !str_ends_with($fetched, "\n")) {
$this->newLine();
}
}
@@ -453,22 +406,25 @@ class SymfonyStyle extends OutputStyle
if (null !== $type) {
$type = sprintf('[%s] ', $type);
- $indentLength = \strlen($type);
+ $indentLength = Helper::width($type);
$lineIndentation = str_repeat(' ', $indentLength);
}
// wrap and add newlines for each element
+ $outputWrapper = new OutputWrapper();
foreach ($messages as $key => $message) {
if ($escape) {
$message = OutputFormatter::escape($message);
}
- $decorationLength = Helper::width($message) - Helper::width(Helper::removeDecoration($this->getFormatter(), $message));
- $messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
- $messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
- foreach ($messageLines as $messageLine) {
- $lines[] = $messageLine;
- }
+ $lines = array_merge(
+ $lines,
+ explode(\PHP_EOL, $outputWrapper->wrap(
+ $message,
+ $this->lineLength - $prefixLength - $indentLength,
+ \PHP_EOL
+ ))
+ );
if (\count($messages) > 1 && $key < \count($messages) - 1) {
$lines[] = '';
diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php
index 80020c9..3eda037 100644
--- a/vendor/symfony/console/Terminal.php
+++ b/vendor/symfony/console/Terminal.php
@@ -11,12 +11,75 @@
namespace Symfony\Component\Console;
+use Symfony\Component\Console\Output\AnsiColorMode;
+
class Terminal
{
+ public const DEFAULT_COLOR_MODE = AnsiColorMode::Ansi4;
+
+ private static ?AnsiColorMode $colorMode = null;
private static ?int $width = null;
private static ?int $height = null;
private static ?bool $stty = null;
+ /**
+ * About Ansi color types: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
+ * For more information about true color support with terminals https://github.com/termstandard/colors/.
+ */
+ public static function getColorMode(): AnsiColorMode
+ {
+ // Use Cache from previous run (or user forced mode)
+ if (null !== self::$colorMode) {
+ return self::$colorMode;
+ }
+
+ // Try with $COLORTERM first
+ if (\is_string($colorterm = getenv('COLORTERM'))) {
+ $colorterm = strtolower($colorterm);
+
+ if (str_contains($colorterm, 'truecolor')) {
+ self::setColorMode(AnsiColorMode::Ansi24);
+
+ return self::$colorMode;
+ }
+
+ if (str_contains($colorterm, '256color')) {
+ self::setColorMode(AnsiColorMode::Ansi8);
+
+ return self::$colorMode;
+ }
+ }
+
+ // Try with $TERM
+ if (\is_string($term = getenv('TERM'))) {
+ $term = strtolower($term);
+
+ if (str_contains($term, 'truecolor')) {
+ self::setColorMode(AnsiColorMode::Ansi24);
+
+ return self::$colorMode;
+ }
+
+ if (str_contains($term, '256color')) {
+ self::setColorMode(AnsiColorMode::Ansi8);
+
+ return self::$colorMode;
+ }
+ }
+
+ self::setColorMode(self::DEFAULT_COLOR_MODE);
+
+ return self::$colorMode;
+ }
+
+ /**
+ * Force a terminal color mode rendering.
+ */
+ public static function setColorMode(?AnsiColorMode $colorMode): void
+ {
+ self::$colorMode = $colorMode;
+ }
+
/**
* Gets the terminal width.
*/
@@ -60,20 +123,19 @@ class Terminal
return self::$stty;
}
- // skip check if exec function is disabled
- if (!\function_exists('exec')) {
+ // skip check if shell_exec function is disabled
+ if (!\function_exists('shell_exec')) {
return false;
}
- exec('stty 2>&1', $output, $exitcode);
-
- return self::$stty = 0 === $exitcode;
+ return self::$stty = (bool) shell_exec('stty 2> '.('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
}
- private static function initDimensions()
+ private static function initDimensions(): void
{
if ('\\' === \DIRECTORY_SEPARATOR) {
- if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) {
+ $ansicon = getenv('ANSICON');
+ if (false !== $ansicon && preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim($ansicon), $matches)) {
// extract [w, H] from "wxh (WxH)"
// or [w, h] from "wxh"
self::$width = (int) $matches[1];
@@ -103,14 +165,14 @@ class Terminal
/**
* Initializes dimensions using the output of an stty columns line.
*/
- private static function initDimensionsUsingStty()
+ private static function initDimensionsUsingStty(): void
{
if ($sttyString = self::getSttyColumns()) {
- if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
+ if (preg_match('/rows.(\d+);.columns.(\d+);/is', $sttyString, $matches)) {
// extract [w, h] from "rows h; columns w;"
self::$width = (int) $matches[2];
self::$height = (int) $matches[1];
- } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
+ } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/is', $sttyString, $matches)) {
// extract [w, h] from "; h rows; w columns"
self::$width = (int) $matches[2];
self::$height = (int) $matches[1];
@@ -139,10 +201,10 @@ class Terminal
*/
private static function getSttyColumns(): ?string
{
- return self::readFromProcess('stty -a | grep columns');
+ return self::readFromProcess(['stty', '-a']);
}
- private static function readFromProcess(string $command): ?string
+ private static function readFromProcess(string|array $command): ?string
{
if (!\function_exists('proc_open')) {
return null;
@@ -153,6 +215,8 @@ class Terminal
2 => ['pipe', 'w'],
];
+ $cp = \function_exists('sapi_windows_cp_set') ? sapi_windows_cp_get() : 0;
+
$process = proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);
if (!\is_resource($process)) {
return null;
@@ -163,6 +227,10 @@ class Terminal
fclose($pipes[2]);
proc_close($process);
+ if ($cp) {
+ sapi_windows_cp_set($cp);
+ }
+
return $info;
}
}
diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php
index 275a305..58aee54 100644
--- a/vendor/symfony/console/Tester/ApplicationTester.php
+++ b/vendor/symfony/console/Tester/ApplicationTester.php
@@ -28,7 +28,7 @@ class ApplicationTester
{
use TesterTrait;
- private $application;
+ private Application $application;
public function __construct(Application $application)
{
diff --git a/vendor/symfony/console/Tester/CommandCompletionTester.php b/vendor/symfony/console/Tester/CommandCompletionTester.php
index ade7327..a90fe52 100644
--- a/vendor/symfony/console/Tester/CommandCompletionTester.php
+++ b/vendor/symfony/console/Tester/CommandCompletionTester.php
@@ -22,7 +22,7 @@ use Symfony\Component\Console\Completion\CompletionSuggestions;
*/
class CommandCompletionTester
{
- private $command;
+ private Command $command;
public function __construct(Command $command)
{
diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php
index f6ee4b7..2ff813b 100644
--- a/vendor/symfony/console/Tester/CommandTester.php
+++ b/vendor/symfony/console/Tester/CommandTester.php
@@ -24,7 +24,7 @@ class CommandTester
{
use TesterTrait;
- private $command;
+ private Command $command;
public function __construct(Command $command)
{
diff --git a/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php b/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php
index a473242..09c6194 100644
--- a/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php
+++ b/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php
@@ -16,33 +16,21 @@ use Symfony\Component\Console\Command\Command;
final class CommandIsSuccessful extends Constraint
{
- /**
- * {@inheritdoc}
- */
public function toString(): string
{
return 'is successful';
}
- /**
- * {@inheritdoc}
- */
protected function matches($other): bool
{
return Command::SUCCESS === $other;
}
- /**
- * {@inheritdoc}
- */
protected function failureDescription($other): string
{
return 'the command '.$this->toString();
}
- /**
- * {@inheritdoc}
- */
protected function additionalFailureDescription($other): string
{
$mapping = [
diff --git a/vendor/symfony/console/Tester/TesterTrait.php b/vendor/symfony/console/Tester/TesterTrait.php
index b238f95..1ab7a70 100644
--- a/vendor/symfony/console/Tester/TesterTrait.php
+++ b/vendor/symfony/console/Tester/TesterTrait.php
@@ -23,10 +23,10 @@ use Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful;
*/
trait TesterTrait
{
- private $output;
+ private StreamOutput $output;
private array $inputs = [];
private bool $captureStreamsIndependently = false;
- private $input;
+ private InputInterface $input;
private int $statusCode;
/**
@@ -128,9 +128,9 @@ trait TesterTrait
* * verbosity: Sets the output verbosity flag
* * capture_stderr_separately: Make output of stdOut and stdErr separately available
*/
- private function initOutput(array $options)
+ private function initOutput(array $options): void
{
- $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
+ $this->captureStreamsIndependently = $options['capture_stderr_separately'] ?? false;
if (!$this->captureStreamsIndependently) {
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated'])) {
@@ -152,12 +152,10 @@ trait TesterTrait
$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));
}
}
diff --git a/vendor/symfony/console/composer.json b/vendor/symfony/console/composer.json
index 7d3947f..0ed1bd9 100644
--- a/vendor/symfony/console/composer.json
+++ b/vendor/symfony/console/composer.json
@@ -2,7 +2,7 @@
"name": "symfony/console",
"type": "library",
"description": "Eases the creation of beautiful and testable command line interfaces",
- "keywords": ["console", "cli", "command line", "terminal"],
+ "keywords": ["console", "cli", "command-line", "terminal"],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
@@ -16,35 +16,33 @@
}
],
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/service-contracts": "^1.1|^2|^3",
- "symfony/string": "^5.4|^6.0"
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^6.4|^7.0"
},
"require-dev": {
- "symfony/config": "^5.4|^6.0",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/lock": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/lock": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0",
"psr/log": "^1|^2|^3"
},
"provide": {
"psr/log-implementation": "1.0|2.0|3.0"
},
- "suggest": {
- "symfony/event-dispatcher": "",
- "symfony/lock": "",
- "symfony/process": "",
- "psr/log": "For using the console logger"
- },
"conflict": {
- "symfony/dependency-injection": "<5.4",
- "symfony/dotenv": "<5.4",
- "symfony/event-dispatcher": "<5.4",
- "symfony/lock": "<5.4",
- "symfony/process": "<5.4"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/process": "<6.4"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Console\\": "" },
diff --git a/vendor/symfony/deprecation-contracts/.gitignore b/vendor/symfony/deprecation-contracts/.gitignore
deleted file mode 100644
index c49a5d8..0000000
--- a/vendor/symfony/deprecation-contracts/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vendor/
-composer.lock
-phpunit.xml
diff --git a/vendor/symfony/deprecation-contracts/LICENSE b/vendor/symfony/deprecation-contracts/LICENSE
index 406242f..0ed3a24 100644
--- a/vendor/symfony/deprecation-contracts/LICENSE
+++ b/vendor/symfony/deprecation-contracts/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2020-2022 Fabien Potencier
+Copyright (c) 2020-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/deprecation-contracts/README.md b/vendor/symfony/deprecation-contracts/README.md
index 4957933..9814864 100644
--- a/vendor/symfony/deprecation-contracts/README.md
+++ b/vendor/symfony/deprecation-contracts/README.md
@@ -22,5 +22,5 @@ trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use
This will generate the following message:
`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`
-While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
+While not recommended, the deprecation notices can be completely ignored by declaring an empty
`function trigger_deprecation() {}` in your application.
diff --git a/vendor/symfony/deprecation-contracts/composer.json b/vendor/symfony/deprecation-contracts/composer.json
index 1c1b4ba..c6d02d8 100644
--- a/vendor/symfony/deprecation-contracts/composer.json
+++ b/vendor/symfony/deprecation-contracts/composer.json
@@ -15,7 +15,7 @@
}
],
"require": {
- "php": ">=8.0.2"
+ "php": ">=8.1"
},
"autoload": {
"files": [
@@ -25,7 +25,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "3.0-dev"
+ "dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/symfony/event-dispatcher-contracts/.gitignore b/vendor/symfony/event-dispatcher-contracts/.gitignore
deleted file mode 100644
index c49a5d8..0000000
--- a/vendor/symfony/event-dispatcher-contracts/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vendor/
-composer.lock
-phpunit.xml
diff --git a/vendor/symfony/event-dispatcher-contracts/Event.php b/vendor/symfony/event-dispatcher-contracts/Event.php
index 384a650..2e7f998 100644
--- a/vendor/symfony/event-dispatcher-contracts/Event.php
+++ b/vendor/symfony/event-dispatcher-contracts/Event.php
@@ -32,9 +32,6 @@ class Event implements StoppableEventInterface
{
private bool $propagationStopped = false;
- /**
- * {@inheritdoc}
- */
public function isPropagationStopped(): bool
{
return $this->propagationStopped;
diff --git a/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php b/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php
index 351dc51..610d6ac 100644
--- a/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php
+++ b/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php
@@ -21,11 +21,13 @@ interface EventDispatcherInterface extends PsrEventDispatcherInterface
/**
* Dispatches an event to all registered listeners.
*
- * @param object $event The event to pass to the event handlers/listeners
+ * @template T of object
+ *
+ * @param T $event The event to pass to the event handlers/listeners
* @param string|null $eventName The name of the event to dispatch. If not supplied,
* the class of $event should be used instead.
*
- * @return object The passed $event MUST be returned
+ * @return T The passed $event MUST be returned
*/
public function dispatch(object $event, string $eventName = null): object;
}
diff --git a/vendor/symfony/event-dispatcher-contracts/LICENSE b/vendor/symfony/event-dispatcher-contracts/LICENSE
index 74cdc2d..7536cae 100644
--- a/vendor/symfony/event-dispatcher-contracts/LICENSE
+++ b/vendor/symfony/event-dispatcher-contracts/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018-2022 Fabien Potencier
+Copyright (c) 2018-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/event-dispatcher-contracts/README.md b/vendor/symfony/event-dispatcher-contracts/README.md
index b1ab4c0..332b961 100644
--- a/vendor/symfony/event-dispatcher-contracts/README.md
+++ b/vendor/symfony/event-dispatcher-contracts/README.md
@@ -3,7 +3,7 @@ Symfony EventDispatcher Contracts
A set of abstractions extracted out of the Symfony components.
-Can be used to build on semantics that the Symfony components proved useful - and
+Can be used to build on semantics that the Symfony components proved useful and
that already have battle tested implementations.
See https://github.com/symfony/contracts/blob/main/README.md for more information.
diff --git a/vendor/symfony/event-dispatcher-contracts/composer.json b/vendor/symfony/event-dispatcher-contracts/composer.json
index b4c3933..3618d53 100644
--- a/vendor/symfony/event-dispatcher-contracts/composer.json
+++ b/vendor/symfony/event-dispatcher-contracts/composer.json
@@ -16,19 +16,16 @@
}
],
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.1",
"psr/event-dispatcher": "^1"
},
- "suggest": {
- "symfony/event-dispatcher-implementation": ""
- },
"autoload": {
"psr-4": { "Symfony\\Contracts\\EventDispatcher\\": "" }
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "3.0-dev"
+ "dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php
index 67bc632..1163e07 100644
--- a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php
+++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\EventDispatcher\Debug;
use Psr\EventDispatcher\StoppableEventInterface;
use Psr\Log\LoggerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -29,17 +30,17 @@ use Symfony\Contracts\Service\ResetInterface;
*/
class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterface
{
- protected $logger;
- protected $stopwatch;
+ protected ?LoggerInterface $logger;
+ protected Stopwatch $stopwatch;
/**
* @var \SplObjectStorage|null
*/
private ?\SplObjectStorage $callStack = null;
- private $dispatcher;
+ private EventDispatcherInterface $dispatcher;
private array $wrappedListeners = [];
private array $orphanedEvents = [];
- private $requestStack;
+ private ?RequestStack $requestStack;
private string $currentRequestHash = '';
public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null, RequestStack $requestStack = null)
@@ -50,26 +51,17 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
$this->requestStack = $requestStack;
}
- /**
- * {@inheritdoc}
- */
- public function addListener(string $eventName, callable|array $listener, int $priority = 0)
+ public function addListener(string $eventName, callable|array $listener, int $priority = 0): void
{
$this->dispatcher->addListener($eventName, $listener, $priority);
}
- /**
- * {@inheritdoc}
- */
- public function addSubscriber(EventSubscriberInterface $subscriber)
+ public function addSubscriber(EventSubscriberInterface $subscriber): void
{
$this->dispatcher->addSubscriber($subscriber);
}
- /**
- * {@inheritdoc}
- */
- public function removeListener(string $eventName, callable|array $listener)
+ public function removeListener(string $eventName, callable|array $listener): void
{
if (isset($this->wrappedListeners[$eventName])) {
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
@@ -81,28 +73,19 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
}
}
- return $this->dispatcher->removeListener($eventName, $listener);
+ $this->dispatcher->removeListener($eventName, $listener);
}
- /**
- * {@inheritdoc}
- */
- public function removeSubscriber(EventSubscriberInterface $subscriber)
+ public function removeSubscriber(EventSubscriberInterface $subscriber): void
{
- return $this->dispatcher->removeSubscriber($subscriber);
+ $this->dispatcher->removeSubscriber($subscriber);
}
- /**
- * {@inheritdoc}
- */
public function getListeners(string $eventName = null): array
{
return $this->dispatcher->getListeners($eventName);
}
- /**
- * {@inheritdoc}
- */
public function getListenerPriority(string $eventName, callable|array $listener): ?int
{
// we might have wrapped listeners for the event (if called while dispatching)
@@ -118,24 +101,16 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
- /**
- * {@inheritdoc}
- */
public function hasListeners(string $eventName = null): bool
{
return $this->dispatcher->hasListeners($eventName);
}
- /**
- * {@inheritdoc}
- */
public function dispatch(object $event, string $eventName = null): object
{
- $eventName = $eventName ?? \get_class($event);
+ $eventName ??= $event::class;
- if (null === $this->callStack) {
- $this->callStack = new \SplObjectStorage();
- }
+ $this->callStack ??= new \SplObjectStorage();
$currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : '';
@@ -187,11 +162,9 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
public function getNotCalledListeners(Request $request = null): array
{
try {
- $allListeners = $this->getListeners();
+ $allListeners = $this->dispatcher instanceof EventDispatcher ? $this->getListenersWithPriority() : $this->getListenersWithoutPriority();
} catch (\Exception $e) {
- if (null !== $this->logger) {
- $this->logger->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]);
- }
+ $this->logger?->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]);
// unable to retrieve the uncalled listeners
return [];
@@ -211,18 +184,19 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
}
$notCalled = [];
+
foreach ($allListeners as $eventName => $listeners) {
- foreach ($listeners as $listener) {
+ foreach ($listeners as [$listener, $priority]) {
if (!\in_array($listener, $calledListeners, true)) {
if (!$listener instanceof WrappedListener) {
- $listener = new WrappedListener($listener, null, $this->stopwatch, $this);
+ $listener = new WrappedListener($listener, null, $this->stopwatch, $this, $priority);
}
$notCalled[] = $listener->getInfo($eventName);
}
}
}
- uasort($notCalled, [$this, 'sortNotCalledListeners']);
+ uasort($notCalled, $this->sortNotCalledListeners(...));
return $notCalled;
}
@@ -240,7 +214,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
return array_merge(...array_values($this->orphanedEvents));
}
- public function reset()
+ public function reset(): void
{
$this->callStack = null;
$this->orphanedEvents = [];
@@ -261,14 +235,14 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
/**
* Called before dispatching the event.
*/
- protected function beforeDispatch(string $eventName, object $event)
+ protected function beforeDispatch(string $eventName, object $event): void
{
}
/**
* Called after dispatching the event.
*/
- protected function afterDispatch(string $eventName, object $event)
+ protected function afterDispatch(string $eventName, object $event): void
{
}
@@ -308,9 +282,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
}
if ($listener->wasCalled()) {
- if (null !== $this->logger) {
- $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context);
- }
+ $this->logger?->debug('Notified event "{event}" to listener "{listener}".', $context);
} else {
$this->callStack->detach($listener);
}
@@ -320,16 +292,14 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
}
if ($listener->stoppedPropagation()) {
- if (null !== $this->logger) {
- $this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context);
- }
+ $this->logger?->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context);
$skipped = true;
}
}
}
- private function sortNotCalledListeners(array $a, array $b)
+ private function sortNotCalledListeners(array $a, array $b): int
{
if (0 !== $cmp = strcmp($a['event'], $b['event'])) {
return $cmp;
@@ -353,4 +323,34 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
return 1;
}
+
+ private function getListenersWithPriority(): array
+ {
+ $result = [];
+
+ $allListeners = new \ReflectionProperty(EventDispatcher::class, 'listeners');
+
+ foreach ($allListeners->getValue($this->dispatcher) as $eventName => $listenersByPriority) {
+ foreach ($listenersByPriority as $priority => $listeners) {
+ foreach ($listeners as $listener) {
+ $result[$eventName][] = [$listener, $priority];
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ private function getListenersWithoutPriority(): array
+ {
+ $result = [];
+
+ foreach ($this->getListeners() as $eventName => $listeners) {
+ foreach ($listeners as $listener) {
+ $result[$eventName][] = [$listener, null];
+ }
+ }
+
+ return $result;
+ }
}
diff --git a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php
index 11bd0c8..f23c963 100644
--- a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php
+++ b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php
@@ -26,28 +26,31 @@ final class WrappedListener
private string $name;
private bool $called = false;
private bool $stoppedPropagation = false;
- private $stopwatch;
- private $dispatcher;
+ private Stopwatch $stopwatch;
+ private ?EventDispatcherInterface $dispatcher;
private string $pretty;
- private $stub;
+ private string $callableRef;
+ private ClassStub|string $stub;
private ?int $priority = null;
private static bool $hasClassStub;
- public function __construct(callable|array $listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
+ public function __construct(callable|array $listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null, int $priority = null)
{
$this->listener = $listener;
- $this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? \Closure::fromCallable($listener) : null);
+ $this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? $listener(...) : null);
$this->stopwatch = $stopwatch;
$this->dispatcher = $dispatcher;
+ $this->priority = $priority;
if (\is_array($listener)) {
- $this->name = \is_object($listener[0]) ? get_debug_type($listener[0]) : $listener[0];
+ [$this->name, $this->callableRef] = $this->parseListener($listener);
$this->pretty = $this->name.'::'.$listener[1];
+ $this->callableRef .= '::'.$listener[1];
} elseif ($listener instanceof \Closure) {
$r = new \ReflectionFunction($listener);
if (str_contains($r->name, '{closure}')) {
$this->pretty = $this->name = 'closure';
- } elseif ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) {
+ } elseif ($class = $r->getClosureCalledClass()) {
$this->name = $class->name;
$this->pretty = $this->name.'::'.$r->name;
} else {
@@ -58,6 +61,7 @@ final class WrappedListener
} else {
$this->name = get_debug_type($listener);
$this->pretty = $this->name.'::__invoke';
+ $this->callableRef = $listener::class.'::__invoke';
}
if (null !== $name) {
@@ -89,11 +93,11 @@ final class WrappedListener
public function getInfo(string $eventName): array
{
- $this->stub ??= self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->listener) : $this->pretty.'()';
+ $this->stub ??= self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->callableRef ?? $this->listener) : $this->pretty.'()';
return [
'event' => $eventName,
- 'priority' => null !== $this->priority ? $this->priority : (null !== $this->dispatcher ? $this->dispatcher->getListenerPriority($eventName, $this->listener) : null),
+ 'priority' => $this->priority ??= $this->dispatcher?->getListenerPriority($eventName, $this->listener),
'pretty' => $this->pretty,
'stub' => $this->stub,
];
@@ -104,18 +108,37 @@ final class WrappedListener
$dispatcher = $this->dispatcher ?: $dispatcher;
$this->called = true;
- $this->priority = $dispatcher->getListenerPriority($eventName, $this->listener);
+ $this->priority ??= $dispatcher->getListenerPriority($eventName, $this->listener);
$e = $this->stopwatch->start($this->name, 'event_listener');
- ($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);
-
- if ($e->isStarted()) {
- $e->stop();
+ try {
+ ($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);
+ } finally {
+ if ($e->isStarted()) {
+ $e->stop();
+ }
}
if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
$this->stoppedPropagation = true;
}
}
+
+ private function parseListener(array $listener): array
+ {
+ if ($listener[0] instanceof \Closure) {
+ foreach ((new \ReflectionFunction($listener[0]))->getAttributes(\Closure::class) as $attribute) {
+ if ($name = $attribute->getArguments()['name'] ?? false) {
+ return [$name, $attribute->getArguments()['class'] ?? $name];
+ }
+ }
+ }
+
+ if (\is_object($listener[0])) {
+ return [get_debug_type($listener[0]), $listener[0]::class];
+ }
+
+ return [$listener[0], $listener[0]];
+ }
}
diff --git a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php
index 90bdeb4..29a76bb 100644
--- a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php
+++ b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php
@@ -48,7 +48,7 @@ class RegisterListenersPass implements CompilerPassInterface
return $this;
}
- public function process(ContainerBuilder $container)
+ public function process(ContainerBuilder $container): void
{
if (!$container->hasDefinition('event_dispatcher') && !$container->hasAlias('event_dispatcher')) {
return;
@@ -73,7 +73,7 @@ class RegisterListenersPass implements CompilerPassInterface
continue;
}
- $event['method'] = $event['method'] ?? '__invoke';
+ $event['method'] ??= '__invoke';
$event['event'] = $this->getEventFromTypeDeclaration($container, $id, $event['method']);
}
@@ -83,17 +83,21 @@ class RegisterListenersPass implements CompilerPassInterface
$event['method'] = 'on'.preg_replace_callback([
'/(?<=\b|_)[a-z]/i',
'/[^a-z0-9]/i',
- ], function ($matches) { return strtoupper($matches[0]); }, $event['event']);
+ ], fn ($matches) => strtoupper($matches[0]), $event['event']);
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
- if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method']) && $r->hasMethod('__invoke')) {
+ if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) {
+ if (!$r->hasMethod('__invoke')) {
+ throw new InvalidArgumentException(sprintf('None of the "%s" or "__invoke" methods exist for the service "%s". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id));
+ }
+
$event['method'] = '__invoke';
}
}
$dispatcherDefinition = $globalDispatcherDefinition;
if (isset($event['dispatcher'])) {
- $dispatcherDefinition = $container->getDefinition($event['dispatcher']);
+ $dispatcherDefinition = $container->findDefinition($event['dispatcher']);
}
$dispatcherDefinition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]);
@@ -132,7 +136,7 @@ class RegisterListenersPass implements CompilerPassInterface
continue;
}
- $dispatcherDefinitions[$attributes['dispatcher']] = $container->getDefinition($attributes['dispatcher']);
+ $dispatcherDefinitions[$attributes['dispatcher']] = $container->findDefinition($attributes['dispatcher']);
}
if (!$dispatcherDefinitions) {
@@ -191,7 +195,7 @@ class ExtractingEventDispatcher extends EventDispatcher implements EventSubscrib
public static array $aliases = [];
public static string $subscriber;
- public function addListener(string $eventName, callable|array $listener, int $priority = 0)
+ public function addListener(string $eventName, callable|array $listener, int $priority = 0): void
{
$this->listeners[] = [$eventName, $listener[1], $priority];
}
diff --git a/vendor/symfony/event-dispatcher/EventDispatcher.php b/vendor/symfony/event-dispatcher/EventDispatcher.php
index 1812c98..65d8626 100644
--- a/vendor/symfony/event-dispatcher/EventDispatcher.php
+++ b/vendor/symfony/event-dispatcher/EventDispatcher.php
@@ -42,12 +42,9 @@ class EventDispatcher implements EventDispatcherInterface
}
}
- /**
- * {@inheritdoc}
- */
public function dispatch(object $event, string $eventName = null): object
{
- $eventName = $eventName ?? \get_class($event);
+ $eventName ??= $event::class;
if (isset($this->optimized)) {
$listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName));
@@ -62,9 +59,6 @@ class EventDispatcher implements EventDispatcherInterface
return $event;
}
- /**
- * {@inheritdoc}
- */
public function getListeners(string $eventName = null): array
{
if (null !== $eventName) {
@@ -88,9 +82,6 @@ class EventDispatcher implements EventDispatcherInterface
return array_filter($this->sorted);
}
- /**
- * {@inheritdoc}
- */
public function getListenerPriority(string $eventName, callable|array $listener): ?int
{
if (empty($this->listeners[$eventName])) {
@@ -99,14 +90,14 @@ class EventDispatcher implements EventDispatcherInterface
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
$listener[0] = $listener[0]();
- $listener[1] = $listener[1] ?? '__invoke';
+ $listener[1] ??= '__invoke';
}
foreach ($this->listeners[$eventName] as $priority => &$listeners) {
foreach ($listeners as &$v) {
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) {
$v[0] = $v[0]();
- $v[1] = $v[1] ?? '__invoke';
+ $v[1] ??= '__invoke';
}
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
return $priority;
@@ -117,9 +108,6 @@ class EventDispatcher implements EventDispatcherInterface
return null;
}
- /**
- * {@inheritdoc}
- */
public function hasListeners(string $eventName = null): bool
{
if (null !== $eventName) {
@@ -135,19 +123,13 @@ class EventDispatcher implements EventDispatcherInterface
return false;
}
- /**
- * {@inheritdoc}
- */
- public function addListener(string $eventName, callable|array $listener, int $priority = 0)
+ public function addListener(string $eventName, callable|array $listener, int $priority = 0): void
{
$this->listeners[$eventName][$priority][] = $listener;
unset($this->sorted[$eventName], $this->optimized[$eventName]);
}
- /**
- * {@inheritdoc}
- */
- public function removeListener(string $eventName, callable|array $listener)
+ public function removeListener(string $eventName, callable|array $listener): void
{
if (empty($this->listeners[$eventName])) {
return;
@@ -155,14 +137,14 @@ class EventDispatcher implements EventDispatcherInterface
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
$listener[0] = $listener[0]();
- $listener[1] = $listener[1] ?? '__invoke';
+ $listener[1] ??= '__invoke';
}
foreach ($this->listeners[$eventName] as $priority => &$listeners) {
foreach ($listeners as $k => &$v) {
if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) {
$v[0] = $v[0]();
- $v[1] = $v[1] ?? '__invoke';
+ $v[1] ??= '__invoke';
}
if ($v === $listener || ($listener instanceof \Closure && $v == $listener)) {
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
@@ -175,10 +157,7 @@ class EventDispatcher implements EventDispatcherInterface
}
}
- /**
- * {@inheritdoc}
- */
- public function addSubscriber(EventSubscriberInterface $subscriber)
+ public function addSubscriber(EventSubscriberInterface $subscriber): void
{
foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
if (\is_string($params)) {
@@ -193,10 +172,7 @@ class EventDispatcher implements EventDispatcherInterface
}
}
- /**
- * {@inheritdoc}
- */
- public function removeSubscriber(EventSubscriberInterface $subscriber)
+ public function removeSubscriber(EventSubscriberInterface $subscriber): void
{
foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
if (\is_array($params) && \is_array($params[0])) {
@@ -219,7 +195,7 @@ class EventDispatcher implements EventDispatcherInterface
* @param string $eventName The name of the event to dispatch
* @param object $event The event object to pass to the event handlers/listeners
*/
- protected function callListeners(iterable $listeners, string $eventName, object $event)
+ protected function callListeners(iterable $listeners, string $eventName, object $event): void
{
$stoppable = $event instanceof StoppableEventInterface;
@@ -234,16 +210,16 @@ class EventDispatcher implements EventDispatcherInterface
/**
* Sorts the internal list of listeners for the given event by priority.
*/
- private function sortListeners(string $eventName)
+ private function sortListeners(string $eventName): void
{
krsort($this->listeners[$eventName]);
$this->sorted[$eventName] = [];
foreach ($this->listeners[$eventName] as &$listeners) {
- foreach ($listeners as $k => &$listener) {
+ foreach ($listeners as &$listener) {
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
$listener[0] = $listener[0]();
- $listener[1] = $listener[1] ?? '__invoke';
+ $listener[1] ??= '__invoke';
}
$this->sorted[$eventName][] = $listener;
}
@@ -265,12 +241,12 @@ class EventDispatcher implements EventDispatcherInterface
$closure = static function (...$args) use (&$listener, &$closure) {
if ($listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
- $listener[1] = $listener[1] ?? '__invoke';
+ $listener[1] ??= '__invoke';
}
- ($closure = \Closure::fromCallable($listener))(...$args);
+ ($closure = $listener(...))(...$args);
};
} else {
- $closure = $listener instanceof \Closure || $listener instanceof WrappedListener ? $listener : \Closure::fromCallable($listener);
+ $closure = $listener instanceof WrappedListener ? $listener : $listener(...);
}
}
}
diff --git a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php
index 97a3017..6d4a5b4 100644
--- a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php
+++ b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php
@@ -28,7 +28,7 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface
* @param int $priority The higher this value, the earlier an event
* listener will be triggered in the chain (defaults to 0)
*/
- public function addListener(string $eventName, callable $listener, int $priority = 0);
+ public function addListener(string $eventName, callable $listener, int $priority = 0): void;
/**
* Adds an event subscriber.
@@ -36,14 +36,14 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface
* The subscriber is asked for all the events it is
* interested in and added as a listener for these events.
*/
- public function addSubscriber(EventSubscriberInterface $subscriber);
+ public function addSubscriber(EventSubscriberInterface $subscriber): void;
/**
* Removes an event listener from the specified events.
*/
- public function removeListener(string $eventName, callable $listener);
+ public function removeListener(string $eventName, callable $listener): void;
- public function removeSubscriber(EventSubscriberInterface $subscriber);
+ public function removeSubscriber(EventSubscriberInterface $subscriber): void;
/**
* Gets the listeners of a specific event or all listeners sorted by descending priority.
diff --git a/vendor/symfony/event-dispatcher/GenericEvent.php b/vendor/symfony/event-dispatcher/GenericEvent.php
index 68a2030..b14faa5 100644
--- a/vendor/symfony/event-dispatcher/GenericEvent.php
+++ b/vendor/symfony/event-dispatcher/GenericEvent.php
@@ -25,8 +25,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
{
- protected $subject;
- protected $arguments;
+ protected mixed $subject;
+ protected array $arguments;
/**
* Encapsulate an event with $subject and $args.
diff --git a/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
index 655ae3d..1e863cc 100644
--- a/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
+++ b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
@@ -18,72 +18,48 @@ namespace Symfony\Component\EventDispatcher;
*/
class ImmutableEventDispatcher implements EventDispatcherInterface
{
- private $dispatcher;
+ private EventDispatcherInterface $dispatcher;
public function __construct(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
- /**
- * {@inheritdoc}
- */
public function dispatch(object $event, string $eventName = null): object
{
return $this->dispatcher->dispatch($event, $eventName);
}
- /**
- * {@inheritdoc}
- */
- public function addListener(string $eventName, callable|array $listener, int $priority = 0)
+ public function addListener(string $eventName, callable|array $listener, int $priority = 0): never
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
- /**
- * {@inheritdoc}
- */
- public function addSubscriber(EventSubscriberInterface $subscriber)
+ public function addSubscriber(EventSubscriberInterface $subscriber): never
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
- /**
- * {@inheritdoc}
- */
- public function removeListener(string $eventName, callable|array $listener)
+ public function removeListener(string $eventName, callable|array $listener): never
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
- /**
- * {@inheritdoc}
- */
- public function removeSubscriber(EventSubscriberInterface $subscriber)
+ public function removeSubscriber(EventSubscriberInterface $subscriber): never
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
- /**
- * {@inheritdoc}
- */
public function getListeners(string $eventName = null): array
{
return $this->dispatcher->getListeners($eventName);
}
- /**
- * {@inheritdoc}
- */
public function getListenerPriority(string $eventName, callable|array $listener): ?int
{
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
- /**
- * {@inheritdoc}
- */
public function hasListeners(string $eventName = null): bool
{
return $this->dispatcher->hasListeners($eventName);
diff --git a/vendor/symfony/event-dispatcher/LICENSE b/vendor/symfony/event-dispatcher/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/event-dispatcher/LICENSE
+++ b/vendor/symfony/event-dispatcher/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/event-dispatcher/composer.json b/vendor/symfony/event-dispatcher/composer.json
index 53a86ee..598bbdc 100644
--- a/vendor/symfony/event-dispatcher/composer.json
+++ b/vendor/symfony/event-dispatcher/composer.json
@@ -16,30 +16,27 @@
}
],
"require": {
- "php": ">=8.0.2",
- "symfony/event-dispatcher-contracts": "^2|^3"
+ "php": ">=8.2",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
},
"require-dev": {
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/config": "^5.4|^6.0",
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/http-foundation": "^5.4|^6.0",
- "symfony/service-contracts": "^1.1|^2|^3",
- "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^6.4|^7.0",
"psr/log": "^1|^2|^3"
},
"conflict": {
- "symfony/dependency-injection": "<5.4"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/service-contracts": "<2.5"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0",
"symfony/event-dispatcher-implementation": "2.0|3.0"
},
- "suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
- },
"autoload": {
"psr-4": { "Symfony\\Component\\EventDispatcher\\": "" },
"exclude-from-classmap": [
diff --git a/vendor/symfony/filesystem/CHANGELOG.md b/vendor/symfony/filesystem/CHANGELOG.md
index fcb7170..b4bd22e 100644
--- a/vendor/symfony/filesystem/CHANGELOG.md
+++ b/vendor/symfony/filesystem/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+7.0
+---
+
+ * Add argument `$lock` to `Filesystem::appendToFile()`
+
5.4
---
diff --git a/vendor/symfony/filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Exception/IOException.php
index bcca860..a3c5445 100644
--- a/vendor/symfony/filesystem/Exception/IOException.php
+++ b/vendor/symfony/filesystem/Exception/IOException.php
@@ -29,9 +29,6 @@ class IOException extends \RuntimeException implements IOExceptionInterface
parent::__construct($message, $code, $previous);
}
- /**
- * {@inheritdoc}
- */
public function getPath(): ?string
{
return $this->path;
diff --git a/vendor/symfony/filesystem/Filesystem.php b/vendor/symfony/filesystem/Filesystem.php
index c96ed6a..e8ba495 100644
--- a/vendor/symfony/filesystem/Filesystem.php
+++ b/vendor/symfony/filesystem/Filesystem.php
@@ -22,7 +22,7 @@ use Symfony\Component\Filesystem\Exception\IOException;
*/
class Filesystem
{
- private static $lastError;
+ private static ?string $lastError = null;
/**
* Copies a file.
@@ -34,7 +34,7 @@ class Filesystem
* @throws FileNotFoundException When originFile doesn't exist
* @throws IOException When copy fails
*/
- public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false)
+ public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false): void
{
$originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
if ($originIsLocal && !is_file($originFile)) {
@@ -84,7 +84,7 @@ class Filesystem
*
* @throws IOException On any directory creation failure
*/
- public function mkdir(string|iterable $dirs, int $mode = 0777)
+ public function mkdir(string|iterable $dirs, int $mode = 0777): void
{
foreach ($this->toIterable($dirs) as $dir) {
if (is_dir($dir)) {
@@ -125,7 +125,7 @@ class Filesystem
*
* @throws IOException When touch fails
*/
- public function touch(string|iterable $files, int $time = null, int $atime = null)
+ public function touch(string|iterable $files, int $time = null, int $atime = null): void
{
foreach ($this->toIterable($files) as $file) {
if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) {
@@ -139,7 +139,7 @@ class Filesystem
*
* @throws IOException When removal fails
*/
- public function remove(string|iterable $files)
+ public function remove(string|iterable $files): void
{
if ($files instanceof \Traversable) {
$files = iterator_to_array($files, false);
@@ -161,12 +161,12 @@ class Filesystem
}
} elseif (is_dir($file)) {
if (!$isRecursive) {
- $tmpName = \dirname(realpath($file)).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-.'));
+ $tmpName = \dirname(realpath($file)).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-_'));
if (file_exists($tmpName)) {
try {
self::doRemove([$tmpName], true);
- } catch (IOException $e) {
+ } catch (IOException) {
}
}
@@ -178,8 +178,8 @@ class Filesystem
}
}
- $files = new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS);
- self::doRemove(iterator_to_array($files, true), true);
+ $filesystemIterator = new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS);
+ self::doRemove(iterator_to_array($filesystemIterator, true), true);
if (!self::box('rmdir', $file) && file_exists($file) && !$isRecursive) {
$lastError = self::$lastError;
@@ -205,10 +205,10 @@ class Filesystem
*
* @throws IOException When the change fails
*/
- public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false)
+ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false): void
{
foreach ($this->toIterable($files) as $file) {
- if (\is_int($mode) && !self::box('chmod', $file, $mode & ~$umask)) {
+ if (!self::box('chmod', $file, $mode & ~$umask)) {
throw new IOException(sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file);
}
if ($recursive && is_dir($file) && !is_link($file)) {
@@ -225,7 +225,7 @@ class Filesystem
*
* @throws IOException When the change fails
*/
- public function chown(string|iterable $files, string|int $user, bool $recursive = false)
+ public function chown(string|iterable $files, string|int $user, bool $recursive = false): void
{
foreach ($this->toIterable($files) as $file) {
if ($recursive && is_dir($file) && !is_link($file)) {
@@ -251,7 +251,7 @@ class Filesystem
*
* @throws IOException When the change fails
*/
- public function chgrp(string|iterable $files, string|int $group, bool $recursive = false)
+ public function chgrp(string|iterable $files, string|int $group, bool $recursive = false): void
{
foreach ($this->toIterable($files) as $file) {
if ($recursive && is_dir($file) && !is_link($file)) {
@@ -275,7 +275,7 @@ class Filesystem
* @throws IOException When target file or directory already exists
* @throws IOException When origin cannot be renamed
*/
- public function rename(string $origin, string $target, bool $overwrite = false)
+ public function rename(string $origin, string $target, bool $overwrite = false): void
{
// we check that target does not exist
if (!$overwrite && $this->isReadable($target)) {
@@ -315,7 +315,7 @@ class Filesystem
*
* @throws IOException When symlink fails
*/
- public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false)
+ public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false): void
{
self::assertFunctionExists('symlink');
@@ -352,7 +352,7 @@ class Filesystem
* @throws FileNotFoundException When original file is missing or not a file
* @throws IOException When link fails, including if link already exists
*/
- public function hardlink(string $originFile, string|iterable $targetFiles)
+ public function hardlink(string $originFile, string|iterable $targetFiles): void
{
self::assertFunctionExists('link');
@@ -381,7 +381,7 @@ class Filesystem
/**
* @param string $linkType Name of the link type, typically 'symbolic' or 'hard'
*/
- private function linkException(string $origin, string $target, string $linkType)
+ private function linkException(string $origin, string $target, string $linkType): never
{
if (self::$lastError) {
if ('\\' === \DIRECTORY_SEPARATOR && str_contains(self::$lastError, 'error code(1314)')) {
@@ -438,11 +438,9 @@ class Filesystem
$startPath = str_replace('\\', '/', $startPath);
}
- $splitDriveLetter = function ($path) {
- return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
- ? [substr($path, 2), strtoupper($path[0])]
- : [$path, null];
- };
+ $splitDriveLetter = fn ($path) => (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
+ ? [substr($path, 2), strtoupper($path[0])]
+ : [$path, null];
$splitPath = function ($path) {
$result = [];
@@ -510,7 +508,7 @@ class Filesystem
*
* @throws IOException When file type is unknown
*/
- public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = [])
+ public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = []): void
{
$targetDir = rtrim($targetDir, '/\\');
$originDir = rtrim($originDir, '/\\');
@@ -634,7 +632,7 @@ class Filesystem
*
* @throws IOException if the file cannot be written to
*/
- public function dumpFile(string $filename, $content)
+ public function dumpFile(string $filename, $content): void
{
if (\is_array($content)) {
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
@@ -642,6 +640,12 @@ class Filesystem
$dir = \dirname($filename);
+ if (is_link($filename) && $linkTarget = $this->readlink($filename)) {
+ $this->dumpFile(Path::makeAbsolute($linkTarget, $dir), $content);
+
+ return;
+ }
+
if (!is_dir($dir)) {
$this->mkdir($dir);
}
@@ -673,7 +677,7 @@ class Filesystem
*
* @throws IOException If the file is not writable
*/
- public function appendToFile(string $filename, $content/* , bool $lock = false */)
+ public function appendToFile(string $filename, $content, bool $lock = false): void
{
if (\is_array($content)) {
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
@@ -685,8 +689,6 @@ class Filesystem
$this->mkdir($dir);
}
- $lock = \func_num_args() > 2 && func_get_arg(2);
-
if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) {
throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename);
}
@@ -719,7 +721,7 @@ class Filesystem
self::assertFunctionExists($func);
self::$lastError = null;
- set_error_handler(__CLASS__.'::handleError');
+ set_error_handler(self::handleError(...));
try {
return $func(...$args);
} finally {
@@ -730,7 +732,7 @@ class Filesystem
/**
* @internal
*/
- public static function handleError(int $type, string $msg)
+ public static function handleError(int $type, string $msg): void
{
self::$lastError = $msg;
}
diff --git a/vendor/symfony/filesystem/LICENSE b/vendor/symfony/filesystem/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/filesystem/LICENSE
+++ b/vendor/symfony/filesystem/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/filesystem/Path.php b/vendor/symfony/filesystem/Path.php
index 9aa3735..6643962 100644
--- a/vendor/symfony/filesystem/Path.php
+++ b/vendor/symfony/filesystem/Path.php
@@ -42,12 +42,9 @@ final class Path
*
* @var array
*/
- private static $buffer = [];
+ private static array $buffer = [];
- /**
- * @var int
- */
- private static $bufferSize = 0;
+ private static int $bufferSize = 0;
/**
* Canonicalizes the given path.
@@ -574,7 +571,7 @@ final class Path
*/
public static function isLocal(string $path): bool
{
- return '' !== $path && false === strpos($path, '://');
+ return '' !== $path && !str_contains($path, '://');
}
/**
@@ -638,7 +635,7 @@ final class Path
// Prevent false positives for common prefixes
// see isBasePath()
- if (0 === strpos($path.'/', $basePath.'/')) {
+ if (str_starts_with($path.'/', $basePath.'/')) {
// next path
continue 2;
}
@@ -666,7 +663,7 @@ final class Path
if (null === $finalPath) {
// For first part we keep slashes, like '/top', 'C:\' or 'phar://'
$finalPath = $path;
- $wasScheme = (false !== strpos($path, '://'));
+ $wasScheme = str_contains($path, '://');
continue;
}
@@ -717,7 +714,7 @@ final class Path
// Don't append a slash for the root "/", because then that root
// won't be discovered as common prefix ("//" is not a prefix of
// "/foobar/").
- return 0 === strpos($ofPath.'/', rtrim($basePath, '/').'/');
+ return str_starts_with($ofPath.'/', rtrim($basePath, '/').'/');
}
/**
@@ -786,7 +783,7 @@ final class Path
$length = \strlen($path);
// Remove and remember root directory
- if (0 === strpos($path, '/')) {
+ if (str_starts_with($path, '/')) {
$root .= '/';
$path = $length > 1 ? substr($path, 1) : '';
} elseif ($length > 1 && ctype_alpha($path[0]) && ':' === $path[1]) {
diff --git a/vendor/symfony/filesystem/composer.json b/vendor/symfony/filesystem/composer.json
index 607dde3..1e054b6 100644
--- a/vendor/symfony/filesystem/composer.json
+++ b/vendor/symfony/filesystem/composer.json
@@ -16,7 +16,7 @@
}
],
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
diff --git a/vendor/symfony/finder/CHANGELOG.md b/vendor/symfony/finder/CHANGELOG.md
index 9e2fc5a..e838302 100644
--- a/vendor/symfony/finder/CHANGELOG.md
+++ b/vendor/symfony/finder/CHANGELOG.md
@@ -1,6 +1,17 @@
CHANGELOG
=========
+6.4
+---
+
+ * Add early directory pruning to `Finder::filter()`
+
+6.2
+---
+
+ * Add `Finder::sortByExtension()` and `Finder::sortBySize()`
+ * Add `Finder::sortByCaseInsensitiveName()` to sort by name with case insensitive sorting methods
+
6.0
---
diff --git a/vendor/symfony/finder/Comparator/Comparator.php b/vendor/symfony/finder/Comparator/Comparator.php
index f1ba97d..bd68583 100644
--- a/vendor/symfony/finder/Comparator/Comparator.php
+++ b/vendor/symfony/finder/Comparator/Comparator.php
@@ -50,19 +50,13 @@ class Comparator
*/
public function test(mixed $test): bool
{
- switch ($this->operator) {
- case '>':
- return $test > $this->target;
- case '>=':
- return $test >= $this->target;
- case '<':
- return $test < $this->target;
- case '<=':
- return $test <= $this->target;
- case '!=':
- return $test != $this->target;
- }
-
- return $test == $this->target;
+ return match ($this->operator) {
+ '>' => $test > $this->target,
+ '>=' => $test >= $this->target,
+ '<' => $test < $this->target,
+ '<=' => $test <= $this->target,
+ '!=' => $test != $this->target,
+ default => $test == $this->target,
+ };
}
}
diff --git a/vendor/symfony/finder/Comparator/DateComparator.php b/vendor/symfony/finder/Comparator/DateComparator.php
index 8f651e1..e0c523d 100644
--- a/vendor/symfony/finder/Comparator/DateComparator.php
+++ b/vendor/symfony/finder/Comparator/DateComparator.php
@@ -30,9 +30,9 @@ class DateComparator extends Comparator
}
try {
- $date = new \DateTime($matches[2]);
+ $date = new \DateTimeImmutable($matches[2]);
$target = $date->format('U');
- } catch (\Exception $e) {
+ } catch (\Exception) {
throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
}
diff --git a/vendor/symfony/finder/Comparator/NumberComparator.php b/vendor/symfony/finder/Comparator/NumberComparator.php
index ff85d96..dd30820 100644
--- a/vendor/symfony/finder/Comparator/NumberComparator.php
+++ b/vendor/symfony/finder/Comparator/NumberComparator.php
@@ -35,7 +35,7 @@ namespace Symfony\Component\Finder\Comparator;
class NumberComparator extends Comparator
{
/**
- * @param string|int $test A comparison string or an integer
+ * @param string|null $test A comparison string or null
*
* @throws \InvalidArgumentException If the test is not understood
*/
diff --git a/vendor/symfony/finder/Finder.php b/vendor/symfony/finder/Finder.php
index e5772c4..d062a60 100644
--- a/vendor/symfony/finder/Finder.php
+++ b/vendor/symfony/finder/Finder.php
@@ -50,6 +50,7 @@ class Finder implements \IteratorAggregate, \Countable
private array $notNames = [];
private array $exclude = [];
private array $filters = [];
+ private array $pruneFilters = [];
private array $depths = [];
private array $sizes = [];
private bool $followLinks = false;
@@ -162,8 +163,8 @@ class Finder implements \IteratorAggregate, \Countable
*
* You can use patterns (delimited with / sign), globs or simple strings.
*
- * $finder->name('*.php')
- * $finder->name('/\.php$/') // same as above
+ * $finder->name('/\.php$/')
+ * $finder->name('*.php') // same as above, without dot files
* $finder->name('test.php')
* $finder->name(['test.py', 'test.php'])
*
@@ -397,7 +398,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @param string|string[] $pattern VCS patterns to ignore
*/
- public static function addVCSPattern(string|array $pattern)
+ public static function addVCSPattern(string|array $pattern): void
{
foreach ((array) $pattern as $p) {
self::$vcsPatterns[] = $p;
@@ -424,6 +425,22 @@ class Finder implements \IteratorAggregate, \Countable
return $this;
}
+ /**
+ * Sorts files and directories by extension.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return $this
+ *
+ * @see SortableIterator
+ */
+ public function sortByExtension(): static
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_EXTENSION;
+
+ return $this;
+ }
+
/**
* Sorts files and directories by name.
*
@@ -440,6 +457,38 @@ class Finder implements \IteratorAggregate, \Countable
return $this;
}
+ /**
+ * Sorts files and directories by name case insensitive.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return $this
+ *
+ * @see SortableIterator
+ */
+ public function sortByCaseInsensitiveName(bool $useNaturalSort = false): static
+ {
+ $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : Iterator\SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE;
+
+ return $this;
+ }
+
+ /**
+ * Sorts files and directories by size.
+ *
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
+ *
+ * @return $this
+ *
+ * @see SortableIterator
+ */
+ public function sortBySize(): static
+ {
+ $this->sort = Iterator\SortableIterator::SORT_BY_SIZE;
+
+ return $this;
+ }
+
/**
* Sorts files and directories by type (directories before files), then by name.
*
@@ -530,14 +579,21 @@ class Finder implements \IteratorAggregate, \Countable
* The anonymous function receives a \SplFileInfo and must return false
* to remove files.
*
+ * @param \Closure(SplFileInfo): bool $closure
+ * @param bool $prune Whether to skip traversing directories further
+ *
* @return $this
*
* @see CustomFilterIterator
*/
- public function filter(\Closure $closure): static
+ public function filter(\Closure $closure, bool $prune = false): static
{
$this->filters[] = $closure;
+ if ($prune) {
+ $this->pruneFilters[] = $closure;
+ }
+
return $this;
}
@@ -585,7 +641,7 @@ class Finder implements \IteratorAggregate, \Countable
$resolvedDirs[] = [$this->normalizeDir($dir)];
} elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0) | \GLOB_ONLYDIR | \GLOB_NOSORT)) {
sort($glob);
- $resolvedDirs[] = array_map([$this, 'normalizeDir'], $glob);
+ $resolvedDirs[] = array_map($this->normalizeDir(...), $glob);
} else {
throw new DirectoryNotFoundException(sprintf('The "%s" directory does not exist.', $dir));
}
@@ -623,9 +679,7 @@ class Finder implements \IteratorAggregate, \Countable
$iterator = new \AppendIterator();
foreach ($this->dirs as $dir) {
- $iterator->append(new \IteratorIterator(new LazyIterator(function () use ($dir) {
- return $this->searchInDirectory($dir);
- })));
+ $iterator->append(new \IteratorIterator(new LazyIterator(fn () => $this->searchInDirectory($dir))));
}
foreach ($this->iterators as $it) {
@@ -693,6 +747,10 @@ class Finder implements \IteratorAggregate, \Countable
$exclude = $this->exclude;
$notPaths = $this->notPaths;
+ if ($this->pruneFilters) {
+ $exclude = array_merge($exclude, $this->pruneFilters);
+ }
+
if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
$exclude = array_merge($exclude, self::$vcsPatterns);
}
diff --git a/vendor/symfony/finder/Gitignore.php b/vendor/symfony/finder/Gitignore.php
index d42cca1..bf05c5b 100644
--- a/vendor/symfony/finder/Gitignore.php
+++ b/vendor/symfony/finder/Gitignore.php
@@ -43,7 +43,7 @@ class Gitignore
foreach ($gitignoreLines as $line) {
$line = preg_replace('~(? '['.('' !== $matches[1] ? '^' : '').str_replace('\\-', '-', $matches[2]).']', $regex);
$regex = preg_replace('~(?:(?:\\\\\*){2,}(/?))+~', '(?:(?:(?!//).(?
*
- * @extends \FilterIterator
- * @implements \RecursiveIterator
+ * @extends \FilterIterator
+ *
+ * @implements \RecursiveIterator
*/
class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator
{
+ /** @var \Iterator */
private \Iterator $iterator;
private bool $isRecursive;
+ /** @var array */
private array $excludedDirs = [];
private ?string $excludedPattern = null;
+ /** @var list */
+ private array $pruneFilters = [];
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param string[] $directories An array of directories to exclude
+ * @param \Iterator $iterator The Iterator to filter
+ * @param list $directories An array of directories to exclude
*/
public function __construct(\Iterator $iterator, array $directories)
{
@@ -36,6 +43,16 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \Recursi
$this->isRecursive = $iterator instanceof \RecursiveIterator;
$patterns = [];
foreach ($directories as $directory) {
+ if (!\is_string($directory)) {
+ if (!\is_callable($directory)) {
+ throw new \InvalidArgumentException('Invalid PHP callback.');
+ }
+
+ $this->pruneFilters[] = $directory;
+
+ continue;
+ }
+
$directory = rtrim($directory, '/');
if (!$this->isRecursive || str_contains($directory, '/')) {
$patterns[] = preg_quote($directory, '#');
@@ -66,6 +83,14 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \Recursi
return !preg_match($this->excludedPattern, $path);
}
+ if ($this->pruneFilters && $this->hasChildren()) {
+ foreach ($this->pruneFilters as $pruneFilter) {
+ if (!$pruneFilter($this->current())) {
+ return false;
+ }
+ }
+ }
+
return true;
}
diff --git a/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php b/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
index 2ed48fb..2130378 100644
--- a/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
+++ b/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
@@ -26,8 +26,8 @@ class FileTypeFilterIterator extends \FilterIterator
private int $mode;
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
+ * @param \Iterator $iterator The Iterator to filter
+ * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
*/
public function __construct(\Iterator $iterator, int $mode)
{
diff --git a/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php b/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
index eaa7a5d..bdc71ff 100644
--- a/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
+++ b/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
@@ -11,13 +11,15 @@
namespace Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\SplFileInfo;
+
/**
* FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
*
* @author Fabien Potencier
* @author Włodzimierz Gajda
*
- * @extends MultiplePcreFilterIterator
+ * @extends MultiplePcreFilterIterator
*/
class FilecontentFilterIterator extends MultiplePcreFilterIterator
{
diff --git a/vendor/symfony/finder/Iterator/LazyIterator.php b/vendor/symfony/finder/Iterator/LazyIterator.php
index 71c4be8..5b5806b 100644
--- a/vendor/symfony/finder/Iterator/LazyIterator.php
+++ b/vendor/symfony/finder/Iterator/LazyIterator.php
@@ -22,7 +22,7 @@ class LazyIterator implements \IteratorAggregate
public function __construct(callable $iteratorFactory)
{
- $this->iteratorFactory = $iteratorFactory instanceof \Closure ? $iteratorFactory : \Closure::fromCallable($iteratorFactory);
+ $this->iteratorFactory = $iteratorFactory(...);
}
public function getIterator(): \Traversable
diff --git a/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
index 1e9e7ff..3450c49 100644
--- a/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
+++ b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
@@ -23,13 +23,13 @@ namespace Symfony\Component\Finder\Iterator;
*/
abstract class MultiplePcreFilterIterator extends \FilterIterator
{
- protected $matchRegexps = [];
- protected $noMatchRegexps = [];
+ protected array $matchRegexps = [];
+ protected array $noMatchRegexps = [];
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param string[] $matchPatterns An array of patterns that need to match
- * @param string[] $noMatchPatterns An array of patterns that need to not match
+ * @param \Iterator $iterator The Iterator to filter
+ * @param string[] $matchPatterns An array of patterns that need to match
+ * @param string[] $noMatchPatterns An array of patterns that need to not match
*/
public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
{
@@ -80,11 +80,7 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
*/
protected function isRegex(string $str): bool
{
- $availableModifiers = 'imsxuADU';
-
- if (\PHP_VERSION_ID >= 80200) {
- $availableModifiers .= 'n';
- }
+ $availableModifiers = 'imsxuADUn';
if (preg_match('/^(.{3,}?)['.$availableModifiers.']*$/', $str, $m)) {
$start = substr($m[1], 0, 1);
diff --git a/vendor/symfony/finder/Iterator/PathFilterIterator.php b/vendor/symfony/finder/Iterator/PathFilterIterator.php
index bfe402a..c6d5813 100644
--- a/vendor/symfony/finder/Iterator/PathFilterIterator.php
+++ b/vendor/symfony/finder/Iterator/PathFilterIterator.php
@@ -11,13 +11,15 @@
namespace Symfony\Component\Finder\Iterator;
+use Symfony\Component\Finder\SplFileInfo;
+
/**
* PathFilterIterator filters files by path patterns (e.g. some/special/dir).
*
* @author Fabien Potencier
* @author Włodzimierz Gajda
*
- * @extends MultiplePcreFilterIterator
+ * @extends MultiplePcreFilterIterator
*/
class PathFilterIterator extends MultiplePcreFilterIterator
{
diff --git a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
index 4c9779f..34cced6 100644
--- a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
+++ b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
@@ -18,11 +18,13 @@ use Symfony\Component\Finder\SplFileInfo;
* Extends the \RecursiveDirectoryIterator to support relative paths.
*
* @author Victor Berchet
+ *
+ * @extends \RecursiveDirectoryIterator
*/
class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
{
private bool $ignoreUnreadableDirs;
- private ?bool $rewindable = null;
+ private bool $ignoreFirstRewind = true;
// these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
private string $rootPath;
@@ -81,7 +83,7 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
parent::getChildren();
return true;
- } catch (\UnexpectedValueException $e) {
+ } catch (\UnexpectedValueException) {
// If directory is unreadable and finder is set to ignore it, skip children
return false;
}
@@ -100,7 +102,6 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
$children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
// performance optimization to avoid redoing the same work in all children
- $children->rewindable = &$this->rewindable;
$children->rootPath = $this->rootPath;
}
@@ -110,36 +111,23 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
}
}
- /**
- * Do nothing for non rewindable stream.
- */
+ public function next(): void
+ {
+ $this->ignoreFirstRewind = false;
+
+ parent::next();
+ }
+
public function rewind(): void
{
- if (false === $this->isRewindable()) {
+ // some streams like FTP are not rewindable, ignore the first rewind after creation,
+ // as newly created DirectoryIterator does not need to be rewound
+ if ($this->ignoreFirstRewind) {
+ $this->ignoreFirstRewind = false;
+
return;
}
parent::rewind();
}
-
- /**
- * Checks if the stream is rewindable.
- */
- public function isRewindable(): bool
- {
- if (null !== $this->rewindable) {
- return $this->rewindable;
- }
-
- if (false !== $stream = @opendir($this->getPath())) {
- $infos = stream_get_meta_data($stream);
- closedir($stream);
-
- if ($infos['seekable']) {
- return $this->rewindable = true;
- }
- }
-
- return $this->rewindable = false;
- }
}
diff --git a/vendor/symfony/finder/Iterator/SortableIterator.php b/vendor/symfony/finder/Iterator/SortableIterator.php
index b6c34b6..177cd0b 100644
--- a/vendor/symfony/finder/Iterator/SortableIterator.php
+++ b/vendor/symfony/finder/Iterator/SortableIterator.php
@@ -27,7 +27,12 @@ class SortableIterator implements \IteratorAggregate
public const SORT_BY_CHANGED_TIME = 4;
public const SORT_BY_MODIFIED_TIME = 5;
public const SORT_BY_NAME_NATURAL = 6;
+ public const SORT_BY_NAME_CASE_INSENSITIVE = 7;
+ public const SORT_BY_NAME_NATURAL_CASE_INSENSITIVE = 8;
+ public const SORT_BY_EXTENSION = 9;
+ public const SORT_BY_SIZE = 10;
+ /** @var \Traversable */
private \Traversable $iterator;
private \Closure|int $sort;
@@ -43,13 +48,13 @@ class SortableIterator implements \IteratorAggregate
$order = $reverseOrder ? -1 : 1;
if (self::SORT_BY_NAME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_NAME_NATURAL === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
+ } elseif (self::SORT_BY_NAME_CASE_INSENSITIVE === $sort) {
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
+ } elseif (self::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE === $sort) {
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_TYPE === $sort) {
$this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
if ($a->isDir() && $b->isFile()) {
@@ -61,21 +66,19 @@ class SortableIterator implements \IteratorAggregate
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
};
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getATime() - $b->getATime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getATime() - $b->getATime());
} elseif (self::SORT_BY_CHANGED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getCTime() - $b->getCTime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getCTime() - $b->getCTime());
} elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getMTime() - $b->getMTime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getMTime() - $b->getMTime());
+ } elseif (self::SORT_BY_EXTENSION === $sort) {
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getExtension(), $b->getExtension());
+ } elseif (self::SORT_BY_SIZE === $sort) {
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getSize() - $b->getSize());
} elseif (self::SORT_BY_NONE === $sort) {
$this->sort = $order;
} elseif (\is_callable($sort)) {
- $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : \Closure::fromCallable($sort);
+ $this->sort = $reverseOrder ? static fn (\SplFileInfo $a, \SplFileInfo $b) => -$sort($a, $b) : $sort(...);
} else {
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
}
diff --git a/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
index e27158c..ddd7007 100644
--- a/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
+++ b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
@@ -13,27 +13,37 @@ namespace Symfony\Component\Finder\Iterator;
use Symfony\Component\Finder\Gitignore;
+/**
+ * @extends \FilterIterator
+ */
final class VcsIgnoredFilterIterator extends \FilterIterator
{
- /**
- * @var string
- */
- private $baseDir;
+ private string $baseDir;
/**
* @var array
*/
- private $gitignoreFilesCache = [];
+ private array $gitignoreFilesCache = [];
/**
* @var array
*/
- private $ignoredPathsCache = [];
+ private array $ignoredPathsCache = [];
+ /**
+ * @param \Iterator $iterator
+ */
public function __construct(\Iterator $iterator, string $baseDir)
{
$this->baseDir = $this->normalizePath($baseDir);
+ foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) {
+ if (@is_dir("{$parentDirectory}/.git")) {
+ $this->baseDir = $parentDirectory;
+ break;
+ }
+ }
+
parent::__construct($iterator);
}
@@ -58,7 +68,7 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
$ignored = false;
- foreach ($this->parentsDirectoryDownward($fileRealPath) as $parentDirectory) {
+ foreach ($this->parentDirectoriesDownwards($fileRealPath) as $parentDirectory) {
if ($this->isIgnored($parentDirectory)) {
// rules in ignored directories are ignored, no need to check further.
break;
@@ -89,11 +99,11 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
/**
* @return list
*/
- private function parentsDirectoryDownward(string $fileRealPath): array
+ private function parentDirectoriesUpwards(string $from): array
{
$parentDirectories = [];
- $parentDirectory = $fileRealPath;
+ $parentDirectory = $from;
while (true) {
$newParentDirectory = \dirname($parentDirectory);
@@ -103,16 +113,28 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
break;
}
- $parentDirectory = $newParentDirectory;
-
- if (0 !== strpos($parentDirectory, $this->baseDir)) {
- break;
- }
-
- $parentDirectories[] = $parentDirectory;
+ $parentDirectories[] = $parentDirectory = $newParentDirectory;
}
- return array_reverse($parentDirectories);
+ return $parentDirectories;
+ }
+
+ private function parentDirectoriesUpTo(string $from, string $upTo): array
+ {
+ return array_filter(
+ $this->parentDirectoriesUpwards($from),
+ static fn (string $directory): bool => str_starts_with($directory, $upTo)
+ );
+ }
+
+ /**
+ * @return list
+ */
+ private function parentDirectoriesDownwards(string $fileRealPath): array
+ {
+ return array_reverse(
+ $this->parentDirectoriesUpTo($fileRealPath, $this->baseDir)
+ );
}
/**
diff --git a/vendor/symfony/finder/LICENSE b/vendor/symfony/finder/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/finder/LICENSE
+++ b/vendor/symfony/finder/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/finder/composer.json b/vendor/symfony/finder/composer.json
index 2e4b324..2b70600 100644
--- a/vendor/symfony/finder/composer.json
+++ b/vendor/symfony/finder/composer.json
@@ -16,7 +16,10 @@
}
],
"require": {
- "php": ">=8.0.2"
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.4|^7.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Finder\\": "" },
diff --git a/vendor/symfony/options-resolver/CHANGELOG.md b/vendor/symfony/options-resolver/CHANGELOG.md
index 791a402..f4de6d0 100644
--- a/vendor/symfony/options-resolver/CHANGELOG.md
+++ b/vendor/symfony/options-resolver/CHANGELOG.md
@@ -1,6 +1,16 @@
CHANGELOG
=========
+6.4
+---
+
+* Improve message with full path on invalid type in nested option
+
+6.3
+---
+
+ * Add `OptionsResolver::setIgnoreUndefined()` and `OptionConfigurator::ignoreUndefined()` to ignore not defined options while resolving
+
6.0
---
diff --git a/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php
index 837fae0..f55ab14 100644
--- a/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php
+++ b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php
@@ -22,7 +22,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
class OptionsResolverIntrospector
{
- private $get;
+ private \Closure $get;
public function __construct(OptionsResolver $optionsResolver)
{
diff --git a/vendor/symfony/options-resolver/LICENSE b/vendor/symfony/options-resolver/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/options-resolver/LICENSE
+++ b/vendor/symfony/options-resolver/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/options-resolver/OptionConfigurator.php b/vendor/symfony/options-resolver/OptionConfigurator.php
index 37d5138..3aa3728 100644
--- a/vendor/symfony/options-resolver/OptionConfigurator.php
+++ b/vendor/symfony/options-resolver/OptionConfigurator.php
@@ -15,8 +15,8 @@ use Symfony\Component\OptionsResolver\Exception\AccessException;
final class OptionConfigurator
{
- private $name;
- private $resolver;
+ private string $name;
+ private OptionsResolver $resolver;
public function __construct(string $name, OptionsResolver $resolver)
{
@@ -134,4 +134,16 @@ final class OptionConfigurator
return $this;
}
+
+ /**
+ * Sets whether ignore undefined options.
+ *
+ * @return $this
+ */
+ public function ignoreUndefined(bool $ignore = true): static
+ {
+ $this->resolver->setIgnoreUndefined($ignore);
+
+ return $this;
+ }
}
diff --git a/vendor/symfony/options-resolver/OptionsResolver.php b/vendor/symfony/options-resolver/OptionsResolver.php
index fe77644..fc378ce 100644
--- a/vendor/symfony/options-resolver/OptionsResolver.php
+++ b/vendor/symfony/options-resolver/OptionsResolver.php
@@ -50,73 +50,73 @@ class OptionsResolver implements Options
/**
* The names of all defined options.
*/
- private $defined = [];
+ private array $defined = [];
/**
* The default option values.
*/
- private $defaults = [];
+ private array $defaults = [];
/**
* A list of closure for nested options.
*
* @var \Closure[][]
*/
- private $nested = [];
+ private array $nested = [];
/**
* The names of required options.
*/
- private $required = [];
+ private array $required = [];
/**
* The resolved option values.
*/
- private $resolved = [];
+ private array $resolved = [];
/**
* A list of normalizer closures.
*
* @var \Closure[][]
*/
- private $normalizers = [];
+ private array $normalizers = [];
/**
* A list of accepted values for each option.
*/
- private $allowedValues = [];
+ private array $allowedValues = [];
/**
* A list of accepted types for each option.
*/
- private $allowedTypes = [];
+ private array $allowedTypes = [];
/**
* A list of info messages for each option.
*/
- private $info = [];
+ private array $info = [];
/**
* A list of closures for evaluating lazy options.
*/
- private $lazy = [];
+ private array $lazy = [];
/**
* A list of lazy options whose closure is currently being called.
*
* This list helps detecting circular dependencies between lazy options.
*/
- private $calling = [];
+ private array $calling = [];
/**
* A list of deprecated options.
*/
- private $deprecated = [];
+ private array $deprecated = [];
/**
* The list of options provided by the user.
*/
- private $given = [];
+ private array $given = [];
/**
* Whether the instance is locked for reading.
@@ -126,19 +126,24 @@ class OptionsResolver implements Options
* process. If any option is changed after being read, all evaluated
* lazy options that depend on this option would become invalid.
*/
- private $locked = false;
+ private bool $locked = false;
- private $parentsOptions = [];
+ private array $parentsOptions = [];
/**
* Whether the whole options definition is marked as array prototype.
*/
- private $prototype;
+ private ?bool $prototype = null;
/**
* The prototype array's index that is being read.
*/
- private $prototypeIndex;
+ private int|string|null $prototypeIndex = null;
+
+ /**
+ * Whether to ignore undefined options.
+ */
+ private bool $ignoreUndefined = false;
/**
* Sets the default value of a given option.
@@ -485,7 +490,7 @@ class OptionsResolver implements Options
* @throws UndefinedOptionsException If the option is undefined
* @throws AccessException If called from a lazy option or normalizer
*/
- public function setNormalizer(string $option, \Closure $normalizer)
+ public function setNormalizer(string $option, \Closure $normalizer): static
{
if ($this->locked) {
throw new AccessException('Normalizers cannot be set from a lazy option or normalizer.');
@@ -537,7 +542,7 @@ class OptionsResolver implements Options
}
if ($forcePrepend) {
- $this->normalizers[$option] = $this->normalizers[$option] ?? [];
+ $this->normalizers[$option] ??= [];
array_unshift($this->normalizers[$option], $normalizer);
} else {
$this->normalizers[$option][] = $normalizer;
@@ -569,7 +574,7 @@ class OptionsResolver implements Options
* @throws UndefinedOptionsException If the option is undefined
* @throws AccessException If called from a lazy option or normalizer
*/
- public function setAllowedValues(string $option, mixed $allowedValues)
+ public function setAllowedValues(string $option, mixed $allowedValues): static
{
if ($this->locked) {
throw new AccessException('Allowed values cannot be set from a lazy option or normalizer.');
@@ -609,7 +614,7 @@ class OptionsResolver implements Options
* @throws UndefinedOptionsException If the option is undefined
* @throws AccessException If called from a lazy option or normalizer
*/
- public function addAllowedValues(string $option, mixed $allowedValues)
+ public function addAllowedValues(string $option, mixed $allowedValues): static
{
if ($this->locked) {
throw new AccessException('Allowed values cannot be added from a lazy option or normalizer.');
@@ -649,7 +654,7 @@ class OptionsResolver implements Options
* @throws UndefinedOptionsException If the option is undefined
* @throws AccessException If called from a lazy option or normalizer
*/
- public function setAllowedTypes(string $option, string|array $allowedTypes)
+ public function setAllowedTypes(string $option, string|array $allowedTypes): static
{
if ($this->locked) {
throw new AccessException('Allowed types cannot be set from a lazy option or normalizer.');
@@ -683,7 +688,7 @@ class OptionsResolver implements Options
* @throws UndefinedOptionsException If the option is undefined
* @throws AccessException If called from a lazy option or normalizer
*/
- public function addAllowedTypes(string $option, string|array $allowedTypes)
+ public function addAllowedTypes(string $option, string|array $allowedTypes): static
{
if ($this->locked) {
throw new AccessException('Allowed types cannot be added from a lazy option or normalizer.');
@@ -862,7 +867,7 @@ class OptionsResolver implements Options
$clone = clone $this;
// Make sure that no unknown options are passed
- $diff = array_diff_key($options, $clone->defined);
+ $diff = $this->ignoreUndefined ? [] : array_diff_key($options, $clone->defined);
if (\count($diff) > 0) {
ksort($clone->defined);
@@ -873,6 +878,10 @@ class OptionsResolver implements Options
// Override options set by the user
foreach ($options as $option => $value) {
+ if ($this->ignoreUndefined && !isset($clone->defined[$option])) {
+ continue;
+ }
+
$clone->given[$option] = true;
$clone->defaults[$option] = $value;
unset($clone->resolved[$option], $clone->lazy[$option]);
@@ -1018,9 +1027,7 @@ class OptionsResolver implements Options
$fmtActualValue = $this->formatValue($value);
$fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
$fmtProvidedTypes = implode('|', array_keys($invalidTypes));
- $allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
- return str_ends_with($item, '[]');
- })) > 0;
+ $allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static fn ($item) => str_ends_with($item, '[]'))) > 0;
if (\is_array($value) && $allowedContainsArrayType) {
throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $this->formatOptions([$option]), $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
@@ -1057,7 +1064,7 @@ class OptionsResolver implements Options
if (!$success) {
$message = sprintf(
'The option "%s" with value %s is invalid.',
- $option,
+ $this->formatOptions([$option]),
$this->formatValue($value)
);
@@ -1134,7 +1141,7 @@ class OptionsResolver implements Options
private function verifyTypes(string $type, mixed $value, array &$invalidTypes, int $level = 0): bool
{
- if (\is_array($value) && '[]' === substr($type, -2)) {
+ if (\is_array($value) && str_ends_with($type, '[]')) {
$type = substr($type, 0, -2);
$valid = true;
@@ -1212,6 +1219,18 @@ class OptionsResolver implements Options
return \count($this->defaults);
}
+ /**
+ * Sets whether ignore undefined options.
+ *
+ * @return $this
+ */
+ public function setIgnoreUndefined(bool $ignore = true): static
+ {
+ $this->ignoreUndefined = $ignore;
+
+ return $this;
+ }
+
/**
* Returns a string representation of the value.
*
@@ -1222,7 +1241,7 @@ class OptionsResolver implements Options
private function formatValue(mixed $value): string
{
if (\is_object($value)) {
- return \get_class($value);
+ return $value::class;
}
if (\is_array($value)) {
@@ -1281,9 +1300,7 @@ class OptionsResolver implements Options
$prefix .= sprintf('[%s]', $this->prototypeIndex);
}
- $options = array_map(static function (string $option) use ($prefix): string {
- return sprintf('%s[%s]', $prefix, $option);
- }, $options);
+ $options = array_map(static fn (string $option): string => sprintf('%s[%s]', $prefix, $option), $options);
}
return implode('", "', $options);
diff --git a/vendor/symfony/options-resolver/composer.json b/vendor/symfony/options-resolver/composer.json
index 4fd80d9..e70640d 100644
--- a/vendor/symfony/options-resolver/composer.json
+++ b/vendor/symfony/options-resolver/composer.json
@@ -16,8 +16,8 @@
}
],
"require": {
- "php": ">=8.0.2",
- "symfony/deprecation-contracts": "^2.1|^3"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3"
},
"autoload": {
"psr-4": { "Symfony\\Component\\OptionsResolver\\": "" },
diff --git a/vendor/symfony/process/CHANGELOG.md b/vendor/symfony/process/CHANGELOG.md
index 31b9ee6..e26819b 100644
--- a/vendor/symfony/process/CHANGELOG.md
+++ b/vendor/symfony/process/CHANGELOG.md
@@ -1,6 +1,14 @@
CHANGELOG
=========
+6.4
+---
+
+ * Add `PhpSubprocess` to handle PHP subprocesses that take over the
+ configuration from their parent
+ * Add `RunProcessMessage` and `RunProcessMessageHandler`
+ * Support using `Process::findExecutable()` independently of `open_basedir`
+
5.2.0
-----
diff --git a/vendor/symfony/process/Exception/ProcessFailedException.php b/vendor/symfony/process/Exception/ProcessFailedException.php
index 328acfd..499809e 100644
--- a/vendor/symfony/process/Exception/ProcessFailedException.php
+++ b/vendor/symfony/process/Exception/ProcessFailedException.php
@@ -20,7 +20,7 @@ use Symfony\Component\Process\Process;
*/
class ProcessFailedException extends RuntimeException
{
- private $process;
+ private Process $process;
public function __construct(Process $process)
{
@@ -47,7 +47,7 @@ class ProcessFailedException extends RuntimeException
$this->process = $process;
}
- public function getProcess()
+ public function getProcess(): Process
{
return $this->process;
}
diff --git a/vendor/symfony/process/Exception/ProcessSignaledException.php b/vendor/symfony/process/Exception/ProcessSignaledException.php
index d4d3227..0fed8ac 100644
--- a/vendor/symfony/process/Exception/ProcessSignaledException.php
+++ b/vendor/symfony/process/Exception/ProcessSignaledException.php
@@ -20,7 +20,7 @@ use Symfony\Component\Process\Process;
*/
final class ProcessSignaledException extends RuntimeException
{
- private $process;
+ private Process $process;
public function __construct(Process $process)
{
diff --git a/vendor/symfony/process/Exception/ProcessTimedOutException.php b/vendor/symfony/process/Exception/ProcessTimedOutException.php
index 94391a4..252e111 100644
--- a/vendor/symfony/process/Exception/ProcessTimedOutException.php
+++ b/vendor/symfony/process/Exception/ProcessTimedOutException.php
@@ -23,8 +23,8 @@ class ProcessTimedOutException extends RuntimeException
public const TYPE_GENERAL = 1;
public const TYPE_IDLE = 2;
- private $process;
- private $timeoutType;
+ private Process $process;
+ private int $timeoutType;
public function __construct(Process $process, int $timeoutType)
{
@@ -38,32 +38,27 @@ class ProcessTimedOutException extends RuntimeException
));
}
- public function getProcess()
+ public function getProcess(): Process
{
return $this->process;
}
- public function isGeneralTimeout()
+ public function isGeneralTimeout(): bool
{
return self::TYPE_GENERAL === $this->timeoutType;
}
- public function isIdleTimeout()
+ public function isIdleTimeout(): bool
{
return self::TYPE_IDLE === $this->timeoutType;
}
- public function getExceededTimeout()
+ public function getExceededTimeout(): ?float
{
- switch ($this->timeoutType) {
- case self::TYPE_GENERAL:
- return $this->process->getTimeout();
-
- case self::TYPE_IDLE:
- return $this->process->getIdleTimeout();
-
- default:
- throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
- }
+ return match ($this->timeoutType) {
+ self::TYPE_GENERAL => $this->process->getTimeout(),
+ self::TYPE_IDLE => $this->process->getIdleTimeout(),
+ default => throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)),
+ };
}
}
diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php
index d9d1110..f044ebc 100644
--- a/vendor/symfony/process/ExecutableFinder.php
+++ b/vendor/symfony/process/ExecutableFinder.php
@@ -19,12 +19,12 @@ namespace Symfony\Component\Process;
*/
class ExecutableFinder
{
- private $suffixes = ['.exe', '.bat', '.cmd', '.com'];
+ private array $suffixes = ['.exe', '.bat', '.cmd', '.com'];
/**
* Replaces default suffixes of executable.
*/
- public function setSuffixes(array $suffixes)
+ public function setSuffixes(array $suffixes): void
{
$this->suffixes = $suffixes;
}
@@ -32,7 +32,7 @@ class ExecutableFinder
/**
* Adds new possible suffix to check for executable.
*/
- public function addSuffix(string $suffix)
+ public function addSuffix(string $suffix): void
{
$this->suffixes[] = $suffix;
}
@@ -46,25 +46,10 @@ class ExecutableFinder
*/
public function find(string $name, string $default = null, array $extraDirs = []): ?string
{
- if (\ini_get('open_basedir')) {
- $searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
- $dirs = [];
- foreach ($searchPath as $path) {
- // Silencing against https://bugs.php.net/69240
- if (@is_dir($path)) {
- $dirs[] = $path;
- } else {
- if (basename($path) == $name && @is_executable($path)) {
- return $path;
- }
- }
- }
- } else {
- $dirs = array_merge(
- explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
- $extraDirs
- );
- }
+ $dirs = array_merge(
+ explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
+ $extraDirs
+ );
$suffixes = [''];
if ('\\' === \DIRECTORY_SEPARATOR) {
@@ -76,9 +61,18 @@ class ExecutableFinder
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
return $file;
}
+
+ if (!@is_dir($dir) && basename($dir) === $name.$suffix && @is_executable($dir)) {
+ return $dir;
+ }
}
}
+ $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v';
+ if (\function_exists('exec') && ($executablePath = strtok(@exec($command.' '.escapeshellarg($name)), \PHP_EOL)) && is_executable($executablePath)) {
+ return $executablePath;
+ }
+
return $default;
}
}
diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php
index b8682ba..d0517de 100644
--- a/vendor/symfony/process/InputStream.php
+++ b/vendor/symfony/process/InputStream.php
@@ -22,17 +22,16 @@ use Symfony\Component\Process\Exception\RuntimeException;
*/
class InputStream implements \IteratorAggregate
{
- /** @var callable|null */
- private $onEmpty = null;
- private $input = [];
- private $open = true;
+ private ?\Closure $onEmpty = null;
+ private array $input = [];
+ private bool $open = true;
/**
* Sets a callback that is called when the write buffer becomes empty.
*/
- public function onEmpty(callable $onEmpty = null)
+ public function onEmpty(callable $onEmpty = null): void
{
- $this->onEmpty = $onEmpty;
+ $this->onEmpty = null !== $onEmpty ? $onEmpty(...) : null;
}
/**
@@ -41,7 +40,7 @@ class InputStream implements \IteratorAggregate
* @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar,
* stream resource or \Traversable
*/
- public function write(mixed $input)
+ public function write(mixed $input): void
{
if (null === $input) {
return;
@@ -55,7 +54,7 @@ class InputStream implements \IteratorAggregate
/**
* Closes the write buffer.
*/
- public function close()
+ public function close(): void
{
$this->open = false;
}
@@ -63,7 +62,7 @@ class InputStream implements \IteratorAggregate
/**
* Tells whether the write buffer is closed or not.
*/
- public function isClosed()
+ public function isClosed(): bool
{
return !$this->open;
}
diff --git a/vendor/symfony/process/LICENSE b/vendor/symfony/process/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/process/LICENSE
+++ b/vendor/symfony/process/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php
index 3fab03e..ae05364 100644
--- a/vendor/symfony/process/PhpExecutableFinder.php
+++ b/vendor/symfony/process/PhpExecutableFinder.php
@@ -19,7 +19,7 @@ namespace Symfony\Component\Process;
*/
class PhpExecutableFinder
{
- private $executableFinder;
+ private ExecutableFinder $executableFinder;
public function __construct()
{
@@ -34,7 +34,7 @@ class PhpExecutableFinder
if ($php = getenv('PHP_BINARY')) {
if (!is_executable($php)) {
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v';
- if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
+ if (\function_exists('exec') && $php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
if (!is_executable($php)) {
return false;
}
@@ -54,7 +54,7 @@ class PhpExecutableFinder
$args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
// PHP_BINARY return the current sapi executable
- if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cgi-fcgi', 'cli', 'cli-server', 'phpdbg'], true)) {
+ if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cli', 'cli-server', 'phpdbg'], true)) {
return \PHP_BINARY.$args;
}
diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php
index cb749f9..0d31e26 100644
--- a/vendor/symfony/process/PhpProcess.php
+++ b/vendor/symfony/process/PhpProcess.php
@@ -50,18 +50,12 @@ class PhpProcess extends Process
parent::__construct($php, $cwd, $env, $script, $timeout);
}
- /**
- * {@inheritdoc}
- */
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, mixed $input = null, ?float $timeout = 60): static
{
throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
}
- /**
- * {@inheritdoc}
- */
- public function start(callable $callback = null, array $env = [])
+ public function start(callable $callback = null, array $env = []): void
{
if (null === $this->getCommandLine()) {
throw new RuntimeException('Unable to find the PHP executable.');
diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php
index bc3a7a6..cbbb727 100644
--- a/vendor/symfony/process/Pipes/AbstractPipes.php
+++ b/vendor/symfony/process/Pipes/AbstractPipes.php
@@ -22,29 +22,25 @@ abstract class AbstractPipes implements PipesInterface
{
public array $pipes = [];
- private $inputBuffer = '';
+ private string $inputBuffer = '';
+ /** @var resource|string|\Iterator */
private $input;
- private $blocked = true;
- private $lastError;
+ private bool $blocked = true;
+ private ?string $lastError = null;
/**
- * @param resource|string|int|float|bool|\Iterator|null $input
+ * @param resource|string|\Iterator $input
*/
- public function __construct(mixed $input)
+ public function __construct($input)
{
if (\is_resource($input) || $input instanceof \Iterator) {
$this->input = $input;
- } elseif (\is_string($input)) {
- $this->inputBuffer = $input;
} else {
$this->inputBuffer = (string) $input;
}
}
- /**
- * {@inheritdoc}
- */
- public function close()
+ public function close(): void
{
foreach ($this->pipes as $pipe) {
if (\is_resource($pipe)) {
@@ -69,7 +65,7 @@ abstract class AbstractPipes implements PipesInterface
/**
* Unblocks streams.
*/
- protected function unblock()
+ protected function unblock(): void
{
if (!$this->blocked) {
return;
@@ -173,7 +169,7 @@ abstract class AbstractPipes implements PipesInterface
/**
* @internal
*/
- public function handleError(int $type, string $msg)
+ public function handleError(int $type, string $msg): void
{
$this->lastError = $msg;
}
diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php
index 50eb5c4..967f8de 100644
--- a/vendor/symfony/process/Pipes/PipesInterface.php
+++ b/vendor/symfony/process/Pipes/PipesInterface.php
@@ -57,5 +57,5 @@ interface PipesInterface
/**
* Closes file handles and pipes.
*/
- public function close();
+ public function close(): void;
}
diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php
index 063aa6a..7bd0db0 100644
--- a/vendor/symfony/process/Pipes/UnixPipes.php
+++ b/vendor/symfony/process/Pipes/UnixPipes.php
@@ -22,9 +22,9 @@ use Symfony\Component\Process\Process;
*/
class UnixPipes extends AbstractPipes
{
- private $ttyMode;
- private $ptyMode;
- private $haveReadSupport;
+ private ?bool $ttyMode;
+ private bool $ptyMode;
+ private bool $haveReadSupport;
public function __construct(?bool $ttyMode, bool $ptyMode, mixed $input, bool $haveReadSupport)
{
@@ -40,7 +40,7 @@ class UnixPipes extends AbstractPipes
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
- public function __wakeup()
+ public function __wakeup(): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
@@ -50,9 +50,6 @@ class UnixPipes extends AbstractPipes
$this->close();
}
- /**
- * {@inheritdoc}
- */
public function getDescriptors(): array
{
if (!$this->haveReadSupport) {
@@ -88,17 +85,11 @@ class UnixPipes extends AbstractPipes
];
}
- /**
- * {@inheritdoc}
- */
public function getFiles(): array
{
return [];
}
- /**
- * {@inheritdoc}
- */
public function readAndWrite(bool $blocking, bool $close = false): array
{
$this->unblock();
@@ -109,7 +100,7 @@ class UnixPipes extends AbstractPipes
unset($r[0]);
// let's have a look if something changed in streams
- set_error_handler([$this, 'handleError']);
+ set_error_handler($this->handleError(...));
if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
restore_error_handler();
// if a system call has been interrupted, forget about it, let's try again
@@ -145,17 +136,11 @@ class UnixPipes extends AbstractPipes
return $read;
}
- /**
- * {@inheritdoc}
- */
public function haveReadSupport(): bool
{
return $this->haveReadSupport;
}
- /**
- * {@inheritdoc}
- */
public function areOpen(): bool
{
return (bool) $this->pipes;
diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php
index e68ed95..637c8f3 100644
--- a/vendor/symfony/process/Pipes/WindowsPipes.php
+++ b/vendor/symfony/process/Pipes/WindowsPipes.php
@@ -26,14 +26,14 @@ use Symfony\Component\Process\Process;
*/
class WindowsPipes extends AbstractPipes
{
- private $files = [];
- private $fileHandles = [];
- private $lockHandles = [];
- private $readBytes = [
+ private array $files = [];
+ private array $fileHandles = [];
+ private array $lockHandles = [];
+ private array $readBytes = [
Process::STDOUT => 0,
Process::STDERR => 0,
];
- private $haveReadSupport;
+ private bool $haveReadSupport;
public function __construct(mixed $input, bool $haveReadSupport)
{
@@ -93,7 +93,7 @@ class WindowsPipes extends AbstractPipes
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
- public function __wakeup()
+ public function __wakeup(): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
@@ -103,9 +103,6 @@ class WindowsPipes extends AbstractPipes
$this->close();
}
- /**
- * {@inheritdoc}
- */
public function getDescriptors(): array
{
if (!$this->haveReadSupport) {
@@ -128,17 +125,11 @@ class WindowsPipes extends AbstractPipes
];
}
- /**
- * {@inheritdoc}
- */
public function getFiles(): array
{
return $this->files;
}
- /**
- * {@inheritdoc}
- */
public function readAndWrite(bool $blocking, bool $close = false): array
{
$this->unblock();
@@ -171,26 +162,17 @@ class WindowsPipes extends AbstractPipes
return $read;
}
- /**
- * {@inheritdoc}
- */
public function haveReadSupport(): bool
{
return $this->haveReadSupport;
}
- /**
- * {@inheritdoc}
- */
public function areOpen(): bool
{
return $this->pipes && $this->fileHandles;
}
- /**
- * {@inheritdoc}
- */
- public function close()
+ public function close(): void
{
parent::close();
foreach ($this->fileHandles as $type => $handle) {
diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php
index 7999388..6b73c31 100644
--- a/vendor/symfony/process/Process.php
+++ b/vendor/symfony/process/Process.php
@@ -17,7 +17,6 @@ use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Exception\ProcessSignaledException;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\RuntimeException;
-use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Pipes\UnixPipes;
use Symfony\Component\Process\Pipes\WindowsPipes;
@@ -51,44 +50,45 @@ class Process implements \IteratorAggregate
public const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating
public const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating
- private $callback;
- private $hasCallback = false;
- private $commandline;
- private $cwd;
- private $env = [];
+ private ?\Closure $callback = null;
+ private array|string $commandline;
+ private ?string $cwd;
+ private array $env = [];
+ /** @var resource|string|\Iterator|null */
private $input;
- private $starttime;
- private $lastOutputTime;
- private $timeout;
- private $idleTimeout;
- private $exitcode;
- private $fallbackStatus = [];
- private $processInformation;
- private $outputDisabled = false;
+ private ?float $starttime = null;
+ private ?float $lastOutputTime = null;
+ private ?float $timeout = null;
+ private ?float $idleTimeout = null;
+ private ?int $exitcode = null;
+ private array $fallbackStatus = [];
+ private array $processInformation;
+ private bool $outputDisabled = false;
+ /** @var resource */
private $stdout;
+ /** @var resource */
private $stderr;
+ /** @var resource|null */
private $process;
- private $status = self::STATUS_READY;
- private $incrementalOutputOffset = 0;
- private $incrementalErrorOutputOffset = 0;
- private $tty = false;
- private $pty;
- private $options = ['suppress_errors' => true, 'bypass_shell' => true];
+ private string $status = self::STATUS_READY;
+ private int $incrementalOutputOffset = 0;
+ private int $incrementalErrorOutputOffset = 0;
+ private bool $tty = false;
+ private bool $pty;
+ private array $options = ['suppress_errors' => true, 'bypass_shell' => true];
- private $useFileHandles = false;
- /** @var PipesInterface */
- private $processPipes;
+ private WindowsPipes|UnixPipes $processPipes;
- private $latestSignal;
+ private ?int $latestSignal = null;
- private static $sigchild;
+ private static ?bool $sigchild = null;
/**
* Exit codes translation table.
*
* User-defined errors must use exit codes in the 64-113 range.
*/
- public static $exitCodes = [
+ public static array $exitCodes = [
0 => 'OK',
1 => 'General error',
2 => 'Misuse of shell builtins',
@@ -162,7 +162,6 @@ class Process implements \IteratorAggregate
$this->setInput($input);
$this->setTimeout($timeout);
- $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR;
$this->pty = false;
}
@@ -200,7 +199,7 @@ class Process implements \IteratorAggregate
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
- public function __wakeup()
+ public function __wakeup(): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
@@ -289,7 +288,7 @@ class Process implements \IteratorAggregate
* @throws RuntimeException When process is already running
* @throws LogicException In case a callback is provided and output has been disabled
*/
- public function start(callable $callback = null, array $env = [])
+ public function start(callable $callback = null, array $env = []): void
{
if ($this->isRunning()) {
throw new RuntimeException('Process is already running.');
@@ -298,8 +297,7 @@ class Process implements \IteratorAggregate
$this->resetProcessData();
$this->starttime = $this->lastOutputTime = microtime(true);
$this->callback = $this->buildCallback($callback);
- $this->hasCallback = null !== $callback;
- $descriptors = $this->getDescriptors();
+ $descriptors = $this->getDescriptors(null !== $callback);
if ($this->env) {
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env;
@@ -308,7 +306,7 @@ class Process implements \IteratorAggregate
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv();
if (\is_array($commandline = $this->commandline)) {
- $commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline));
+ $commandline = implode(' ', array_map($this->escapeArgument(...), $commandline));
if ('\\' !== \DIRECTORY_SEPARATOR) {
// exec is mandatory to deal with sending a signal to the process
@@ -320,17 +318,13 @@ class Process implements \IteratorAggregate
if ('\\' === \DIRECTORY_SEPARATOR) {
$commandline = $this->prepareWindowsCommandLine($commandline, $env);
- } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) {
+ } elseif ($this->isSigchildEnabled()) {
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
$descriptors[3] = ['pipe', 'w'];
// See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
$commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
- $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
-
- // Workaround for the bug, when PTS functionality is enabled.
- // @see : https://bugs.php.net/69442
- $ptsWorkaround = fopen(__FILE__, 'r');
+ $commandline .= 'pid=$!; echo $pid >&3; wait $pid 2>/dev/null; code=$?; echo $code >&3; exit $code';
}
$envPairs = [];
@@ -344,11 +338,12 @@ class Process implements \IteratorAggregate
throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd));
}
- $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
+ $process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
- if (!\is_resource($this->process)) {
+ if (!\is_resource($process)) {
throw new RuntimeException('Unable to launch a new process.');
}
+ $this->process = $process;
$this->status = self::STATUS_STARTED;
if (isset($descriptors[3])) {
@@ -421,7 +416,7 @@ class Process implements \IteratorAggregate
do {
$this->checkTimeout();
- $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
+ $running = $this->isRunning() && ('\\' === \DIRECTORY_SEPARATOR || $this->processPipes->areOpen());
$this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
} while ($running);
@@ -604,6 +599,8 @@ class Process implements \IteratorAggregate
*
* @param int $flags A bit field of Process::ITER_* flags
*
+ * @return \Generator
+ *
* @throws LogicException in case the output has been disabled
* @throws LogicException In case the process is not started
*/
@@ -872,7 +869,7 @@ class Process implements \IteratorAggregate
* Stops the process.
*
* @param int|float $timeout The timeout in seconds
- * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
+ * @param int|null $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
*
* @return int|null The exit-code of the process or null if it's not running
*/
@@ -910,7 +907,7 @@ class Process implements \IteratorAggregate
*
* @internal
*/
- public function addOutput(string $line)
+ public function addOutput(string $line): void
{
$this->lastOutputTime = microtime(true);
@@ -924,7 +921,7 @@ class Process implements \IteratorAggregate
*
* @internal
*/
- public function addErrorOutput(string $line)
+ public function addErrorOutput(string $line): void
{
$this->lastOutputTime = microtime(true);
@@ -946,7 +943,7 @@ class Process implements \IteratorAggregate
*/
public function getCommandLine(): string
{
- return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline;
+ return \is_array($this->commandline) ? implode(' ', array_map($this->escapeArgument(...), $this->commandline)) : $this->commandline;
}
/**
@@ -1115,7 +1112,7 @@ class Process implements \IteratorAggregate
*
* This content will be passed to the underlying process standard input.
*
- * @param string|int|float|bool|resource|\Traversable|null $input The content
+ * @param string|resource|\Traversable|self|null $input The content
*
* @return $this
*
@@ -1140,7 +1137,7 @@ class Process implements \IteratorAggregate
*
* @throws ProcessTimedOutException In case the timeout was reached
*/
- public function checkTimeout()
+ public function checkTimeout(): void
{
if (self::STATUS_STARTED !== $this->status) {
return;
@@ -1179,7 +1176,7 @@ class Process implements \IteratorAggregate
* Enabling the "create_new_console" option allows a subprocess to continue
* to run after the main process exited, on both Windows and *nix
*/
- public function setOptions(array $options)
+ public function setOptions(array $options): void
{
if ($this->isRunning()) {
throw new RuntimeException('Setting options while the process is running is not possible.');
@@ -1204,11 +1201,7 @@ class Process implements \IteratorAggregate
{
static $isTtySupported;
- if (null === $isTtySupported) {
- $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
- }
-
- return $isTtySupported;
+ return $isTtySupported ??= ('/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT));
}
/**
@@ -1232,15 +1225,15 @@ class Process implements \IteratorAggregate
/**
* Creates the descriptors needed by the proc_open.
*/
- private function getDescriptors(): array
+ private function getDescriptors(bool $hasCallback): array
{
if ($this->input instanceof \Iterator) {
$this->input->rewind();
}
if ('\\' === \DIRECTORY_SEPARATOR) {
- $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
+ $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $hasCallback);
} else {
- $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
+ $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $hasCallback);
}
return $this->processPipes->getDescriptors();
@@ -1257,9 +1250,7 @@ class Process implements \IteratorAggregate
protected function buildCallback(callable $callback = null): \Closure
{
if ($this->outputDisabled) {
- return function ($type, $data) use ($callback): bool {
- return null !== $callback && $callback($type, $data);
- };
+ return fn ($type, $data): bool => null !== $callback && $callback($type, $data);
}
$out = self::OUT;
@@ -1280,7 +1271,7 @@ class Process implements \IteratorAggregate
*
* @param bool $blocking Whether to use a blocking read call
*/
- protected function updateStatus(bool $blocking)
+ protected function updateStatus(bool $blocking): void
{
if (self::STATUS_STARTED !== $this->status) {
return;
@@ -1327,7 +1318,7 @@ class Process implements \IteratorAggregate
*
* @throws LogicException in case output has been disabled or process is not started
*/
- private function readPipesForOutput(string $caller, bool $blocking = false)
+ private function readPipesForOutput(string $caller, bool $blocking = false): void
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
@@ -1362,7 +1353,7 @@ class Process implements \IteratorAggregate
* @param bool $blocking Whether to use blocking calls or not
* @param bool $close Whether to close file handles or not
*/
- private function readPipes(bool $blocking, bool $close)
+ private function readPipes(bool $blocking, bool $close): void
{
$result = $this->processPipes->readAndWrite($blocking, $close);
@@ -1411,13 +1402,13 @@ class Process implements \IteratorAggregate
/**
* Resets data related to the latest run of the process.
*/
- private function resetProcessData()
+ private function resetProcessData(): void
{
$this->starttime = null;
$this->callback = null;
$this->exitcode = null;
$this->fallbackStatus = [];
- $this->processInformation = null;
+ $this->processInformation = [];
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
$this->process = null;
@@ -1484,8 +1475,6 @@ class Process implements \IteratorAggregate
private function prepareWindowsCommandLine(string $cmd, array &$env): string
{
$uid = uniqid('', true);
- $varCount = 0;
- $varCache = [];
$cmd = preg_replace_callback(
'/"(?:(
[^"%!^]*+
@@ -1494,7 +1483,9 @@ class Process implements \IteratorAggregate
[^"%!^]*+
)++
) | [^"]*+ )"/x',
- function ($m) use (&$env, &$varCache, &$varCount, $uid) {
+ function ($m) use (&$env, $uid) {
+ static $varCount = 0;
+ static $varCache = [];
if (!isset($m[1])) {
return $m[0];
}
@@ -1532,7 +1523,7 @@ class Process implements \IteratorAggregate
*
* @throws LogicException if the process has not run
*/
- private function requireProcessIsStarted(string $functionName)
+ private function requireProcessIsStarted(string $functionName): void
{
if (!$this->isStarted()) {
throw new LogicException(sprintf('Process must be started before calling "%s()".', $functionName));
@@ -1544,7 +1535,7 @@ class Process implements \IteratorAggregate
*
* @throws LogicException if the process is not yet terminated
*/
- private function requireProcessIsTerminated(string $functionName)
+ private function requireProcessIsTerminated(string $functionName): void
{
if (!$this->isTerminated()) {
throw new LogicException(sprintf('Process must be terminated before calling "%s()".', $functionName));
@@ -1573,7 +1564,7 @@ class Process implements \IteratorAggregate
return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"';
}
- private function replacePlaceholders(string $commandline, array $env)
+ private function replacePlaceholders(string $commandline, array $env): string
{
return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) {
if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) {
diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php
index 744399d..092c5cc 100644
--- a/vendor/symfony/process/ProcessUtils.php
+++ b/vendor/symfony/process/ProcessUtils.php
@@ -43,9 +43,6 @@ class ProcessUtils
if (\is_resource($input)) {
return $input;
}
- if (\is_string($input)) {
- return $input;
- }
if (\is_scalar($input)) {
return (string) $input;
}
diff --git a/vendor/symfony/process/README.md b/vendor/symfony/process/README.md
index 8777de4..afce5e4 100644
--- a/vendor/symfony/process/README.md
+++ b/vendor/symfony/process/README.md
@@ -3,17 +3,6 @@ Process Component
The Process component executes commands in sub-processes.
-Sponsor
--------
-
-The Process component for Symfony 5.4/6.0 is [backed][1] by [SensioLabs][2].
-
-As the creator of Symfony, SensioLabs supports companies using Symfony, with an
-offering encompassing consultancy, expertise, services, training, and technical
-assistance to ensure the success of web application development projects.
-
-Help Symfony by [sponsoring][3] its development!
-
Resources
---------
@@ -22,7 +11,3 @@ Resources
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)
-
-[1]: https://symfony.com/backers
-[2]: https://sensiolabs.com
-[3]: https://symfony.com/sponsor
diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json
index 9f1aa8c..dda5575 100644
--- a/vendor/symfony/process/composer.json
+++ b/vendor/symfony/process/composer.json
@@ -16,7 +16,7 @@
}
],
"require": {
- "php": ">=8.0.2"
+ "php": ">=8.2"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Process\\": "" },
diff --git a/vendor/symfony/service-contracts/.gitignore b/vendor/symfony/service-contracts/.gitignore
deleted file mode 100644
index c49a5d8..0000000
--- a/vendor/symfony/service-contracts/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vendor/
-composer.lock
-phpunit.xml
diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php
index 10d1bc3..d98e1df 100644
--- a/vendor/symfony/service-contracts/Attribute/SubscribedService.php
+++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php
@@ -11,9 +11,14 @@
namespace Symfony\Contracts\Service\Attribute;
+use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Symfony\Contracts\Service\ServiceSubscriberTrait;
/**
+ * For use as the return value for {@see ServiceSubscriberInterface}.
+ *
+ * @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi'))
+ *
* Use with {@see ServiceSubscriberTrait} to mark a method's return type
* as a subscribed service.
*
@@ -22,12 +27,21 @@ use Symfony\Contracts\Service\ServiceSubscriberTrait;
#[\Attribute(\Attribute::TARGET_METHOD)]
final class SubscribedService
{
+ /** @var object[] */
+ public array $attributes;
+
/**
- * @param string|null $key The key to use for the service
- * If null, use "ClassName::methodName"
+ * @param string|null $key The key to use for the service
+ * @param class-string|null $type The service class
+ * @param bool $nullable Whether the service is optional
+ * @param object|object[] $attributes One or more dependency injection attributes to use
*/
public function __construct(
- public ?string $key = null
+ public ?string $key = null,
+ public ?string $type = null,
+ public bool $nullable = false,
+ array|object $attributes = [],
) {
+ $this->attributes = \is_array($attributes) ? $attributes : [$attributes];
}
}
diff --git a/vendor/symfony/service-contracts/LICENSE b/vendor/symfony/service-contracts/LICENSE
index 74cdc2d..7536cae 100644
--- a/vendor/symfony/service-contracts/LICENSE
+++ b/vendor/symfony/service-contracts/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018-2022 Fabien Potencier
+Copyright (c) 2018-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/service-contracts/README.md b/vendor/symfony/service-contracts/README.md
index 41e054a..42841a5 100644
--- a/vendor/symfony/service-contracts/README.md
+++ b/vendor/symfony/service-contracts/README.md
@@ -3,7 +3,7 @@ Symfony Service Contracts
A set of abstractions extracted out of the Symfony components.
-Can be used to build on semantics that the Symfony components proved useful - and
+Can be used to build on semantics that the Symfony components proved useful and
that already have battle tested implementations.
See https://github.com/symfony/contracts/blob/main/README.md for more information.
diff --git a/vendor/symfony/service-contracts/ResetInterface.php b/vendor/symfony/service-contracts/ResetInterface.php
index 1af1075..a4f389b 100644
--- a/vendor/symfony/service-contracts/ResetInterface.php
+++ b/vendor/symfony/service-contracts/ResetInterface.php
@@ -26,5 +26,8 @@ namespace Symfony\Contracts\Service;
*/
interface ResetInterface
{
+ /**
+ * @return void
+ */
public function reset();
}
diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php
index 19d3e80..b62ec3e 100644
--- a/vendor/symfony/service-contracts/ServiceLocatorTrait.php
+++ b/vendor/symfony/service-contracts/ServiceLocatorTrait.php
@@ -31,24 +31,18 @@ trait ServiceLocatorTrait
private array $providedTypes;
/**
- * @param callable[] $factories
+ * @param array $factories
*/
public function __construct(array $factories)
{
$this->factories = $factories;
}
- /**
- * {@inheritdoc}
- */
public function has(string $id): bool
{
return isset($this->factories[$id]);
}
- /**
- * {@inheritdoc}
- */
public function get(string $id): mixed
{
if (!isset($this->factories[$id])) {
@@ -71,9 +65,6 @@ trait ServiceLocatorTrait
}
}
- /**
- * {@inheritdoc}
- */
public function getProvidedServices(): array
{
if (!isset($this->providedTypes)) {
diff --git a/vendor/symfony/service-contracts/ServiceProviderInterface.php b/vendor/symfony/service-contracts/ServiceProviderInterface.php
index c60ad0b..2e71f00 100644
--- a/vendor/symfony/service-contracts/ServiceProviderInterface.php
+++ b/vendor/symfony/service-contracts/ServiceProviderInterface.php
@@ -18,9 +18,18 @@ use Psr\Container\ContainerInterface;
*
* @author Nicolas Grekas
* @author Mateusz Sip
+ *
+ * @template-covariant T of mixed
*/
interface ServiceProviderInterface extends ContainerInterface
{
+ /**
+ * @return T
+ */
+ public function get(string $id): mixed;
+
+ public function has(string $id): bool;
+
/**
* Returns an associative array of service types keyed by the identifiers provided by the current container.
*
@@ -30,7 +39,7 @@ interface ServiceProviderInterface extends ContainerInterface
* * ['foo' => '?'] means the container provides service name "foo" of unspecified type
* * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null
*
- * @return string[] The provided service types, keyed by service names
+ * @return array The provided service types, keyed by service names
*/
public function getProvidedServices(): array;
}
diff --git a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php
index 881ab97..3da1916 100644
--- a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php
+++ b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Contracts\Service;
+use Symfony\Contracts\Service\Attribute\SubscribedService;
+
/**
* A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method.
*
@@ -29,7 +31,8 @@ namespace Symfony\Contracts\Service;
interface ServiceSubscriberInterface
{
/**
- * Returns an array of service types required by such instances, optionally keyed by the service names used internally.
+ * Returns an array of service types (or {@see SubscribedService} objects) required
+ * by such instances, optionally keyed by the service names used internally.
*
* For mandatory dependencies:
*
@@ -47,7 +50,13 @@ interface ServiceSubscriberInterface
* * ['?Psr\Log\LoggerInterface'] is a shortcut for
* * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
*
- * @return string[] The required service types, optionally keyed by service names
+ * additionally, an array of {@see SubscribedService}'s can be returned:
+ *
+ * * [new SubscribedService('logger', Psr\Log\LoggerInterface::class)]
+ * * [new SubscribedService(type: Psr\Log\LoggerInterface::class, nullable: true)]
+ * * [new SubscribedService('http_client', HttpClientInterface::class, attributes: new Target('githubApi'))]
+ *
+ * @return string[]|SubscribedService[] The required service types, optionally keyed by service names
*/
public static function getSubscribedServices(): array;
}
diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
index ee9d9d9..f3b450c 100644
--- a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
+++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
@@ -12,6 +12,7 @@
namespace Symfony\Contracts\Service;
use Psr\Container\ContainerInterface;
+use Symfony\Contracts\Service\Attribute\Required;
use Symfony\Contracts\Service\Attribute\SubscribedService;
/**
@@ -25,9 +26,6 @@ trait ServiceSubscriberTrait
/** @var ContainerInterface */
protected $container;
- /**
- * {@inheritdoc}
- */
public static function getSubscribedServices(): array
{
$services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : [];
@@ -49,29 +47,32 @@ trait ServiceSubscriberTrait
throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class));
}
- $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
+ /* @var SubscribedService $attribute */
+ $attribute = $attribute->newInstance();
+ $attribute->key ??= self::class.'::'.$method->name;
+ $attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
+ $attribute->nullable = $returnType->allowsNull();
- if ($returnType->allowsNull()) {
- $serviceId = '?'.$serviceId;
+ if ($attribute->attributes) {
+ $services[] = $attribute;
+ } else {
+ $services[$attribute->key] = ($attribute->nullable ? '?' : '').$attribute->type;
}
-
- $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId;
}
return $services;
}
- /**
- * @required
- */
+ #[Required]
public function setContainer(ContainerInterface $container): ?ContainerInterface
{
- $this->container = $container;
-
+ $ret = null;
if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) {
- return parent::setContainer($container);
+ $ret = parent::setContainer($container);
}
- return null;
+ $this->container = $container;
+
+ return $ret;
}
}
diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php
index 88f6a06..07d12b4 100644
--- a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php
+++ b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php
@@ -11,82 +11,13 @@
namespace Symfony\Contracts\Service\Test;
-use PHPUnit\Framework\TestCase;
-use Psr\Container\ContainerInterface;
-use Symfony\Contracts\Service\ServiceLocatorTrait;
+class_alias(ServiceLocatorTestCase::class, ServiceLocatorTest::class);
-abstract class ServiceLocatorTest extends TestCase
-{
- protected function getServiceLocator(array $factories): ContainerInterface
+if (false) {
+ /**
+ * @deprecated since PHPUnit 9.6
+ */
+ class ServiceLocatorTest
{
- return new class($factories) implements ContainerInterface {
- use ServiceLocatorTrait;
- };
- }
-
- public function testHas()
- {
- $locator = $this->getServiceLocator([
- 'foo' => function () { return 'bar'; },
- 'bar' => function () { return 'baz'; },
- function () { return 'dummy'; },
- ]);
-
- $this->assertTrue($locator->has('foo'));
- $this->assertTrue($locator->has('bar'));
- $this->assertFalse($locator->has('dummy'));
- }
-
- public function testGet()
- {
- $locator = $this->getServiceLocator([
- 'foo' => function () { return 'bar'; },
- 'bar' => function () { return 'baz'; },
- ]);
-
- $this->assertSame('bar', $locator->get('foo'));
- $this->assertSame('baz', $locator->get('bar'));
- }
-
- public function testGetDoesNotMemoize()
- {
- $i = 0;
- $locator = $this->getServiceLocator([
- 'foo' => function () use (&$i) {
- ++$i;
-
- return 'bar';
- },
- ]);
-
- $this->assertSame('bar', $locator->get('foo'));
- $this->assertSame('bar', $locator->get('foo'));
- $this->assertSame(2, $i);
- }
-
- public function testThrowsOnUndefinedInternalService()
- {
- if (!$this->getExpectedException()) {
- $this->expectException(\Psr\Container\NotFoundExceptionInterface::class);
- $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.');
- }
- $locator = $this->getServiceLocator([
- 'foo' => function () use (&$locator) { return $locator->get('bar'); },
- ]);
-
- $locator->get('foo');
- }
-
- public function testThrowsOnCircularReference()
- {
- $this->expectException(\Psr\Container\ContainerExceptionInterface::class);
- $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".');
- $locator = $this->getServiceLocator([
- 'foo' => function () use (&$locator) { return $locator->get('bar'); },
- 'bar' => function () use (&$locator) { return $locator->get('baz'); },
- 'baz' => function () use (&$locator) { return $locator->get('bar'); },
- ]);
-
- $locator->get('foo');
}
}
diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json
index d3b047f..a64188b 100644
--- a/vendor/symfony/service-contracts/composer.json
+++ b/vendor/symfony/service-contracts/composer.json
@@ -16,22 +16,22 @@
}
],
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.1",
"psr/container": "^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
},
- "suggest": {
- "symfony/service-implementation": ""
- },
"autoload": {
- "psr-4": { "Symfony\\Contracts\\Service\\": "" }
+ "psr-4": { "Symfony\\Contracts\\Service\\": "" },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "3.0-dev"
+ "dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/symfony/stopwatch/LICENSE b/vendor/symfony/stopwatch/LICENSE
index 0083704..0138f8f 100644
--- a/vendor/symfony/stopwatch/LICENSE
+++ b/vendor/symfony/stopwatch/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2023 Fabien Potencier
+Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/stopwatch/Stopwatch.php b/vendor/symfony/stopwatch/Stopwatch.php
index 3d6c976..bf65ac3 100644
--- a/vendor/symfony/stopwatch/Stopwatch.php
+++ b/vendor/symfony/stopwatch/Stopwatch.php
@@ -59,7 +59,7 @@ class Stopwatch implements ResetInterface
*
* @throws \LogicException When the section to re-open is not reachable
*/
- public function openSection(string $id = null)
+ public function openSection(string $id = null): void
{
$current = end($this->activeSections);
@@ -81,7 +81,7 @@ class Stopwatch implements ResetInterface
*
* @throws \LogicException When there's no started section to be stopped
*/
- public function stopSection(string $id)
+ public function stopSection(string $id): void
{
$this->stop('__section__');
@@ -146,7 +146,7 @@ class Stopwatch implements ResetInterface
/**
* Resets the stopwatch to its original state.
*/
- public function reset()
+ public function reset(): void
{
$this->sections = $this->activeSections = ['__root__' => new Section(null, $this->morePrecision)];
}
diff --git a/vendor/symfony/stopwatch/StopwatchEvent.php b/vendor/symfony/stopwatch/StopwatchEvent.php
index 518937d..4492d2d 100644
--- a/vendor/symfony/stopwatch/StopwatchEvent.php
+++ b/vendor/symfony/stopwatch/StopwatchEvent.php
@@ -117,7 +117,7 @@ class StopwatchEvent
/**
* Stops all non already stopped periods.
*/
- public function ensureStopped()
+ public function ensureStopped(): void
{
while (\count($this->started)) {
$this->stop();
diff --git a/vendor/symfony/stopwatch/composer.json b/vendor/symfony/stopwatch/composer.json
index bb68c24..3556869 100644
--- a/vendor/symfony/stopwatch/composer.json
+++ b/vendor/symfony/stopwatch/composer.json
@@ -16,8 +16,8 @@
}
],
"require": {
- "php": ">=8.0.2",
- "symfony/service-contracts": "^1|^2|^3"
+ "php": ">=8.2",
+ "symfony/service-contracts": "^2.5|^3"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Stopwatch\\": "" },
diff --git a/vendor/symfony/string/AbstractString.php b/vendor/symfony/string/AbstractString.php
index cf96a83..10231a2 100644
--- a/vendor/symfony/string/AbstractString.php
+++ b/vendor/symfony/string/AbstractString.php
@@ -39,8 +39,8 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE;
public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE;
- protected $string = '';
- protected $ignoreCase = false;
+ protected string $string = '';
+ protected ?bool $ignoreCase = false;
abstract public function __construct(string $string = '');
@@ -74,7 +74,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
foreach ($values as $k => $v) {
if (\is_string($k) && '' !== $k && $k !== $j = (string) new static($k)) {
- $keys = $keys ?? array_keys($values);
+ $keys ??= array_keys($values);
$keys[$i] = $j;
}
@@ -448,19 +448,11 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
$delimiter .= 'i';
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
if (false === $chunks = preg_split($delimiter, $this->string, $limit, $flags)) {
- $lastError = preg_last_error();
-
- foreach (get_defined_constants(true)['pcre'] as $k => $v) {
- if ($lastError === $v && '_ERROR' === substr($k, -6)) {
- throw new RuntimeException('Splitting failed with '.$k.'.');
- }
- }
-
- throw new RuntimeException('Splitting failed with unknown error code.');
+ throw new RuntimeException('Splitting failed with error: '.preg_last_error_msg());
}
} finally {
restore_error_handler();
@@ -515,20 +507,14 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
return $b;
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
-
try {
- try {
- $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8');
- } catch (InvalidArgumentException $e) {
- if (!\function_exists('iconv')) {
- throw $e;
- }
-
- $b->string = iconv('UTF-8', $toEncoding, $this->string);
+ $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8');
+ } catch (\ValueError $e) {
+ if (!\function_exists('iconv')) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
- } finally {
- restore_error_handler();
+
+ $b->string = iconv('UTF-8', $toEncoding, $this->string);
}
return $b;
@@ -558,7 +544,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
*/
public function trimPrefix($prefix): static
{
- if (\is_array($prefix) || $prefix instanceof \Traversable) {
+ if (\is_array($prefix) || $prefix instanceof \Traversable) { // don't use is_iterable(), it's slow
foreach ($prefix as $s) {
$t = $this->trimPrefix($s);
@@ -592,7 +578,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
*/
public function trimSuffix($suffix): static
{
- if (\is_array($suffix) || $suffix instanceof \Traversable) {
+ if (\is_array($suffix) || $suffix instanceof \Traversable) { // don't use is_iterable(), it's slow
foreach ($suffix as $s) {
$t = $this->trimSuffix($s);
diff --git a/vendor/symfony/string/AbstractUnicodeString.php b/vendor/symfony/string/AbstractUnicodeString.php
index 00096df..df7265f 100644
--- a/vendor/symfony/string/AbstractUnicodeString.php
+++ b/vendor/symfony/string/AbstractUnicodeString.php
@@ -37,20 +37,16 @@ abstract class AbstractUnicodeString extends AbstractString
private const ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
// the subset of folded case mappings that is not in lower case mappings
- private const FOLD_FROM = ['İ', 'µ', 'ſ', "\xCD\x85", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "\xE1\xBE\xBE", 'ß', 'İ', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ'];
- private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'i̇', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ'];
-
- // the subset of upper case mappings that map one code point to many code points
- private const UPPER_FROM = ['ß', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'և', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ', 'ʼn', 'ΐ', 'ΰ', 'ǰ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾶ', 'ῆ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῶ'];
- private const UPPER_TO = ['SS', 'FF', 'FI', 'FL', 'FFI', 'FFL', 'ST', 'ST', 'ԵՒ', 'ՄՆ', 'ՄԵ', 'ՄԻ', 'ՎՆ', 'ՄԽ', 'ʼN', 'Ϊ́', 'Ϋ́', 'J̌', 'H̱', 'T̈', 'W̊', 'Y̊', 'Aʾ', 'Υ̓', 'Υ̓̀', 'Υ̓́', 'Υ̓͂', 'Α͂', 'Η͂', 'Ϊ̀', 'Ϊ́', 'Ι͂', 'Ϊ͂', 'Ϋ̀', 'Ϋ́', 'Ρ̓', 'Υ͂', 'Ϋ͂', 'Ω͂'];
+ private const FOLD_FROM = ['İ', 'µ', 'ſ', "\xCD\x85", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "\xE1\xBE\xBE", 'ß', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ῖ', 'ῗ', 'ῢ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ'];
+ private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ῖ', 'ῗ', 'ῢ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ'];
// the subset of https://github.com/unicode-org/cldr/blob/master/common/transforms/Latin-ASCII.xml that is not in NFKD
private const TRANSLIT_FROM = ['Æ', 'Ð', 'Ø', 'Þ', 'ß', 'æ', 'ð', 'ø', 'þ', 'Đ', 'đ', 'Ħ', 'ħ', 'ı', 'ĸ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'ʼn', 'Ŋ', 'ŋ', 'Œ', 'œ', 'Ŧ', 'ŧ', 'ƀ', 'Ɓ', 'Ƃ', 'ƃ', 'Ƈ', 'ƈ', 'Ɖ', 'Ɗ', 'Ƌ', 'ƌ', 'Ɛ', 'Ƒ', 'ƒ', 'Ɠ', 'ƕ', 'Ɩ', 'Ɨ', 'Ƙ', 'ƙ', 'ƚ', 'Ɲ', 'ƞ', 'Ƣ', 'ƣ', 'Ƥ', 'ƥ', 'ƫ', 'Ƭ', 'ƭ', 'Ʈ', 'Ʋ', 'Ƴ', 'ƴ', 'Ƶ', 'ƶ', 'DŽ', 'Dž', 'dž', 'Ǥ', 'ǥ', 'ȡ', 'Ȥ', 'ȥ', 'ȴ', 'ȵ', 'ȶ', 'ȷ', 'ȸ', 'ȹ', 'Ⱥ', 'Ȼ', 'ȼ', 'Ƚ', 'Ⱦ', 'ȿ', 'ɀ', 'Ƀ', 'Ʉ', 'Ɇ', 'ɇ', 'Ɉ', 'ɉ', 'Ɍ', 'ɍ', 'Ɏ', 'ɏ', 'ɓ', 'ɕ', 'ɖ', 'ɗ', 'ɛ', 'ɟ', 'ɠ', 'ɡ', 'ɢ', 'ɦ', 'ɧ', 'ɨ', 'ɪ', 'ɫ', 'ɬ', 'ɭ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɶ', 'ɼ', 'ɽ', 'ɾ', 'ʀ', 'ʂ', 'ʈ', 'ʉ', 'ʋ', 'ʏ', 'ʐ', 'ʑ', 'ʙ', 'ʛ', 'ʜ', 'ʝ', 'ʟ', 'ʠ', 'ʣ', 'ʥ', 'ʦ', 'ʪ', 'ʫ', 'ᴀ', 'ᴁ', 'ᴃ', 'ᴄ', 'ᴅ', 'ᴆ', 'ᴇ', 'ᴊ', 'ᴋ', 'ᴌ', 'ᴍ', 'ᴏ', 'ᴘ', 'ᴛ', 'ᴜ', 'ᴠ', 'ᴡ', 'ᴢ', 'ᵫ', 'ᵬ', 'ᵭ', 'ᵮ', 'ᵯ', 'ᵰ', 'ᵱ', 'ᵲ', 'ᵳ', 'ᵴ', 'ᵵ', 'ᵶ', 'ᵺ', 'ᵻ', 'ᵽ', 'ᵾ', 'ᶀ', 'ᶁ', 'ᶂ', 'ᶃ', 'ᶄ', 'ᶅ', 'ᶆ', 'ᶇ', 'ᶈ', 'ᶉ', 'ᶊ', 'ᶌ', 'ᶍ', 'ᶎ', 'ᶏ', 'ᶑ', 'ᶒ', 'ᶓ', 'ᶖ', 'ᶙ', 'ẚ', 'ẜ', 'ẝ', 'ẞ', 'Ỻ', 'ỻ', 'Ỽ', 'ỽ', 'Ỿ', 'ỿ', '©', '®', '₠', '₢', '₣', '₤', '₧', '₺', '₹', 'ℌ', '℞', '㎧', '㎮', '㏆', '㏗', '㏞', '㏟', '¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '〇', '‘', '’', '‚', '‛', '“', '”', '„', '‟', '′', '″', '〝', '〞', '«', '»', '‹', '›', '‐', '‑', '‒', '–', '—', '―', '︱', '︲', '﹘', '‖', '⁄', '⁅', '⁆', '⁎', '、', '。', '〈', '〉', '《', '》', '〔', '〕', '〘', '〙', '〚', '〛', '︑', '︒', '︹', '︺', '︽', '︾', '︿', '﹀', '﹑', '﹝', '﹞', '⦅', '⦆', '。', '、', '×', '÷', '−', '∕', '∖', '∣', '∥', '≪', '≫', '⦅', '⦆'];
private const TRANSLIT_TO = ['AE', 'D', 'O', 'TH', 'ss', 'ae', 'd', 'o', 'th', 'D', 'd', 'H', 'h', 'i', 'q', 'L', 'l', 'L', 'l', '\'n', 'N', 'n', 'OE', 'oe', 'T', 't', 'b', 'B', 'B', 'b', 'C', 'c', 'D', 'D', 'D', 'd', 'E', 'F', 'f', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'N', 'n', 'OI', 'oi', 'P', 'p', 't', 'T', 't', 'T', 'V', 'Y', 'y', 'Z', 'z', 'DZ', 'Dz', 'dz', 'G', 'g', 'd', 'Z', 'z', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's', 'z', 'B', 'U', 'E', 'e', 'J', 'j', 'R', 'r', 'Y', 'y', 'b', 'c', 'd', 'd', 'e', 'j', 'g', 'g', 'G', 'h', 'h', 'i', 'I', 'l', 'l', 'l', 'm', 'n', 'n', 'N', 'OE', 'r', 'r', 'r', 'R', 's', 't', 'u', 'v', 'Y', 'z', 'z', 'B', 'G', 'H', 'j', 'L', 'q', 'dz', 'dz', 'ts', 'ls', 'lz', 'A', 'AE', 'B', 'C', 'D', 'D', 'E', 'J', 'K', 'L', 'M', 'O', 'P', 'T', 'U', 'V', 'W', 'Z', 'ue', 'b', 'd', 'f', 'm', 'n', 'p', 'r', 'r', 's', 't', 'z', 'th', 'I', 'p', 'U', 'b', 'd', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'v', 'x', 'z', 'a', 'd', 'e', 'e', 'i', 'u', 'a', 's', 's', 'SS', 'LL', 'll', 'V', 'v', 'Y', 'y', '(C)', '(R)', 'CE', 'Cr', 'Fr.', 'L.', 'Pts', 'TL', 'Rs', 'x', 'Rx', 'm/s', 'rad/s', 'C/kg', 'pH', 'V/m', 'A/m', ' 1/4', ' 1/2', ' 3/4', ' 1/3', ' 2/3', ' 1/5', ' 2/5', ' 3/5', ' 4/5', ' 1/6', ' 5/6', ' 1/8', ' 3/8', ' 5/8', ' 7/8', ' 1/', '0', '\'', '\'', ',', '\'', '"', '"', ',,', '"', '\'', '"', '"', '"', '<<', '>>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))'];
- private static $transliterators = [];
- private static $tableZero;
- private static $tableWide;
+ private static array $transliterators = [];
+ private static array $tableZero;
+ private static array $tableWide;
public static function fromCodePoints(int ...$codes): static
{
@@ -121,10 +117,10 @@ abstract class AbstractUnicodeString extends AbstractString
$s = preg_replace("/([AUO])\u{0308}(?=\p{Ll})/u", '$1e', $s);
$s = str_replace(["a\u{0308}", "o\u{0308}", "u\u{0308}", "A\u{0308}", "O\u{0308}", "U\u{0308}"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s);
} elseif (\function_exists('transliterator_transliterate')) {
- if (null === $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule)) {
+ if (null === $transliterator = self::$transliterators[$rule] ??= \Transliterator::create($rule)) {
if ('any-latin/bgn' === $rule) {
$rule = 'any-latin';
- $transliterator = self::$transliterators[$rule] ?? self::$transliterators[$rule] = \Transliterator::create($rule);
+ $transliterator = self::$transliterators[$rule] ??= \Transliterator::create($rule);
}
if (null === $transliterator) {
@@ -159,7 +155,9 @@ abstract class AbstractUnicodeString extends AbstractString
public function camel(): static
{
$str = clone $this;
- $str->string = str_replace(' ', '', preg_replace_callback('/\b.(?![A-Z]{2,})/u', static function ($m) use (&$i) {
+ $str->string = str_replace(' ', '', preg_replace_callback('/\b.(?![A-Z]{2,})/u', static function ($m) {
+ static $i = 0;
+
return 1 === ++$i ? ('İ' === $m[0] ? 'i̇' : mb_strtolower($m[0], 'UTF-8')) : mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
}, preg_replace('/[^\pL0-9]++/u', ' ', $this->string)));
@@ -230,19 +228,11 @@ abstract class AbstractUnicodeString extends AbstractString
$regexp .= 'i';
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
if (false === $match($regexp.'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
- $lastError = preg_last_error();
-
- foreach (get_defined_constants(true)['pcre'] as $k => $v) {
- if ($lastError === $v && '_ERROR' === substr($k, -6)) {
- throw new RuntimeException('Matching failed with '.$k.'.');
- }
- }
-
- throw new RuntimeException('Matching failed with unknown error code.');
+ throw new RuntimeException('Matching failed with error: '.preg_last_error_msg());
}
} finally {
restore_error_handler();
@@ -322,14 +312,14 @@ abstract class AbstractUnicodeString extends AbstractString
$replace = 'preg_replace';
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
if (null === $string = $replace($fromRegexp.'u', $to, $this->string)) {
$lastError = preg_last_error();
foreach (get_defined_constants(true)['pcre'] as $k => $v) {
- if ($lastError === $v && '_ERROR' === substr($k, -6)) {
+ if ($lastError === $v && str_ends_with($k, '_ERROR')) {
throw new RuntimeException('Matching failed with '.$k.'.');
}
}
@@ -368,9 +358,7 @@ abstract class AbstractUnicodeString extends AbstractString
$limit = $allWords ? -1 : 1;
- $str->string = preg_replace_callback('/\b./u', static function (array $m): string {
- return mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
- }, $str->string, $limit);
+ $str->string = preg_replace_callback('/\b./u', static fn (array $m): string => mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'), $str->string, $limit);
return $str;
}
@@ -467,7 +455,7 @@ abstract class AbstractUnicodeString extends AbstractString
$width = 0;
$s = str_replace(["\x00", "\x05", "\x07"], '', $this->string);
- if (false !== strpos($s, "\r")) {
+ if (str_contains($s, "\r")) {
$s = str_replace(["\r\n", "\r"], "\n", $s);
}
@@ -558,9 +546,7 @@ abstract class AbstractUnicodeString extends AbstractString
return -1;
}
- if (null === self::$tableZero) {
- self::$tableZero = require __DIR__.'/Resources/data/wcswidth_table_zero.php';
- }
+ self::$tableZero ??= require __DIR__.'/Resources/data/wcswidth_table_zero.php';
if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) {
$lbound = 0;
@@ -577,9 +563,7 @@ abstract class AbstractUnicodeString extends AbstractString
}
}
- if (null === self::$tableWide) {
- self::$tableWide = require __DIR__.'/Resources/data/wcswidth_table_wide.php';
- }
+ self::$tableWide ??= require __DIR__.'/Resources/data/wcswidth_table_wide.php';
if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) {
$lbound = 0;
diff --git a/vendor/symfony/string/ByteString.php b/vendor/symfony/string/ByteString.php
index 639d643..f5050dd 100644
--- a/vendor/symfony/string/ByteString.php
+++ b/vendor/symfony/string/ByteString.php
@@ -48,7 +48,7 @@ class ByteString extends AbstractString
throw new InvalidArgumentException(sprintf('A strictly positive length is expected, "%d" given.', $length));
}
- $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC;
+ $alphabet ??= self::ALPHABET_ALPHANUMERIC;
$alphabetSize = \strlen($alphabet);
$bits = (int) ceil(log($alphabetSize, 2.0));
if ($bits <= 0 || $bits > 56) {
@@ -236,19 +236,11 @@ class ByteString extends AbstractString
$regexp .= 'i';
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
if (false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
- $lastError = preg_last_error();
-
- foreach (get_defined_constants(true)['pcre'] as $k => $v) {
- if ($lastError === $v && '_ERROR' === substr($k, -6)) {
- throw new RuntimeException('Matching failed with '.$k.'.');
- }
- }
-
- throw new RuntimeException('Matching failed with unknown error code.');
+ throw new RuntimeException('Matching failed with error: '.preg_last_error_msg());
}
} finally {
restore_error_handler();
@@ -308,14 +300,14 @@ class ByteString extends AbstractString
$replace = \is_array($to) || $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace';
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
if (null === $string = $replace($fromRegexp, $to, $this->string)) {
$lastError = preg_last_error();
foreach (get_defined_constants(true)['pcre'] as $k => $v) {
- if ($lastError === $v && '_ERROR' === substr($k, -6)) {
+ if ($lastError === $v && str_ends_with($k, '_ERROR')) {
throw new RuntimeException('Matching failed with '.$k.'.');
}
}
@@ -366,7 +358,7 @@ class ByteString extends AbstractString
public function split(string $delimiter, int $limit = null, int $flags = null): array
{
- if (1 > $limit = $limit ?? \PHP_INT_MAX) {
+ if (1 > $limit ??= \PHP_INT_MAX) {
throw new InvalidArgumentException('Split limit must be a positive integer.');
}
@@ -425,7 +417,7 @@ class ByteString extends AbstractString
return $u;
}
- set_error_handler(static function ($t, $m) { throw new InvalidArgumentException($m); });
+ set_error_handler(static fn ($t, $m) => throw new InvalidArgumentException($m));
try {
try {
diff --git a/vendor/symfony/string/CHANGELOG.md b/vendor/symfony/string/CHANGELOG.md
index 53af364..31a3b54 100644
--- a/vendor/symfony/string/CHANGELOG.md
+++ b/vendor/symfony/string/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+6.2
+---
+
+ * Add support for emoji in `AsciiSlugger`
+
5.4
---
diff --git a/vendor/symfony/string/CodePointString.php b/vendor/symfony/string/CodePointString.php
index 926ff79..f5c900f 100644
--- a/vendor/symfony/string/CodePointString.php
+++ b/vendor/symfony/string/CodePointString.php
@@ -210,7 +210,7 @@ class CodePointString extends AbstractUnicodeString
public function split(string $delimiter, int $limit = null, int $flags = null): array
{
- if (1 > $limit = $limit ?? \PHP_INT_MAX) {
+ if (1 > $limit ??= \PHP_INT_MAX) {
throw new InvalidArgumentException('Split limit must be a positive integer.');
}
diff --git a/vendor/symfony/string/Inflector/EnglishInflector.php b/vendor/symfony/string/Inflector/EnglishInflector.php
index 9f2fac6..feea7f6 100644
--- a/vendor/symfony/string/Inflector/EnglishInflector.php
+++ b/vendor/symfony/string/Inflector/EnglishInflector.php
@@ -21,7 +21,7 @@ final class EnglishInflector implements InflectorInterface
private const PLURAL_MAP = [
// First entry: plural suffix, reversed
// Second entry: length of plural suffix
- // Third entry: Whether the suffix may succeed a vocal
+ // Third entry: Whether the suffix may succeed a vowel
// Fourth entry: Whether the suffix may succeed a consonant
// Fifth entry: singular suffix, normal
@@ -55,6 +55,9 @@ final class EnglishInflector implements InflectorInterface
// indices (index), appendices (appendix), prices (price)
['seci', 4, false, true, ['ex', 'ix', 'ice']],
+ // codes (code)
+ ['sedoc', 5, false, true, 'code'],
+
// selfies (selfie)
['seifles', 7, true, true, 'selfie'],
@@ -64,6 +67,9 @@ final class EnglishInflector implements InflectorInterface
// movies (movie)
['seivom', 6, true, true, 'movie'],
+ // names (name)
+ ['seman', 5, true, false, 'name'],
+
// conspectuses (conspectus), prospectuses (prospectus)
['sesutcep', 8, true, true, 'pectus'],
@@ -88,6 +94,9 @@ final class EnglishInflector implements InflectorInterface
// accesses (access), addresses (address), kisses (kiss)
['sess', 4, true, false, 'ss'],
+ // statuses (status)
+ ['sesutats', 8, true, true, 'status'],
+
// analyses (analysis), ellipses (ellipsis), fungi (fungus),
// neuroses (neurosis), theses (thesis), emphases (emphasis),
// oases (oasis), crises (crisis), houses (house), bases (base),
@@ -132,6 +141,9 @@ final class EnglishInflector implements InflectorInterface
// shoes (shoe)
['se', 2, true, true, ['', 'e']],
+ // status (status)
+ ['sutats', 6, true, true, 'status'],
+
// tags (tag)
['s', 1, true, true, ''],
@@ -150,7 +162,7 @@ final class EnglishInflector implements InflectorInterface
private const SINGULAR_MAP = [
// First entry: singular suffix, reversed
// Second entry: length of singular suffix
- // Third entry: Whether the suffix may succeed a vocal
+ // Third entry: Whether the suffix may succeed a vowel
// Fourth entry: Whether the suffix may succeed a consonant
// Fifth entry: plural suffix, normal
@@ -241,6 +253,9 @@ final class EnglishInflector implements InflectorInterface
// seasons (season), treasons (treason), poisons (poison), lessons (lesson)
['nos', 3, true, true, 'sons'],
+ // icons (icon)
+ ['noc', 3, true, true, 'cons'],
+
// bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
['no', 2, true, true, 'a'],
@@ -273,6 +288,9 @@ final class EnglishInflector implements InflectorInterface
// circuses (circus)
['suc', 3, true, true, 'cuses'],
+ // status (status)
+ ['sutats', 6, true, true, ['status', 'statuses']],
+
// conspectuses (conspectus), prospectuses (prospectus)
['sutcep', 6, true, true, 'pectuses'],
@@ -328,15 +346,30 @@ final class EnglishInflector implements InflectorInterface
// deer
'reed',
+ // equipment
+ 'tnempiuqe',
+
// feedback
'kcabdeef',
// fish
'hsif',
+ // health
+ 'htlaeh',
+
+ // history
+ 'yrotsih',
+
// info
'ofni',
+ // information
+ 'noitamrofni',
+
+ // money
+ 'yenom',
+
// moose
'esoom',
@@ -348,11 +381,11 @@ final class EnglishInflector implements InflectorInterface
// species
'seiceps',
+
+ // traffic
+ 'ciffart',
];
- /**
- * {@inheritdoc}
- */
public function singularize(string $plural): array
{
$pluralRev = strrev($plural);
@@ -384,14 +417,14 @@ final class EnglishInflector implements InflectorInterface
if ($j === $suffixLength) {
// Is there any character preceding the suffix in the plural string?
if ($j < $pluralLength) {
- $nextIsVocal = false !== strpos('aeiou', $lowerPluralRev[$j]);
+ $nextIsVowel = str_contains('aeiou', $lowerPluralRev[$j]);
- if (!$map[2] && $nextIsVocal) {
- // suffix may not succeed a vocal but next char is one
+ if (!$map[2] && $nextIsVowel) {
+ // suffix may not succeed a vowel but next char is one
break;
}
- if (!$map[3] && !$nextIsVocal) {
+ if (!$map[3] && !$nextIsVowel) {
// suffix may not succeed a consonant but next char is one
break;
}
@@ -429,9 +462,6 @@ final class EnglishInflector implements InflectorInterface
return [$plural];
}
- /**
- * {@inheritdoc}
- */
public function pluralize(string $singular): array
{
$singularRev = strrev($singular);
@@ -464,14 +494,14 @@ final class EnglishInflector implements InflectorInterface
if ($j === $suffixLength) {
// Is there any character preceding the suffix in the plural string?
if ($j < $singularLength) {
- $nextIsVocal = false !== strpos('aeiou', $lowerSingularRev[$j]);
+ $nextIsVowel = str_contains('aeiou', $lowerSingularRev[$j]);
- if (!$map[2] && $nextIsVocal) {
- // suffix may not succeed a vocal but next char is one
+ if (!$map[2] && $nextIsVowel) {
+ // suffix may not succeed a vowel but next char is one
break;
}
- if (!$map[3] && !$nextIsVocal) {
+ if (!$map[3] && !$nextIsVowel) {
// suffix may not succeed a consonant but next char is one
break;
}
diff --git a/vendor/symfony/string/Inflector/FrenchInflector.php b/vendor/symfony/string/Inflector/FrenchInflector.php
index 612c8f2..955abbf 100644
--- a/vendor/symfony/string/Inflector/FrenchInflector.php
+++ b/vendor/symfony/string/Inflector/FrenchInflector.php
@@ -110,9 +110,6 @@ final class FrenchInflector implements InflectorInterface
*/
private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sans|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i';
- /**
- * {@inheritdoc}
- */
public function singularize(string $plural): array
{
if ($this->isInflectedWord($plural)) {
@@ -130,9 +127,6 @@ final class FrenchInflector implements InflectorInterface
return [$plural];
}
- /**
- * {@inheritdoc}
- */
public function pluralize(string $singular): array
{
if ($this->isInflectedWord($singular)) {
diff --git a/vendor/symfony/string/LICENSE b/vendor/symfony/string/LICENSE
index 5c7ba05..f37c76b 100644
--- a/vendor/symfony/string/LICENSE
+++ b/vendor/symfony/string/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019-2023 Fabien Potencier
+Copyright (c) 2019-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/string/LazyString.php b/vendor/symfony/string/LazyString.php
index 3733078..0341bea 100644
--- a/vendor/symfony/string/LazyString.php
+++ b/vendor/symfony/string/LazyString.php
@@ -30,11 +30,13 @@ class LazyString implements \Stringable, \JsonSerializable
}
$lazyString = new static();
- $lazyString->value = static function () use (&$callback, &$arguments, &$value): string {
+ $lazyString->value = static function () use (&$callback, &$arguments): string {
+ static $value;
+
if (null !== $arguments) {
if (!\is_callable($callback)) {
$callback[0] = $callback[0]();
- $callback[1] = $callback[1] ?? '__invoke';
+ $callback[1] ??= '__invoke';
}
$value = $callback(...$arguments);
$callback = self::getPrettyName($callback);
@@ -50,7 +52,7 @@ class LazyString implements \Stringable, \JsonSerializable
public static function fromStringable(string|int|float|bool|\Stringable $value): static
{
if (\is_object($value)) {
- return static::fromCallable([$value, '__toString']);
+ return static::fromCallable($value->__toString(...));
}
$lazyString = new static();
@@ -86,7 +88,7 @@ class LazyString implements \Stringable, \JsonSerializable
try {
return $this->value = ($this->value)();
} catch (\Throwable $e) {
- if (\TypeError::class === \get_class($e) && __FILE__ === $e->getFile()) {
+ if (\TypeError::class === $e::class && __FILE__ === $e->getFile()) {
$type = explode(', ', $e->getMessage());
$type = substr(array_pop($type), 0, -\strlen(' returned'));
$r = new \ReflectionFunction($this->value);
@@ -127,7 +129,7 @@ class LazyString implements \Stringable, \JsonSerializable
} elseif ($callback instanceof \Closure) {
$r = new \ReflectionFunction($callback);
- if (false !== strpos($r->name, '{closure}') || !$class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) {
+ if (str_contains($r->name, '{closure}') || !$class = $r->getClosureCalledClass()) {
return $r->name;
}
diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php
index 5a647e6..8314c8f 100644
--- a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php
+++ b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php
@@ -3,8 +3,8 @@
/*
* This file has been auto-generated by the Symfony String Component for internal use.
*
- * Unicode version: 15.0.0
- * Date: 2022-10-05T17:16:36+02:00
+ * Unicode version: 15.1.0
+ * Date: 2023-09-13T11:47:12+00:00
*/
return [
@@ -166,7 +166,7 @@ return [
],
[
12272,
- 12283,
+ 12287,
],
[
12288,
@@ -396,6 +396,10 @@ return [
12736,
12771,
],
+ [
+ 12783,
+ 12783,
+ ],
[
12784,
12799,
@@ -1110,6 +1114,14 @@ return [
],
[
191457,
+ 191471,
+ ],
+ [
+ 191472,
+ 192093,
+ ],
+ [
+ 192094,
194559,
],
[
diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_zero.php b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php
index 9ae7330..e5b26a2 100644
--- a/vendor/symfony/string/Resources/data/wcswidth_table_zero.php
+++ b/vendor/symfony/string/Resources/data/wcswidth_table_zero.php
@@ -3,8 +3,8 @@
/*
* This file has been auto-generated by the Symfony String Component for internal use.
*
- * Unicode version: 15.0.0
- * Date: 2022-10-05T17:16:37+02:00
+ * Unicode version: 15.1.0
+ * Date: 2023-09-13T11:47:13+00:00
*/
return [
diff --git a/vendor/symfony/string/Resources/functions.php b/vendor/symfony/string/Resources/functions.php
index c950894..7a97040 100644
--- a/vendor/symfony/string/Resources/functions.php
+++ b/vendor/symfony/string/Resources/functions.php
@@ -31,7 +31,7 @@ if (!\function_exists(s::class)) {
*/
function s(?string $string = ''): AbstractString
{
- $string = $string ?? '';
+ $string ??= '';
return preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string);
}
diff --git a/vendor/symfony/string/Slugger/AsciiSlugger.php b/vendor/symfony/string/Slugger/AsciiSlugger.php
index 548a6b9..9f7eba9 100644
--- a/vendor/symfony/string/Slugger/AsciiSlugger.php
+++ b/vendor/symfony/string/Slugger/AsciiSlugger.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\String\Slugger;
+use Symfony\Component\Intl\Transliterator\EmojiTransliterator;
use Symfony\Component\String\AbstractUnicodeString;
use Symfony\Component\String\UnicodeString;
use Symfony\Contracts\Translation\LocaleAwareInterface;
@@ -58,6 +59,7 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
private \Closure|array $symbolsMap = [
'en' => ['@' => 'at', '&' => 'and'],
];
+ private bool|string $emoji = false;
/**
* Cache of transliterators per locale.
@@ -72,44 +74,54 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
$this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
}
- /**
- * {@inheritdoc}
- */
- public function setLocale(string $locale)
+ public function setLocale(string $locale): void
{
$this->defaultLocale = $locale;
}
- /**
- * {@inheritdoc}
- */
public function getLocale(): string
{
return $this->defaultLocale;
}
/**
- * {@inheritdoc}
+ * @param bool|string $emoji true will use the same locale,
+ * false will disable emoji,
+ * and a string to use a specific locale
*/
+ public function withEmoji(bool|string $emoji = true): static
+ {
+ if (false !== $emoji && !class_exists(EmojiTransliterator::class)) {
+ throw new \LogicException(sprintf('You cannot use the "%s()" method as the "symfony/intl" package is not installed. Try running "composer require symfony/intl".', __METHOD__));
+ }
+
+ $new = clone $this;
+ $new->emoji = $emoji;
+
+ return $new;
+ }
+
public function slug(string $string, string $separator = '-', string $locale = null): AbstractUnicodeString
{
- $locale = $locale ?? $this->defaultLocale;
+ $locale ??= $this->defaultLocale;
$transliterator = [];
- if ($locale && ('de' === $locale || 0 === strpos($locale, 'de_'))) {
+ if ($locale && ('de' === $locale || str_starts_with($locale, 'de_'))) {
// Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl)
$transliterator = ['de-ASCII'];
} elseif (\function_exists('transliterator_transliterate') && $locale) {
$transliterator = (array) $this->createTransliterator($locale);
}
+ if ($emojiTransliterator = $this->createEmojiTransliterator($locale)) {
+ $transliterator[] = $emojiTransliterator;
+ }
+
if ($this->symbolsMap instanceof \Closure) {
// If the symbols map is passed as a closure, there is no need to fallback to the parent locale
// as the closure can just provide substitutions for all locales of interest.
$symbolsMap = $this->symbolsMap;
- array_unshift($transliterator, static function ($s) use ($symbolsMap, $locale) {
- return $symbolsMap($s, $locale);
- });
+ array_unshift($transliterator, static fn ($s) => $symbolsMap($s, $locale));
}
$unicodeString = (new UnicodeString($string))->ascii($transliterator);
@@ -161,6 +173,25 @@ class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null;
}
+ private function createEmojiTransliterator(?string $locale): ?EmojiTransliterator
+ {
+ if (\is_string($this->emoji)) {
+ $locale = $this->emoji;
+ } elseif (!$this->emoji) {
+ return null;
+ }
+
+ while (null !== $locale) {
+ try {
+ return EmojiTransliterator::create("emoji-$locale");
+ } catch (\IntlException) {
+ $locale = self::getParentLocale($locale);
+ }
+ }
+
+ return null;
+ }
+
private static function getParentLocale(?string $locale): ?string
{
if (!$locale) {
diff --git a/vendor/symfony/string/UnicodeString.php b/vendor/symfony/string/UnicodeString.php
index 70cf4c5..bc09627 100644
--- a/vendor/symfony/string/UnicodeString.php
+++ b/vendor/symfony/string/UnicodeString.php
@@ -34,23 +34,32 @@ class UnicodeString extends AbstractUnicodeString
{
public function __construct(string $string = '')
{
- $this->string = normalizer_is_normalized($string) ? $string : normalizer_normalize($string);
+ if ('' === $string || normalizer_is_normalized($this->string = $string)) {
+ return;
+ }
- if (false === $this->string) {
+ if (false === $string = normalizer_normalize($string)) {
throw new InvalidArgumentException('Invalid UTF-8 string.');
}
+
+ $this->string = $string;
}
public function append(string ...$suffix): static
{
$str = clone $this;
$str->string = $this->string.(1 >= \count($suffix) ? ($suffix[0] ?? '') : implode('', $suffix));
- normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);
- if (false === $str->string) {
+ if (normalizer_is_normalized($str->string)) {
+ return $str;
+ }
+
+ if (false === $string = normalizer_normalize($str->string)) {
throw new InvalidArgumentException('Invalid UTF-8 string.');
}
+ $str->string = $string;
+
return $str;
}
@@ -139,7 +148,7 @@ class UnicodeString extends AbstractUnicodeString
try {
$i = $this->ignoreCase ? grapheme_stripos($this->string, $needle, $offset) : grapheme_strpos($this->string, $needle, $offset);
- } catch (\ValueError $e) {
+ } catch (\ValueError) {
return null;
}
@@ -209,12 +218,17 @@ class UnicodeString extends AbstractUnicodeString
{
$str = clone $this;
$str->string = (1 >= \count($prefix) ? ($prefix[0] ?? '') : implode('', $prefix)).$this->string;
- normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);
- if (false === $str->string) {
+ if (normalizer_is_normalized($str->string)) {
+ return $str;
+ }
+
+ if (false === $string = normalizer_normalize($str->string)) {
throw new InvalidArgumentException('Invalid UTF-8 string.');
}
+ $str->string = $string;
+
return $str;
}
@@ -235,11 +249,16 @@ class UnicodeString extends AbstractUnicodeString
}
$str->string = $result.$tail;
- normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);
- if (false === $str->string) {
+ if (normalizer_is_normalized($str->string)) {
+ return $str;
+ }
+
+ if (false === $string = normalizer_normalize($str->string)) {
throw new InvalidArgumentException('Invalid UTF-8 string.');
}
+
+ $str->string = $string;
}
return $str;
@@ -269,18 +288,23 @@ class UnicodeString extends AbstractUnicodeString
$start = $start ? \strlen(grapheme_substr($this->string, 0, $start)) : 0;
$length = $length ? \strlen(grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length;
$str->string = substr_replace($this->string, $replacement, $start, $length ?? 2147483647);
- normalizer_is_normalized($str->string) ?: $str->string = normalizer_normalize($str->string);
- if (false === $str->string) {
+ if (normalizer_is_normalized($str->string)) {
+ return $str;
+ }
+
+ if (false === $string = normalizer_normalize($str->string)) {
throw new InvalidArgumentException('Invalid UTF-8 string.');
}
+ $str->string = $string;
+
return $str;
}
public function split(string $delimiter, int $limit = null, int $flags = null): array
{
- if (1 > $limit = $limit ?? 2147483647) {
+ if (1 > $limit ??= 2147483647) {
throw new InvalidArgumentException('Split limit must be a positive integer.');
}
@@ -338,7 +362,7 @@ class UnicodeString extends AbstractUnicodeString
return $prefix === grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES);
}
- public function __wakeup()
+ public function __wakeup(): void
{
if (!\is_string($this->string)) {
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
diff --git a/vendor/symfony/string/composer.json b/vendor/symfony/string/composer.json
index 187323f..26ce26d 100644
--- a/vendor/symfony/string/composer.json
+++ b/vendor/symfony/string/composer.json
@@ -16,20 +16,21 @@
}
],
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/http-client": "^5.4|^6.0",
- "symfony/translation-contracts": "^2.0|^3.0",
- "symfony/var-exporter": "^5.4|^6.0"
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^6.4|^7.0"
},
"conflict": {
- "symfony/translation-contracts": "<2.0"
+ "symfony/translation-contracts": "<2.5"
},
"autoload": {
"psr-4": { "Symfony\\Component\\String\\": "" },
diff --git a/vendor/theseer/tokenizer/.php_cs.dist b/vendor/theseer/tokenizer/.php_cs.dist
deleted file mode 100644
index 8ac26d0..0000000
--- a/vendor/theseer/tokenizer/.php_cs.dist
+++ /dev/null
@@ -1,213 +0,0 @@
-registerCustomFixers([
- new \PharIo\CSFixer\PhpdocSingleLineVarFixer()
- ])
- ->setRiskyAllowed(true)
- ->setRules(
- [
- 'PharIo/phpdoc_single_line_var_fixer' => true,
-
- 'align_multiline_comment' => true,
- 'array_indentation' => true,
- 'array_syntax' => ['syntax' => 'short'],
- 'binary_operator_spaces' => [
- 'operators' => [
- '=' => 'align_single_space_minimal',
- '=>' => 'align',
- ],
- ],
- 'blank_line_after_namespace' => true,
- 'blank_line_after_opening_tag' => false,
- 'blank_line_before_statement' => [
- 'statements' => [
- 'break',
- 'continue',
- 'declare',
- 'do',
- 'for',
- 'foreach',
- 'if',
- 'include',
- 'include_once',
- 'require',
- 'require_once',
- 'return',
- 'switch',
- 'throw',
- 'try',
- 'while',
- 'yield',
- ],
- ],
- 'braces' => [
- 'allow_single_line_closure' => false,
- 'position_after_anonymous_constructs' => 'same',
- 'position_after_control_structures' => 'same',
- 'position_after_functions_and_oop_constructs' => 'same'
- ],
- 'cast_spaces' => ['space' => 'none'],
-
- // This fixer removes the blank line at class start, no way to disable that, so we disable the fixer :(
- //'class_attributes_separation' => ['elements' => ['const', 'method', 'property']],
-
- 'combine_consecutive_issets' => true,
- 'combine_consecutive_unsets' => true,
- 'compact_nullable_typehint' => true,
- 'concat_space' => ['spacing' => 'one'],
- 'date_time_immutable' => true,
- 'declare_equal_normalize' => ['space' => 'single'],
- 'declare_strict_types' => true,
- 'dir_constant' => true,
- 'elseif' => true,
- 'encoding' => true,
- 'full_opening_tag' => true,
- 'fully_qualified_strict_types' => true,
- 'function_declaration' => [
- 'closure_function_spacing' => 'one'
- ],
- 'header_comment' => false,
- 'indentation_type' => true,
- 'is_null' => true,
- 'line_ending' => true,
- 'list_syntax' => ['syntax' => 'short'],
- 'logical_operators' => true,
- 'lowercase_cast' => true,
- 'lowercase_constants' => true,
- 'lowercase_keywords' => true,
- 'lowercase_static_reference' => true,
- 'magic_constant_casing' => true,
- 'method_argument_space' => ['ensure_fully_multiline' => true],
- 'modernize_types_casting' => true,
- 'multiline_comment_opening_closing' => true,
- 'multiline_whitespace_before_semicolons' => true,
- 'native_constant_invocation' => true,
- 'native_function_casing' => true,
- 'native_function_invocation' => true,
- 'new_with_braces' => false,
- 'no_alias_functions' => true,
- 'no_alternative_syntax' => true,
- 'no_blank_lines_after_class_opening' => false,
- 'no_blank_lines_after_phpdoc' => true,
- 'no_blank_lines_before_namespace' => true,
- 'no_closing_tag' => true,
- 'no_empty_comment' => true,
- 'no_empty_phpdoc' => true,
- 'no_empty_statement' => true,
- 'no_extra_blank_lines' => true,
- 'no_homoglyph_names' => true,
- 'no_leading_import_slash' => true,
- 'no_leading_namespace_whitespace' => true,
- 'no_mixed_echo_print' => ['use' => 'print'],
- 'no_multiline_whitespace_around_double_arrow' => true,
- 'no_null_property_initialization' => true,
- 'no_php4_constructor' => true,
- 'no_short_bool_cast' => true,
- 'no_short_echo_tag' => true,
- 'no_singleline_whitespace_before_semicolons' => true,
- 'no_spaces_after_function_name' => true,
- 'no_spaces_inside_parenthesis' => true,
- 'no_superfluous_elseif' => true,
- 'no_superfluous_phpdoc_tags' => true,
- 'no_trailing_comma_in_list_call' => true,
- 'no_trailing_comma_in_singleline_array' => true,
- 'no_trailing_whitespace' => true,
- 'no_trailing_whitespace_in_comment' => true,
- 'no_unneeded_control_parentheses' => false,
- 'no_unneeded_curly_braces' => false,
- 'no_unneeded_final_method' => true,
- 'no_unreachable_default_argument_value' => true,
- 'no_unset_on_property' => true,
- 'no_unused_imports' => true,
- 'no_useless_else' => true,
- 'no_useless_return' => true,
- 'no_whitespace_before_comma_in_array' => true,
- 'no_whitespace_in_blank_line' => true,
- 'non_printable_character' => true,
- 'normalize_index_brace' => true,
- 'object_operator_without_whitespace' => true,
- 'ordered_class_elements' => [
- 'order' => [
- 'use_trait',
- 'constant_public',
- 'constant_protected',
- 'constant_private',
- 'property_public_static',
- 'property_protected_static',
- 'property_private_static',
- 'property_public',
- 'property_protected',
- 'property_private',
- 'method_public_static',
- 'construct',
- 'destruct',
- 'magic',
- 'phpunit',
- 'method_public',
- 'method_protected',
- 'method_private',
- 'method_protected_static',
- 'method_private_static',
- ],
- ],
- 'ordered_imports' => true,
- 'phpdoc_add_missing_param_annotation' => true,
- 'phpdoc_align' => true,
- 'phpdoc_annotation_without_dot' => true,
- 'phpdoc_indent' => true,
- 'phpdoc_no_access' => true,
- 'phpdoc_no_empty_return' => true,
- 'phpdoc_no_package' => true,
- 'phpdoc_order' => true,
- 'phpdoc_return_self_reference' => true,
- 'phpdoc_scalar' => true,
- 'phpdoc_separation' => true,
- 'phpdoc_single_line_var_spacing' => true,
- 'phpdoc_to_comment' => false,
- 'phpdoc_trim' => true,
- 'phpdoc_trim_consecutive_blank_line_separation' => true,
- 'phpdoc_types' => ['groups' => ['simple', 'meta']],
- 'phpdoc_types_order' => true,
- 'phpdoc_to_return_type' => true,
- 'phpdoc_var_without_name' => true,
- 'pow_to_exponentiation' => true,
- 'protected_to_private' => true,
- 'return_assignment' => true,
- 'return_type_declaration' => ['space_before' => 'none'],
- 'self_accessor' => false,
- 'semicolon_after_instruction' => true,
- 'set_type_to_cast' => true,
- 'short_scalar_cast' => true,
- 'simplified_null_return' => true,
- 'single_blank_line_at_eof' => true,
- 'single_import_per_statement' => true,
- 'single_line_after_imports' => true,
- 'single_quote' => true,
- 'standardize_not_equals' => true,
- 'ternary_to_null_coalescing' => true,
- 'trailing_comma_in_multiline_array' => false,
- 'trim_array_spaces' => true,
- 'unary_operator_spaces' => true,
- 'visibility_required' => [
- 'elements' => [
- 'const',
- 'method',
- 'property',
- ],
- ],
- 'void_return' => true,
- 'whitespace_after_comma_in_array' => true,
- 'yoda_style' => false
- ]
- )
- ->setFinder(
- PhpCsFixer\Finder::create()
- ->files()
- ->in(__DIR__ . '/src')
- ->in(__DIR__ . '/tests')
- ->notName('*.phpt')
- ->notName('autoload.php')
- );
diff --git a/vendor/theseer/tokenizer/CHANGELOG.md b/vendor/theseer/tokenizer/CHANGELOG.md
index 1eff383..f3e79f4 100644
--- a/vendor/theseer/tokenizer/CHANGELOG.md
+++ b/vendor/theseer/tokenizer/CHANGELOG.md
@@ -2,6 +2,12 @@
All notable changes to Tokenizer are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+## [1.2.2] - 2023-11-20
+
+### Fixed
+
+* [#18](https://github.com/theseer/tokenizer/issues/18): Tokenizer fails on protobuf metadata files
+
## [1.2.1] - 2021-07-28
diff --git a/vendor/theseer/tokenizer/README.md b/vendor/theseer/tokenizer/README.md
index e91ed89..a5f891b 100644
--- a/vendor/theseer/tokenizer/README.md
+++ b/vendor/theseer/tokenizer/README.md
@@ -3,9 +3,6 @@
A small library for converting tokenized PHP source code into XML.
[](https://github.com/theseer/tokenizer/actions/workflows/ci.yml)
-[](https://scrutinizer-ci.com/g/theseer/tokenizer/?branch=master)
-[](https://scrutinizer-ci.com/g/theseer/tokenizer/?branch=master)
-[](https://scrutinizer-ci.com/g/theseer/tokenizer/build-status/master)
## Installation
diff --git a/vendor/theseer/tokenizer/src/Tokenizer.php b/vendor/theseer/tokenizer/src/Tokenizer.php
index f582d95..03437bf 100644
--- a/vendor/theseer/tokenizer/src/Tokenizer.php
+++ b/vendor/theseer/tokenizer/src/Tokenizer.php
@@ -1,6 +1,8 @@
addToken(
+ new Token(
+ $line,
+ \token_name($tok[0]),
+ '{binary data}'
+ )
+ );
+
+ continue;
+ }
+
foreach ($values as $v) {
$token = new Token(
$line,
@@ -100,13 +114,6 @@ class Tokenizer {
$final = new TokenCollection();
foreach ($tokens as $token) {
- if ($prev === null) {
- $final->addToken($token);
- $prev = $token;
-
- continue;
- }
-
$gap = $token->getLine() - $prev->getLine();
while ($gap > 1) {
diff --git a/writable/logs/.gitkeep b/writable/logs/.gitkeep
new file mode 100644
index 0000000..e69de29