Commaaa2
This commit is contained in:
@@ -53,7 +53,7 @@ final class CompletionInput extends ArgvInput
|
||||
* Create an input based on an COMP_WORDS token list.
|
||||
*
|
||||
* @param string[] $tokens the set of split tokens (e.g. COMP_WORDS or argv)
|
||||
* @param $currentIndex the index of the cursor (e.g. COMP_CWORD)
|
||||
* @param int $currentIndex the index of the cursor (e.g. COMP_CWORD)
|
||||
*/
|
||||
public static function fromTokens(array $tokens, int $currentIndex): self
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ class StreamOutput extends Output
|
||||
protected function hasColorSupport()
|
||||
{
|
||||
// Follow https://no-color.org/
|
||||
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
|
||||
if ('' !== ($_SERVER['NO_COLOR'] ?? getenv('NO_COLOR') ?: '')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
11
vendor/symfony/css-selector/CHANGELOG.md
vendored
11
vendor/symfony/css-selector/CHANGELOG.md
vendored
@@ -1,6 +1,17 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
7.1
|
||||
---
|
||||
|
||||
* Add support for `:is()`
|
||||
* Add support for `:where()`
|
||||
|
||||
6.3
|
||||
---
|
||||
|
||||
* Add support for `:scope`
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use Symfony\Component\CssSelector\XPath\Translator;
|
||||
*/
|
||||
class CssSelectorConverter
|
||||
{
|
||||
private $translator;
|
||||
private Translator $translator;
|
||||
private array $cache;
|
||||
|
||||
private static array $xmlCache = [];
|
||||
@@ -62,6 +62,6 @@ class CssSelectorConverter
|
||||
*/
|
||||
public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string
|
||||
{
|
||||
return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix);
|
||||
return $this->cache[$prefix][$cssExpr] ??= $this->translator->cssToXPath($cssExpr, $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,11 @@ class SyntaxErrorException extends ParseException
|
||||
return new self('Got nested ::not().');
|
||||
}
|
||||
|
||||
public static function notAtTheStartOfASelector(string $pseudoElement): self
|
||||
{
|
||||
return new self(sprintf('Got immediate child pseudo-element ":%s" not at the start of a selector', $pseudoElement));
|
||||
}
|
||||
|
||||
public static function stringAsFunctionArgument(): self
|
||||
{
|
||||
return new self('String not allowed as function argument.');
|
||||
|
||||
2
vendor/symfony/css-selector/LICENSE
vendored
2
vendor/symfony/css-selector/LICENSE
vendored
@@ -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
|
||||
|
||||
@@ -23,19 +23,13 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class AttributeNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private ?string $namespace;
|
||||
private string $attribute;
|
||||
private string $operator;
|
||||
private ?string $value;
|
||||
|
||||
public function __construct(NodeInterface $selector, ?string $namespace, string $attribute, string $operator, ?string $value)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->namespace = $namespace;
|
||||
$this->attribute = $attribute;
|
||||
$this->operator = $operator;
|
||||
$this->value = $value;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
private ?string $namespace,
|
||||
private string $attribute,
|
||||
private string $operator,
|
||||
private ?string $value,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -63,9 +57,6 @@ class AttributeNode extends AbstractNode
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
|
||||
14
vendor/symfony/css-selector/Node/ClassNode.php
vendored
14
vendor/symfony/css-selector/Node/ClassNode.php
vendored
@@ -23,13 +23,10 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class ClassNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private string $name;
|
||||
|
||||
public function __construct(NodeInterface $selector, string $name)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->name = $name;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
private string $name,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -42,9 +39,6 @@ class ClassNode extends AbstractNode
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
|
||||
@@ -23,15 +23,11 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class CombinedSelectorNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private string $combinator;
|
||||
private $subSelector;
|
||||
|
||||
public function __construct(NodeInterface $selector, string $combinator, NodeInterface $subSelector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->combinator = $combinator;
|
||||
$this->subSelector = $subSelector;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
private string $combinator,
|
||||
private NodeInterface $subSelector,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -49,9 +45,6 @@ class CombinedSelectorNode extends AbstractNode
|
||||
return $this->subSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
||||
|
||||
14
vendor/symfony/css-selector/Node/ElementNode.php
vendored
14
vendor/symfony/css-selector/Node/ElementNode.php
vendored
@@ -23,13 +23,10 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class ElementNode extends AbstractNode
|
||||
{
|
||||
private ?string $namespace;
|
||||
private ?string $element;
|
||||
|
||||
public function __construct(string $namespace = null, string $element = null)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->element = $element;
|
||||
public function __construct(
|
||||
private ?string $namespace = null,
|
||||
private ?string $element = null,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getNamespace(): ?string
|
||||
@@ -42,9 +39,6 @@ class ElementNode extends AbstractNode
|
||||
return $this->element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return new Specificity(0, 0, $this->element ? 1 : 0);
|
||||
|
||||
@@ -25,18 +25,17 @@ use Symfony\Component\CssSelector\Parser\Token;
|
||||
*/
|
||||
class FunctionNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private string $name;
|
||||
private array $arguments;
|
||||
|
||||
/**
|
||||
* @param Token[] $arguments
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, string $name, array $arguments = [])
|
||||
{
|
||||
$this->selector = $selector;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
string $name,
|
||||
private array $arguments = [],
|
||||
) {
|
||||
$this->name = strtolower($name);
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -57,9 +56,6 @@ class FunctionNode extends AbstractNode
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
@@ -67,9 +63,7 @@ class FunctionNode extends AbstractNode
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$arguments = implode(', ', array_map(function (Token $token) {
|
||||
return "'".$token->getValue()."'";
|
||||
}, $this->arguments));
|
||||
$arguments = implode(', ', array_map(fn (Token $token) => "'".$token->getValue()."'", $this->arguments));
|
||||
|
||||
return sprintf('%s[%s:%s(%s)]', $this->getNodeName(), $this->selector, $this->name, $arguments ? '['.$arguments.']' : '');
|
||||
}
|
||||
|
||||
14
vendor/symfony/css-selector/Node/HashNode.php
vendored
14
vendor/symfony/css-selector/Node/HashNode.php
vendored
@@ -23,13 +23,10 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class HashNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private string $id;
|
||||
|
||||
public function __construct(NodeInterface $selector, string $id)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->id = $id;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
private string $id,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -42,9 +39,6 @@ class HashNode extends AbstractNode
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0));
|
||||
|
||||
@@ -23,13 +23,10 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class NegationNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private $subSelector;
|
||||
|
||||
public function __construct(NodeInterface $selector, NodeInterface $subSelector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->subSelector = $subSelector;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
private NodeInterface $subSelector,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getSelector(): NodeInterface
|
||||
@@ -42,9 +39,6 @@ class NegationNode extends AbstractNode
|
||||
return $this->subSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
||||
|
||||
@@ -21,11 +21,9 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface NodeInterface
|
||||
interface NodeInterface extends \Stringable
|
||||
{
|
||||
public function getNodeName(): string;
|
||||
|
||||
public function getSpecificity(): Specificity;
|
||||
|
||||
public function __toString(): string;
|
||||
}
|
||||
|
||||
11
vendor/symfony/css-selector/Node/PseudoNode.php
vendored
11
vendor/symfony/css-selector/Node/PseudoNode.php
vendored
@@ -23,12 +23,12 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class PseudoNode extends AbstractNode
|
||||
{
|
||||
private $selector;
|
||||
private string $identifier;
|
||||
|
||||
public function __construct(NodeInterface $selector, string $identifier)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
public function __construct(
|
||||
private NodeInterface $selector,
|
||||
string $identifier,
|
||||
) {
|
||||
$this->identifier = strtolower($identifier);
|
||||
}
|
||||
|
||||
@@ -42,9 +42,6 @@ class PseudoNode extends AbstractNode
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
class SelectorNode extends AbstractNode
|
||||
{
|
||||
private $tree;
|
||||
private ?string $pseudoElement;
|
||||
|
||||
public function __construct(NodeInterface $tree, string $pseudoElement = null)
|
||||
{
|
||||
$this->tree = $tree;
|
||||
public function __construct(
|
||||
private NodeInterface $tree,
|
||||
?string $pseudoElement = null,
|
||||
) {
|
||||
$this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null;
|
||||
}
|
||||
|
||||
@@ -42,9 +42,6 @@ class SelectorNode extends AbstractNode
|
||||
return $this->pseudoElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0));
|
||||
|
||||
14
vendor/symfony/css-selector/Node/Specificity.php
vendored
14
vendor/symfony/css-selector/Node/Specificity.php
vendored
@@ -29,15 +29,11 @@ class Specificity
|
||||
public const B_FACTOR = 10;
|
||||
public const C_FACTOR = 1;
|
||||
|
||||
private int $a;
|
||||
private int $b;
|
||||
private int $c;
|
||||
|
||||
public function __construct(int $a, int $b, int $c)
|
||||
{
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
$this->c = $c;
|
||||
public function __construct(
|
||||
private int $a,
|
||||
private int $b,
|
||||
private int $c,
|
||||
) {
|
||||
}
|
||||
|
||||
public function plus(self $specificity): self
|
||||
|
||||
@@ -26,9 +26,6 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class CommentHandler implements HandlerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
if ('/*' !== $reader->getSubstring(2)) {
|
||||
|
||||
@@ -29,18 +29,12 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class HashHandler implements HandlerInterface
|
||||
{
|
||||
private $patterns;
|
||||
private $escaping;
|
||||
|
||||
public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping)
|
||||
{
|
||||
$this->patterns = $patterns;
|
||||
$this->escaping = $escaping;
|
||||
public function __construct(
|
||||
private TokenizerPatterns $patterns,
|
||||
private TokenizerEscaping $escaping,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getHashPattern());
|
||||
|
||||
@@ -29,18 +29,12 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class IdentifierHandler implements HandlerInterface
|
||||
{
|
||||
private $patterns;
|
||||
private $escaping;
|
||||
|
||||
public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping)
|
||||
{
|
||||
$this->patterns = $patterns;
|
||||
$this->escaping = $escaping;
|
||||
public function __construct(
|
||||
private TokenizerPatterns $patterns,
|
||||
private TokenizerEscaping $escaping,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getIdentifierPattern());
|
||||
|
||||
@@ -28,16 +28,11 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class NumberHandler implements HandlerInterface
|
||||
{
|
||||
private $patterns;
|
||||
|
||||
public function __construct(TokenizerPatterns $patterns)
|
||||
{
|
||||
$this->patterns = $patterns;
|
||||
public function __construct(
|
||||
private TokenizerPatterns $patterns,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getNumberPattern());
|
||||
|
||||
@@ -31,18 +31,12 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class StringHandler implements HandlerInterface
|
||||
{
|
||||
private $patterns;
|
||||
private $escaping;
|
||||
|
||||
public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping)
|
||||
{
|
||||
$this->patterns = $patterns;
|
||||
$this->escaping = $escaping;
|
||||
public function __construct(
|
||||
private TokenizerPatterns $patterns,
|
||||
private TokenizerEscaping $escaping,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$quote = $reader->getSubstring(1);
|
||||
|
||||
@@ -27,9 +27,6 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
||||
*/
|
||||
class WhitespaceHandler implements HandlerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern('~^[ \t\r\n\f]+~');
|
||||
|
||||
72
vendor/symfony/css-selector/Parser/Parser.php
vendored
72
vendor/symfony/css-selector/Parser/Parser.php
vendored
@@ -19,7 +19,7 @@ use Symfony\Component\CssSelector\Parser\Tokenizer\Tokenizer;
|
||||
* CSS selector parser.
|
||||
*
|
||||
* This component is a port of the Python cssselect library,
|
||||
* which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
|
||||
* which is copyright Ian Bicking, @see https://github.com/scrapy/cssselect.
|
||||
*
|
||||
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
||||
*
|
||||
@@ -27,16 +27,13 @@ use Symfony\Component\CssSelector\Parser\Tokenizer\Tokenizer;
|
||||
*/
|
||||
class Parser implements ParserInterface
|
||||
{
|
||||
private $tokenizer;
|
||||
private Tokenizer $tokenizer;
|
||||
|
||||
public function __construct(Tokenizer $tokenizer = null)
|
||||
public function __construct(?Tokenizer $tokenizer = null)
|
||||
{
|
||||
$this->tokenizer = $tokenizer ?? new Tokenizer();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(string $source): array
|
||||
{
|
||||
$reader = new Reader($source);
|
||||
@@ -60,9 +57,7 @@ class Parser implements ParserInterface
|
||||
}
|
||||
}
|
||||
|
||||
$joined = trim(implode('', array_map(function (Token $token) {
|
||||
return $token->getValue();
|
||||
}, $tokens)));
|
||||
$joined = trim(implode('', array_map(fn (Token $token) => $token->getValue(), $tokens)));
|
||||
|
||||
$int = function ($string) {
|
||||
if (!is_numeric($string)) {
|
||||
@@ -92,13 +87,17 @@ class Parser implements ParserInterface
|
||||
];
|
||||
}
|
||||
|
||||
private function parseSelectorList(TokenStream $stream): array
|
||||
private function parseSelectorList(TokenStream $stream, bool $isArgument = false): array
|
||||
{
|
||||
$stream->skipWhitespace();
|
||||
$selectors = [];
|
||||
|
||||
while (true) {
|
||||
$selectors[] = $this->parserSelectorNode($stream);
|
||||
if ($isArgument && $stream->getPeek()->isDelimiter([')'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$selectors[] = $this->parserSelectorNode($stream, $isArgument);
|
||||
|
||||
if ($stream->getPeek()->isDelimiter([','])) {
|
||||
$stream->getNext();
|
||||
@@ -111,15 +110,19 @@ class Parser implements ParserInterface
|
||||
return $selectors;
|
||||
}
|
||||
|
||||
private function parserSelectorNode(TokenStream $stream): Node\SelectorNode
|
||||
private function parserSelectorNode(TokenStream $stream, bool $isArgument = false): Node\SelectorNode
|
||||
{
|
||||
[$result, $pseudoElement] = $this->parseSimpleSelector($stream);
|
||||
[$result, $pseudoElement] = $this->parseSimpleSelector($stream, false, $isArgument);
|
||||
|
||||
while (true) {
|
||||
$stream->skipWhitespace();
|
||||
$peek = $stream->getPeek();
|
||||
|
||||
if ($peek->isFileEnd() || $peek->isDelimiter([','])) {
|
||||
if (
|
||||
$peek->isFileEnd()
|
||||
|| $peek->isDelimiter([','])
|
||||
|| ($isArgument && $peek->isDelimiter([')']))
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -134,7 +137,7 @@ class Parser implements ParserInterface
|
||||
$combinator = ' ';
|
||||
}
|
||||
|
||||
[$nextSelector, $pseudoElement] = $this->parseSimpleSelector($stream);
|
||||
[$nextSelector, $pseudoElement] = $this->parseSimpleSelector($stream, false, $isArgument);
|
||||
$result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector);
|
||||
}
|
||||
|
||||
@@ -146,7 +149,7 @@ class Parser implements ParserInterface
|
||||
*
|
||||
* @throws SyntaxErrorException
|
||||
*/
|
||||
private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = false): array
|
||||
private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = false, bool $isArgument = false): array
|
||||
{
|
||||
$stream->skipWhitespace();
|
||||
|
||||
@@ -159,7 +162,7 @@ class Parser implements ParserInterface
|
||||
if ($peek->isWhitespace()
|
||||
|| $peek->isFileEnd()
|
||||
|| $peek->isDelimiter([',', '+', '>', '~'])
|
||||
|| ($insideNegation && $peek->isDelimiter([')']))
|
||||
|| ($isArgument && $peek->isDelimiter([')']))
|
||||
) {
|
||||
break;
|
||||
}
|
||||
@@ -197,7 +200,18 @@ class Parser implements ParserInterface
|
||||
|
||||
if (!$stream->getPeek()->isDelimiter(['('])) {
|
||||
$result = new Node\PseudoNode($result, $identifier);
|
||||
|
||||
if ('Pseudo[Element[*]:scope]' === $result->__toString()) {
|
||||
$used = \count($stream->getUsed());
|
||||
if (!(2 === $used
|
||||
|| 3 === $used && $stream->getUsed()[0]->isWhiteSpace()
|
||||
|| $used >= 3 && $stream->getUsed()[$used - 3]->isDelimiter([','])
|
||||
|| $used >= 4
|
||||
&& $stream->getUsed()[$used - 3]->isWhiteSpace()
|
||||
&& $stream->getUsed()[$used - 4]->isDelimiter([','])
|
||||
)) {
|
||||
throw SyntaxErrorException::notAtTheStartOfASelector('scope');
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -209,7 +223,7 @@ class Parser implements ParserInterface
|
||||
throw SyntaxErrorException::nestedNot();
|
||||
}
|
||||
|
||||
[$argument, $argumentPseudoElement] = $this->parseSimpleSelector($stream, true);
|
||||
[$argument, $argumentPseudoElement] = $this->parseSimpleSelector($stream, true, true);
|
||||
$next = $stream->getNext();
|
||||
|
||||
if (null !== $argumentPseudoElement) {
|
||||
@@ -221,6 +235,24 @@ class Parser implements ParserInterface
|
||||
}
|
||||
|
||||
$result = new Node\NegationNode($result, $argument);
|
||||
} elseif ('is' === strtolower($identifier)) {
|
||||
$selectors = $this->parseSelectorList($stream, true);
|
||||
|
||||
$next = $stream->getNext();
|
||||
if (!$next->isDelimiter([')'])) {
|
||||
throw SyntaxErrorException::unexpectedToken('")"', $next);
|
||||
}
|
||||
|
||||
$result = new Node\MatchingNode($result, $selectors);
|
||||
} elseif ('where' === strtolower($identifier)) {
|
||||
$selectors = $this->parseSelectorList($stream, true);
|
||||
|
||||
$next = $stream->getNext();
|
||||
if (!$next->isDelimiter([')'])) {
|
||||
throw SyntaxErrorException::unexpectedToken('")"', $next);
|
||||
}
|
||||
|
||||
$result = new Node\SpecificityAdjustmentNode($result, $selectors);
|
||||
} else {
|
||||
$arguments = [];
|
||||
$next = null;
|
||||
@@ -242,7 +274,7 @@ class Parser implements ParserInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($arguments)) {
|
||||
if (!$arguments) {
|
||||
throw SyntaxErrorException::unexpectedToken('at least one argument', $next);
|
||||
}
|
||||
|
||||
|
||||
13
vendor/symfony/css-selector/Parser/Reader.php
vendored
13
vendor/symfony/css-selector/Parser/Reader.php
vendored
@@ -23,13 +23,12 @@ namespace Symfony\Component\CssSelector\Parser;
|
||||
*/
|
||||
class Reader
|
||||
{
|
||||
private string $source;
|
||||
private int $length;
|
||||
private int $position = 0;
|
||||
|
||||
public function __construct(string $source)
|
||||
{
|
||||
$this->source = $source;
|
||||
public function __construct(
|
||||
private string $source,
|
||||
) {
|
||||
$this->length = \strlen($source);
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ class Reader
|
||||
return substr($this->source, $this->position + $offset, $length);
|
||||
}
|
||||
|
||||
public function getOffset(string $string)
|
||||
public function getOffset(string $string): int|false
|
||||
{
|
||||
$position = strpos($this->source, $string, $this->position);
|
||||
|
||||
@@ -71,12 +70,12 @@ class Reader
|
||||
return false;
|
||||
}
|
||||
|
||||
public function moveForward(int $length)
|
||||
public function moveForward(int $length): void
|
||||
{
|
||||
$this->position += $length;
|
||||
}
|
||||
|
||||
public function moveToEnd()
|
||||
public function moveToEnd(): void
|
||||
{
|
||||
$this->position = $this->length;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,6 @@ use Symfony\Component\CssSelector\Parser\ParserInterface;
|
||||
*/
|
||||
class ClassParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, optional element, and required class
|
||||
|
||||
@@ -27,9 +27,6 @@ use Symfony\Component\CssSelector\Parser\ParserInterface;
|
||||
*/
|
||||
class ElementParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, required element or `*`
|
||||
|
||||
@@ -31,9 +31,6 @@ use Symfony\Component\CssSelector\Parser\ParserInterface;
|
||||
*/
|
||||
class EmptyStringParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an empty string
|
||||
|
||||
@@ -28,9 +28,6 @@ use Symfony\Component\CssSelector\Parser\ParserInterface;
|
||||
*/
|
||||
class HashParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, optional element, and required id
|
||||
|
||||
18
vendor/symfony/css-selector/Parser/Token.php
vendored
18
vendor/symfony/css-selector/Parser/Token.php
vendored
@@ -31,15 +31,11 @@ class Token
|
||||
public const TYPE_NUMBER = 'number';
|
||||
public const TYPE_STRING = 'string';
|
||||
|
||||
private ?string $type;
|
||||
private ?string $value;
|
||||
private ?int $position;
|
||||
|
||||
public function __construct(?string $type, ?string $value, ?int $position)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
$this->position = $position;
|
||||
public function __construct(
|
||||
private ?string $type,
|
||||
private ?string $value,
|
||||
private ?int $position,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getType(): ?int
|
||||
@@ -68,11 +64,11 @@ class Token
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($values)) {
|
||||
if (!$values) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return \in_array($this->value, $values);
|
||||
return \in_array($this->value, $values, true);
|
||||
}
|
||||
|
||||
public function isWhitespace(): bool
|
||||
|
||||
@@ -37,7 +37,7 @@ class TokenStream
|
||||
private array $used = [];
|
||||
|
||||
private int $cursor = 0;
|
||||
private $peeked;
|
||||
private ?Token $peeked;
|
||||
private bool $peeking = false;
|
||||
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ class TokenStream
|
||||
/**
|
||||
* Skips next whitespace if any.
|
||||
*/
|
||||
public function skipWhitespace()
|
||||
public function skipWhitespace(): void
|
||||
{
|
||||
$peek = $this->getPeek();
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@ namespace Symfony\Component\CssSelector\Parser\Tokenizer;
|
||||
*/
|
||||
class TokenizerEscaping
|
||||
{
|
||||
private $patterns;
|
||||
|
||||
public function __construct(TokenizerPatterns $patterns)
|
||||
{
|
||||
$this->patterns = $patterns;
|
||||
public function __construct(
|
||||
private TokenizerPatterns $patterns,
|
||||
) {
|
||||
}
|
||||
|
||||
public function escapeUnicode(string $value): string
|
||||
|
||||
@@ -23,41 +23,26 @@ namespace Symfony\Component\CssSelector\XPath\Extension;
|
||||
*/
|
||||
abstract class AbstractExtension implements ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNodeTranslators(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCombinationTranslators(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctionTranslators(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPseudoClassTranslators(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributeMatchingTranslators(): array
|
||||
{
|
||||
return [];
|
||||
|
||||
@@ -26,20 +26,17 @@ use Symfony\Component\CssSelector\XPath\XPathExpr;
|
||||
*/
|
||||
class AttributeMatchingExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributeMatchingTranslators(): array
|
||||
{
|
||||
return [
|
||||
'exists' => [$this, 'translateExists'],
|
||||
'=' => [$this, 'translateEquals'],
|
||||
'~=' => [$this, 'translateIncludes'],
|
||||
'|=' => [$this, 'translateDashMatch'],
|
||||
'^=' => [$this, 'translatePrefixMatch'],
|
||||
'$=' => [$this, 'translateSuffixMatch'],
|
||||
'*=' => [$this, 'translateSubstringMatch'],
|
||||
'!=' => [$this, 'translateDifferent'],
|
||||
'exists' => $this->translateExists(...),
|
||||
'=' => $this->translateEquals(...),
|
||||
'~=' => $this->translateIncludes(...),
|
||||
'|=' => $this->translateDashMatch(...),
|
||||
'^=' => $this->translatePrefixMatch(...),
|
||||
'$=' => $this->translateSuffixMatch(...),
|
||||
'*=' => $this->translateSubstringMatch(...),
|
||||
'!=' => $this->translateDifferent(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -109,9 +106,6 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'attribute-matching';
|
||||
|
||||
@@ -25,16 +25,13 @@ use Symfony\Component\CssSelector\XPath\XPathExpr;
|
||||
*/
|
||||
class CombinationExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCombinationTranslators(): array
|
||||
{
|
||||
return [
|
||||
' ' => [$this, 'translateDescendant'],
|
||||
'>' => [$this, 'translateChild'],
|
||||
'+' => [$this, 'translateDirectAdjacent'],
|
||||
'~' => [$this, 'translateIndirectAdjacent'],
|
||||
' ' => $this->translateDescendant(...),
|
||||
'>' => $this->translateChild(...),
|
||||
'+' => $this->translateDirectAdjacent(...),
|
||||
'~' => $this->translateIndirectAdjacent(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -61,9 +58,6 @@ class CombinationExtension extends AbstractExtension
|
||||
return $xpath->join('/following-sibling::', $combinedXpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'combination';
|
||||
|
||||
@@ -30,18 +30,15 @@ use Symfony\Component\CssSelector\XPath\XPathExpr;
|
||||
*/
|
||||
class FunctionExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctionTranslators(): array
|
||||
{
|
||||
return [
|
||||
'nth-child' => [$this, 'translateNthChild'],
|
||||
'nth-last-child' => [$this, 'translateNthLastChild'],
|
||||
'nth-of-type' => [$this, 'translateNthOfType'],
|
||||
'nth-last-of-type' => [$this, 'translateNthLastOfType'],
|
||||
'contains' => [$this, 'translateContains'],
|
||||
'lang' => [$this, 'translateLang'],
|
||||
'nth-child' => $this->translateNthChild(...),
|
||||
'nth-last-child' => $this->translateNthLastChild(...),
|
||||
'nth-of-type' => $this->translateNthOfType(...),
|
||||
'nth-last-of-type' => $this->translateNthLastOfType(...),
|
||||
'contains' => $this->translateContains(...),
|
||||
'lang' => $this->translateLang(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -161,9 +158,6 @@ class FunctionExtension extends AbstractExtension
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'function';
|
||||
|
||||
@@ -36,30 +36,24 @@ class HtmlExtension extends AbstractExtension
|
||||
->setFlag(NodeExtension::ATTRIBUTE_NAME_IN_LOWER_CASE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPseudoClassTranslators(): array
|
||||
{
|
||||
return [
|
||||
'checked' => [$this, 'translateChecked'],
|
||||
'link' => [$this, 'translateLink'],
|
||||
'disabled' => [$this, 'translateDisabled'],
|
||||
'enabled' => [$this, 'translateEnabled'],
|
||||
'selected' => [$this, 'translateSelected'],
|
||||
'invalid' => [$this, 'translateInvalid'],
|
||||
'hover' => [$this, 'translateHover'],
|
||||
'visited' => [$this, 'translateVisited'],
|
||||
'checked' => $this->translateChecked(...),
|
||||
'link' => $this->translateLink(...),
|
||||
'disabled' => $this->translateDisabled(...),
|
||||
'enabled' => $this->translateEnabled(...),
|
||||
'selected' => $this->translateSelected(...),
|
||||
'invalid' => $this->translateInvalid(...),
|
||||
'hover' => $this->translateHover(...),
|
||||
'visited' => $this->translateVisited(...),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctionTranslators(): array
|
||||
{
|
||||
return [
|
||||
'lang' => [$this, 'translateLang'],
|
||||
'lang' => $this->translateLang(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -177,9 +171,6 @@ class HtmlExtension extends AbstractExtension
|
||||
return $xpath->addCondition('0');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'html';
|
||||
|
||||
@@ -31,11 +31,9 @@ class NodeExtension extends AbstractExtension
|
||||
public const ATTRIBUTE_NAME_IN_LOWER_CASE = 2;
|
||||
public const ATTRIBUTE_VALUE_IN_LOWER_CASE = 4;
|
||||
|
||||
private int $flags;
|
||||
|
||||
public function __construct(int $flags = 0)
|
||||
{
|
||||
$this->flags = $flags;
|
||||
public function __construct(
|
||||
private int $flags = 0,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,21 +57,20 @@ class NodeExtension extends AbstractExtension
|
||||
return (bool) ($this->flags & $flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNodeTranslators(): array
|
||||
{
|
||||
return [
|
||||
'Selector' => [$this, 'translateSelector'],
|
||||
'CombinedSelector' => [$this, 'translateCombinedSelector'],
|
||||
'Negation' => [$this, 'translateNegation'],
|
||||
'Function' => [$this, 'translateFunction'],
|
||||
'Pseudo' => [$this, 'translatePseudo'],
|
||||
'Attribute' => [$this, 'translateAttribute'],
|
||||
'Class' => [$this, 'translateClass'],
|
||||
'Hash' => [$this, 'translateHash'],
|
||||
'Element' => [$this, 'translateElement'],
|
||||
'Selector' => $this->translateSelector(...),
|
||||
'CombinedSelector' => $this->translateCombinedSelector(...),
|
||||
'Negation' => $this->translateNegation(...),
|
||||
'Matching' => $this->translateMatching(...),
|
||||
'SpecificityAdjustment' => $this->translateSpecificityAdjustment(...),
|
||||
'Function' => $this->translateFunction(...),
|
||||
'Pseudo' => $this->translatePseudo(...),
|
||||
'Attribute' => $this->translateAttribute(...),
|
||||
'Class' => $this->translateClass(...),
|
||||
'Hash' => $this->translateHash(...),
|
||||
'Element' => $this->translateElement(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -100,6 +97,36 @@ class NodeExtension extends AbstractExtension
|
||||
return $xpath->addCondition('0');
|
||||
}
|
||||
|
||||
public function translateMatching(Node\MatchingNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->selector);
|
||||
|
||||
foreach ($node->arguments as $argument) {
|
||||
$expr = $translator->nodeToXPath($argument);
|
||||
$expr->addNameTest();
|
||||
if ($condition = $expr->getCondition()) {
|
||||
$xpath->addCondition($condition, 'or');
|
||||
}
|
||||
}
|
||||
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
public function translateSpecificityAdjustment(Node\SpecificityAdjustmentNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->selector);
|
||||
|
||||
foreach ($node->arguments as $argument) {
|
||||
$expr = $translator->nodeToXPath($argument);
|
||||
$expr->addNameTest();
|
||||
if ($condition = $expr->getCondition()) {
|
||||
$xpath->addCondition($condition, 'or');
|
||||
}
|
||||
}
|
||||
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
public function translateFunction(Node\FunctionNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
@@ -182,9 +209,6 @@ class NodeExtension extends AbstractExtension
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'node';
|
||||
|
||||
@@ -26,20 +26,18 @@ use Symfony\Component\CssSelector\XPath\XPathExpr;
|
||||
*/
|
||||
class PseudoClassExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPseudoClassTranslators(): array
|
||||
{
|
||||
return [
|
||||
'root' => [$this, 'translateRoot'],
|
||||
'first-child' => [$this, 'translateFirstChild'],
|
||||
'last-child' => [$this, 'translateLastChild'],
|
||||
'first-of-type' => [$this, 'translateFirstOfType'],
|
||||
'last-of-type' => [$this, 'translateLastOfType'],
|
||||
'only-child' => [$this, 'translateOnlyChild'],
|
||||
'only-of-type' => [$this, 'translateOnlyOfType'],
|
||||
'empty' => [$this, 'translateEmpty'],
|
||||
'root' => $this->translateRoot(...),
|
||||
'scope' => $this->translateScopePseudo(...),
|
||||
'first-child' => $this->translateFirstChild(...),
|
||||
'last-child' => $this->translateLastChild(...),
|
||||
'first-of-type' => $this->translateFirstOfType(...),
|
||||
'last-of-type' => $this->translateLastOfType(...),
|
||||
'only-child' => $this->translateOnlyChild(...),
|
||||
'only-of-type' => $this->translateOnlyOfType(...),
|
||||
'empty' => $this->translateEmpty(...),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -48,6 +46,11 @@ class PseudoClassExtension extends AbstractExtension
|
||||
return $xpath->addCondition('not(parent::*)');
|
||||
}
|
||||
|
||||
public function translateScopePseudo(XPathExpr $xpath): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition('1');
|
||||
}
|
||||
|
||||
public function translateFirstChild(XPathExpr $xpath): XPathExpr
|
||||
{
|
||||
return $xpath
|
||||
@@ -112,9 +115,6 @@ class PseudoClassExtension extends AbstractExtension
|
||||
return $xpath->addCondition('not(*) and not(string-length())');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'pseudo-class';
|
||||
|
||||
12
vendor/symfony/css-selector/XPath/Translator.php
vendored
12
vendor/symfony/css-selector/XPath/Translator.php
vendored
@@ -30,7 +30,7 @@ use Symfony\Component\CssSelector\Parser\ParserInterface;
|
||||
*/
|
||||
class Translator implements TranslatorInterface
|
||||
{
|
||||
private $mainParser;
|
||||
private ParserInterface $mainParser;
|
||||
|
||||
/**
|
||||
* @var ParserInterface[]
|
||||
@@ -48,7 +48,7 @@ class Translator implements TranslatorInterface
|
||||
private array $pseudoClassTranslators = [];
|
||||
private array $attributeMatchingTranslators = [];
|
||||
|
||||
public function __construct(ParserInterface $parser = null)
|
||||
public function __construct(?ParserInterface $parser = null)
|
||||
{
|
||||
$this->mainParser = $parser ?? new Parser();
|
||||
|
||||
@@ -87,9 +87,6 @@ class Translator implements TranslatorInterface
|
||||
return sprintf('concat(%s)', implode(', ', $parts));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string
|
||||
{
|
||||
$selectors = $this->parseSelectors($cssExpr);
|
||||
@@ -106,9 +103,6 @@ class Translator implements TranslatorInterface
|
||||
return implode(' | ', $selectors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string
|
||||
{
|
||||
return ($prefix ?: '').$this->nodeToXPath($selector);
|
||||
@@ -220,7 +214,7 @@ class Translator implements TranslatorInterface
|
||||
foreach ($this->shortcutParsers as $shortcut) {
|
||||
$tokens = $shortcut->parse($css);
|
||||
|
||||
if (!empty($tokens)) {
|
||||
if ($tokens) {
|
||||
return $tokens;
|
||||
}
|
||||
}
|
||||
|
||||
22
vendor/symfony/css-selector/XPath/XPathExpr.php
vendored
22
vendor/symfony/css-selector/XPath/XPathExpr.php
vendored
@@ -23,16 +23,12 @@ namespace Symfony\Component\CssSelector\XPath;
|
||||
*/
|
||||
class XPathExpr
|
||||
{
|
||||
private string $path;
|
||||
private string $element;
|
||||
private string $condition;
|
||||
|
||||
public function __construct(string $path = '', string $element = '*', string $condition = '', bool $starPrefix = false)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->element = $element;
|
||||
$this->condition = $condition;
|
||||
|
||||
public function __construct(
|
||||
private string $path = '',
|
||||
private string $element = '*',
|
||||
private string $condition = '',
|
||||
bool $starPrefix = false,
|
||||
) {
|
||||
if ($starPrefix) {
|
||||
$this->addStarPrefix();
|
||||
}
|
||||
@@ -46,9 +42,9 @@ class XPathExpr
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addCondition(string $condition): static
|
||||
public function addCondition(string $condition, string $operator = 'and'): static
|
||||
{
|
||||
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
|
||||
$this->condition = $this->condition ? sprintf('(%s) %s (%s)', $this->condition, $operator, $condition) : $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -104,7 +100,7 @@ class XPathExpr
|
||||
public function __toString(): string
|
||||
{
|
||||
$path = $this->path.$this->element;
|
||||
$condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']';
|
||||
$condition = '' === $this->condition ? '' : '['.$this->condition.']';
|
||||
|
||||
return $path.$condition;
|
||||
}
|
||||
|
||||
2
vendor/symfony/css-selector/composer.json
vendored
2
vendor/symfony/css-selector/composer.json
vendored
@@ -20,7 +20,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.2"
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\CssSelector\\": "" },
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
2
vendor/symfony/deprecation-contracts/LICENSE
vendored
2
vendor/symfony/deprecation-contracts/LICENSE
vendored
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
||||
@@ -33,7 +33,7 @@ class FatalError extends \Error
|
||||
}
|
||||
}
|
||||
} elseif (null !== $traceOffset) {
|
||||
if (\function_exists('xdebug_get_function_stack') && $trace = @xdebug_get_function_stack()) {
|
||||
if (\function_exists('xdebug_get_function_stack') && \in_array(\ini_get('xdebug.mode'), ['develop', false], true) && $trace = @xdebug_get_function_stack()) {
|
||||
if (0 < $traceOffset) {
|
||||
array_splice($trace, -$traceOffset);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ class ErrorHandler
|
||||
\E_USER_DEPRECATED => 'User Deprecated',
|
||||
\E_NOTICE => 'Notice',
|
||||
\E_USER_NOTICE => 'User Notice',
|
||||
\E_STRICT => 'Runtime Notice',
|
||||
\E_WARNING => 'Warning',
|
||||
\E_USER_WARNING => 'User Warning',
|
||||
\E_COMPILE_WARNING => 'Compile Warning',
|
||||
@@ -73,7 +72,6 @@ class ErrorHandler
|
||||
\E_USER_DEPRECATED => [null, LogLevel::INFO],
|
||||
\E_NOTICE => [null, LogLevel::WARNING],
|
||||
\E_USER_NOTICE => [null, LogLevel::WARNING],
|
||||
\E_STRICT => [null, LogLevel::WARNING],
|
||||
\E_WARNING => [null, LogLevel::WARNING],
|
||||
\E_USER_WARNING => [null, LogLevel::WARNING],
|
||||
\E_COMPILE_WARNING => [null, LogLevel::WARNING],
|
||||
@@ -183,6 +181,11 @@ class ErrorHandler
|
||||
|
||||
public function __construct(?BufferingLogger $bootstrappingLogger = null, bool $debug = false)
|
||||
{
|
||||
if (\PHP_VERSION_ID < 80400) {
|
||||
$this->levels[\E_STRICT] = 'Runtime Notice';
|
||||
$this->loggers[\E_STRICT] = [null, LogLevel::WARNING];
|
||||
}
|
||||
|
||||
if ($bootstrappingLogger) {
|
||||
$this->bootstrappingLogger = $bootstrappingLogger;
|
||||
$this->setDefaultLogger($bootstrappingLogger);
|
||||
|
||||
@@ -72,7 +72,7 @@ class HtmlErrorRenderer implements ErrorRendererInterface
|
||||
{
|
||||
$headers = ['Content-Type' => 'text/html; charset='.$this->charset];
|
||||
if (\is_bool($this->debug) ? $this->debug : ($this->debug)($exception)) {
|
||||
$headers['X-Debug-Exception'] = rawurlencode($exception->getMessage());
|
||||
$headers['X-Debug-Exception'] = rawurlencode(substr($exception->getMessage(), 0, 2000));
|
||||
$headers['X-Debug-Exception-File'] = rawurlencode($exception->getFile()).':'.$exception->getLine();
|
||||
}
|
||||
|
||||
@@ -274,12 +274,10 @@ class HtmlErrorRenderer implements ErrorRendererInterface
|
||||
if (\PHP_VERSION_ID >= 80300) {
|
||||
// remove main pre/code tags
|
||||
$code = preg_replace('#^<pre.*?>\s*<code.*?>(.*)</code>\s*</pre>#s', '\\1', $code);
|
||||
// split multiline code tags
|
||||
$code = preg_replace_callback('#<code ([^>]++)>((?:[^<]*+\\n)++[^<]*+)</code>#', function ($m) {
|
||||
return "<code $m[1]>".str_replace("\n", "</code>\n<code $m[1]>", $m[2]).'</code>';
|
||||
// split multiline span tags
|
||||
$code = preg_replace_callback('#<span ([^>]++)>((?:[^<\\n]*+\\n)++[^<]*+)</span>#', function ($m) {
|
||||
return "<span $m[1]>".str_replace("\n", "</span>\n<span $m[1]>", $m[2]).'</span>';
|
||||
}, $code);
|
||||
// Convert spaces to html entities to preserve indentation when rendered
|
||||
$code = str_replace(' ', ' ', $code);
|
||||
$content = explode("\n", $code);
|
||||
} else {
|
||||
// remove main code/span tags
|
||||
|
||||
@@ -58,7 +58,7 @@ class SerializerErrorRenderer implements ErrorRendererInterface
|
||||
$headers = ['Vary' => 'Accept'];
|
||||
$debug = \is_bool($this->debug) ? $this->debug : ($this->debug)($exception);
|
||||
if ($debug) {
|
||||
$headers['X-Debug-Exception'] = rawurlencode($exception->getMessage());
|
||||
$headers['X-Debug-Exception'] = rawurlencode(substr($exception->getMessage(), 0, 2000));
|
||||
$headers['X-Debug-Exception-File'] = rawurlencode($exception->getFile()).':'.$exception->getLine();
|
||||
}
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ header .container { display: flex; justify-content: space-between; }
|
||||
.trace-code li { color: #969896; margin: 0; padding-left: 10px; float: left; width: 100%; }
|
||||
.trace-code li + li { margin-top: 5px; }
|
||||
.trace-code li.selected { background: var(--trace-selected-background); margin-top: 2px; }
|
||||
.trace-code li code { color: var(--base-6); white-space: nowrap; }
|
||||
.trace-code li code { color: var(--base-6); white-space: pre; }
|
||||
|
||||
.trace-as-text .stacktrace { line-height: 1.8; margin: 0 0 15px; white-space: pre-wrap; }
|
||||
|
||||
|
||||
0
vendor/symfony/error-handler/Resources/bin/extract-tentative-return-types.php
vendored
Normal file → Executable file
0
vendor/symfony/error-handler/Resources/bin/extract-tentative-return-types.php
vendored
Normal file → Executable file
0
vendor/symfony/error-handler/Resources/bin/patch-type-declarations
vendored
Normal file → Executable file
0
vendor/symfony/error-handler/Resources/bin/patch-type-declarations
vendored
Normal file → Executable file
@@ -1,3 +0,0 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
@@ -32,9 +32,6 @@ class Event implements StoppableEventInterface
|
||||
{
|
||||
private bool $propagationStopped = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isPropagationStopped(): bool
|
||||
{
|
||||
return $this->propagationStopped;
|
||||
|
||||
@@ -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;
|
||||
public function dispatch(object $event, ?string $eventName = null): object;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
||||
@@ -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;
|
||||
@@ -36,13 +37,13 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
* @var \SplObjectStorage<WrappedListener, array{string, string}>|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)
|
||||
public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, ?LoggerInterface $logger = null, ?RequestStack $requestStack = null)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->stopwatch = $stopwatch;
|
||||
@@ -51,7 +52,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function addListener(string $eventName, callable|array $listener, int $priority = 0)
|
||||
{
|
||||
@@ -59,7 +60,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function removeListener(string $eventName, callable|array $listener)
|
||||
{
|
||||
@@ -81,28 +82,22 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dispatcher->removeListener($eventName, $listener);
|
||||
$this->dispatcher->removeListener($eventName, $listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function removeSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
return $this->dispatcher->removeSubscriber($subscriber);
|
||||
$this->dispatcher->removeSubscriber($subscriber);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListeners(string $eventName = null): array
|
||||
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 +113,16 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
return $this->dispatcher->getListenerPriority($eventName, $listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasListeners(string $eventName = null): bool
|
||||
public function hasListeners(?string $eventName = null): bool
|
||||
{
|
||||
return $this->dispatcher->hasListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dispatch(object $event, string $eventName = null): object
|
||||
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) : '';
|
||||
|
||||
@@ -166,7 +153,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
return $event;
|
||||
}
|
||||
|
||||
public function getCalledListeners(Request $request = null): array
|
||||
public function getCalledListeners(?Request $request = null): array
|
||||
{
|
||||
if (null === $this->callStack) {
|
||||
return [];
|
||||
@@ -184,14 +171,12 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
return $called;
|
||||
}
|
||||
|
||||
public function getNotCalledListeners(Request $request = null): array
|
||||
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,23 +196,24 @@ 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;
|
||||
}
|
||||
|
||||
public function getOrphanedEvents(Request $request = null): array
|
||||
public function getOrphanedEvents(?Request $request = null): array
|
||||
{
|
||||
if ($request) {
|
||||
return $this->orphanedEvents[spl_object_hash($request)] ?? [];
|
||||
@@ -240,6 +226,9 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
return array_merge(...array_values($this->orphanedEvents));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->callStack = null;
|
||||
@@ -260,6 +249,8 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
|
||||
/**
|
||||
* Called before dispatching the event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function beforeDispatch(string $eventName, object $event)
|
||||
{
|
||||
@@ -267,6 +258,8 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa
|
||||
|
||||
/**
|
||||
* Called after dispatching the event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function afterDispatch(string $eventName, object $event)
|
||||
{
|
||||
@@ -308,9 +301,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 +311,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 +342,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,26 +26,29 @@ 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}')) {
|
||||
if (str_contains($r->name, '{closure')) {
|
||||
$this->pretty = $this->name = 'closure';
|
||||
} elseif ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) {
|
||||
$this->name = $class->name;
|
||||
@@ -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]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('event_dispatcher') && !$container->hasAlias('event_dispatcher')) {
|
||||
@@ -73,7 +76,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$event['method'] = $event['method'] ?? '__invoke';
|
||||
$event['method'] ??= '__invoke';
|
||||
$event['event'] = $this->getEventFromTypeDeclaration($container, $id, $event['method']);
|
||||
}
|
||||
|
||||
@@ -83,17 +86,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 +139,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$dispatcherDefinitions[$attributes['dispatcher']] = $container->getDefinition($attributes['dispatcher']);
|
||||
$dispatcherDefinitions[$attributes['dispatcher']] = $container->findDefinition($attributes['dispatcher']);
|
||||
}
|
||||
|
||||
if (!$dispatcherDefinitions) {
|
||||
@@ -191,7 +198,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];
|
||||
}
|
||||
|
||||
@@ -42,12 +42,9 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dispatch(object $event, string $eventName = null): object
|
||||
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,10 +59,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListeners(string $eventName = null): array
|
||||
public function getListeners(?string $eventName = null): array
|
||||
{
|
||||
if (null !== $eventName) {
|
||||
if (empty($this->listeners[$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,10 +108,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasListeners(string $eventName = null): bool
|
||||
public function hasListeners(?string $eventName = null): bool
|
||||
{
|
||||
if (null !== $eventName) {
|
||||
return !empty($this->listeners[$eventName]);
|
||||
@@ -136,7 +124,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function addListener(string $eventName, callable|array $listener, int $priority = 0)
|
||||
{
|
||||
@@ -145,7 +133,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function removeListener(string $eventName, callable|array $listener)
|
||||
{
|
||||
@@ -155,14 +143,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]);
|
||||
@@ -176,7 +164,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
@@ -194,7 +182,7 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return void
|
||||
*/
|
||||
public function removeSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
@@ -218,6 +206,8 @@ class EventDispatcher implements EventDispatcherInterface
|
||||
* @param callable[] $listeners The event listeners
|
||||
* @param string $eventName The name of the event to dispatch
|
||||
* @param object $event The event object to pass to the event handlers/listeners
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function callListeners(iterable $listeners, string $eventName, object $event)
|
||||
{
|
||||
@@ -234,16 +224,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 +255,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(...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ 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)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addListener(string $eventName, callable $listener, int $priority = 0);
|
||||
|
||||
@@ -35,14 +37,21 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface
|
||||
*
|
||||
* The subscriber is asked for all the events it is
|
||||
* interested in and added as a listener for these events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber);
|
||||
|
||||
/**
|
||||
* Removes an event listener from the specified events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeListener(string $eventName, callable $listener);
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeSubscriber(EventSubscriberInterface $subscriber);
|
||||
|
||||
/**
|
||||
@@ -50,7 +59,7 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface
|
||||
*
|
||||
* @return array<callable[]|callable>
|
||||
*/
|
||||
public function getListeners(string $eventName = null): array;
|
||||
public function getListeners(?string $eventName = null): array;
|
||||
|
||||
/**
|
||||
* Gets the listener priority for a specific event.
|
||||
@@ -62,5 +71,5 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface
|
||||
/**
|
||||
* Checks whether an event has any registered listeners.
|
||||
*/
|
||||
public function hasListeners(string $eventName = null): bool;
|
||||
public function hasListeners(?string $eventName = null): bool;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* Encapsulate an event with $subject and $args.
|
||||
* Encapsulate an event with $subject and $arguments.
|
||||
*
|
||||
* @param mixed $subject The subject of the event, usually an object or a callable
|
||||
* @param array $arguments Arguments to store in the event
|
||||
|
||||
@@ -18,23 +18,20 @@ 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
|
||||
public function dispatch(object $event, ?string $eventName = null): object
|
||||
{
|
||||
return $this->dispatcher->dispatch($event, $eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return never
|
||||
*/
|
||||
public function addListener(string $eventName, callable|array $listener, int $priority = 0)
|
||||
{
|
||||
@@ -42,7 +39,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return never
|
||||
*/
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
@@ -50,7 +47,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return never
|
||||
*/
|
||||
public function removeListener(string $eventName, callable|array $listener)
|
||||
{
|
||||
@@ -58,33 +55,24 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return never
|
||||
*/
|
||||
public function removeSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListeners(string $eventName = null): array
|
||||
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
|
||||
public function hasListeners(?string $eventName = null): bool
|
||||
{
|
||||
return $this->dispatcher->hasListeners($eventName);
|
||||
}
|
||||
|
||||
2
vendor/symfony/event-dispatcher/LICENSE
vendored
2
vendor/symfony/event-dispatcher/LICENSE
vendored
@@ -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
|
||||
|
||||
25
vendor/symfony/event-dispatcher/composer.json
vendored
25
vendor/symfony/event-dispatcher/composer.json
vendored
@@ -16,30 +16,27 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"symfony/event-dispatcher-contracts": "^2|^3"
|
||||
"php": ">=8.1",
|
||||
"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": "^5.4|^6.0|^7.0",
|
||||
"symfony/expression-language": "^5.4|^6.0|^7.0",
|
||||
"symfony/config": "^5.4|^6.0|^7.0",
|
||||
"symfony/error-handler": "^5.4|^6.0|^7.0",
|
||||
"symfony/http-foundation": "^5.4|^6.0|^7.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/stopwatch": "^5.4|^6.0|^7.0",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<5.4"
|
||||
"symfony/dependency-injection": "<5.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": [
|
||||
|
||||
@@ -286,7 +286,11 @@ class HeaderUtils
|
||||
}
|
||||
|
||||
foreach ($partMatches as $matches) {
|
||||
$parts[] = '' === $separators ? self::unquote($matches[0][0]) : self::groupParts($matches, $separators, false);
|
||||
if ('' === $separators && '' !== $unquoted = self::unquote($matches[0][0])) {
|
||||
$parts[] = $unquoted;
|
||||
} elseif ($groupedParts = self::groupParts($matches, $separators, false)) {
|
||||
$parts[] = $groupedParts;
|
||||
}
|
||||
}
|
||||
|
||||
return $parts;
|
||||
|
||||
@@ -226,14 +226,11 @@ class MockArraySessionStorage implements SessionStorageInterface
|
||||
/**
|
||||
* Generates a session ID.
|
||||
*
|
||||
* This doesn't need to be particularly cryptographically secure since this is just
|
||||
* a mock.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateId()
|
||||
{
|
||||
return hash('sha256', uniqid('ss_mock_', true));
|
||||
return bin2hex(random_bytes(16));
|
||||
}
|
||||
|
||||
protected function loadSession()
|
||||
|
||||
2
vendor/symfony/http-foundation/composer.json
vendored
2
vendor/symfony/http-foundation/composer.json
vendored
@@ -22,7 +22,7 @@
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"predis/predis": "~1.0",
|
||||
"predis/predis": "^1.0|^2.0",
|
||||
"symfony/cache": "^4.4|^5.0|^6.0",
|
||||
"symfony/dependency-injection": "^5.4|^6.0",
|
||||
"symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
|
||||
|
||||
@@ -66,7 +66,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
$sessionMetadata = [];
|
||||
$sessionAttributes = [];
|
||||
$flashes = [];
|
||||
if ($request->hasSession()) {
|
||||
if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) {
|
||||
$session = $request->getSession();
|
||||
if ($session->isStarted()) {
|
||||
$sessionMetadata['Created'] = date(\DATE_RFC822, $session->getMetadataBag()->getCreated());
|
||||
|
||||
@@ -16,7 +16,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Base class for events thrown in the HttpKernel component.
|
||||
* Base class for events dispatched in the HttpKernel component.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ class ProfilerListener implements EventSubscriberInterface
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null;
|
||||
$session = !$request->attributes->getBoolean('_stateless') && $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null;
|
||||
|
||||
if ($session instanceof Session) {
|
||||
$usageIndexValue = $usageIndexReference = &$session->getUsageIndex();
|
||||
|
||||
6
vendor/symfony/http-kernel/Kernel.php
vendored
6
vendor/symfony/http-kernel/Kernel.php
vendored
@@ -78,11 +78,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
||||
*/
|
||||
private static $freshCache = [];
|
||||
|
||||
public const VERSION = '5.4.39';
|
||||
public const VERSION_ID = 50439;
|
||||
public const VERSION = '5.4.42';
|
||||
public const VERSION_ID = 50442;
|
||||
public const MAJOR_VERSION = 5;
|
||||
public const MINOR_VERSION = 4;
|
||||
public const RELEASE_VERSION = 39;
|
||||
public const RELEASE_VERSION = 42;
|
||||
public const EXTRA_VERSION = '';
|
||||
|
||||
public const END_OF_MAINTENANCE = '11/2024';
|
||||
|
||||
11
vendor/symfony/mime/Message.php
vendored
11
vendor/symfony/mime/Message.php
vendored
@@ -124,11 +124,18 @@ class Message extends RawMessage
|
||||
|
||||
public function ensureValidity()
|
||||
{
|
||||
if (!$this->headers->has('To') && !$this->headers->has('Cc') && !$this->headers->has('Bcc')) {
|
||||
$to = (null !== $header = $this->headers->get('To')) ? $header->getBody() : null;
|
||||
$cc = (null !== $header = $this->headers->get('Cc')) ? $header->getBody() : null;
|
||||
$bcc = (null !== $header = $this->headers->get('Bcc')) ? $header->getBody() : null;
|
||||
|
||||
if (!$to && !$cc && !$bcc) {
|
||||
throw new LogicException('An email must have a "To", "Cc", or "Bcc" header.');
|
||||
}
|
||||
|
||||
if (!$this->headers->has('From') && !$this->headers->has('Sender')) {
|
||||
$from = (null !== $header = $this->headers->get('From')) ? $header->getBody() : null;
|
||||
$sender = (null !== $header = $this->headers->get('Sender')) ? $header->getBody() : null;
|
||||
|
||||
if (!$from && !$sender) {
|
||||
throw new LogicException('An email must have a "From" or a "Sender" header.');
|
||||
}
|
||||
|
||||
|
||||
20
vendor/symfony/polyfill-intl-idn/Idn.php
vendored
20
vendor/symfony/polyfill-intl-idn/Idn.php
vendored
@@ -280,10 +280,6 @@ final class Idn
|
||||
|
||||
switch ($data['status']) {
|
||||
case 'disallowed':
|
||||
$info->errors |= self::ERROR_DISALLOWED;
|
||||
|
||||
// no break.
|
||||
|
||||
case 'valid':
|
||||
$str .= mb_chr($codePoint, 'utf-8');
|
||||
|
||||
@@ -294,7 +290,7 @@ final class Idn
|
||||
break;
|
||||
|
||||
case 'mapped':
|
||||
$str .= $data['mapping'];
|
||||
$str .= $transitional && 0x1E9E === $codePoint ? 'ss' : $data['mapping'];
|
||||
|
||||
break;
|
||||
|
||||
@@ -346,6 +342,18 @@ final class Idn
|
||||
$validationOptions = $options;
|
||||
|
||||
if ('xn--' === substr($label, 0, 4)) {
|
||||
// Step 4.1. If the label contains any non-ASCII code point (i.e., a code point greater than U+007F),
|
||||
// record that there was an error, and continue with the next label.
|
||||
if (preg_match('/[^\x00-\x7F]/', $label)) {
|
||||
$info->errors |= self::ERROR_PUNYCODE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Step 4.2. Attempt to convert the rest of the label to Unicode according to Punycode [RFC3492]. If
|
||||
// that conversion fails, record that there was an error, and continue
|
||||
// with the next label. Otherwise replace the original label in the string by the results of the
|
||||
// conversion.
|
||||
try {
|
||||
$label = self::punycodeDecode(substr($label, 4));
|
||||
} catch (\Exception $e) {
|
||||
@@ -516,6 +524,8 @@ final class Idn
|
||||
if ('-' === substr($label, -1, 1)) {
|
||||
$info->errors |= self::ERROR_TRAILING_HYPHEN;
|
||||
}
|
||||
} elseif ('xn--' === substr($label, 0, 4)) {
|
||||
$info->errors |= self::ERROR_PUNYCODE;
|
||||
}
|
||||
|
||||
// Step 4. The label must not contain a U+002E (.) FULL STOP.
|
||||
|
||||
77
vendor/symfony/polyfill-mbstring/Mbstring.php
vendored
77
vendor/symfony/polyfill-mbstring/Mbstring.php
vendored
@@ -48,6 +48,8 @@ namespace Symfony\Polyfill\Mbstring;
|
||||
* - mb_strstr - Finds first occurrence of a string within another
|
||||
* - mb_strwidth - Return width of string
|
||||
* - mb_substr_count - Count the number of substring occurrences
|
||||
* - mb_ucfirst - Make a string's first character uppercase
|
||||
* - mb_lcfirst - Make a string's first character lowercase
|
||||
*
|
||||
* Not implemented:
|
||||
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
|
||||
@@ -80,6 +82,21 @@ final class Mbstring
|
||||
|
||||
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
|
||||
{
|
||||
if (\is_array($s)) {
|
||||
if (PHP_VERSION_ID < 70200) {
|
||||
trigger_error('mb_convert_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$r = [];
|
||||
foreach ($s as $str) {
|
||||
$r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) {
|
||||
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
|
||||
} else {
|
||||
@@ -410,7 +427,7 @@ final class Mbstring
|
||||
|
||||
public static function mb_check_encoding($var = null, $encoding = null)
|
||||
{
|
||||
if (PHP_VERSION_ID < 70200 && \is_array($var)) {
|
||||
if (\PHP_VERSION_ID < 70200 && \is_array($var)) {
|
||||
trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
@@ -437,7 +454,6 @@ final class Mbstring
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
|
||||
@@ -827,7 +843,7 @@ final class Mbstring
|
||||
return $code;
|
||||
}
|
||||
|
||||
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string
|
||||
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string
|
||||
{
|
||||
if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) {
|
||||
throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
|
||||
@@ -835,17 +851,8 @@ final class Mbstring
|
||||
|
||||
if (null === $encoding) {
|
||||
$encoding = self::mb_internal_encoding();
|
||||
}
|
||||
|
||||
try {
|
||||
$validEncoding = @self::mb_check_encoding('', $encoding);
|
||||
} catch (\ValueError $e) {
|
||||
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
|
||||
}
|
||||
|
||||
// BC for PHP 7.3 and lower
|
||||
if (!$validEncoding) {
|
||||
throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
|
||||
} else {
|
||||
self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given');
|
||||
}
|
||||
|
||||
if (self::mb_strlen($pad_string, $encoding) <= 0) {
|
||||
@@ -871,6 +878,34 @@ final class Mbstring
|
||||
}
|
||||
}
|
||||
|
||||
public static function mb_ucfirst(string $string, ?string $encoding = null): string
|
||||
{
|
||||
if (null === $encoding) {
|
||||
$encoding = self::mb_internal_encoding();
|
||||
} else {
|
||||
self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
|
||||
}
|
||||
|
||||
$firstChar = mb_substr($string, 0, 1, $encoding);
|
||||
$firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
|
||||
|
||||
return $firstChar.mb_substr($string, 1, null, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_lcfirst(string $string, ?string $encoding = null): string
|
||||
{
|
||||
if (null === $encoding) {
|
||||
$encoding = self::mb_internal_encoding();
|
||||
} else {
|
||||
self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
|
||||
}
|
||||
|
||||
$firstChar = mb_substr($string, 0, 1, $encoding);
|
||||
$firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
|
||||
|
||||
return $firstChar.mb_substr($string, 1, null, $encoding);
|
||||
}
|
||||
|
||||
private static function getSubpart($pos, $part, $haystack, $encoding)
|
||||
{
|
||||
if (false === $pos) {
|
||||
@@ -944,4 +979,18 @@ final class Mbstring
|
||||
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
private static function assertEncoding(string $encoding, string $errorFormat): void
|
||||
{
|
||||
try {
|
||||
$validEncoding = @self::mb_check_encoding('', $encoding);
|
||||
} catch (\ValueError $e) {
|
||||
throw new \ValueError(\sprintf($errorFormat, $encoding));
|
||||
}
|
||||
|
||||
// BC for PHP 7.3 and lower
|
||||
if (!$validEncoding) {
|
||||
throw new \ValueError(\sprintf($errorFormat, $encoding));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,14 @@ if (!function_exists('mb_str_pad')) {
|
||||
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ucfirst')) {
|
||||
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_lcfirst')) {
|
||||
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,6 +132,14 @@ if (!function_exists('mb_str_pad')) {
|
||||
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_ucfirst')) {
|
||||
function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (!function_exists('mb_lcfirst')) {
|
||||
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
|
||||
}
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
return;
|
||||
}
|
||||
|
||||
1
vendor/symfony/polyfill-php72/Php72.php
vendored
1
vendor/symfony/polyfill-php72/Php72.php
vendored
@@ -141,6 +141,7 @@ final class Php72
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$stat = @fstat($stream);
|
||||
|
||||
// Check if formatted mode is S_IFCHR
|
||||
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
|
||||
}
|
||||
|
||||
19
vendor/symfony/polyfill-php81/LICENSE
vendored
19
vendor/symfony/polyfill-php81/LICENSE
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2021-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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
37
vendor/symfony/polyfill-php81/Php81.php
vendored
37
vendor/symfony/polyfill-php81/Php81.php
vendored
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Php81;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Php81
|
||||
{
|
||||
public static function array_is_list(array $array): bool
|
||||
{
|
||||
if ([] === $array || $array === array_values($array)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$nextKey = -1;
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if ($k !== ++$nextKey) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
18
vendor/symfony/polyfill-php81/README.md
vendored
18
vendor/symfony/polyfill-php81/README.md
vendored
@@ -1,18 +0,0 @@
|
||||
Symfony Polyfill / Php81
|
||||
========================
|
||||
|
||||
This component provides features added to PHP 8.1 core:
|
||||
|
||||
- [`array_is_list`](https://php.net/array_is_list)
|
||||
- [`enum_exists`](https://php.net/enum-exists)
|
||||
- [`MYSQLI_REFRESH_REPLICA`](https://php.net/mysqli.constants#constantmysqli-refresh-replica) constant
|
||||
- [`ReturnTypeWillChange`](https://wiki.php.net/rfc/internal_method_return_types)
|
||||
- [`CURLStringFile`](https://php.net/CURLStringFile) (but only if PHP >= 7.4 is used)
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if (\PHP_VERSION_ID < 80100) {
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class ReturnTypeWillChange
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
28
vendor/symfony/polyfill-php81/bootstrap.php
vendored
28
vendor/symfony/polyfill-php81/bootstrap.php
vendored
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Php81 as p;
|
||||
|
||||
if (\PHP_VERSION_ID >= 80100) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (defined('MYSQLI_REFRESH_SLAVE') && !defined('MYSQLI_REFRESH_REPLICA')) {
|
||||
define('MYSQLI_REFRESH_REPLICA', 64);
|
||||
}
|
||||
|
||||
if (!function_exists('array_is_list')) {
|
||||
function array_is_list(array $array): bool { return p\Php81::array_is_list($array); }
|
||||
}
|
||||
|
||||
if (!function_exists('enum_exists')) {
|
||||
function enum_exists(string $enum, bool $autoload = true): bool { return $autoload && class_exists($enum) && false; }
|
||||
}
|
||||
33
vendor/symfony/polyfill-php81/composer.json
vendored
33
vendor/symfony/polyfill-php81/composer.json
vendored
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Php81\\": "" },
|
||||
"files": [ "bootstrap.php" ],
|
||||
"classmap": [ "Resources/stubs" ]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
vendor/symfony/routing/Router.php
vendored
2
vendor/symfony/routing/Router.php
vendored
@@ -294,6 +294,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
$cache->write($dumper->dump(), $this->getRouteCollection()->getResources());
|
||||
unset(self::$cache[$cache->getPath()]);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -325,6 +326,7 @@ class Router implements RouterInterface, RequestMatcherInterface
|
||||
$dumper = $this->getGeneratorDumperInstance();
|
||||
|
||||
$cache->write($dumper->dump(), $this->getRouteCollection()->getResources());
|
||||
unset(self::$cache[$cache->getPath()]);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
3
vendor/symfony/service-contracts/.gitignore
vendored
3
vendor/symfony/service-contracts/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
@@ -11,10 +11,15 @@
|
||||
|
||||
namespace Symfony\Contracts\Service\Attribute;
|
||||
|
||||
use Symfony\Contracts\Service\ServiceSubscriberTrait;
|
||||
use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait;
|
||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Use with {@see ServiceSubscriberTrait} to mark a method's return type
|
||||
* For use as the return value for {@see ServiceSubscriberInterface}.
|
||||
*
|
||||
* @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi'))
|
||||
*
|
||||
* Use with {@see ServiceMethodsSubscriberTrait} to mark a method's return type
|
||||
* as a subscribed service.
|
||||
*
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/symfony/service-contracts/README.md
vendored
2
vendor/symfony/service-contracts/README.md
vendored
@@ -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.
|
||||
|
||||
@@ -26,5 +26,8 @@ namespace Symfony\Contracts\Service;
|
||||
*/
|
||||
interface ResetInterface
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset();
|
||||
}
|
||||
|
||||
@@ -26,34 +26,24 @@ class_exists(NotFoundExceptionInterface::class);
|
||||
*/
|
||||
trait ServiceLocatorTrait
|
||||
{
|
||||
private $factories;
|
||||
private $loading = [];
|
||||
private $providedTypes;
|
||||
private array $factories;
|
||||
private array $loading = [];
|
||||
private array $providedTypes;
|
||||
|
||||
/**
|
||||
* @param callable[] $factories
|
||||
* @param array<string, callable> $factories
|
||||
*/
|
||||
public function __construct(array $factories)
|
||||
{
|
||||
$this->factories = $factories;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $id)
|
||||
public function has(string $id): bool
|
||||
{
|
||||
return isset($this->factories[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(string $id)
|
||||
public function get(string $id): mixed
|
||||
{
|
||||
if (!isset($this->factories[$id])) {
|
||||
throw $this->createNotFoundException($id);
|
||||
@@ -75,12 +65,9 @@ trait ServiceLocatorTrait
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProvidedServices(): array
|
||||
{
|
||||
if (null === $this->providedTypes) {
|
||||
if (!isset($this->providedTypes)) {
|
||||
$this->providedTypes = [];
|
||||
|
||||
foreach ($this->factories as $name => $factory) {
|
||||
|
||||
@@ -18,9 +18,18 @@ use Psr\Container\ContainerInterface;
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author Mateusz Sip <mateusz.sip@gmail.com>
|
||||
*
|
||||
* @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<string, string> The provided service types, keyed by service names
|
||||
*/
|
||||
public function getProvidedServices(): array;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
public static function getSubscribedServices(): array;
|
||||
}
|
||||
|
||||
@@ -12,91 +12,65 @@
|
||||
namespace Symfony\Contracts\Service;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
use Symfony\Contracts\Service\Attribute\SubscribedService;
|
||||
|
||||
trigger_deprecation('symfony/contracts', 'v3.5', '"%s" is deprecated, use "ServiceMethodsSubscriberTrait" instead.', ServiceSubscriberTrait::class);
|
||||
|
||||
/**
|
||||
* Implementation of ServiceSubscriberInterface that determines subscribed services from
|
||||
* method return types. Service ids are available as "ClassName::methodName".
|
||||
* Implementation of ServiceSubscriberInterface that determines subscribed services
|
||||
* from methods that have the #[SubscribedService] attribute.
|
||||
*
|
||||
* Service ids are available as "ClassName::methodName" so that the implementation
|
||||
* of subscriber methods can be just `return $this->container->get(__METHOD__);`.
|
||||
*
|
||||
* @property ContainerInterface $container
|
||||
*
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
*
|
||||
* @deprecated since symfony/contracts v3.5, use ServiceMethodsSubscriberTrait instead
|
||||
*/
|
||||
trait ServiceSubscriberTrait
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedServices(): array
|
||||
{
|
||||
$services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : [];
|
||||
$attributeOptIn = false;
|
||||
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
|
||||
if (self::class !== $method->getDeclaringClass()->name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
|
||||
throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name));
|
||||
}
|
||||
|
||||
if (!$returnType = $method->getReturnType()) {
|
||||
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;
|
||||
|
||||
if ($returnType->allowsNull()) {
|
||||
$serviceId = '?'.$serviceId;
|
||||
}
|
||||
|
||||
$services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId;
|
||||
$attributeOptIn = true;
|
||||
foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
|
||||
if (self::class !== $method->getDeclaringClass()->name) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$attributeOptIn) {
|
||||
foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
|
||||
if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
|
||||
continue;
|
||||
}
|
||||
if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::class !== $method->getDeclaringClass()->name) {
|
||||
continue;
|
||||
}
|
||||
if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
|
||||
throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name));
|
||||
}
|
||||
|
||||
if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) {
|
||||
continue;
|
||||
}
|
||||
if (!$returnType = $method->getReturnType()) {
|
||||
throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class));
|
||||
}
|
||||
|
||||
if ($returnType->isBuiltin()) {
|
||||
continue;
|
||||
}
|
||||
/* @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 (\PHP_VERSION_ID >= 80000) {
|
||||
trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class);
|
||||
}
|
||||
|
||||
$services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType);
|
||||
if ($attribute->attributes) {
|
||||
$services[] = $attribute;
|
||||
} else {
|
||||
$services[$attribute->key] = ($attribute->nullable ? '?' : '').$attribute->type;
|
||||
}
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* @required
|
||||
*
|
||||
* @return ContainerInterface|null
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container)
|
||||
#[Required]
|
||||
public function setContainer(ContainerInterface $container): ?ContainerInterface
|
||||
{
|
||||
$ret = null;
|
||||
if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) {
|
||||
|
||||
16
vendor/symfony/service-contracts/composer.json
vendored
16
vendor/symfony/service-contracts/composer.json
vendored
@@ -16,23 +16,23 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"psr/container": "^1.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3"
|
||||
"php": ">=8.1",
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3"
|
||||
},
|
||||
"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": "2.5-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
||||
46
vendor/symfony/string/AbstractString.php
vendored
46
vendor/symfony/string/AbstractString.php
vendored
@@ -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;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
|
||||
return '' === $this->string;
|
||||
}
|
||||
|
||||
abstract public function join(array $strings, string $lastGlue = null): static;
|
||||
abstract public function join(array $strings, ?string $lastGlue = null): static;
|
||||
|
||||
public function jsonSerialize(): string
|
||||
{
|
||||
@@ -429,16 +429,16 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
|
||||
|
||||
abstract public function reverse(): static;
|
||||
|
||||
abstract public function slice(int $start = 0, int $length = null): static;
|
||||
abstract public function slice(int $start = 0, ?int $length = null): static;
|
||||
|
||||
abstract public function snake(): static;
|
||||
|
||||
abstract public function splice(string $replacement, int $start = 0, int $length = null): static;
|
||||
abstract public function splice(string $replacement, int $start = 0, ?int $length = null): static;
|
||||
|
||||
/**
|
||||
* @return static[]
|
||||
*/
|
||||
public function split(string $delimiter, int $limit = null, int $flags = null): array
|
||||
public function split(string $delimiter, ?int $limit = null, ?int $flags = null): array
|
||||
{
|
||||
if (null === $flags) {
|
||||
throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.');
|
||||
@@ -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();
|
||||
@@ -503,7 +495,7 @@ abstract class AbstractString implements \Stringable, \JsonSerializable
|
||||
|
||||
abstract public function title(bool $allWords = false): static;
|
||||
|
||||
public function toByteString(string $toEncoding = null): ByteString
|
||||
public function toByteString(?string $toEncoding = null): ByteString
|
||||
{
|
||||
$b = new ByteString();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
56
vendor/symfony/string/AbstractUnicodeString.php
vendored
56
vendor/symfony/string/AbstractUnicodeString.php
vendored
@@ -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.(?!\p{Lu})/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)));
|
||||
|
||||
@@ -192,7 +190,7 @@ abstract class AbstractUnicodeString extends AbstractString
|
||||
|
||||
if (!$compat || !\defined('Normalizer::NFKC_CF')) {
|
||||
$str->string = normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC);
|
||||
$str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8');
|
||||
$str->string = mb_strtolower(str_replace(self::FOLD_FROM, self::FOLD_TO, $str->string), 'UTF-8');
|
||||
} else {
|
||||
$str->string = normalizer_normalize($str->string, \Normalizer::NFKC_CF);
|
||||
}
|
||||
@@ -200,7 +198,7 @@ abstract class AbstractUnicodeString extends AbstractString
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function join(array $strings, string $lastGlue = null): static
|
||||
public function join(array $strings, ?string $lastGlue = null): static
|
||||
{
|
||||
$str = clone $this;
|
||||
|
||||
@@ -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;
|
||||
|
||||
36
vendor/symfony/string/ByteString.php
vendored
36
vendor/symfony/string/ByteString.php
vendored
@@ -42,13 +42,13 @@ class ByteString extends AbstractString
|
||||
* Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/)
|
||||
*/
|
||||
|
||||
public static function fromRandom(int $length = 16, string $alphabet = null): self
|
||||
public static function fromRandom(int $length = 16, ?string $alphabet = null): self
|
||||
{
|
||||
if ($length <= 0) {
|
||||
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) {
|
||||
@@ -205,7 +205,7 @@ class ByteString extends AbstractString
|
||||
return '' === $this->string || preg_match('//u', $this->string);
|
||||
}
|
||||
|
||||
public function join(array $strings, string $lastGlue = null): static
|
||||
public function join(array $strings, ?string $lastGlue = null): static
|
||||
{
|
||||
$str = clone $this;
|
||||
|
||||
@@ -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.'.');
|
||||
}
|
||||
}
|
||||
@@ -340,7 +332,7 @@ class ByteString extends AbstractString
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function slice(int $start = 0, int $length = null): static
|
||||
public function slice(int $start = 0, ?int $length = null): static
|
||||
{
|
||||
$str = clone $this;
|
||||
$str->string = (string) substr($this->string, $start, $length ?? \PHP_INT_MAX);
|
||||
@@ -356,7 +348,7 @@ class ByteString extends AbstractString
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function splice(string $replacement, int $start = 0, int $length = null): static
|
||||
public function splice(string $replacement, int $start = 0, ?int $length = null): static
|
||||
{
|
||||
$str = clone $this;
|
||||
$str->string = substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
|
||||
@@ -364,9 +356,9 @@ class ByteString extends AbstractString
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function split(string $delimiter, int $limit = null, int $flags = null): array
|
||||
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.');
|
||||
}
|
||||
|
||||
@@ -410,12 +402,12 @@ class ByteString extends AbstractString
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function toUnicodeString(string $fromEncoding = null): UnicodeString
|
||||
public function toUnicodeString(?string $fromEncoding = null): UnicodeString
|
||||
{
|
||||
return new UnicodeString($this->toCodePointString($fromEncoding)->string);
|
||||
}
|
||||
|
||||
public function toCodePointString(string $fromEncoding = null): CodePointString
|
||||
public function toCodePointString(?string $fromEncoding = null): CodePointString
|
||||
{
|
||||
$u = new CodePointString();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user