Merge branch '4.1'

* 4.1: (27 commits)
  Added the Code of Conduct file
  do not override custom access decision configs
  [Security] Do not deauthenticate user when the first refreshed user has changed
  fix a return type hint
  invalidate stale commits for PRs too
  add missing cache prefix seed attribute to XSD
  fix command description
  Fix class documentation
  [Validator] Add a missing translation
  [FrameworkBundle] Fix 3.4 tests
  [DI] fix dumping inline services again
  Rename consumer to receiver
  Register messenger before the profiler
  Fix phpdocs
  [EventDispatcher] Remove template method in test case
  Added LB translation for #27993 (UUID validator message translation)
  Replace deprecated validateValue with validate
  [FWBundle] Automatically enable PropertyInfo when using Flex
  [Process] fix locking of pipe files on Windows
  Correct PHPDoc type for float ttl
  ...
This commit is contained in:
Nicolas Grekas 2018-10-10 06:54:27 -07:00
commit 8848a1aa30
33 changed files with 613 additions and 107 deletions

View File

@ -104,8 +104,7 @@ foreach ($composerJsons as list($dir, $lockedPackages)) {
}
}
if (!$referencedCommits || (isset($_SERVER['TRAVIS_PULL_REQUEST']) && 'false' !== $_SERVER['TRAVIS_PULL_REQUEST'])) {
// cached commits cannot be stale for PRs
if (!$referencedCommits) {
return;
}

View File

@ -7,6 +7,17 @@ in 4.1 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.1.0...v4.1.1
* 4.1.6 (2018-10-03)
* bug #28604 [Finder] fixed root directory access for ftp/sftp wrapper (DerDu)
* bug #28688 [FWBundle] Throw if PropertyInfo is enabled, but the component isn't installed (dunglas)
* bug #28638 [Console] Fix clearing sections containing questions (chalasr)
* bug #28690 [FrameworkBundle] dont suggest hidden services in debug:container and debug:autow commands (nicolas-grekas)
* bug #28648 [PHPUnitBridge] Fix ClockMock microtime() format (acasademont)
* bug #28678 [DI] fix dumping setters before their inlined instances (nicolas-grekas)
* bug #28672 [DI] fix error in dumped container (nicolas-grekas)
* bug #28664 [Console] Don't return early as this bypasses the auto exit feature (duncan3dc)
* 4.1.5 (2018-09-30)
* bug #28636 [HttpFoundation] X-Accel-Mapping does not use HTTP key=value syntax (c960657)

83
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,83 @@
Code of Conduct
===============
Our Pledge
----------
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnic origin, gender identity and expression, level of
experience, education, socio-economic status, nationality, personal appearance,
religion, or sexual identity and orientation.
Our Standards
-------------
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
Our Responsibilities
--------------------
[CoC Active Response Ensurers, or CARE][1], are responsible for clarifying the
standards of acceptable behavior and are expected to take appropriate and fair
corrective action in response to any instances of unacceptable behavior.
CARE team members have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
Scope
-----
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by CARE team members.
Enforcement
-----------
Instances of abusive, harassing, or otherwise unacceptable behavior
[may be reported][2] by contacting the [CARE team members][1].
All complaints will be reviewed and investigated and will result in a response
that is deemed necessary and appropriate to the circumstances. The CARE team is
obligated to maintain confidentiality with regard to the reporter of an
incident. Further details of specific enforcement policies may be posted
separately.
CARE team members who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by the
[core team][3].
Attribution
-----------
This Code of Conduct is adapted from the [Contributor Covenant version 1.4][4].
[1]: https://symfony.com/doc/current/contributing/code_of_conduct/care_team.html
[2]: https://symfony.com/doc/current/contributing/code_of_conduct/reporting_guidelines.html
[3]: https://symfony.com/doc/current/contributing/code/core_team.html
[4]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

View File

@ -253,6 +253,13 @@ class FrameworkExtension extends Extension
$this->registerTemplatingConfiguration($config['templating'], $container, $loader);
}
if ($this->messengerConfigEnabled = $this->isConfigEnabled($container, $config['messenger'])) {
$this->registerMessengerConfiguration($config['messenger'], $container, $loader, $config['serializer'], $config['validation']);
} else {
$container->removeDefinition('console.command.messenger_consume_messages');
$container->removeDefinition('console.command.messenger_debug');
}
$this->registerValidationConfiguration($config['validation'], $container, $loader);
$this->registerEsiConfiguration($config['esi'], $container, $loader);
$this->registerSsiConfiguration($config['ssi'], $container, $loader);
@ -282,13 +289,6 @@ class FrameworkExtension extends Extension
$this->registerLockConfiguration($config['lock'], $container, $loader);
}
if ($this->messengerConfigEnabled = $this->isConfigEnabled($container, $config['messenger'])) {
$this->registerMessengerConfiguration($config['messenger'], $container, $loader, $config['serializer'], $config['validation']);
} else {
$container->removeDefinition('console.command.messenger_consume_messages');
$container->removeDefinition('console.command.messenger_debug');
}
if ($this->isConfigEnabled($container, $config['web_link'])) {
if (!class_exists(HttpHeaderSerializer::class)) {
throw new LogicException('WebLink support cannot be enabled as the WebLink component is not installed.');

View File

@ -260,6 +260,8 @@
<xsd:element name="default-memcached-provider" type="xsd:string" minOccurs="0" maxOccurs="1" />
<xsd:element name="pool" type="cache_pool" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="prefix-seed" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="cache_pool">

View File

@ -60,9 +60,7 @@ class MainConfiguration implements ConfigurationInterface
return false;
})
->then(function ($v) {
$v['access_decision_manager'] = array(
'strategy' => AccessDecisionManager::STRATEGY_AFFIRMATIVE,
);
$v['access_decision_manager']['strategy'] = AccessDecisionManager::STRATEGY_AFFIRMATIVE;
return $v;
})

View File

@ -414,11 +414,22 @@ abstract class CompleteConfigurationTest extends TestCase
/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedExceptionMessage "strategy" and "service" cannot be used together.
* @expectedExceptionMessage Invalid configuration for path "security.access_decision_manager": "strategy" and "service" cannot be used together.
*/
public function testAccessDecisionManagerServiceAndStrategyCannotBeUsedAtTheSameTime()
{
$container = $this->getContainer('access_decision_manager_service_and_strategy');
$this->getContainer('access_decision_manager_service_and_strategy');
}
public function testAccessDecisionManagerOptionsAreNotOverriddenByImplicitStrategy()
{
$container = $this->getContainer('access_decision_manager_customized_config');
$accessDecisionManagerDefinition = $container->getDefinition('security.access.decision_manager');
$this->assertSame(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $accessDecisionManagerDefinition->getArgument(1));
$this->assertTrue($accessDecisionManagerDefinition->getArgument(2));
$this->assertFalse($accessDecisionManagerDefinition->getArgument(3));
}
/**

View File

@ -0,0 +1,20 @@
<?php
$container->loadFromExtension('security', array(
'access_decision_manager' => array(
'allow_if_all_abstain' => true,
'allow_if_equal_granted_denied' => false,
),
'providers' => array(
'default' => array(
'memory' => array(
'users' => array(
'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'),
),
),
),
),
'firewalls' => array(
'simple' => array('pattern' => '/login', 'security' => false),
),
));

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<access-decision-manager allow-if-all-abstain="true" allow-if-equal-granted-denied="false" />
<provider name="default">
<memory>
<user name="foo" password="foo" roles="ROLE_USER" />
</memory>
</provider>
<firewall name="simple" pattern="/login" security="false" />
</config>
</srv:container>

View File

@ -0,0 +1,11 @@
security:
access_decision_manager:
allow_if_all_abstain: true
allow_if_equal_granted_denied: false
providers:
default:
memory:
users:
foo: { password: foo, roles: ROLE_USER }
firewalls:
simple: { pattern: /login, security: false }

View File

@ -40,7 +40,7 @@ class ServerStatusCommand extends Command
new InputOption('pidfile', null, InputOption::VALUE_REQUIRED, 'PID file'),
new InputOption('filter', null, InputOption::VALUE_REQUIRED, 'The value to display (one of port, host, or address)'),
))
->setDescription('Outputs the status of the local web server for the given address')
->setDescription('Outputs the status of the local web server')
->setHelp(<<<'EOF'
<info>%command.name%</info> shows the details of the given local web
server, such as the address and port where it is listening to:

View File

@ -361,10 +361,12 @@ class Command
/**
* Adds an argument.
*
* @param string $name The argument name
* @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
* @param string $name The argument name
* @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param string $description A description text
* @param string|string[]|null $default The default value (for self::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*
* @return $this
*/
@ -378,11 +380,13 @@ class Command
/**
* Adds an option.
*
* @param string $name The option name
* @param string $shortcut The shortcut (can be null)
* @param int $mode The option mode: One of the InputOption::VALUE_* constants
* @param string $description A description text
* @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*
* @return $this
*/

View File

@ -519,10 +519,6 @@ EOF;
}
}
if (false !== strpos($this->dumpLiteralClass($this->dumpValue($definition->getClass())), '$')) {
return false;
}
return true;
}
@ -589,18 +585,16 @@ EOF;
$return = array();
if ($class = $definition->getClass()) {
$class = $this->container->resolveEnvPlaceholders($class);
$class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
$return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\'));
} elseif ($definition->getFactory()) {
$factory = $definition->getFactory();
if (\is_string($factory)) {
$return[] = sprintf('@return object An instance returned by %s()', $factory);
} elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
if (\is_string($factory[0]) || $factory[0] instanceof Reference) {
$return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]);
} elseif ($factory[0] instanceof Definition) {
$return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]);
}
$class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0];
$class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class);
$return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]);
}
}
@ -696,7 +690,7 @@ EOF;
if (\is_array($argument)) {
$hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
} elseif ($argument instanceof Reference) {
$hasSelfRef = $this->addInlineReference($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
$hasSelfRef = $this->addInlineReference($head, $id, $argument, $forConstructor) || $hasSelfRef;
} elseif ($argument instanceof Definition) {
$hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
}
@ -705,37 +699,31 @@ EOF;
return $hasSelfRef;
}
private function addInlineReference(string &$head, string &$tail, string $id, string $targetId, bool $forConstructor): bool
private function addInlineReference(string &$code, string $id, string $targetId, bool $forConstructor): bool
{
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
return isset($this->circularReferences[$id][$targetId]);
return $hasSelfRef;
}
list($callCount, $behavior) = $this->serviceCalls[$targetId];
if (2 > $callCount && (!$forConstructor || !isset($this->circularReferences[$id][$targetId]))) {
return isset($this->circularReferences[$id][$targetId]);
if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) {
return $hasSelfRef;
}
$name = $this->getNextVariableName();
$this->referenceVariables[$targetId] = new Variable($name);
$reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null;
$code = sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
$code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
if (!isset($this->circularReferences[$id][$targetId])) {
$head .= $code;
return false;
if (!$hasSelfRef || !$forConstructor) {
return $hasSelfRef;
}
if (!$forConstructor) {
$tail .= $code;
return true;
}
$head .= $code.sprintf(<<<'EOTXT'
$code .= sprintf(<<<'EOTXT'
if (isset($this->%s['%s'])) {
return $this->%1$s['%2$s'];
@ -758,7 +746,7 @@ EOTXT
$arguments = array($definition->getArguments(), $definition->getFactory());
if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator() && false === strpos($this->dumpValue($definition->getClass()), '$')) {
if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) {
return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor);
}
@ -766,9 +754,13 @@ EOTXT
$this->definitionVariables[$definition] = new Variable($name);
$code = '';
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
if ($forConstructor) {
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
} else {
$hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor);
}
$code .= $this->addNewInstance($definition, ' $'.$name.' = ', $id);
$hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
$hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
$code = '';
$arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator());

View File

@ -910,6 +910,28 @@ class PhpDumperTest extends TestCase
$this->assertEquals((object) array('p2' => (object) array('p3' => (object) array())), $container->get('foo')->bClone);
}
public function testInlineSelfRef()
{
$container = new ContainerBuilder();
$bar = (new Definition('App\Bar'))
->setProperty('foo', new Reference('App\Foo'));
$baz = (new Definition('App\Baz'))
->setProperty('bar', $bar)
->addArgument($bar);
$container->register('App\Foo')
->setPublic(true)
->addArgument($baz);
$passConfig = $container->getCompiler()->getPassConfig();
$container->compile();
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_self_ref.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Inline_Self_Ref')));
}
public function testHotPathOptimizations()
{
$container = include self::$fixturesPath.'/containers/container_inline_requires.php';
@ -987,6 +1009,18 @@ class PhpDumperTest extends TestCase
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
}
public function testAdawsonContainer()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services_adawson.yml');
$container->compile();
$dumper = new PhpDumper($container);
$dump = $dumper->dump();
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_adawson.php', $dumper->dump());
}
/**
* This test checks the trigger of a deprecation note and should not be removed in major releases.
*

View File

@ -7,9 +7,12 @@ require_once __DIR__.'/../includes/classes.php';
$container = new ContainerBuilder();
$container->setParameter('env(FOO)', 'Bar\FaooClass');
$container->setParameter('foo', '%env(FOO)%');
$container
->register('service_from_anonymous_factory', 'Bar\FooClass')
->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'))
->register('service_from_anonymous_factory', '%foo%')
->setFactory(array(new Definition('%foo%'), 'getInstance'))
->setPublic(true)
;

View File

@ -21,6 +21,8 @@ class ProjectServiceContainer extends Container
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = array();
$this->methodMap = array(
'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService',
@ -51,11 +53,11 @@ class ProjectServiceContainer extends Container
/**
* Gets the public 'service_from_anonymous_factory' shared service.
*
* @return \Bar\FooClass
* @return object A %env(FOO)% instance
*/
protected function getServiceFromAnonymousFactoryService()
{
return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance();
return $this->services['service_from_anonymous_factory'] = (new ${($_ = $this->getEnv('FOO')) && false ?: "_"}())->getInstance();
}
/**
@ -71,4 +73,80 @@ class ProjectServiceContainer extends Container
return $instance;
}
public function getParameter($name)
{
$name = (string) $name;
if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}
if (isset($this->loadedDynamicParameters[$name])) {
return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
}
return $this->parameters[$name];
}
public function hasParameter($name)
{
$name = (string) $name;
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
}
public function setParameter($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}
public function getParameterBag()
{
if (null === $this->parameterBag) {
$parameters = $this->parameters;
foreach ($this->loadedDynamicParameters as $name => $loaded) {
$parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
}
$this->parameterBag = new FrozenParameterBag($parameters);
}
return $this->parameterBag;
}
private $loadedDynamicParameters = array(
'foo' => false,
);
private $dynamicParameters = array();
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*
* @throws InvalidArgumentException When the dynamic parameter does not exist
*/
private function getDynamicParameter($name)
{
switch ($name) {
case 'foo': $value = $this->getEnv('FOO'); break;
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
}
$this->loadedDynamicParameters[$name] = true;
return $this->dynamicParameters[$name] = $value;
}
/**
* Gets the default parameters.
*
* @return array An array of the default parameters
*/
protected function getDefaultParameters()
{
return array(
'env(FOO)' => 'Bar\\FaooClass',
);
}
}

View File

@ -0,0 +1,109 @@
<?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*
* @final since Symfony 3.3
*/
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();
public function __construct()
{
$this->services = $this->privates = array();
$this->methodMap = array(
'App\\Bus' => 'getBusService',
'App\\Db' => 'getDbService',
);
$this->aliases = array();
}
public function compile()
{
throw new LogicException('You cannot compile a dumped container that was already compiled.');
}
public function isCompiled()
{
return true;
}
public function getRemovedIds()
{
return array(
'App\\Handler1' => true,
'App\\Handler2' => true,
'App\\Processor' => true,
'App\\Registry' => true,
'App\\Schema' => true,
'Psr\\Container\\ContainerInterface' => true,
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
);
}
/**
* Gets the public 'App\Bus' shared service.
*
* @return \App\Bus
*/
protected function getBusService()
{
$a = ($this->services['App\Db'] ?? $this->getDbService());
$this->services['App\Bus'] = $instance = new \App\Bus($a);
$b = ($this->privates['App\Schema'] ?? $this->getSchemaService());
$d = new \App\Registry();
$d->processor = array(0 => $a, 1 => $instance);
$c = new \App\Processor($d, $a);
$instance->handler1 = new \App\Handler1($a, $b, $c);
$instance->handler2 = new \App\Handler2($a, $b, $c);
return $instance;
}
/**
* Gets the public 'App\Db' shared service.
*
* @return \App\Db
*/
protected function getDbService()
{
$this->services['App\Db'] = $instance = new \App\Db();
$instance->schema = ($this->privates['App\Schema'] ?? $this->getSchemaService());
return $instance;
}
/**
* Gets the private 'App\Schema' shared service.
*
* @return \App\Schema
*/
protected function getSchemaService()
{
$a = ($this->services['App\Db'] ?? $this->getDbService());
if (isset($this->privates['App\Schema'])) {
return $this->privates['App\Schema'];
}
return $this->privates['App\Schema'] = new \App\Schema($a);
}
}

View File

@ -0,0 +1,68 @@
<?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*
* @final since Symfony 3.3
*/
class Symfony_DI_PhpDumper_Test_Inline_Self_Ref extends Container
{
private $parameters;
private $targetDirs = array();
public function __construct()
{
$this->services = $this->privates = array();
$this->methodMap = array(
'App\\Foo' => 'getFooService',
);
$this->aliases = array();
}
public function compile()
{
throw new LogicException('You cannot compile a dumped container that was already compiled.');
}
public function isCompiled()
{
return true;
}
public function getRemovedIds()
{
return array(
'Psr\\Container\\ContainerInterface' => true,
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
);
}
/**
* Gets the public 'App\Foo' shared service.
*
* @return \App\Foo
*/
protected function getFooService()
{
$b = new \App\Bar();
$a = new \App\Baz($b);
$this->services['App\Foo'] = $instance = new \App\Foo($a);
$b->foo = $instance;
$a->bar = $b;
return $instance;
}
}

View File

@ -0,0 +1,28 @@
services:
App\Db:
public: true
properties:
schema: '@App\Schema'
App\Bus:
public: true
arguments: ['@App\Db']
properties:
handler1: '@App\Handler1'
handler2: '@App\Handler2'
App\Handler1:
['@App\Db', '@App\Schema', '@App\Processor']
App\Handler2:
['@App\Db', '@App\Schema', '@App\Processor']
App\Processor:
['@App\Registry', '@App\Db']
App\Registry:
properties:
processor: ['@App\Db', '@App\Bus']
App\Schema:
arguments: ['@App\Db']

View File

@ -31,8 +31,6 @@ class GenericEventTest extends TestCase
*/
protected function setUp()
{
parent::setUp();
$this->subject = new \stdClass();
$this->event = new GenericEvent($this->subject, array('name' => 'Event'));
}
@ -44,8 +42,6 @@ class GenericEventTest extends TestCase
{
$this->subject = null;
$this->event = null;
parent::tearDown();
}
public function testConstruct()

View File

@ -68,7 +68,7 @@ class DateTimeToRfc3339Transformer extends BaseDateTimeTransformer
return;
}
if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})T\d{2}:\d{2}(?::\d{2})?(?:\.\d)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))$/', $rfc3339, $matches)) {
if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})T\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))$/', $rfc3339, $matches)) {
throw new TransformationFailedException(sprintf('The date "%s" is not a valid date.', $rfc3339));
}

View File

@ -235,9 +235,9 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
}
/**
* Converts an unresolved child into a {@link FormBuilder} instance.
* Converts an unresolved child into a {@link FormBuilderInterface} instance.
*/
private function resolveChild(string $name): self
private function resolveChild(string $name): FormBuilderInterface
{
$info = $this->unresolvedChildren[$name];
$child = $this->create($name, $info['type'], $info['options']);

View File

@ -67,6 +67,7 @@ class DateTimeToRfc3339TransformerTest extends TestCase
array('UTC', 'UTC', '2010-02-03 04:05:00 UTC', '2010-02-03T04:05Z'),
array('America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:00 America/New_York', '2010-02-03T17:05+08:00'),
array('Europe/Amsterdam', 'Europe/Amsterdam', '2013-08-21 10:30:00 Europe/Amsterdam', '2013-08-21T08:30:00Z'),
array('UTC', 'UTC', '2018-10-03T10:00:00.000Z', '2018-10-03T10:00:00.000Z'),
));
}

View File

@ -13,7 +13,9 @@ namespace Symfony\Component\Form\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\ButtonBuilder;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\SubmitButtonBuilder;
class FormBuilderTest extends TestCase
@ -228,6 +230,14 @@ class FormBuilderTest extends TestCase
$this->assertEmpty($unresolvedChildren->getValue($config));
}
public function testGetButtonBuilderBeforeExplicitlyResolvingAllChildren()
{
$builder = new FormBuilder('name', null, $this->dispatcher, (new FormFactoryBuilder())->getFormFactory());
$builder->add('submit', SubmitType::class);
$this->assertInstanceOf(ButtonBuilder::class, $builder->get('submit'));
}
private function getFormBuilder($name = 'name')
{
$mock = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')

View File

@ -17,7 +17,7 @@ namespace Symfony\Component\HttpFoundation;
* A StreamedResponse uses a callback for its content.
*
* The callback should use the standard PHP functions like echo
* to stream the response back to the client. The flush() method
* to stream the response back to the client. The flush() function
* can also be used if needed.
*
* @see flush()

View File

@ -36,9 +36,9 @@ class Factory implements LoggerAwareInterface
/**
* Creates a lock for the given resource.
*
* @param string $resource The resource to lock
* @param float $ttl Maximum expected lock duration in seconds
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
* @param string $resource The resource to lock
* @param float|null $ttl Maximum expected lock duration in seconds
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
*
* @return Lock
*/

View File

@ -21,9 +21,9 @@ class WrapIntoReceivedMessage implements ReceiverInterface
{
private $decoratedReceiver;
public function __construct(ReceiverInterface $decoratedConsumer)
public function __construct(ReceiverInterface $decoratedReceiver)
{
$this->decoratedReceiver = $decoratedConsumer;
$this->decoratedReceiver = $decoratedReceiver;
}
public function receive(callable $handler): void

View File

@ -28,6 +28,7 @@ class WindowsPipes extends AbstractPipes
{
private $files = array();
private $fileHandles = array();
private $lockHandles = array();
private $readBytes = array(
Process::STDOUT => 0,
Process::STDERR => 0,
@ -47,31 +48,33 @@ class WindowsPipes extends AbstractPipes
Process::STDOUT => Process::OUT,
Process::STDERR => Process::ERR,
);
$tmpCheck = false;
$tmpDir = sys_get_temp_dir();
$lastError = 'unknown reason';
set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
for ($i = 0;; ++$i) {
foreach ($pipes as $pipe => $name) {
$file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
if (file_exists($file) && !unlink($file)) {
continue 2;
}
$h = fopen($file, 'xb');
if (!$h) {
$error = $lastError;
if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
continue;
}
if (!$h = fopen($file.'.lock', 'w')) {
restore_error_handler();
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $lastError));
}
if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
if (!flock($h, LOCK_EX | LOCK_NB)) {
continue 2;
}
if (isset($this->files[$pipe])) {
unlink($this->files[$pipe]);
if (isset($this->lockHandles[$pipe])) {
flock($this->lockHandles[$pipe], LOCK_UN);
fclose($this->lockHandles[$pipe]);
}
$this->lockHandles[$pipe] = $h;
if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) {
flock($this->lockHandles[$pipe], LOCK_UN);
fclose($this->lockHandles[$pipe]);
unset($this->lockHandles[$pipe]);
continue 2;
}
$this->fileHandles[$pipe] = $h;
$this->files[$pipe] = $file;
}
break;
@ -85,7 +88,6 @@ class WindowsPipes extends AbstractPipes
public function __destruct()
{
$this->close();
$this->removeFiles();
}
/**
@ -145,8 +147,11 @@ class WindowsPipes extends AbstractPipes
$read[$type] = $data;
}
if ($close) {
ftruncate($fileHandle, 0);
fclose($fileHandle);
unset($this->fileHandles[$type]);
flock($this->lockHandles[$type], LOCK_UN);
fclose($this->lockHandles[$type]);
unset($this->fileHandles[$type], $this->lockHandles[$type]);
}
}
@ -175,22 +180,12 @@ class WindowsPipes extends AbstractPipes
public function close()
{
parent::close();
foreach ($this->fileHandles as $handle) {
foreach ($this->fileHandles as $type => $handle) {
ftruncate($handle, 0);
fclose($handle);
flock($this->lockHandles[$type], LOCK_UN);
fclose($this->lockHandles[$type]);
}
$this->fileHandles = array();
}
/**
* Removes temporary files.
*/
private function removeFiles()
{
foreach ($this->files as $filename) {
if (file_exists($filename)) {
@unlink($filename);
}
}
$this->files = array();
$this->fileHandles = $this->lockHandles = array();
}
}

View File

@ -161,6 +161,7 @@ class ContextListener implements ListenerInterface
}
$userNotFoundByProvider = false;
$userDeauthenticated = false;
foreach ($this->userProviders as $provider) {
if (!$provider instanceof UserProviderInterface) {
@ -169,17 +170,26 @@ class ContextListener implements ListenerInterface
try {
$refreshedUser = $provider->refreshUser($user);
$token->setUser($refreshedUser);
$newToken = unserialize(serialize($token));
$newToken->setUser($refreshedUser);
// tokens can be deauthenticated if the user has been changed.
if (!$token->isAuthenticated()) {
if (null !== $this->logger) {
$this->logger->debug('Token was deauthenticated after trying to refresh it.', array('username' => $refreshedUser->getUsername(), 'provider' => \get_class($provider)));
if (!$newToken->isAuthenticated()) {
if ($this->logoutOnUserChange) {
$userDeauthenticated = true;
if (null !== $this->logger) {
$this->logger->debug('Cannot refresh token because user has changed.', array('username' => $refreshedUser->getUsername(), 'provider' => \get_class($provider)));
}
continue;
}
return null;
}
$token->setUser($refreshedUser);
if (null !== $this->logger) {
$context = array('provider' => \get_class($provider), 'username' => $refreshedUser->getUsername());
@ -205,6 +215,14 @@ class ContextListener implements ListenerInterface
}
}
if ($userDeauthenticated) {
if (null !== $this->logger) {
$this->logger->debug('Token was deauthenticated after trying to refresh it.');
}
return null;
}
if ($userNotFoundByProvider) {
return null;
}

View File

@ -260,6 +260,15 @@ class ContextListenerTest extends TestCase
$this->assertNull($tokenStorage->getToken());
}
public function testIfTokenIsNotDeauthenticated()
{
$tokenStorage = new TokenStorage();
$badRefreshedUser = new User('foobar', 'baz');
$goodRefreshedUser = new User('foobar', 'bar');
$this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider($badRefreshedUser), new SupportingUserProvider($goodRefreshedUser)), $goodRefreshedUser, true);
$this->assertSame($goodRefreshedUser, $tokenStorage->getToken()->getUser());
}
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
{
$tokenStorage = new TokenStorage();

View File

@ -97,7 +97,7 @@ interface ExecutionContextInterface
* {
* $validator = $this->context->getValidator();
*
* $violations = $validator->validateValue($value, new Length(array('min' => 3)));
* $violations = $validator->validate($value, new Length(array('min' => 3)));
*
* if (count($violations) > 0) {
* // ...

View File

@ -318,6 +318,10 @@
<source>Error</source>
<target>Feeler</target>
</trans-unit>
<trans-unit id="83">
<source>This is not a valid UUID.</source>
<target>Dëst ass keng gëlteg UUID.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -318,6 +318,10 @@
<source>Error</source>
<target>Błąd</target>
</trans-unit>
<trans-unit id="83">
<source>This is not a valid UUID.</source>
<target>To nie jest poprawne UUID.</target>
</trans-unit>
</body>
</file>
</xliff>