mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-03 13:40:00 +09:00
Dependency updates and update version number
This commit is contained in:
5
vendor/symfony/console/Command/Command.php
vendored
5
vendor/symfony/console/Command/Command.php
vendored
@@ -218,12 +218,11 @@ class Command
|
||||
|
||||
if (null !== $this->processTitle) {
|
||||
if (function_exists('cli_set_process_title')) {
|
||||
if (false === @cli_set_process_title($this->processTitle)) {
|
||||
if (!@cli_set_process_title($this->processTitle)) {
|
||||
if ('Darwin' === PHP_OS) {
|
||||
$output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
|
||||
} else {
|
||||
$error = error_get_last();
|
||||
trigger_error($error['message'], E_USER_WARNING);
|
||||
cli_set_process_title($this->processTitle);
|
||||
}
|
||||
}
|
||||
} elseif (function_exists('setproctitle')) {
|
||||
|
||||
@@ -21,7 +21,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
interface DescriptorInterface
|
||||
{
|
||||
/**
|
||||
* Describes an InputArgument instance.
|
||||
* Describes an object if supported.
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @param object $object
|
||||
|
||||
@@ -121,7 +121,7 @@ class JsonDescriptor extends Descriptor
|
||||
{
|
||||
return array(
|
||||
'name' => '--'.$option->getName(),
|
||||
'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
|
||||
'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '',
|
||||
'accept_value' => $option->acceptValue(),
|
||||
'is_value_required' => $option->isValueRequired(),
|
||||
'is_multiple' => $option->isArray(),
|
||||
|
||||
@@ -70,7 +70,7 @@ class MarkdownDescriptor extends Descriptor
|
||||
{
|
||||
$name = '--'.$option->getName();
|
||||
if ($option->getShortcut()) {
|
||||
$name .= '|-'.implode('|-', explode('|', $option->getShortcut())).'';
|
||||
$name .= '|-'.str_replace('|', '|-', $option->getShortcut()).'';
|
||||
}
|
||||
|
||||
$this->write(
|
||||
|
||||
@@ -224,7 +224,7 @@ class XmlDescriptor extends Descriptor
|
||||
$pos = strpos($option->getShortcut(), '|');
|
||||
if (false !== $pos) {
|
||||
$objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
|
||||
$objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
|
||||
$objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut()));
|
||||
} else {
|
||||
$objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@ class ErrorListener implements EventSubscriberInterface
|
||||
$error = $event->getError();
|
||||
|
||||
if (!$inputString = $this->getInputString($event)) {
|
||||
return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage()));
|
||||
return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('exception' => $error, 'message' => $error->getMessage()));
|
||||
}
|
||||
|
||||
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage()));
|
||||
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()));
|
||||
}
|
||||
|
||||
public function onConsoleTerminate(ConsoleTerminateEvent $event)
|
||||
|
||||
@@ -305,7 +305,7 @@ class QuestionHelper extends Helper
|
||||
|
||||
foreach ($autocomplete as $value) {
|
||||
// If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
|
||||
if (0 === strpos($value, $ret) && $i !== strlen($value)) {
|
||||
if (0 === strpos($value, $ret)) {
|
||||
$matches[$numMatches++] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
19
vendor/symfony/console/Input/ArgvInput.php
vendored
19
vendor/symfony/console/Input/ArgvInput.php
vendored
@@ -282,7 +282,11 @@ class ArgvInput extends Input
|
||||
return false;
|
||||
}
|
||||
foreach ($values as $value) {
|
||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||
// Options with values:
|
||||
// For long options, test for '--option=' at beginning
|
||||
// For short options, test for '-o' at beginning
|
||||
$leading = 0 === strpos($value, '--') ? $value.'=' : $value;
|
||||
if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -306,13 +310,16 @@ class ArgvInput extends Input
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||
if (false !== $pos = strpos($token, '=')) {
|
||||
return substr($token, $pos + 1);
|
||||
}
|
||||
|
||||
if ($token === $value) {
|
||||
return array_shift($tokens);
|
||||
}
|
||||
// Options with values:
|
||||
// For long options, test for '--option=' at beginning
|
||||
// For short options, test for '-o' at beginning
|
||||
$leading = 0 === strpos($value, '--') ? $value.'=' : $value;
|
||||
if ('' !== $leading && 0 === strpos($token, $leading)) {
|
||||
return substr($token, strlen($leading));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/symfony/console/Input/ArrayInput.php
vendored
2
vendor/symfony/console/Input/ArrayInput.php
vendored
@@ -114,7 +114,7 @@ class ArrayInput extends Input
|
||||
$params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
|
||||
}
|
||||
} else {
|
||||
$params[] = is_array($val) ? array_map(array($this, 'escapeToken'), $val) : $this->escapeToken($val);
|
||||
$params[] = is_array($val) ? implode(' ', array_map(array($this, 'escapeToken'), $val)) : $this->escapeToken($val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ interface InputInterface
|
||||
*
|
||||
* This method is to be used to introspect the input parameters
|
||||
* before they have been validated. It must be used carefully.
|
||||
* Does not necessarily return the correct result for short options
|
||||
* when multiple flags are combined in the same option.
|
||||
*
|
||||
* @param string|array $values The values to look for in the raw parameters (can be an array)
|
||||
* @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
|
||||
@@ -46,6 +48,8 @@ interface InputInterface
|
||||
*
|
||||
* This method is to be used to introspect the input parameters
|
||||
* before they have been validated. It must be used carefully.
|
||||
* Does not necessarily return the correct result for short options
|
||||
* when multiple flags are combined in the same option.
|
||||
*
|
||||
* @param string|array $values The value(s) to look for in the raw parameters (can be an array)
|
||||
* @param mixed $default The default value to return if no result is found
|
||||
|
||||
2
vendor/symfony/console/Input/InputOption.php
vendored
2
vendor/symfony/console/Input/InputOption.php
vendored
@@ -195,7 +195,7 @@ class InputOption
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function equals(InputOption $option)
|
||||
public function equals(self $option)
|
||||
{
|
||||
return $option->getName() === $this->getName()
|
||||
&& $option->getShortcut() === $this->getShortcut()
|
||||
|
||||
23
vendor/symfony/console/Output/StreamOutput.php
vendored
23
vendor/symfony/console/Output/StreamOutput.php
vendored
@@ -83,21 +83,34 @@ class StreamOutput extends Output
|
||||
*
|
||||
* Colorization is disabled if not supported by the stream:
|
||||
*
|
||||
* - Windows != 10.0.10586 without Ansicon, ConEmu or Mintty
|
||||
* - non tty consoles
|
||||
* This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
|
||||
* terminals via named pipes, so we can only check the environment.
|
||||
*
|
||||
* Reference: Composer\XdebugHandler\Process::supportsColor
|
||||
* https://github.com/composer/xdebug-handler
|
||||
*
|
||||
* @return bool true if the stream supports colorization, false otherwise
|
||||
*/
|
||||
protected function hasColorSupport()
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
return
|
||||
'10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
|
||||
return (function_exists('sapi_windows_vt100_support')
|
||||
&& @sapi_windows_vt100_support($this->stream))
|
||||
|| false !== getenv('ANSICON')
|
||||
|| 'ON' === getenv('ConEmuANSI')
|
||||
|| 'xterm' === getenv('TERM');
|
||||
}
|
||||
|
||||
return function_exists('posix_isatty') && @posix_isatty($this->stream);
|
||||
if (function_exists('stream_isatty')) {
|
||||
return @stream_isatty($this->stream);
|
||||
}
|
||||
|
||||
if (function_exists('posix_isatty')) {
|
||||
return @posix_isatty($this->stream);
|
||||
}
|
||||
|
||||
$stat = @fstat($this->stream);
|
||||
// Check if formatted mode is S_IFCHR
|
||||
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ErrorListenerTest extends TestCase
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error')
|
||||
->with('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred'))
|
||||
->with('Error thrown while running command "{command}". Message: "{message}"', array('exception' => $error, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred'))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
@@ -49,7 +49,7 @@ class ErrorListenerTest extends TestCase
|
||||
$logger
|
||||
->expects($this->once())
|
||||
->method('error')
|
||||
->with('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => 'An error occurred'))
|
||||
->with('An error occurred while using the console. Message: "{message}"', array('exception' => $error, 'message' => 'An error occurred'))
|
||||
;
|
||||
|
||||
$listener = new ErrorListener($logger);
|
||||
|
||||
@@ -157,6 +157,29 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAskWithAutocompleteWithExactMatch()
|
||||
{
|
||||
if (!$this->hasSttyAvailable()) {
|
||||
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
|
||||
}
|
||||
|
||||
$inputStream = $this->getInputStream("b\n");
|
||||
|
||||
$possibleChoices = array(
|
||||
'a' => 'berlin',
|
||||
'b' => 'copenhagen',
|
||||
'c' => 'amsterdam',
|
||||
);
|
||||
|
||||
$dialog = new QuestionHelper();
|
||||
$dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));
|
||||
|
||||
$question = new ChoiceQuestion('Please select a city', $possibleChoices);
|
||||
$question->setMaxAttempts(1);
|
||||
|
||||
$this->assertSame('b', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAutocompleteWithTrailingBackslash()
|
||||
{
|
||||
if (!$this->hasSttyAvailable()) {
|
||||
|
||||
@@ -314,6 +314,10 @@ class ArgvInputTest extends TestCase
|
||||
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
|
||||
$this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '-etest'));
|
||||
$this->assertTrue($input->hasParameterOption('-e'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
$this->assertFalse($input->hasParameterOption('-s'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '--foo', 'foo'));
|
||||
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
|
||||
@@ -339,6 +343,46 @@ class ArgvInputTest extends TestCase
|
||||
$this->assertFalse($input->hasParameterOption('--foo', true), '->hasParameterOption() returns false if the given option is in the raw input but after an end of options signal');
|
||||
}
|
||||
|
||||
public function testHasParameterOptionEdgeCasesAndLimitations()
|
||||
{
|
||||
$input = new ArgvInput(array('cli.php', '-fh'));
|
||||
// hasParameterOption does not know if the previous short option, -f,
|
||||
// takes a value or not. If -f takes a value, then -fh does NOT include
|
||||
// -h; Otherwise it does. Since we do not know which short options take
|
||||
// values, hasParameterOption does not support this use-case.
|
||||
$this->assertFalse($input->hasParameterOption('-h'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
// hasParameterOption does detect that `-fh` contains `-f`, since
|
||||
// `-f` is the first short option in the set.
|
||||
$this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
// The test below happens to pass, although it might make more sense
|
||||
// to disallow it, and require the use of
|
||||
// $input->hasParameterOption('-f') && $input->hasParameterOption('-h')
|
||||
// instead.
|
||||
$this->assertTrue($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
// In theory, if -fh is supported, then -hf should also work.
|
||||
// However, this is not supported.
|
||||
$this->assertFalse($input->hasParameterOption('-hf'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
|
||||
$input = new ArgvInput(array('cli.php', '-f', '-h'));
|
||||
// If hasParameterOption('-fh') is supported for 'cli.php -fh', then
|
||||
// one might also expect that it should also be supported for
|
||||
// 'cli.php -f -h'. However, this is not supported.
|
||||
$this->assertFalse($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input');
|
||||
}
|
||||
|
||||
public function testNoWarningOnInvalidParameterOption()
|
||||
{
|
||||
$input = new ArgvInput(array('cli.php', '-edev'));
|
||||
|
||||
$this->assertTrue($input->hasParameterOption(array('-e', '')));
|
||||
// No warning thrown
|
||||
$this->assertFalse($input->hasParameterOption(array('-m', '')));
|
||||
|
||||
$this->assertEquals('dev', $input->getParameterOption(array('-e', '')));
|
||||
// No warning thrown
|
||||
$this->assertFalse($input->getParameterOption(array('-m', '')));
|
||||
}
|
||||
|
||||
public function testToString()
|
||||
{
|
||||
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
|
||||
|
||||
@@ -170,5 +170,8 @@ class ArrayInputTest extends TestCase
|
||||
|
||||
$input = new ArrayInput(array('-b' => array('bval_1', 'bval_2'), '--f' => array('fval_1', 'fval_2')));
|
||||
$this->assertSame('-b=bval_1 -b=bval_2 --f=fval_1 --f=fval_2', (string) $input);
|
||||
|
||||
$input = new ArrayInput(array('array_arg' => array('val_1', 'val_2')));
|
||||
$this->assertSame('val_1 val_2', (string) $input);
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/symfony/console/composer.json
vendored
2
vendor/symfony/console/composer.json
vendored
@@ -32,7 +32,7 @@
|
||||
"symfony/event-dispatcher": "",
|
||||
"symfony/lock": "",
|
||||
"symfony/process": "",
|
||||
"psr/log": "For using the console logger"
|
||||
"psr/log-implementation": "For using the console logger"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<3.4",
|
||||
|
||||
@@ -31,7 +31,7 @@ class CssSelectorConverter
|
||||
/**
|
||||
* @param bool $html Whether HTML support should be enabled. Disable it for XML documents
|
||||
*/
|
||||
public function __construct($html = true)
|
||||
public function __construct(bool $html = true)
|
||||
{
|
||||
$this->translator = new Translator();
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ abstract class AbstractNode implements NodeInterface
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeName()
|
||||
public function getNodeName(): string
|
||||
{
|
||||
if (null === $this->nodeName) {
|
||||
$this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', get_called_class());
|
||||
|
||||
@@ -29,14 +29,7 @@ class AttributeNode extends AbstractNode
|
||||
private $operator;
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $selector
|
||||
* @param string $namespace
|
||||
* @param string $attribute
|
||||
* @param string $operator
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $namespace, $attribute, $operator, $value)
|
||||
public function __construct(NodeInterface $selector, ?string $namespace, string $attribute, string $operator, ?string $value)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->namespace = $namespace;
|
||||
@@ -45,42 +38,27 @@ class AttributeNode extends AbstractNode
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
public function getNamespace(): ?string
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAttribute()
|
||||
public function getAttribute(): string
|
||||
{
|
||||
return $this->attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOperator()
|
||||
public function getOperator(): string
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): ?string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
@@ -88,7 +66,7 @@ class AttributeNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
}
|
||||
@@ -96,7 +74,7 @@ class AttributeNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$attribute = $this->namespace ? $this->namespace.'|'.$this->attribute : $this->attribute;
|
||||
|
||||
|
||||
20
vendor/symfony/css-selector/Node/ClassNode.php
vendored
20
vendor/symfony/css-selector/Node/ClassNode.php
vendored
@@ -26,28 +26,18 @@ class ClassNode extends AbstractNode
|
||||
private $selector;
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $selector
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $name)
|
||||
public function __construct(NodeInterface $selector, string $name)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@@ -55,7 +45,7 @@ class ClassNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
}
|
||||
@@ -63,7 +53,7 @@ class ClassNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name);
|
||||
}
|
||||
|
||||
@@ -27,38 +27,24 @@ class CombinedSelectorNode extends AbstractNode
|
||||
private $combinator;
|
||||
private $subSelector;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $selector
|
||||
* @param string $combinator
|
||||
* @param NodeInterface $subSelector
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $combinator, NodeInterface $subSelector)
|
||||
public function __construct(NodeInterface $selector, string $combinator, NodeInterface $subSelector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->combinator = $combinator;
|
||||
$this->subSelector = $subSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCombinator()
|
||||
public function getCombinator(): string
|
||||
{
|
||||
return $this->combinator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSubSelector()
|
||||
public function getSubSelector(): NodeInterface
|
||||
{
|
||||
return $this->subSelector;
|
||||
}
|
||||
@@ -66,7 +52,7 @@ class CombinedSelectorNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
||||
}
|
||||
@@ -74,7 +60,7 @@ class CombinedSelectorNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$combinator = ' ' === $this->combinator ? '<followed>' : $this->combinator;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ElementNode extends AbstractNode
|
||||
* @param string|null $namespace
|
||||
* @param string|null $element
|
||||
*/
|
||||
public function __construct($namespace = null, $element = null)
|
||||
public function __construct(string $namespace = null, string $element = null)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->element = $element;
|
||||
@@ -55,7 +55,7 @@ class ElementNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return new Specificity(0, 0, $this->element ? 1 : 0);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ class ElementNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$element = $this->element ?: '*';
|
||||
|
||||
|
||||
@@ -34,25 +34,19 @@ class FunctionNode extends AbstractNode
|
||||
* @param string $name
|
||||
* @param Token[] $arguments
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $name, array $arguments = array())
|
||||
public function __construct(NodeInterface $selector, string $name, array $arguments = array())
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->name = strtolower($name);
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@@ -68,7 +62,7 @@ class FunctionNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
}
|
||||
@@ -76,7 +70,7 @@ class FunctionNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$arguments = implode(', ', array_map(function (Token $token) {
|
||||
return "'".$token->getValue()."'";
|
||||
|
||||
20
vendor/symfony/css-selector/Node/HashNode.php
vendored
20
vendor/symfony/css-selector/Node/HashNode.php
vendored
@@ -26,28 +26,18 @@ class HashNode extends AbstractNode
|
||||
private $selector;
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $selector
|
||||
* @param string $id
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $id)
|
||||
public function __construct(NodeInterface $selector, string $id)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
@@ -55,7 +45,7 @@ class HashNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0));
|
||||
}
|
||||
@@ -63,7 +53,7 @@ class HashNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class NegationNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class NegationNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector);
|
||||
}
|
||||
|
||||
@@ -23,24 +23,9 @@ namespace Symfony\Component\CssSelector\Node;
|
||||
*/
|
||||
interface NodeInterface
|
||||
{
|
||||
/**
|
||||
* Returns node's name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeName();
|
||||
public function getNodeName(): string;
|
||||
|
||||
/**
|
||||
* Returns node's specificity.
|
||||
*
|
||||
* @return Specificity
|
||||
*/
|
||||
public function getSpecificity();
|
||||
public function getSpecificity(): Specificity;
|
||||
|
||||
/**
|
||||
* Returns node's string representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
public function __toString(): string;
|
||||
}
|
||||
|
||||
20
vendor/symfony/css-selector/Node/PseudoNode.php
vendored
20
vendor/symfony/css-selector/Node/PseudoNode.php
vendored
@@ -26,28 +26,18 @@ class PseudoNode extends AbstractNode
|
||||
private $selector;
|
||||
private $identifier;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $selector
|
||||
* @param string $identifier
|
||||
*/
|
||||
public function __construct(NodeInterface $selector, $identifier)
|
||||
public function __construct(NodeInterface $selector, string $identifier)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
$this->identifier = strtolower($identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getSelector()
|
||||
public function getSelector(): NodeInterface
|
||||
{
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier()
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return $this->identifier;
|
||||
}
|
||||
@@ -55,7 +45,7 @@ class PseudoNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
||||
}
|
||||
@@ -63,7 +53,7 @@ class PseudoNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier);
|
||||
}
|
||||
|
||||
@@ -26,28 +26,18 @@ class SelectorNode extends AbstractNode
|
||||
private $tree;
|
||||
private $pseudoElement;
|
||||
|
||||
/**
|
||||
* @param NodeInterface $tree
|
||||
* @param null|string $pseudoElement
|
||||
*/
|
||||
public function __construct(NodeInterface $tree, $pseudoElement = null)
|
||||
public function __construct(NodeInterface $tree, string $pseudoElement = null)
|
||||
{
|
||||
$this->tree = $tree;
|
||||
$this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NodeInterface
|
||||
*/
|
||||
public function getTree()
|
||||
public function getTree(): NodeInterface
|
||||
{
|
||||
return $this->tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getPseudoElement()
|
||||
public function getPseudoElement(): ?string
|
||||
{
|
||||
return $this->pseudoElement;
|
||||
}
|
||||
@@ -55,7 +45,7 @@ class SelectorNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSpecificity()
|
||||
public function getSpecificity(): Specificity
|
||||
{
|
||||
return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0));
|
||||
}
|
||||
@@ -63,7 +53,7 @@ class SelectorNode extends AbstractNode
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : '');
|
||||
}
|
||||
|
||||
21
vendor/symfony/css-selector/Node/Specificity.php
vendored
21
vendor/symfony/css-selector/Node/Specificity.php
vendored
@@ -33,32 +33,19 @@ class Specificity
|
||||
private $b;
|
||||
private $c;
|
||||
|
||||
/**
|
||||
* @param int $a
|
||||
* @param int $b
|
||||
* @param int $c
|
||||
*/
|
||||
public function __construct($a, $b, $c)
|
||||
public function __construct(int $a, int $b, int $c)
|
||||
{
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
$this->c = $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function plus(Specificity $specificity)
|
||||
public function plus(self $specificity): self
|
||||
{
|
||||
return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns global specificity value.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): int
|
||||
{
|
||||
return $this->a * self::A_FACTOR + $this->b * self::B_FACTOR + $this->c * self::C_FACTOR;
|
||||
}
|
||||
@@ -69,7 +56,7 @@ class Specificity
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function compareTo(Specificity $specificity)
|
||||
public function compareTo(self $specificity)
|
||||
{
|
||||
if ($this->a !== $specificity->a) {
|
||||
return $this->a > $specificity->a ? 1 : -1;
|
||||
|
||||
@@ -29,7 +29,7 @@ class CommentHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
if ('/*' !== $reader->getSubstring(2)) {
|
||||
return false;
|
||||
|
||||
@@ -29,5 +29,5 @@ interface HandlerInterface
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream);
|
||||
public function handle(Reader $reader, TokenStream $stream): bool;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class HashHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getHashPattern());
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class IdentifierHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getIdentifierPattern());
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class NumberHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern($this->patterns->getNumberPattern());
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class StringHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$quote = $reader->getSubstring(1);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class WhitespaceHandler implements HandlerInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Reader $reader, TokenStream $stream)
|
||||
public function handle(Reader $reader, TokenStream $stream): bool
|
||||
{
|
||||
$match = $reader->findPattern('~^[ \t\r\n\f]+~');
|
||||
|
||||
|
||||
45
vendor/symfony/css-selector/Parser/Parser.php
vendored
45
vendor/symfony/css-selector/Parser/Parser.php
vendored
@@ -37,7 +37,7 @@ class Parser implements ParserInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($source)
|
||||
public function parse(string $source): array
|
||||
{
|
||||
$reader = new Reader($source);
|
||||
$stream = $this->tokenizer->tokenize($reader);
|
||||
@@ -50,11 +50,9 @@ class Parser implements ParserInterface
|
||||
*
|
||||
* @param Token[] $tokens
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws SyntaxErrorException
|
||||
*/
|
||||
public static function parseSeries(array $tokens)
|
||||
public static function parseSeries(array $tokens): array
|
||||
{
|
||||
foreach ($tokens as $token) {
|
||||
if ($token->isString()) {
|
||||
@@ -94,12 +92,7 @@ class Parser implements ParserInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses selector nodes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseSelectorList(TokenStream $stream)
|
||||
private function parseSelectorList(TokenStream $stream): array
|
||||
{
|
||||
$stream->skipWhitespace();
|
||||
$selectors = array();
|
||||
@@ -118,14 +111,7 @@ class Parser implements ParserInterface
|
||||
return $selectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next selector or combined node.
|
||||
*
|
||||
* @return Node\SelectorNode
|
||||
*
|
||||
* @throws SyntaxErrorException
|
||||
*/
|
||||
private function parserSelectorNode(TokenStream $stream)
|
||||
private function parserSelectorNode(TokenStream $stream): Node\SelectorNode
|
||||
{
|
||||
list($result, $pseudoElement) = $this->parseSimpleSelector($stream);
|
||||
|
||||
@@ -158,14 +144,9 @@ class Parser implements ParserInterface
|
||||
/**
|
||||
* Parses next simple node (hash, class, pseudo, negation).
|
||||
*
|
||||
* @param TokenStream $stream
|
||||
* @param bool $insideNegation
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws SyntaxErrorException
|
||||
*/
|
||||
private function parseSimpleSelector(TokenStream $stream, $insideNegation = false)
|
||||
private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = false): array
|
||||
{
|
||||
$stream->skipWhitespace();
|
||||
|
||||
@@ -279,12 +260,7 @@ class Parser implements ParserInterface
|
||||
return array($result, $pseudoElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next element node.
|
||||
*
|
||||
* @return Node\ElementNode
|
||||
*/
|
||||
private function parseElementNode(TokenStream $stream)
|
||||
private function parseElementNode(TokenStream $stream): Node\ElementNode
|
||||
{
|
||||
$peek = $stream->getPeek();
|
||||
|
||||
@@ -310,14 +286,7 @@ class Parser implements ParserInterface
|
||||
return new Node\ElementNode($namespace, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next attribute node.
|
||||
*
|
||||
* @return Node\AttributeNode
|
||||
*
|
||||
* @throws SyntaxErrorException
|
||||
*/
|
||||
private function parseAttributeNode(Node\NodeInterface $selector, TokenStream $stream)
|
||||
private function parseAttributeNode(Node\NodeInterface $selector, TokenStream $stream): Node\AttributeNode
|
||||
{
|
||||
$stream->skipWhitespace();
|
||||
$attribute = $stream->getNextIdentifierOrStar();
|
||||
|
||||
@@ -28,9 +28,7 @@ interface ParserInterface
|
||||
/**
|
||||
* Parses given selector source into an array of tokens.
|
||||
*
|
||||
* @param string $source
|
||||
*
|
||||
* @return SelectorNode[]
|
||||
*/
|
||||
public function parse($source);
|
||||
public function parse(string $source): array;
|
||||
}
|
||||
|
||||
44
vendor/symfony/css-selector/Parser/Reader.php
vendored
44
vendor/symfony/css-selector/Parser/Reader.php
vendored
@@ -27,56 +27,33 @@ class Reader
|
||||
private $length;
|
||||
private $position = 0;
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*/
|
||||
public function __construct($source)
|
||||
public function __construct(string $source)
|
||||
{
|
||||
$this->source = $source;
|
||||
$this->length = strlen($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEOF()
|
||||
public function isEOF(): bool
|
||||
{
|
||||
return $this->position >= $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPosition()
|
||||
public function getPosition(): int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRemainingLength()
|
||||
public function getRemainingLength(): int
|
||||
{
|
||||
return $this->length - $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @param int $offset
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSubstring($length, $offset = 0)
|
||||
public function getSubstring(int $length, int $offset = 0): string
|
||||
{
|
||||
return substr($this->source, $this->position + $offset, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset($string)
|
||||
public function getOffset(string $string)
|
||||
{
|
||||
$position = strpos($this->source, $string, $this->position);
|
||||
|
||||
@@ -84,11 +61,9 @@ class Reader
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function findPattern($pattern)
|
||||
public function findPattern(string $pattern)
|
||||
{
|
||||
$source = substr($this->source, $this->position);
|
||||
|
||||
@@ -99,10 +74,7 @@ class Reader
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
*/
|
||||
public function moveForward($length)
|
||||
public function moveForward(int $length)
|
||||
{
|
||||
$this->position += $length;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ClassParser implements ParserInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($source)
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, optional element, and required class
|
||||
// $source = 'test|input.ab6bd_field';
|
||||
|
||||
@@ -30,7 +30,7 @@ class ElementParser implements ParserInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($source)
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, required element or `*`
|
||||
// $source = 'testns|testel';
|
||||
|
||||
@@ -34,7 +34,7 @@ class EmptyStringParser implements ParserInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($source)
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an empty string
|
||||
if ('' == $source) {
|
||||
|
||||
@@ -31,7 +31,7 @@ class HashParser implements ParserInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($source)
|
||||
public function parse(string $source): array
|
||||
{
|
||||
// Matches an optional namespace, optional element, and required id
|
||||
// $source = 'test|input#ab6bd_field';
|
||||
|
||||
62
vendor/symfony/css-selector/Parser/Token.php
vendored
62
vendor/symfony/css-selector/Parser/Token.php
vendored
@@ -35,54 +35,34 @@ class Token
|
||||
private $value;
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
* @param string $value
|
||||
* @param int $position
|
||||
*/
|
||||
public function __construct($type, $value, $position)
|
||||
public function __construct(?string $type, ?string $value, ?int $position)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
$this->position = $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType()
|
||||
public function getType(): ?int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): ?string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPosition()
|
||||
public function getPosition(): ?int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFileEnd()
|
||||
public function isFileEnd(): bool
|
||||
{
|
||||
return self::TYPE_FILE_END === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelimiter(array $values = array())
|
||||
public function isDelimiter(array $values = array()): bool
|
||||
{
|
||||
if (self::TYPE_DELIMITER !== $this->type) {
|
||||
return false;
|
||||
@@ -95,50 +75,32 @@ class Token
|
||||
return in_array($this->value, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWhitespace()
|
||||
public function isWhitespace(): bool
|
||||
{
|
||||
return self::TYPE_WHITESPACE === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isIdentifier()
|
||||
public function isIdentifier(): bool
|
||||
{
|
||||
return self::TYPE_IDENTIFIER === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHash()
|
||||
public function isHash(): bool
|
||||
{
|
||||
return self::TYPE_HASH === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNumber()
|
||||
public function isNumber(): bool
|
||||
{
|
||||
return self::TYPE_NUMBER === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isString()
|
||||
public function isString(): bool
|
||||
{
|
||||
return self::TYPE_STRING === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->value) {
|
||||
return sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position);
|
||||
|
||||
@@ -30,36 +30,21 @@ class TokenizerEscaping
|
||||
$this->patterns = $patterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function escapeUnicode($value)
|
||||
public function escapeUnicode(string $value): string
|
||||
{
|
||||
$value = $this->replaceUnicodeSequences($value);
|
||||
|
||||
return preg_replace($this->patterns->getSimpleEscapePattern(), '$1', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function escapeUnicodeAndNewLine($value)
|
||||
public function escapeUnicodeAndNewLine(string $value): string
|
||||
{
|
||||
$value = preg_replace($this->patterns->getNewLineEscapePattern(), '', $value);
|
||||
|
||||
return $this->escapeUnicode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replaceUnicodeSequences($value)
|
||||
private function replaceUnicodeSequences(string $value): string
|
||||
{
|
||||
return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) {
|
||||
$c = hexdec($match[1]);
|
||||
|
||||
@@ -46,66 +46,43 @@ class TokenizerPatterns
|
||||
$this->nonAsciiPattern = '[^\x00-\x7F]';
|
||||
$this->nmCharPattern = '[_a-z0-9-]|'.$this->escapePattern.'|'.$this->nonAsciiPattern;
|
||||
$this->nmStartPattern = '[_a-z]|'.$this->escapePattern.'|'.$this->nonAsciiPattern;
|
||||
$this->identifierPattern = '(?:'.$this->nmStartPattern.')(?:'.$this->nmCharPattern.')*';
|
||||
$this->identifierPattern = '-?(?:'.$this->nmStartPattern.')(?:'.$this->nmCharPattern.')*';
|
||||
$this->hashPattern = '#((?:'.$this->nmCharPattern.')+)';
|
||||
$this->numberPattern = '[+-]?(?:[0-9]*\.[0-9]+|[0-9]+)';
|
||||
$this->quotedStringPattern = '([^\n\r\f%s]|'.$this->stringEscapePattern.')*';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNewLineEscapePattern()
|
||||
public function getNewLineEscapePattern(): string
|
||||
{
|
||||
return '~^'.$this->newLineEscapePattern.'~';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSimpleEscapePattern()
|
||||
public function getSimpleEscapePattern(): string
|
||||
{
|
||||
return '~^'.$this->simpleEscapePattern.'~';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUnicodeEscapePattern()
|
||||
public function getUnicodeEscapePattern(): string
|
||||
{
|
||||
return '~^'.$this->unicodeEscapePattern.'~i';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifierPattern()
|
||||
public function getIdentifierPattern(): string
|
||||
{
|
||||
return '~^'.$this->identifierPattern.'~i';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHashPattern()
|
||||
public function getHashPattern(): string
|
||||
{
|
||||
return '~^'.$this->hashPattern.'~i';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNumberPattern()
|
||||
public function getNumberPattern(): string
|
||||
{
|
||||
return '~^'.$this->numberPattern.'~';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $quote
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQuotedStringPattern($quote)
|
||||
public function getQuotedStringPattern(string $quote): string
|
||||
{
|
||||
return '~^'.sprintf($this->quotedStringPattern, $quote).'~i';
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class CssSelectorConverterTest extends TestCase
|
||||
array('h1', 'h1'),
|
||||
array('foo|h1', 'foo:h1'),
|
||||
array('h1, h2, h3', 'h1 | h2 | h3'),
|
||||
array('h1:nth-child(3n+1)', "*/*[name() = 'h1' and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"),
|
||||
array('h1:nth-child(3n+1)', "*/*[(name() = 'h1') and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"),
|
||||
array('h1 > p', 'h1/p'),
|
||||
array('h1#foo', "h1[@id = 'foo']"),
|
||||
array('h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"),
|
||||
|
||||
@@ -186,6 +186,7 @@ class ParserTest extends TestCase
|
||||
array('foo:after', 'Element[foo]', 'after'),
|
||||
array('foo::selection', 'Element[foo]', 'selection'),
|
||||
array('lorem#ipsum ~ a#b.c[href]:empty::selection', 'CombinedSelector[Hash[Element[lorem]#ipsum] ~ Pseudo[Attribute[Class[Hash[Element[a]#b].c][href]]:empty]]', 'selection'),
|
||||
array('video::-webkit-media-controls', 'Element[video]', '-webkit-media-controls'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,18 +102,20 @@ class TranslatorTest extends TestCase
|
||||
array('e[foo^="bar"]', "e[@foo and starts-with(@foo, 'bar')]"),
|
||||
array('e[foo$="bar"]', "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']"),
|
||||
array('e[foo*="bar"]', "e[@foo and contains(@foo, 'bar')]"),
|
||||
array('e[foo!="bar"]', "e[not(@foo) or @foo != 'bar']"),
|
||||
array('e[foo!="bar"][foo!="baz"]', "e[(not(@foo) or @foo != 'bar') and (not(@foo) or @foo != 'baz')]"),
|
||||
array('e[hreflang|="en"]', "e[@hreflang and (@hreflang = 'en' or starts-with(@hreflang, 'en-'))]"),
|
||||
array('e:nth-child(1)', "*/*[name() = 'e' and (position() = 1)]"),
|
||||
array('e:nth-last-child(1)', "*/*[name() = 'e' and (position() = last() - 0)]"),
|
||||
array('e:nth-last-child(2n+2)', "*/*[name() = 'e' and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"),
|
||||
array('e:nth-child(1)', "*/*[(name() = 'e') and (position() = 1)]"),
|
||||
array('e:nth-last-child(1)', "*/*[(name() = 'e') and (position() = last() - 0)]"),
|
||||
array('e:nth-last-child(2n+2)', "*/*[(name() = 'e') and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"),
|
||||
array('e:nth-of-type(1)', '*/e[position() = 1]'),
|
||||
array('e:nth-last-of-type(1)', '*/e[position() = last() - 0]'),
|
||||
array('div e:nth-last-of-type(1) .aclass', "div/descendant-or-self::*/e[position() = last() - 0]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' aclass ')]"),
|
||||
array('e:first-child', "*/*[name() = 'e' and (position() = 1)]"),
|
||||
array('e:last-child', "*/*[name() = 'e' and (position() = last())]"),
|
||||
array('e:first-child', "*/*[(name() = 'e') and (position() = 1)]"),
|
||||
array('e:last-child', "*/*[(name() = 'e') and (position() = last())]"),
|
||||
array('e:first-of-type', '*/e[position() = 1]'),
|
||||
array('e:last-of-type', '*/e[position() = last()]'),
|
||||
array('e:only-child', "*/*[name() = 'e' and (last() = 1)]"),
|
||||
array('e:only-child', "*/*[(name() = 'e') and (last() = 1)]"),
|
||||
array('e:only-of-type', 'e[last() = 1]'),
|
||||
array('e:empty', 'e[not(*) and not(string-length())]'),
|
||||
array('e:EmPTY', 'e[not(*) and not(string-length())]'),
|
||||
@@ -127,7 +129,7 @@ class TranslatorTest extends TestCase
|
||||
array('e:nOT(*)', 'e[0]'),
|
||||
array('e f', 'e/descendant-or-self::*/f'),
|
||||
array('e > f', 'e/f'),
|
||||
array('e + f', "e/following-sibling::*[name() = 'f' and (position() = 1)]"),
|
||||
array('e + f', "e/following-sibling::*[(name() = 'f') and (position() = 1)]"),
|
||||
array('e ~ f', 'e/following-sibling::f'),
|
||||
array('div#container p', "div[@id = 'container']/descendant-or-self::*/p"),
|
||||
);
|
||||
|
||||
@@ -43,38 +43,17 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateExists(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateExists(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateEquals(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateEquals(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateIncludes(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition($value ? sprintf(
|
||||
'%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)',
|
||||
@@ -83,14 +62,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
) : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateDashMatch(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition(sprintf(
|
||||
'%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))',
|
||||
@@ -100,14 +72,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translatePrefixMatch(XPathExpr $xpath, $attribute, $value)
|
||||
public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition($value ? sprintf(
|
||||
'%1$s and starts-with(%1$s, %2$s)',
|
||||
@@ -116,14 +81,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
) : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateSuffixMatch(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition($value ? sprintf(
|
||||
'%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s',
|
||||
@@ -133,14 +91,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
) : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateSubstringMatch(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition($value ? sprintf(
|
||||
'%1$s and contains(%1$s, %2$s)',
|
||||
@@ -149,14 +100,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
||||
) : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateDifferent(XPathExpr $xpath, $attribute, $value)
|
||||
public function translateDifferent(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
|
||||
{
|
||||
return $xpath->addCondition(sprintf(
|
||||
$value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s',
|
||||
|
||||
@@ -28,7 +28,7 @@ class CombinationExtension extends AbstractExtension
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCombinationTranslators()
|
||||
public function getCombinationTranslators(): array
|
||||
{
|
||||
return array(
|
||||
' ' => array($this, 'translateDescendant'),
|
||||
@@ -41,7 +41,7 @@ class CombinationExtension extends AbstractExtension
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath)
|
||||
public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
|
||||
{
|
||||
return $xpath->join('/descendant-or-self::*/', $combinedXpath);
|
||||
}
|
||||
|
||||
@@ -46,16 +46,9 @@ class FunctionExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param FunctionNode $function
|
||||
* @param bool $last
|
||||
* @param bool $addNameTest
|
||||
*
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true)
|
||||
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr
|
||||
{
|
||||
try {
|
||||
list($a, $b) = Parser::parseSeries($function->getArguments());
|
||||
@@ -110,28 +103,20 @@ class FunctionExtension extends AbstractExtension
|
||||
// -1n+6 means elements 6 and previous
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function)
|
||||
public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
return $this->translateNthChild($xpath, $function, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateNthOfType(XPathExpr $xpath, FunctionNode $function)
|
||||
public function translateNthOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
return $this->translateNthChild($xpath, $function, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function)
|
||||
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
if ('*' === $xpath->getElement()) {
|
||||
throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.');
|
||||
@@ -141,11 +126,9 @@ class FunctionExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function translateContains(XPathExpr $xpath, FunctionNode $function)
|
||||
public function translateContains(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
$arguments = $function->getArguments();
|
||||
foreach ($arguments as $token) {
|
||||
@@ -164,11 +147,9 @@ class FunctionExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function translateLang(XPathExpr $xpath, FunctionNode $function)
|
||||
public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
$arguments = $function->getArguments();
|
||||
foreach ($arguments as $token) {
|
||||
|
||||
@@ -33,21 +33,15 @@ class NodeExtension extends AbstractExtension
|
||||
|
||||
private $flags;
|
||||
|
||||
/**
|
||||
* @param int $flags
|
||||
*/
|
||||
public function __construct($flags = 0)
|
||||
public function __construct(int $flags = 0)
|
||||
{
|
||||
$this->flags = $flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $flag
|
||||
* @param bool $on
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFlag($flag, $on)
|
||||
public function setFlag(int $flag, bool $on)
|
||||
{
|
||||
if ($on && !$this->hasFlag($flag)) {
|
||||
$this->flags += $flag;
|
||||
@@ -60,12 +54,7 @@ class NodeExtension extends AbstractExtension
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $flag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFlag($flag)
|
||||
public function hasFlag(int $flag): bool
|
||||
{
|
||||
return (bool) ($this->flags & $flag);
|
||||
}
|
||||
@@ -88,26 +77,17 @@ class NodeExtension extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateSelector(Node\SelectorNode $node, Translator $translator)
|
||||
public function translateSelector(Node\SelectorNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
return $translator->nodeToXPath($node->getTree());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator)
|
||||
public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateNegation(Node\NegationNode $node, Translator $translator)
|
||||
public function translateNegation(Node\NegationNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
$subXpath = $translator->nodeToXPath($node->getSubSelector());
|
||||
@@ -120,30 +100,21 @@ class NodeExtension extends AbstractExtension
|
||||
return $xpath->addCondition('0');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateFunction(Node\FunctionNode $node, Translator $translator)
|
||||
public function translateFunction(Node\FunctionNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
|
||||
return $translator->addFunction($xpath, $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translatePseudo(Node\PseudoNode $node, Translator $translator)
|
||||
public function translatePseudo(Node\PseudoNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
|
||||
return $translator->addPseudoClass($xpath, $node->getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateAttribute(Node\AttributeNode $node, Translator $translator)
|
||||
public function translateAttribute(Node\AttributeNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$name = $node->getAttribute();
|
||||
$safe = $this->isSafeName($name);
|
||||
@@ -168,30 +139,21 @@ class NodeExtension extends AbstractExtension
|
||||
return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateClass(Node\ClassNode $node, Translator $translator)
|
||||
public function translateClass(Node\ClassNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
|
||||
return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateHash(Node\HashNode $node, Translator $translator)
|
||||
public function translateHash(Node\HashNode $node, Translator $translator): XPathExpr
|
||||
{
|
||||
$xpath = $translator->nodeToXPath($node->getSelector());
|
||||
|
||||
return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*/
|
||||
public function translateElement(Node\ElementNode $node)
|
||||
public function translateElement(Node\ElementNode $node): XPathExpr
|
||||
{
|
||||
$element = $node->getElement();
|
||||
|
||||
@@ -228,14 +190,7 @@ class NodeExtension extends AbstractExtension
|
||||
return 'node';
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if given name is safe.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isSafeName($name)
|
||||
private function isSafeName(string $name): bool
|
||||
{
|
||||
return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name);
|
||||
}
|
||||
|
||||
67
vendor/symfony/css-selector/XPath/Translator.php
vendored
67
vendor/symfony/css-selector/XPath/Translator.php
vendored
@@ -61,12 +61,7 @@ class Translator implements TranslatorInterface
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getXpathLiteral($element)
|
||||
public static function getXpathLiteral(string $element): string
|
||||
{
|
||||
if (false === strpos($element, "'")) {
|
||||
return "'".$element."'";
|
||||
@@ -95,7 +90,7 @@ class Translator implements TranslatorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::')
|
||||
public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string
|
||||
{
|
||||
$selectors = $this->parseSelectors($cssExpr);
|
||||
|
||||
@@ -114,17 +109,12 @@ class Translator implements TranslatorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::')
|
||||
public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string
|
||||
{
|
||||
return ($prefix ?: '').$this->nodeToXPath($selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an extension.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function registerExtension(Extension\ExtensionInterface $extension)
|
||||
public function registerExtension(Extension\ExtensionInterface $extension): self
|
||||
{
|
||||
$this->extensions[$extension->getName()] = $extension;
|
||||
|
||||
@@ -138,13 +128,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Extension\ExtensionInterface
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function getExtension($name)
|
||||
public function getExtension(string $name): Extension\ExtensionInterface
|
||||
{
|
||||
if (!isset($this->extensions[$name])) {
|
||||
throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name));
|
||||
@@ -153,12 +139,7 @@ class Translator implements TranslatorInterface
|
||||
return $this->extensions[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a shortcut parser.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function registerParserShortcut(ParserInterface $shortcut)
|
||||
public function registerParserShortcut(ParserInterface $shortcut): self
|
||||
{
|
||||
$this->shortcutParsers[] = $shortcut;
|
||||
|
||||
@@ -166,11 +147,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function nodeToXPath(NodeInterface $node)
|
||||
public function nodeToXPath(NodeInterface $node): XPathExpr
|
||||
{
|
||||
if (!isset($this->nodeTranslators[$node->getNodeName()])) {
|
||||
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
|
||||
@@ -180,15 +159,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $combiner
|
||||
* @param NodeInterface $xpath
|
||||
* @param NodeInterface $combinedXpath
|
||||
*
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function addCombination($combiner, NodeInterface $xpath, NodeInterface $combinedXpath)
|
||||
public function addCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr
|
||||
{
|
||||
if (!isset($this->combinationTranslators[$combiner])) {
|
||||
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
|
||||
@@ -198,11 +171,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function addFunction(XPathExpr $xpath, FunctionNode $function)
|
||||
public function addFunction(XPathExpr $xpath, FunctionNode $function): XPathExpr
|
||||
{
|
||||
if (!isset($this->functionTranslators[$function->getName()])) {
|
||||
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
|
||||
@@ -212,14 +183,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $pseudoClass
|
||||
*
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function addPseudoClass(XPathExpr $xpath, $pseudoClass)
|
||||
public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr
|
||||
{
|
||||
if (!isset($this->pseudoClassTranslators[$pseudoClass])) {
|
||||
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
|
||||
@@ -229,16 +195,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XPathExpr $xpath
|
||||
* @param string $operator
|
||||
* @param string $attribute
|
||||
* @param string $value
|
||||
*
|
||||
* @return XPathExpr
|
||||
*
|
||||
* @throws ExpressionErrorException
|
||||
*/
|
||||
public function addAttributeMatching(XPathExpr $xpath, $operator, $attribute, $value)
|
||||
public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, $value): XPathExpr
|
||||
{
|
||||
if (!isset($this->attributeMatchingTranslators[$operator])) {
|
||||
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
|
||||
@@ -248,11 +207,9 @@ class Translator implements TranslatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $css
|
||||
*
|
||||
* @return SelectorNode[]
|
||||
*/
|
||||
private function parseSelectors($css)
|
||||
private function parseSelectors(string $css)
|
||||
{
|
||||
foreach ($this->shortcutParsers as $shortcut) {
|
||||
$tokens = $shortcut->parse($css);
|
||||
|
||||
@@ -27,21 +27,11 @@ interface TranslatorInterface
|
||||
{
|
||||
/**
|
||||
* Translates a CSS selector to an XPath expression.
|
||||
*
|
||||
* @param string $cssExpr
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::');
|
||||
public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string;
|
||||
|
||||
/**
|
||||
* Translates a parsed selector node to an XPath expression.
|
||||
*
|
||||
* @param SelectorNode $selector
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::');
|
||||
public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string;
|
||||
}
|
||||
|
||||
47
vendor/symfony/css-selector/XPath/XPathExpr.php
vendored
47
vendor/symfony/css-selector/XPath/XPathExpr.php
vendored
@@ -27,13 +27,7 @@ class XPathExpr
|
||||
private $element;
|
||||
private $condition;
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $element
|
||||
* @param string $condition
|
||||
* @param bool $starPrefix
|
||||
*/
|
||||
public function __construct($path = '', $element = '*', $condition = '', $starPrefix = false)
|
||||
public function __construct(string $path = '', string $element = '*', string $condition = '', bool $starPrefix = false)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->element = $element;
|
||||
@@ -44,38 +38,24 @@ class XPathExpr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getElement()
|
||||
public function getElement(): string
|
||||
{
|
||||
return $this->element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $condition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCondition($condition)
|
||||
public function addCondition(string $condition): self
|
||||
{
|
||||
$this->condition = $this->condition ? sprintf('%s and (%s)', $this->condition, $condition) : $condition;
|
||||
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCondition()
|
||||
public function getCondition(): string
|
||||
{
|
||||
return $this->condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addNameTest()
|
||||
public function addNameTest(): self
|
||||
{
|
||||
if ('*' !== $this->element) {
|
||||
$this->addCondition('name() = '.Translator::getXpathLiteral($this->element));
|
||||
@@ -85,10 +65,7 @@ class XPathExpr
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addStarPrefix()
|
||||
public function addStarPrefix(): self
|
||||
{
|
||||
$this->path .= '*/';
|
||||
|
||||
@@ -98,12 +75,9 @@ class XPathExpr
|
||||
/**
|
||||
* Joins another XPathExpr with a combiner.
|
||||
*
|
||||
* @param string $combiner
|
||||
* @param XPathExpr $expr
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function join($combiner, XPathExpr $expr)
|
||||
public function join(string $combiner, self $expr): self
|
||||
{
|
||||
$path = $this->__toString().$combiner;
|
||||
|
||||
@@ -118,10 +92,7 @@ class XPathExpr
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
$path = $this->path.$this->element;
|
||||
$condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']';
|
||||
|
||||
4
vendor/symfony/css-selector/composer.json
vendored
4
vendor/symfony/css-selector/composer.json
vendored
@@ -20,7 +20,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\CssSelector\\": "" },
|
||||
@@ -31,7 +31,7 @@
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/symfony/debug/Debug.php
vendored
2
vendor/symfony/debug/Debug.php
vendored
@@ -45,7 +45,7 @@ class Debug
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
|
||||
if ('cli' !== PHP_SAPI) {
|
||||
if (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
|
||||
ini_set('display_errors', 0);
|
||||
ExceptionHandler::register();
|
||||
} elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {
|
||||
|
||||
2
vendor/symfony/debug/DebugClassLoader.php
vendored
2
vendor/symfony/debug/DebugClassLoader.php
vendored
@@ -141,7 +141,7 @@ class DebugClassLoader
|
||||
if ($this->isFinder && !isset($this->loaded[$class])) {
|
||||
$this->loaded[$class] = true;
|
||||
if ($file = $this->classLoader[0]->findFile($class) ?: false) {
|
||||
$wasCached = \function_exists('opcache_is_script_cached') && opcache_is_script_cached($file);
|
||||
$wasCached = \function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file);
|
||||
|
||||
require $file;
|
||||
|
||||
|
||||
28
vendor/symfony/debug/ErrorHandler.php
vendored
28
vendor/symfony/debug/ErrorHandler.php
vendored
@@ -136,9 +136,20 @@ class ErrorHandler
|
||||
}
|
||||
if (!$replace && $prev) {
|
||||
restore_error_handler();
|
||||
$handlerIsRegistered = is_array($prev) && $handler === $prev[0];
|
||||
} else {
|
||||
$handlerIsRegistered = true;
|
||||
}
|
||||
if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] === $handler) {
|
||||
if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
|
||||
restore_exception_handler();
|
||||
if (!$handlerIsRegistered) {
|
||||
$handler = $prev[0];
|
||||
} elseif ($handler !== $prev[0] && $replace) {
|
||||
set_exception_handler(array($handler, 'handleException'));
|
||||
$p = $prev[0]->setExceptionHandler(null);
|
||||
$handler->setExceptionHandler($p);
|
||||
$prev[0]->setExceptionHandler($p);
|
||||
}
|
||||
} else {
|
||||
$handler->setExceptionHandler($prev);
|
||||
}
|
||||
@@ -372,14 +383,16 @@ class ErrorHandler
|
||||
public function handleError($type, $message, $file, $line)
|
||||
{
|
||||
// Level is the current error reporting level to manage silent error.
|
||||
$level = error_reporting();
|
||||
$silenced = 0 === ($level & $type);
|
||||
// Strong errors are not authorized to be silenced.
|
||||
$level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
|
||||
$level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
|
||||
$log = $this->loggedErrors & $type;
|
||||
$throw = $this->thrownErrors & $type & $level;
|
||||
$type &= $level | $this->screamedErrors;
|
||||
|
||||
if (!$type || (!$log && !$throw)) {
|
||||
return $type && $log;
|
||||
return !$silenced && $type && $log;
|
||||
}
|
||||
$scope = $this->scopedErrors & $type;
|
||||
|
||||
@@ -513,7 +526,7 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
return $type && $log;
|
||||
return !$silenced && $type && $log;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -568,15 +581,16 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
$exceptionHandler = $this->exceptionHandler;
|
||||
$this->exceptionHandler = null;
|
||||
try {
|
||||
if (null !== $this->exceptionHandler) {
|
||||
return \call_user_func($this->exceptionHandler, $exception);
|
||||
if (null !== $exceptionHandler) {
|
||||
return \call_user_func($exceptionHandler, $exception);
|
||||
}
|
||||
$handlerException = $handlerException ?: $exception;
|
||||
} catch (\Exception $handlerException) {
|
||||
} catch (\Throwable $handlerException) {
|
||||
}
|
||||
$this->exceptionHandler = null;
|
||||
if ($exception === $handlerException) {
|
||||
self::$reservedMemory = null; // Disable the fatal error handler
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
|
||||
@@ -36,7 +36,8 @@ class FatalThrowableError extends FatalErrorException
|
||||
$e->getCode(),
|
||||
$severity,
|
||||
$e->getFile(),
|
||||
$e->getLine()
|
||||
$e->getLine(),
|
||||
$e->getPrevious()
|
||||
);
|
||||
|
||||
$this->setTrace($e->getTrace());
|
||||
|
||||
@@ -157,7 +157,7 @@ class FlattenException
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function setPrevious(FlattenException $previous)
|
||||
public function setPrevious(self $previous)
|
||||
{
|
||||
$this->previous = $previous;
|
||||
}
|
||||
|
||||
26
vendor/symfony/debug/ExceptionHandler.php
vendored
26
vendor/symfony/debug/ExceptionHandler.php
vendored
@@ -40,7 +40,7 @@ class ExceptionHandler
|
||||
{
|
||||
$this->debug = $debug;
|
||||
$this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
|
||||
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
||||
$this->fileLinkFormat = $fileLinkFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,13 +355,29 @@ EOF;
|
||||
private function formatPath($path, $line)
|
||||
{
|
||||
$file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path);
|
||||
$fmt = $this->fileLinkFormat;
|
||||
$fmt = $this->fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
||||
|
||||
if ($fmt && $link = is_string($fmt) ? strtr($fmt, array('%f' => $path, '%l' => $line)) : $fmt->format($path, $line)) {
|
||||
return sprintf('<span class="block trace-file-path">in <a href="%s" title="Go to source">%s (line %d)</a></span>', $this->escapeHtml($link), $file, $line);
|
||||
if (!$fmt) {
|
||||
return sprintf('<span class="block trace-file-path">in <a title="%s%3$s"><strong>%s</strong>%s</a></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
|
||||
}
|
||||
|
||||
return sprintf('<span class="block trace-file-path">in <a title="%s line %3$d"><strong>%s</strong> (line %d)</a></span>', $this->escapeHtml($path), $file, $line);
|
||||
if (\is_string($fmt)) {
|
||||
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: strlen($f);
|
||||
$fmt = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
for ($i = 1; isset($fmt[$i]); ++$i) {
|
||||
if (0 === strpos($path, $k = $fmt[$i++])) {
|
||||
$path = substr_replace($path, $fmt[$i], 0, strlen($k));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$link = strtr($fmt[0], array('%f' => $path, '%l' => $line));
|
||||
} else {
|
||||
$link = $fmt->format($path, $line);
|
||||
}
|
||||
|
||||
return sprintf('<span class="block trace-file-path">in <a href="%s" title="Go to source"><strong>%s</string>%s</a></span>', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
40
vendor/symfony/debug/Tests/ErrorHandlerTest.php
vendored
40
vendor/symfony/debug/Tests/ErrorHandlerTest.php
vendored
@@ -35,7 +35,7 @@ class ErrorHandlerTest extends TestCase
|
||||
|
||||
$newHandler = new ErrorHandler();
|
||||
|
||||
$this->assertSame($newHandler, ErrorHandler::register($newHandler, false));
|
||||
$this->assertSame($handler, ErrorHandler::register($newHandler, false));
|
||||
$h = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
$this->assertSame(array($handler, 'handleError'), $h);
|
||||
@@ -65,6 +65,30 @@ class ErrorHandlerTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorGetLast()
|
||||
{
|
||||
$handler = ErrorHandler::register();
|
||||
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
||||
$handler->setDefaultLogger($logger);
|
||||
$handler->screamAt(E_ALL);
|
||||
|
||||
try {
|
||||
@trigger_error('Hello', E_USER_WARNING);
|
||||
$expected = array(
|
||||
'type' => E_USER_WARNING,
|
||||
'message' => 'Hello',
|
||||
'file' => __FILE__,
|
||||
'line' => __LINE__ - 5,
|
||||
);
|
||||
$this->assertSame($expected, error_get_last());
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testNotice()
|
||||
{
|
||||
ErrorHandler::register();
|
||||
@@ -545,4 +569,18 @@ class ErrorHandlerTest extends TestCase
|
||||
restore_exception_handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @group no-hhvm
|
||||
*/
|
||||
public function testCustomExceptionHandler()
|
||||
{
|
||||
$handler = new ErrorHandler();
|
||||
$handler->setExceptionHandler(function ($e) use ($handler) {
|
||||
$handler->handleException($e);
|
||||
});
|
||||
|
||||
$handler->handleException(new \Exception());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testFlattenHttpException(\Exception $exception, $statusCode)
|
||||
public function testFlattenHttpException(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened2 = FlattenException::create($exception);
|
||||
@@ -126,7 +126,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testPrevious(\Exception $exception, $statusCode)
|
||||
public function testPrevious(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened2 = FlattenException::create($exception);
|
||||
@@ -173,7 +173,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testToArray(\Exception $exception, $statusCode)
|
||||
public function testToArray(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened->setTrace(array(), 'foo.php', 123);
|
||||
@@ -193,7 +193,7 @@ class FlattenExceptionTest extends TestCase
|
||||
public function flattenDataProvider()
|
||||
{
|
||||
return array(
|
||||
array(new \Exception('test', 123), 500),
|
||||
array(new \Exception('test', 123)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
13
vendor/symfony/event-dispatcher/CHANGELOG.md
vendored
13
vendor/symfony/event-dispatcher/CHANGELOG.md
vendored
@@ -1,6 +1,19 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.1.0
|
||||
-----
|
||||
|
||||
* added support for invokable event listeners tagged with `kernel.event_listener` by default
|
||||
* The `TraceableEventDispatcher::getOrphanedEvents()` method has been added.
|
||||
* The `TraceableEventDispatcherInterface` has been deprecated.
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
* removed the `ContainerAwareEventDispatcher` class
|
||||
* added the `reset()` method to the `TraceableEventDispatcherInterface`
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\EventDispatcher;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Lazily loads listeners and subscribers from the dependency injection
|
||||
* container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
* @author Jordan Alliot <jordan.alliot@gmail.com>
|
||||
*
|
||||
* @deprecated since 3.3, to be removed in 4.0. Use EventDispatcher with closure factories instead.
|
||||
*/
|
||||
class ContainerAwareEventDispatcher extends EventDispatcher
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* The service IDs of the event listeners and subscribers.
|
||||
*/
|
||||
private $listenerIds = array();
|
||||
|
||||
/**
|
||||
* The services registered as listeners.
|
||||
*/
|
||||
private $listeners = array();
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
$class = get_class($this);
|
||||
if ($this instanceof \PHPUnit_Framework_MockObject_MockObject || $this instanceof \Prophecy\Doubler\DoubleInterface) {
|
||||
$class = get_parent_class($class);
|
||||
}
|
||||
if (__CLASS__ !== $class) {
|
||||
@trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service as event listener.
|
||||
*
|
||||
* @param string $eventName Event for which the listener is added
|
||||
* @param array $callback The service ID of the listener service & the method
|
||||
* name that has to be called
|
||||
* @param int $priority The higher this value, the earlier an event listener
|
||||
* will be triggered in the chain.
|
||||
* Defaults to 0.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addListenerService($eventName, $callback, $priority = 0)
|
||||
{
|
||||
@trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
|
||||
if (!is_array($callback) || 2 !== count($callback)) {
|
||||
throw new \InvalidArgumentException('Expected an array("service", "method") argument');
|
||||
}
|
||||
|
||||
$this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
|
||||
}
|
||||
|
||||
public function removeListener($eventName, $listener)
|
||||
{
|
||||
$this->lazyLoad($eventName);
|
||||
|
||||
if (isset($this->listenerIds[$eventName])) {
|
||||
foreach ($this->listenerIds[$eventName] as $i => list($serviceId, $method)) {
|
||||
$key = $serviceId.'.'.$method;
|
||||
if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) {
|
||||
unset($this->listeners[$eventName][$key]);
|
||||
if (empty($this->listeners[$eventName])) {
|
||||
unset($this->listeners[$eventName]);
|
||||
}
|
||||
unset($this->listenerIds[$eventName][$i]);
|
||||
if (empty($this->listenerIds[$eventName])) {
|
||||
unset($this->listenerIds[$eventName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::removeListener($eventName, $listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasListeners($eventName = null)
|
||||
{
|
||||
if (null === $eventName) {
|
||||
return $this->listenerIds || $this->listeners || parent::hasListeners();
|
||||
}
|
||||
|
||||
if (isset($this->listenerIds[$eventName])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::hasListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListeners($eventName = null)
|
||||
{
|
||||
if (null === $eventName) {
|
||||
foreach ($this->listenerIds as $serviceEventName => $args) {
|
||||
$this->lazyLoad($serviceEventName);
|
||||
}
|
||||
} else {
|
||||
$this->lazyLoad($eventName);
|
||||
}
|
||||
|
||||
return parent::getListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListenerPriority($eventName, $listener)
|
||||
{
|
||||
$this->lazyLoad($eventName);
|
||||
|
||||
return parent::getListenerPriority($eventName, $listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service as event subscriber.
|
||||
*
|
||||
* @param string $serviceId The service ID of the subscriber service
|
||||
* @param string $class The service's class name (which must implement EventSubscriberInterface)
|
||||
*/
|
||||
public function addSubscriberService($serviceId, $class)
|
||||
{
|
||||
@trigger_error(sprintf('The %s class is deprecated since Symfony 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
|
||||
|
||||
foreach ($class::getSubscribedEvents() as $eventName => $params) {
|
||||
if (is_string($params)) {
|
||||
$this->listenerIds[$eventName][] = array($serviceId, $params, 0);
|
||||
} elseif (is_string($params[0])) {
|
||||
$this->listenerIds[$eventName][] = array($serviceId, $params[0], isset($params[1]) ? $params[1] : 0);
|
||||
} else {
|
||||
foreach ($params as $listener) {
|
||||
$this->listenerIds[$eventName][] = array($serviceId, $listener[0], isset($listener[1]) ? $listener[1] : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getContainer()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 as its class will be removed in 4.0. Inject the container or the services you need in your listeners/subscribers instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily loads listeners for this event from the dependency injection
|
||||
* container.
|
||||
*
|
||||
* @param string $eventName The name of the event to dispatch. The name of
|
||||
* the event is the name of the method that is
|
||||
* invoked on listeners.
|
||||
*/
|
||||
protected function lazyLoad($eventName)
|
||||
{
|
||||
if (isset($this->listenerIds[$eventName])) {
|
||||
foreach ($this->listenerIds[$eventName] as list($serviceId, $method, $priority)) {
|
||||
$listener = $this->container->get($serviceId);
|
||||
|
||||
$key = $serviceId.'.'.$method;
|
||||
if (!isset($this->listeners[$eventName][$key])) {
|
||||
$this->addListener($eventName, array($listener, $method), $priority);
|
||||
} elseif ($this->listeners[$eventName][$key] !== $listener) {
|
||||
parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method));
|
||||
$this->addListener($eventName, array($listener, $method), $priority);
|
||||
}
|
||||
|
||||
$this->listeners[$eventName][$key] = $listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
||||
private $called;
|
||||
private $dispatcher;
|
||||
private $wrappedListeners;
|
||||
private $orphanedEvents;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
|
||||
{
|
||||
@@ -40,6 +41,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
||||
$this->logger = $logger;
|
||||
$this->called = array();
|
||||
$this->wrappedListeners = array();
|
||||
$this->orphanedEvents = array();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,6 +209,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
||||
return $notCalled;
|
||||
}
|
||||
|
||||
public function getOrphanedEvents(): array
|
||||
{
|
||||
return $this->orphanedEvents;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->called = array();
|
||||
@@ -247,6 +254,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
||||
|
||||
private function preProcess($eventName)
|
||||
{
|
||||
if (!$this->dispatcher->hasListeners($eventName)) {
|
||||
$this->orphanedEvents[] = $eventName;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
|
||||
$priority = $this->getListenerPriority($eventName, $listener);
|
||||
$wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this);
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace Symfony\Component\EventDispatcher\Debug;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @deprecated since Symfony 4.1
|
||||
*
|
||||
* @method reset() Resets the trace.
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface TraceableEventDispatcherInterface extends EventDispatcherInterface
|
||||
{
|
||||
@@ -33,4 +33,9 @@ interface TraceableEventDispatcherInterface extends EventDispatcherInterface
|
||||
* @return array An array of not called listeners
|
||||
*/
|
||||
public function getNotCalledListeners();
|
||||
|
||||
/**
|
||||
* Resets the trace.
|
||||
*/
|
||||
public function reset();
|
||||
}
|
||||
|
||||
@@ -31,12 +31,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
private $hotPathEvents = array();
|
||||
private $hotPathTagName;
|
||||
|
||||
/**
|
||||
* @param string $dispatcherService Service name of the event dispatcher in processed container
|
||||
* @param string $listenerTag Tag name used for listener
|
||||
* @param string $subscriberTag Tag name used for subscribers
|
||||
*/
|
||||
public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
|
||||
public function __construct(string $dispatcherService = 'event_dispatcher', string $listenerTag = 'kernel.event_listener', string $subscriberTag = 'kernel.event_subscriber')
|
||||
{
|
||||
$this->dispatcherService = $dispatcherService;
|
||||
$this->listenerTag = $listenerTag;
|
||||
@@ -73,6 +68,10 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
'/[^a-z0-9]/i',
|
||||
), function ($matches) { return 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')) {
|
||||
$event['method'] = '__invoke';
|
||||
}
|
||||
}
|
||||
|
||||
$definition->addMethodCall('addListener', array($event['event'], array(new ServiceClosureArgument(new Reference($id)), $event['method']), $priority));
|
||||
@@ -89,17 +88,15 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
$def = $container->getDefinition($id);
|
||||
|
||||
// We must assume that the class value has been correctly filled, even if the service is created by a factory
|
||||
$class = $container->getParameterBag()->resolveValue($def->getClass());
|
||||
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
|
||||
$class = $def->getClass();
|
||||
|
||||
if (!is_subclass_of($class, $interface)) {
|
||||
if (!class_exists($class, false)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
|
||||
if (!$r = $container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
$container->addObjectResource($class);
|
||||
if (!$r->isSubclassOf(EventSubscriberInterface::class)) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class));
|
||||
}
|
||||
$class = $r->name;
|
||||
|
||||
ExtractingEventDispatcher::$subscriber = $class;
|
||||
$extractingDispatcher->addSubscriber($extractingDispatcher);
|
||||
|
||||
@@ -158,7 +158,7 @@ abstract class AbstractEventDispatcherTest extends TestCase
|
||||
// be executed
|
||||
// Manually set priority to enforce $this->listener to be called first
|
||||
$this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'), 10);
|
||||
$this->dispatcher->addListener('post.foo', array($otherListener, 'preFoo'));
|
||||
$this->dispatcher->addListener('post.foo', array($otherListener, 'postFoo'));
|
||||
$this->dispatcher->dispatch(self::postFoo);
|
||||
$this->assertTrue($this->listener->postFooInvoked);
|
||||
$this->assertFalse($otherListener->postFooInvoked);
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\EventDispatcher\Tests;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
|
||||
{
|
||||
protected function createEventDispatcher()
|
||||
{
|
||||
$container = new Container();
|
||||
|
||||
return new ContainerAwareEventDispatcher($container);
|
||||
}
|
||||
|
||||
public function testAddAListenerService()
|
||||
{
|
||||
$event = new Event();
|
||||
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEvent')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
|
||||
|
||||
$dispatcher->dispatch('onEvent', $event);
|
||||
}
|
||||
|
||||
public function testAddASubscriberService()
|
||||
{
|
||||
$event = new Event();
|
||||
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\SubscriberService')->getMock();
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEvent')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEventWithPriority')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEventNested')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.subscriber', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addSubscriberService('service.subscriber', 'Symfony\Component\EventDispatcher\Tests\SubscriberService');
|
||||
|
||||
$dispatcher->dispatch('onEvent', $event);
|
||||
$dispatcher->dispatch('onEventWithPriority', $event);
|
||||
$dispatcher->dispatch('onEventNested', $event);
|
||||
}
|
||||
|
||||
public function testPreventDuplicateListenerService()
|
||||
{
|
||||
$event = new Event();
|
||||
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEvent')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'), 5);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'), 10);
|
||||
|
||||
$dispatcher->dispatch('onEvent', $event);
|
||||
}
|
||||
|
||||
public function testHasListenersOnLazyLoad()
|
||||
{
|
||||
$event = new Event();
|
||||
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
|
||||
|
||||
$service
|
||||
->expects($this->once())
|
||||
->method('onEvent')
|
||||
->with($event)
|
||||
;
|
||||
|
||||
$this->assertTrue($dispatcher->hasListeners());
|
||||
|
||||
if ($dispatcher->hasListeners('onEvent')) {
|
||||
$dispatcher->dispatch('onEvent');
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetListenersOnLazyLoad()
|
||||
{
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
|
||||
|
||||
$listeners = $dispatcher->getListeners();
|
||||
|
||||
$this->assertArrayHasKey('onEvent', $listeners);
|
||||
|
||||
$this->assertCount(1, $dispatcher->getListeners('onEvent'));
|
||||
}
|
||||
|
||||
public function testRemoveAfterDispatch()
|
||||
{
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
|
||||
|
||||
$dispatcher->dispatch('onEvent', new Event());
|
||||
$dispatcher->removeListener('onEvent', array($container->get('service.listener'), 'onEvent'));
|
||||
$this->assertFalse($dispatcher->hasListeners('onEvent'));
|
||||
}
|
||||
|
||||
public function testRemoveBeforeDispatch()
|
||||
{
|
||||
$service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
|
||||
|
||||
$container = new Container();
|
||||
$container->set('service.listener', $service);
|
||||
|
||||
$dispatcher = new ContainerAwareEventDispatcher($container);
|
||||
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
|
||||
|
||||
$dispatcher->removeListener('onEvent', array($container->get('service.listener'), 'onEvent'));
|
||||
$this->assertFalse($dispatcher->hasListeners('onEvent'));
|
||||
}
|
||||
}
|
||||
|
||||
class Service
|
||||
{
|
||||
public function onEvent(Event $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SubscriberService implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
'onEvent' => 'onEvent',
|
||||
'onEventWithPriority' => array('onEventWithPriority', 10),
|
||||
'onEventNested' => array(array('onEventNested')),
|
||||
);
|
||||
}
|
||||
|
||||
public function onEvent(Event $e)
|
||||
{
|
||||
}
|
||||
|
||||
public function onEventWithPriority(Event $e)
|
||||
{
|
||||
}
|
||||
|
||||
public function onEventNested(Event $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -153,6 +153,31 @@ class TraceableEventDispatcherTest extends TestCase
|
||||
$this->assertCount(2, $dispatcher->getCalledListeners());
|
||||
}
|
||||
|
||||
public function testItReturnsNoOrphanedEventsWhenCreated()
|
||||
{
|
||||
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||
$events = $tdispatcher->getOrphanedEvents();
|
||||
$this->assertEmpty($events);
|
||||
}
|
||||
|
||||
public function testItReturnsOrphanedEventsAfterDispatch()
|
||||
{
|
||||
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||
$tdispatcher->dispatch('foo');
|
||||
$events = $tdispatcher->getOrphanedEvents();
|
||||
$this->assertCount(1, $events);
|
||||
$this->assertEquals(array('foo'), $events);
|
||||
}
|
||||
|
||||
public function testItDoesNotReturnHandledEvents()
|
||||
{
|
||||
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||
$tdispatcher->addListener('foo', function () {});
|
||||
$tdispatcher->dispatch('foo');
|
||||
$events = $tdispatcher->getOrphanedEvents();
|
||||
$this->assertEmpty($events);
|
||||
}
|
||||
|
||||
public function testLogger()
|
||||
{
|
||||
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
||||
|
||||
@@ -27,29 +27,10 @@ class RegisterListenersPassTest extends TestCase
|
||||
*/
|
||||
public function testEventSubscriberWithoutInterface()
|
||||
{
|
||||
// one service, not implementing any interface
|
||||
$services = array(
|
||||
'my_event_subscriber' => array(0 => array()),
|
||||
);
|
||||
|
||||
$definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
|
||||
$definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->will($this->returnValue('stdClass'));
|
||||
|
||||
$builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock();
|
||||
$builder->expects($this->any())
|
||||
->method('hasDefinition')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We don't test kernel.event_listener here
|
||||
$builder->expects($this->atLeastOnce())
|
||||
->method('findTaggedServiceIds')
|
||||
->will($this->onConsecutiveCalls(array(), $services));
|
||||
|
||||
$builder->expects($this->atLeastOnce())
|
||||
->method('getDefinition')
|
||||
->will($this->returnValue($definition));
|
||||
$builder = new ContainerBuilder();
|
||||
$builder->register('event_dispatcher');
|
||||
$builder->register('my_event_subscriber', 'stdClass')
|
||||
->addTag('kernel.event_subscriber');
|
||||
|
||||
$registerListenersPass = new RegisterListenersPass();
|
||||
$registerListenersPass->process($builder);
|
||||
@@ -61,31 +42,25 @@ class RegisterListenersPassTest extends TestCase
|
||||
'my_event_subscriber' => array(0 => array()),
|
||||
);
|
||||
|
||||
$definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
|
||||
$definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'));
|
||||
|
||||
$builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition'))->getMock();
|
||||
$builder->expects($this->any())
|
||||
->method('hasDefinition')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We don't test kernel.event_listener here
|
||||
$builder->expects($this->atLeastOnce())
|
||||
->method('findTaggedServiceIds')
|
||||
->will($this->onConsecutiveCalls(array(), $services));
|
||||
|
||||
$builder->expects($this->atLeastOnce())
|
||||
->method('getDefinition')
|
||||
->will($this->returnValue($definition));
|
||||
|
||||
$builder->expects($this->atLeastOnce())
|
||||
->method('findDefinition')
|
||||
->will($this->returnValue($definition));
|
||||
$builder = new ContainerBuilder();
|
||||
$eventDispatcherDefinition = $builder->register('event_dispatcher');
|
||||
$builder->register('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')
|
||||
->addTag('kernel.event_subscriber');
|
||||
|
||||
$registerListenersPass = new RegisterListenersPass();
|
||||
$registerListenersPass->process($builder);
|
||||
|
||||
$expectedCalls = array(
|
||||
array(
|
||||
'addListener',
|
||||
array(
|
||||
'event',
|
||||
array(new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onEvent'),
|
||||
0,
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expectedCalls, $eventDispatcherDefinition->getMethodCalls());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,6 +141,47 @@ class RegisterListenersPassTest extends TestCase
|
||||
$registerListenersPass = new RegisterListenersPass();
|
||||
$registerListenersPass->process($container);
|
||||
}
|
||||
|
||||
public function testInvokableEventListener()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', \stdClass::class)->addTag('kernel.event_listener', array('event' => 'foo.bar'));
|
||||
$container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', array('event' => 'foo.bar'));
|
||||
$container->register('baz', InvokableListenerService::class)->addTag('kernel.event_listener', array('event' => 'event'));
|
||||
$container->register('event_dispatcher', \stdClass::class);
|
||||
|
||||
$registerListenersPass = new RegisterListenersPass();
|
||||
$registerListenersPass->process($container);
|
||||
|
||||
$definition = $container->getDefinition('event_dispatcher');
|
||||
$expectedCalls = array(
|
||||
array(
|
||||
'addListener',
|
||||
array(
|
||||
'foo.bar',
|
||||
array(new ServiceClosureArgument(new Reference('foo')), 'onFooBar'),
|
||||
0,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'addListener',
|
||||
array(
|
||||
'foo.bar',
|
||||
array(new ServiceClosureArgument(new Reference('bar')), '__invoke'),
|
||||
0,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'addListener',
|
||||
array(
|
||||
'event',
|
||||
array(new ServiceClosureArgument(new Reference('baz')), 'onEvent'),
|
||||
0,
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
|
||||
}
|
||||
}
|
||||
|
||||
class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
@@ -177,3 +193,14 @@ class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubsc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InvokableListenerService
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
|
||||
public function onEvent()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
14
vendor/symfony/event-dispatcher/composer.json
vendored
14
vendor/symfony/event-dispatcher/composer.json
vendored
@@ -16,17 +16,17 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5.9|>=7.0.8"
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "~3.3|~4.0",
|
||||
"symfony/expression-language": "~2.8|~3.0|~4.0",
|
||||
"symfony/config": "~2.8|~3.0|~4.0",
|
||||
"symfony/stopwatch": "~2.8|~3.0|~4.0",
|
||||
"symfony/dependency-injection": "~3.4|~4.0",
|
||||
"symfony/expression-language": "~3.4|~4.0",
|
||||
"symfony/config": "~3.4|~4.0",
|
||||
"symfony/stopwatch": "~3.4|~4.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<3.3"
|
||||
"symfony/dependency-injection": "<3.4"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
@@ -41,7 +41,7 @@
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.4-dev"
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
vendor/symfony/finder/Finder.php
vendored
24
vendor/symfony/finder/Finder.php
vendored
@@ -297,6 +297,10 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
/**
|
||||
* Excludes directories.
|
||||
*
|
||||
* Directories passed as argument must be relative to the ones defined with the `in()` method. For example:
|
||||
*
|
||||
* $finder->in(__DIR__)->exclude('ruby');
|
||||
*
|
||||
* @param string|array $dirs A directory path or an array of directories
|
||||
*
|
||||
* @return $this
|
||||
@@ -313,6 +317,8 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
/**
|
||||
* Excludes "hidden" directories and files (starting with a dot).
|
||||
*
|
||||
* This option is enabled by default.
|
||||
*
|
||||
* @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
|
||||
*
|
||||
* @return $this
|
||||
@@ -333,6 +339,8 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
/**
|
||||
* Forces the finder to ignore version control directories.
|
||||
*
|
||||
* This option is enabled by default.
|
||||
*
|
||||
* @param bool $ignoreVCS Whether to exclude VCS files or not
|
||||
*
|
||||
* @return $this
|
||||
@@ -532,9 +540,9 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
|
||||
foreach ((array) $dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$resolvedDirs[] = $dir;
|
||||
$resolvedDirs[] = $this->normalizeDir($dir);
|
||||
} elseif ($glob = glob($dir, (defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
|
||||
$resolvedDirs = array_merge($resolvedDirs, $glob);
|
||||
$resolvedDirs = array_merge($resolvedDirs, array_map(array($this, 'normalizeDir'), $glob));
|
||||
} else {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
|
||||
}
|
||||
@@ -720,4 +728,16 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
|
||||
return $iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes given directory names by removing trailing slashes.
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalizeDir($dir)
|
||||
{
|
||||
return rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
7
vendor/symfony/finder/SplFileInfo.php
vendored
7
vendor/symfony/finder/SplFileInfo.php
vendored
@@ -66,12 +66,11 @@ class SplFileInfo extends \SplFileInfo
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
$level = error_reporting(0);
|
||||
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
|
||||
$content = file_get_contents($this->getPathname());
|
||||
error_reporting($level);
|
||||
restore_error_handler();
|
||||
if (false === $content) {
|
||||
$error = error_get_last();
|
||||
throw new \RuntimeException($error['message']);
|
||||
throw new \RuntimeException($error);
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
41
vendor/symfony/finder/Tests/FinderTest.php
vendored
41
vendor/symfony/finder/Tests/FinderTest.php
vendored
@@ -46,6 +46,45 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
$this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
|
||||
}
|
||||
|
||||
public function testRemoveTrailingSlash()
|
||||
{
|
||||
$finder = $this->buildFinder();
|
||||
|
||||
$expected = $this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar'));
|
||||
$in = self::$tmpDir.'//';
|
||||
|
||||
$this->assertIterator($expected, $finder->in($in)->files()->getIterator());
|
||||
}
|
||||
|
||||
public function testSymlinksNotResolved()
|
||||
{
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('symlinks are not supported on Windows');
|
||||
}
|
||||
|
||||
$finder = $this->buildFinder();
|
||||
|
||||
symlink($this->toAbsolute('foo'), $this->toAbsolute('baz'));
|
||||
$expected = $this->toAbsolute(array('baz/bar.tmp'));
|
||||
$in = self::$tmpDir.'/baz/';
|
||||
try {
|
||||
$this->assertIterator($expected, $finder->in($in)->files()->getIterator());
|
||||
unlink($this->toAbsolute('baz'));
|
||||
} catch (\Exception $e) {
|
||||
unlink($this->toAbsolute('baz'));
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testBackPathNotNormalized()
|
||||
{
|
||||
$finder = $this->buildFinder();
|
||||
|
||||
$expected = $this->toAbsolute(array('foo/../foo/bar.tmp'));
|
||||
$in = self::$tmpDir.'/foo/../foo/';
|
||||
$this->assertIterator($expected, $finder->in($in)->files()->getIterator());
|
||||
}
|
||||
|
||||
public function testDepth()
|
||||
{
|
||||
$finder = $this->buildFinder();
|
||||
@@ -261,7 +300,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
public function testInWithGlob()
|
||||
{
|
||||
$finder = $this->buildFinder();
|
||||
$finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
|
||||
$finder->in(array(__DIR__.'/Fixtures/*/B/C/', __DIR__.'/Fixtures/*/*/B/C/'))->getIterator();
|
||||
|
||||
$this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
|
||||
}
|
||||
|
||||
8
vendor/symfony/http-foundation/Cookie.php
vendored
8
vendor/symfony/http-foundation/Cookie.php
vendored
@@ -145,12 +145,12 @@ class Cookie
|
||||
$str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
|
||||
|
||||
if ('' === (string) $this->getValue()) {
|
||||
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001';
|
||||
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
|
||||
} else {
|
||||
$str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
|
||||
|
||||
if (0 !== $this->getExpiresTime()) {
|
||||
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; max-age='.$this->getMaxAge();
|
||||
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,9 @@ class Cookie
|
||||
*/
|
||||
public function getMaxAge()
|
||||
{
|
||||
return 0 !== $this->expire ? $this->expire - time() : 0;
|
||||
$maxAge = $this->expire - time();
|
||||
|
||||
return 0 >= $maxAge ? 0 : $maxAge;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
8
vendor/symfony/http-foundation/File/File.php
vendored
8
vendor/symfony/http-foundation/File/File.php
vendored
@@ -93,9 +93,11 @@ class File extends \SplFileInfo
|
||||
{
|
||||
$target = $this->getTargetFile($directory, $name);
|
||||
|
||||
if (!@rename($this->getPathname(), $target)) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
||||
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
|
||||
$renamed = rename($this->getPathname(), $target);
|
||||
restore_error_handler();
|
||||
if (!$renamed) {
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
|
||||
}
|
||||
|
||||
@chmod($target, 0666 & ~umask());
|
||||
|
||||
@@ -43,7 +43,21 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return '\\' !== DIRECTORY_SEPARATOR && function_exists('passthru') && function_exists('escapeshellarg');
|
||||
static $supported = null;
|
||||
|
||||
if (null !== $supported) {
|
||||
return $supported;
|
||||
}
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR || !function_exists('passthru') || !function_exists('escapeshellarg')) {
|
||||
return $supported = false;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
passthru('command -v file', $exitStatus);
|
||||
$binPath = trim(ob_get_clean());
|
||||
|
||||
return $supported = 0 === $exitStatus && '' !== $binPath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -599,6 +599,7 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
|
||||
'application/x-xliff+xml' => 'xlf',
|
||||
'application/x-xpinstall' => 'xpi',
|
||||
'application/x-xz' => 'xz',
|
||||
'application/x-zip-compressed' => 'zip',
|
||||
'application/x-zmachine' => 'z1',
|
||||
'application/xaml+xml' => 'xaml',
|
||||
'application/xcap-diff+xml' => 'xdf',
|
||||
|
||||
@@ -80,13 +80,8 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
if (FileBinaryMimeTypeGuesser::isSupported()) {
|
||||
$this->register(new FileBinaryMimeTypeGuesser());
|
||||
}
|
||||
|
||||
if (FileinfoMimeTypeGuesser::isSupported()) {
|
||||
$this->register(new FileinfoMimeTypeGuesser());
|
||||
}
|
||||
$this->register(new FileBinaryMimeTypeGuesser());
|
||||
$this->register(new FileinfoMimeTypeGuesser());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,18 +120,14 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface
|
||||
throw new AccessDeniedException($path);
|
||||
}
|
||||
|
||||
if (!$this->guessers) {
|
||||
$msg = 'Unable to guess the mime type as no guessers are available';
|
||||
if (!FileinfoMimeTypeGuesser::isSupported()) {
|
||||
$msg .= ' (Did you enable the php_fileinfo extension?)';
|
||||
}
|
||||
throw new \LogicException($msg);
|
||||
}
|
||||
|
||||
foreach ($this->guessers as $guesser) {
|
||||
if (null !== $mimeType = $guesser->guess($path)) {
|
||||
return $mimeType;
|
||||
}
|
||||
}
|
||||
|
||||
if (2 === \count($this->guessers) && !FileBinaryMimeTypeGuesser::isSupported() && !FileinfoMimeTypeGuesser::isSupported()) {
|
||||
throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,9 +192,11 @@ class UploadedFile extends File
|
||||
|
||||
$target = $this->getTargetFile($directory, $name);
|
||||
|
||||
if (!@move_uploaded_file($this->getPathname(), $target)) {
|
||||
$error = error_get_last();
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
||||
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
|
||||
$moved = move_uploaded_file($this->getPathname(), $target);
|
||||
restore_error_handler();
|
||||
if (!$moved) {
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
|
||||
}
|
||||
|
||||
@chmod($target, 0666 & ~umask());
|
||||
|
||||
50
vendor/symfony/http-foundation/Request.php
vendored
50
vendor/symfony/http-foundation/Request.php
vendored
@@ -144,7 +144,7 @@ class Request
|
||||
public $headers;
|
||||
|
||||
/**
|
||||
* @var string|resource
|
||||
* @var string|resource|false|null
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
@@ -242,13 +242,13 @@ class Request
|
||||
);
|
||||
|
||||
/**
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string|resource $content The raw body data
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string|resource|null $content The raw body data
|
||||
*/
|
||||
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
||||
{
|
||||
@@ -260,13 +260,13 @@ class Request
|
||||
*
|
||||
* This method also re-initializes all properties.
|
||||
*
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string|resource $content The raw body data
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string|resource|null $content The raw body data
|
||||
*/
|
||||
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
||||
{
|
||||
@@ -329,13 +329,13 @@ class Request
|
||||
* The information contained in the URI always take precedence
|
||||
* over the other information (server and parameters).
|
||||
*
|
||||
* @param string $uri The URI
|
||||
* @param string $method The HTTP method
|
||||
* @param array $parameters The query (GET) or request (POST) parameters
|
||||
* @param array $cookies The request cookies ($_COOKIE)
|
||||
* @param array $files The request files ($_FILES)
|
||||
* @param array $server The server parameters ($_SERVER)
|
||||
* @param string|resource $content The raw body data
|
||||
* @param string $uri The URI
|
||||
* @param string $method The HTTP method
|
||||
* @param array $parameters The query (GET) or request (POST) parameters
|
||||
* @param array $cookies The request cookies ($_COOKIE)
|
||||
* @param array $files The request files ($_FILES)
|
||||
* @param array $server The server parameters ($_SERVER)
|
||||
* @param string|resource|null $content The raw body data
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
@@ -557,7 +557,7 @@ class Request
|
||||
*/
|
||||
public function overrideGlobals()
|
||||
{
|
||||
$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null, '&')));
|
||||
$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), '', '&')));
|
||||
|
||||
$_GET = $this->query->all();
|
||||
$_POST = $this->request->all();
|
||||
@@ -641,7 +641,7 @@ class Request
|
||||
public static function setTrustedHosts(array $hostPatterns)
|
||||
{
|
||||
self::$trustedHostPatterns = array_map(function ($hostPattern) {
|
||||
return sprintf('#%s#i', $hostPattern);
|
||||
return sprintf('{%s}i', $hostPattern);
|
||||
}, $hostPatterns);
|
||||
// we need to reset trusted hosts on trusted host patterns change
|
||||
self::$trustedHosts = array();
|
||||
@@ -1378,7 +1378,7 @@ class Request
|
||||
*
|
||||
* @param string $format The format
|
||||
*
|
||||
* @return string The associated mime type (null if not found)
|
||||
* @return string|null The associated mime type (null if not found)
|
||||
*/
|
||||
public function getMimeType($format)
|
||||
{
|
||||
|
||||
24
vendor/symfony/http-foundation/Response.php
vendored
24
vendor/symfony/http-foundation/Response.php
vendored
@@ -21,6 +21,7 @@ class Response
|
||||
const HTTP_CONTINUE = 100;
|
||||
const HTTP_SWITCHING_PROTOCOLS = 101;
|
||||
const HTTP_PROCESSING = 102; // RFC2518
|
||||
const HTTP_EARLY_HINTS = 103; // RFC8297
|
||||
const HTTP_OK = 200;
|
||||
const HTTP_CREATED = 201;
|
||||
const HTTP_ACCEPTED = 202;
|
||||
@@ -327,7 +328,7 @@ class Response
|
||||
}
|
||||
|
||||
// headers
|
||||
foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
|
||||
foreach ($this->headers->allPreserveCase() as $name => $values) {
|
||||
foreach ($values as $value) {
|
||||
header($name.': '.$value, false, $this->statusCode);
|
||||
}
|
||||
@@ -336,15 +337,6 @@ class Response
|
||||
// status
|
||||
header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
|
||||
|
||||
// cookies
|
||||
foreach ($this->headers->getCookies() as $cookie) {
|
||||
if ($cookie->isRaw()) {
|
||||
setrawcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
||||
} else {
|
||||
setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -372,7 +364,7 @@ class Response
|
||||
|
||||
if (function_exists('fastcgi_finish_request')) {
|
||||
fastcgi_finish_request();
|
||||
} elseif ('cli' !== PHP_SAPI) {
|
||||
} elseif (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
|
||||
static::closeOutputBuffers(0, true);
|
||||
}
|
||||
|
||||
@@ -519,13 +511,19 @@ class Response
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the response is worth caching under any circumstance.
|
||||
* Returns true if the response may safely be kept in a shared (surrogate) cache.
|
||||
*
|
||||
* Responses marked "private" with an explicit Cache-Control directive are
|
||||
* considered uncacheable.
|
||||
*
|
||||
* Responses with neither a freshness lifetime (Expires, max-age) nor cache
|
||||
* validator (Last-Modified, ETag) are considered uncacheable.
|
||||
* validator (Last-Modified, ETag) are considered uncacheable because there is
|
||||
* no way to tell when or how to remove them from the cache.
|
||||
*
|
||||
* Note that RFC 7231 and RFC 7234 possibly allow for a more permissive implementation,
|
||||
* for example "status codes that are defined as cacheable by default [...]
|
||||
* can be reused by a cache with heuristic expiration unless otherwise indicated"
|
||||
* (https://tools.ietf.org/html/rfc7231#section-6.1)
|
||||
*
|
||||
* @return bool true if the response is worth caching, false otherwise
|
||||
*
|
||||
|
||||
@@ -80,7 +80,9 @@ class MemcachedSessionHandler extends AbstractSessionHandler
|
||||
*/
|
||||
public function updateTimestamp($sessionId, $data)
|
||||
{
|
||||
return $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl);
|
||||
$this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -164,7 +164,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
* * db_connection_options: An array of driver-specific connection options [default: array()]
|
||||
* * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL]
|
||||
*
|
||||
* @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or null
|
||||
* @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or URL string or null
|
||||
* @param array $options An associative array of options
|
||||
*
|
||||
* @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
|
||||
@@ -178,6 +178,8 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
|
||||
$this->pdo = $pdoOrDsn;
|
||||
$this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
} elseif (is_string($pdoOrDsn) && false !== strpos($pdoOrDsn, '://')) {
|
||||
$this->dsn = $this->buildDsnFromUrl($pdoOrDsn);
|
||||
} else {
|
||||
$this->dsn = $pdoOrDsn;
|
||||
}
|
||||
@@ -431,6 +433,102 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
$this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a PDO DSN from a URL-like connection string.
|
||||
*
|
||||
* @param string $dsnOrUrl
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @todo implement missing support for oci DSN (which look totally different from other PDO ones)
|
||||
*/
|
||||
private function buildDsnFromUrl($dsnOrUrl)
|
||||
{
|
||||
// (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid
|
||||
$url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $dsnOrUrl);
|
||||
|
||||
$params = parse_url($url);
|
||||
|
||||
if (false === $params) {
|
||||
return $dsnOrUrl; // If the URL is not valid, let's assume it might be a DSN already.
|
||||
}
|
||||
|
||||
$params = array_map('rawurldecode', $params);
|
||||
|
||||
// Override the default username and password. Values passed through options will still win over these in the constructor.
|
||||
if (isset($params['user'])) {
|
||||
$this->username = $params['user'];
|
||||
}
|
||||
|
||||
if (isset($params['pass'])) {
|
||||
$this->password = $params['pass'];
|
||||
}
|
||||
|
||||
if (!isset($params['scheme'])) {
|
||||
throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler');
|
||||
}
|
||||
|
||||
$driverAliasMap = array(
|
||||
'mssql' => 'sqlsrv',
|
||||
'mysql2' => 'mysql', // Amazon RDS, for some weird reason
|
||||
'postgres' => 'pgsql',
|
||||
'postgresql' => 'pgsql',
|
||||
'sqlite3' => 'sqlite',
|
||||
);
|
||||
|
||||
$driver = isset($driverAliasMap[$params['scheme']]) ? $driverAliasMap[$params['scheme']] : $params['scheme'];
|
||||
|
||||
// Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here.
|
||||
if (0 === strpos($driver, 'pdo_') || 0 === strpos($driver, 'pdo-')) {
|
||||
$driver = substr($driver, 4);
|
||||
}
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
case 'pgsql':
|
||||
$dsn = $driver.':';
|
||||
|
||||
if (isset($params['host']) && '' !== $params['host']) {
|
||||
$dsn .= 'host='.$params['host'].';';
|
||||
}
|
||||
|
||||
if (isset($params['port']) && '' !== $params['port']) {
|
||||
$dsn .= 'port='.$params['port'].';';
|
||||
}
|
||||
|
||||
if (isset($params['path'])) {
|
||||
$dbName = substr($params['path'], 1); // Remove the leading slash
|
||||
$dsn .= 'dbname='.$dbName.';';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
|
||||
case 'sqlite':
|
||||
return 'sqlite:'.substr($params['path'], 1);
|
||||
|
||||
case 'sqlsrv':
|
||||
$dsn = 'sqlsrv:server=';
|
||||
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= $params['host'];
|
||||
}
|
||||
|
||||
if (isset($params['port']) && '' !== $params['port']) {
|
||||
$dsn .= ','.$params['port'];
|
||||
}
|
||||
|
||||
if (isset($params['path'])) {
|
||||
$dbName = substr($params['path'], 1); // Remove the leading slash
|
||||
$dsn .= ';Database='.$dbName;
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.', $params['scheme']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to begin a transaction.
|
||||
*
|
||||
@@ -518,6 +616,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
$selectSql = $this->getSelectSql();
|
||||
$selectStmt = $this->pdo->prepare($selectSql);
|
||||
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
|
||||
$insertStmt = null;
|
||||
|
||||
do {
|
||||
$selectStmt->execute();
|
||||
@@ -533,6 +632,11 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
|
||||
}
|
||||
|
||||
if (null !== $insertStmt) {
|
||||
$this->rollback();
|
||||
throw new \RuntimeException('Failed to read session: INSERT reported a duplicate id but next SELECT did not return any data.');
|
||||
}
|
||||
|
||||
if (!ini_get('session.use_strict_mode') && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
|
||||
// In strict mode, session fixation is not possible: new sessions always start with a unique
|
||||
// random id, so that concurrency is not possible and this code path can be skipped.
|
||||
@@ -578,14 +682,16 @@ class PdoSessionHandler extends AbstractSessionHandler
|
||||
{
|
||||
switch ($this->driver) {
|
||||
case 'mysql':
|
||||
// MySQL 5.7.5 and later enforces a maximum length on lock names of 64 characters. Previously, no limit was enforced.
|
||||
$lockId = \substr($sessionId, 0, 64);
|
||||
// should we handle the return value? 0 on timeout, null on error
|
||||
// we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout
|
||||
$stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)');
|
||||
$stmt->bindValue(':key', $sessionId, \PDO::PARAM_STR);
|
||||
$stmt->bindValue(':key', $lockId, \PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
$releaseStmt = $this->pdo->prepare('DO RELEASE_LOCK(:key)');
|
||||
$releaseStmt->bindValue(':key', $sessionId, \PDO::PARAM_STR);
|
||||
$releaseStmt->bindValue(':key', $lockId, \PDO::PARAM_STR);
|
||||
|
||||
return $releaseStmt;
|
||||
case 'pgsql':
|
||||
|
||||
@@ -349,7 +349,7 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||
}
|
||||
|
||||
$validOptions = array_flip(array(
|
||||
'cache_limiter', 'cache_expire', 'cookie_domain', 'cookie_httponly',
|
||||
'cache_expire', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
|
||||
'cookie_lifetime', 'cookie_path', 'cookie_secure',
|
||||
'entropy_file', 'entropy_length', 'gc_divisor',
|
||||
'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
|
||||
@@ -357,13 +357,13 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||
'serialize_handler', 'use_strict_mode', 'use_cookies',
|
||||
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
|
||||
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
|
||||
'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
|
||||
'upload_progress.freq', 'upload_progress.min_freq', 'url_rewriter.tags',
|
||||
'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags',
|
||||
));
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
if (isset($validOptions[$key])) {
|
||||
ini_set('session.'.$key, $value);
|
||||
ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,13 +162,13 @@ class CookieTest extends TestCase
|
||||
public function testToString()
|
||||
{
|
||||
$cookie = new Cookie('foo', 'bar', $expire = strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
|
||||
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
|
||||
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
|
||||
|
||||
$cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
|
||||
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
|
||||
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
|
||||
|
||||
$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
|
||||
$this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; max-age='.($expire - time()).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
|
||||
$this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; Max-Age=0; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
|
||||
|
||||
$cookie = new Cookie('foo', 'bar', 0, '/', '');
|
||||
$this->assertEquals('foo=bar; path=/; httponly', (string) $cookie);
|
||||
@@ -194,7 +194,7 @@ class CookieTest extends TestCase
|
||||
$this->assertEquals($expire - time(), $cookie->getMaxAge());
|
||||
|
||||
$cookie = new Cookie('foo', 'bar', $expire = time() - 100);
|
||||
$this->assertEquals($expire - time(), $cookie->getMaxAge());
|
||||
$this->assertEquals(0, $cookie->getMaxAge());
|
||||
}
|
||||
|
||||
public function testFromString()
|
||||
|
||||
39
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/common.inc
vendored
Normal file
39
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/common.inc
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
$parent = __DIR__;
|
||||
while (!@file_exists($parent.'/vendor/autoload.php')) {
|
||||
if (!@file_exists($parent)) {
|
||||
// open_basedir restriction in effect
|
||||
break;
|
||||
}
|
||||
if ($parent === dirname($parent)) {
|
||||
echo "vendor/autoload.php not found\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$parent = dirname($parent);
|
||||
}
|
||||
|
||||
require $parent.'/vendor/autoload.php';
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('html_errors', 0);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
header_remove('X-Powered-By');
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
|
||||
register_shutdown_function(function () {
|
||||
echo "\n";
|
||||
session_write_close();
|
||||
print_r(headers_list());
|
||||
echo "shutdown\n";
|
||||
});
|
||||
ob_start();
|
||||
|
||||
$r = new Response();
|
||||
$r->headers->set('Date', 'Sat, 12 Nov 1955 20:04:00 GMT');
|
||||
|
||||
return $r;
|
||||
11
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_max_age.expected
vendored
Normal file
11
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_max_age.expected
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
Warning: Expiry date cannot have a year greater than 9999 in %scookie_max_age.php on line 10
|
||||
|
||||
Array
|
||||
(
|
||||
[0] => Content-Type: text/plain; charset=utf-8
|
||||
[1] => Cache-Control: no-cache, private
|
||||
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
|
||||
[3] => Set-Cookie: foo=bar; expires=Sat, 01-Jan-10000 02:46:40 GMT; Max-Age=%d; path=/
|
||||
)
|
||||
shutdown
|
||||
10
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_max_age.php
vendored
Normal file
10
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_max_age.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
|
||||
$r = require __DIR__.'/common.inc';
|
||||
|
||||
$r->headers->setCookie(new Cookie('foo', 'bar', 253402310800, '', null, false, false));
|
||||
$r->sendHeaders();
|
||||
|
||||
setcookie('foo2', 'bar', 253402310800, '/');
|
||||
10
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected
vendored
Normal file
10
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.expected
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
Array
|
||||
(
|
||||
[0] => Content-Type: text/plain; charset=utf-8
|
||||
[1] => Cache-Control: no-cache, private
|
||||
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
|
||||
[3] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/
|
||||
[4] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/
|
||||
)
|
||||
shutdown
|
||||
12
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php
vendored
Normal file
12
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_raw_urlencode.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
|
||||
$r = require __DIR__.'/common.inc';
|
||||
|
||||
$str = '?*():@&+$/%#[]';
|
||||
|
||||
$r->headers->setCookie(new Cookie($str, $str, 0, '/', null, false, false, true));
|
||||
$r->sendHeaders();
|
||||
|
||||
setrawcookie($str, $str, 0, '/', null, false, false);
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
Array
|
||||
(
|
||||
[0] => Content-Type: text/plain; charset=utf-8
|
||||
[1] => Cache-Control: no-cache, private
|
||||
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
|
||||
[3] => Set-Cookie: CookieSamesiteLaxTest=LaxValue; path=/; httponly; samesite=lax
|
||||
)
|
||||
shutdown
|
||||
8
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php
vendored
Normal file
8
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_samesite_lax.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
|
||||
$r = require __DIR__.'/common.inc';
|
||||
|
||||
$r->headers->setCookie(new Cookie('CookieSamesiteLaxTest', 'LaxValue', 0, '/', null, false, true, false, Cookie::SAMESITE_LAX));
|
||||
$r->sendHeaders();
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
Array
|
||||
(
|
||||
[0] => Content-Type: text/plain; charset=utf-8
|
||||
[1] => Cache-Control: no-cache, private
|
||||
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
|
||||
[3] => Set-Cookie: CookieSamesiteStrictTest=StrictValue; path=/; httponly; samesite=strict
|
||||
)
|
||||
shutdown
|
||||
8
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php
vendored
Normal file
8
vendor/symfony/http-foundation/Tests/Fixtures/response-functional/cookie_samesite_strict.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
|
||||
$r = require __DIR__.'/common.inc';
|
||||
|
||||
$r->headers->setCookie(new Cookie('CookieSamesiteStrictTest', 'StrictValue', 0, '/', null, false, true, false, Cookie::SAMESITE_STRICT));
|
||||
$r->sendHeaders();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user