diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 77286ee416f82..949fef6d8ff5a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -36,6 +36,7 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; @@ -1626,7 +1627,7 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont private function registerCacheConfiguration(array $config, ContainerBuilder $container) { - $version = substr(str_replace('/', '-', base64_encode(hash('sha256', uniqid(mt_rand(), true), true))), 0, 22); + $version = new Parameter('container.build_id'); $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 0540aa1fe7e18..cabccb38c1b32 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -1045,6 +1045,9 @@ protected function createContainer(array $data = array()) 'kernel.name' => 'kernel', 'kernel.root_dir' => __DIR__, 'kernel.container_class' => 'testContainer', + 'container.build_hash' => 'Abc1234', + 'container.build_id' => hash('crc32', 'Abc123423456789'), + 'container.build_time' => 23456789, ), $data))); } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index e2382363bebc5..1f0f233feb0db 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -20,7 +20,7 @@ "ext-xml": "*", "symfony/cache": "~3.4|~4.0", "symfony/class-loader": "~3.2", - "symfony/dependency-injection": "~3.4|~4.0", + "symfony/dependency-injection": "^3.4.3|^4.0.3", "symfony/config": "~3.4|~4.0", "symfony/event-dispatcher": "~3.4|~4.0", "symfony/http-foundation": "^3.3.11|~4.0", diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index bb4af0367a6d3..a514ab04a8327 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -289,7 +289,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto ->arrayNode('anonymous') ->canBeUnset() ->children() - ->scalarNode('secret')->defaultValue(uniqid('', true))->end() + ->scalarNode('secret')->defaultNull()->end() ->end() ->end() ->arrayNode('switch_user') diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php index f226b47cf5cc5..d79b96dadcced 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php @@ -14,6 +14,7 @@ use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; /** @@ -27,13 +28,14 @@ class InMemoryFactory implements UserProviderFactoryInterface public function create(ContainerBuilder $container, $id, $config) { $definition = $container->setDefinition($id, new ChildDefinition('security.user.provider.in_memory')); + $defaultPassword = new Parameter('container.build_id'); foreach ($config['users'] as $username => $user) { $userId = $id.'_'.$username; $container ->setDefinition($userId, new ChildDefinition('security.user.provider.in_memory.user')) - ->setArguments(array($username, (string) $user['password'], $user['roles'])) + ->setArguments(array($username, null !== $user['password'] ? (string) $user['password'] : $defaultPassword, $user['roles'])) ; $definition->addMethodCall('createUser', array(new Reference($userId))); @@ -55,7 +57,7 @@ public function addConfiguration(NodeDefinition $node) ->normalizeKeys(false) ->prototype('array') ->children() - ->scalarNode('password')->defaultValue(uniqid('', true))->end() + ->scalarNode('password')->defaultNull()->end() ->arrayNode('roles') ->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); })->end() ->prototype('scalar')->end() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index cb127350e296a..a2be3a24be751 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -22,6 +22,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Config\FileLocator; use Symfony\Component\Security\Core\Authorization\ExpressionLanguage; @@ -529,6 +530,10 @@ private function createAuthenticationListeners($container, $id, $firewall, &$aut // Anonymous if (isset($firewall['anonymous'])) { + if (null === $firewall['anonymous']['secret']) { + $firewall['anonymous']['secret'] = new Parameter('container.build_hash'); + } + $listenerId = 'security.authentication.listener.anonymous.'.$id; $container ->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.anonymous')) diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index d1bf164f0a1f8..45e6b3663c185 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -19,8 +19,8 @@ "php": "^5.5.9|>=7.0.8", "ext-xml": "*", "symfony/security": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/http-kernel": "~3.3|~4.0", + "symfony/dependency-injection": "^3.4.3|^4.0.3", + "symfony/http-kernel": "~3.4|~4.0", "symfony/polyfill-php70": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 1a55cc219cbe7..27a845e42a866 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1239,6 +1239,8 @@ private function doResolveServices($value, array &$inlineServices = array()) $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices); } elseif ($value instanceof Definition) { $value = $this->createService($value, $inlineServices); + } elseif ($value instanceof Parameter) { + $value = $this->getParameter((string) $value); } elseif ($value instanceof Expression) { $value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this)); } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index f68f82da58ff5..9f13ef307ba92 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -211,6 +211,8 @@ public function dump(array $options = array()) array_pop($code); $code["Container{$hash}/{$options['class']}.php"] = substr_replace($files[$options['class'].'.php'], "namespace ? "\nnamespace {$this->namespace};\n" : ''; + $time = time(); + $id = hash('crc32', $hash.$time); $code[$options['class'].'.php'] = << '$hash', + 'container.build_id' => '$id', + 'container.build_time' => $time, +)); EOF; } else { @@ -564,7 +570,7 @@ private function isTrivialInstance(Definition $definition) } foreach ($definition->getArguments() as $arg) { - if (!$arg) { + if (!$arg || $arg instanceof Parameter) { continue; } if (is_array($arg) && 3 >= count($arg)) { @@ -572,7 +578,7 @@ private function isTrivialInstance(Definition $definition) if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { return false; } - if (!$v) { + if (!$v || $v instanceof Parameter) { continue; } if ($v instanceof Reference && $this->container->has($id = (string) $v) && $this->container->findDefinition($id)->isSynthetic()) { @@ -892,10 +898,10 @@ private function addNewInstance(Definition $definition, $return, $instantiation, } if (0 === strpos($class, 'new ')) { - return $return.sprintf("(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); + return $return.sprintf("(%s)->%s(%s);\n", $class, $callable[1], $arguments ? implode(', ', $arguments) : ''); } - return $return.sprintf("\\call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); + return $return.sprintf("\\call_user_func(array(%s, '%s')%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); } return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); @@ -957,6 +963,11 @@ public function __construct() EOF; } + if ($this->asFiles) { + $code = str_replace('$parameters', "\$buildParameters;\n private \$parameters", $code); + $code = str_replace('__construct()', '__construct(array $buildParameters = array())', $code); + $code .= " \$this->buildParameters = \$buildParameters;\n"; + } if ($this->container->isCompiled()) { if ($this->container->getParameterBag()->all()) { @@ -1283,6 +1294,9 @@ private function addDefaultParametersMethod() public function getParameter($name) { + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { $name = $this->normalizeParameterName($name); @@ -1299,6 +1313,9 @@ public function getParameter($name) public function hasParameter($name) { + if (isset($this->buildParameters[$name])) { + return true; + } $name = $this->normalizeParameterName($name); return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); @@ -1316,6 +1333,9 @@ public function getParameterBag() foreach ($this->loadedDynamicParameters as $name => $loaded) { $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } $this->parameterBag = new FrozenParameterBag($parameters); } @@ -1323,6 +1343,9 @@ public function getParameterBag() } EOF; + if (!$this->asFiles) { + $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code); + } if ($dynamicPhp) { $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8); @@ -1717,16 +1740,21 @@ private function dumpValue($value, $interpolate = true) throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $factory[1] ?: 'n/a')); } + $class = $this->dumpValue($factory[0]); if (is_string($factory[0])) { - return sprintf('%s::%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory[0])), $factory[1], implode(', ', $arguments)); + return sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $factory[1], implode(', ', $arguments)); } if ($factory[0] instanceof Definition) { - return sprintf("\\call_user_func(array(%s, '%s')%s)", $this->dumpValue($factory[0]), $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); + if (0 === strpos($class, 'new ')) { + return sprintf('(%s)->%s(%s)', $class, $factory[1], implode(', ', $arguments)); + } + + return sprintf("\\call_user_func(array(%s, '%s')%s)", $class, $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); } if ($factory[0] instanceof Reference) { - return sprintf('%s->%s(%s)', $this->dumpValue($factory[0]), $factory[1], implode(', ', $arguments)); + return sprintf('%s->%s(%s)', $class, $factory[1], implode(', ', $arguments)); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt index ffdc3296f86f6..7ab5cb487be69 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt @@ -276,15 +276,17 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; */ class ProjectServiceContainer extends Container { + private $buildParameters; private $parameters; private $targetDirs = array(); - public function __construct() + public function __construct(array $buildParameters = array()) { $dir = $this->targetDirs[0] = \dirname(__DIR__); for ($i = 1; $i <= 5; ++$i) { $this->targetDirs[$i] = $dir = \dirname($dir); } + $this->buildParameters = $buildParameters; $this->parameters = $this->getDefaultParameters(); $this->services = array(); @@ -382,6 +384,9 @@ class ProjectServiceContainer extends Container public function getParameter($name) { + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { $name = $this->normalizeParameterName($name); @@ -398,6 +403,9 @@ class ProjectServiceContainer extends Container public function hasParameter($name) { + if (isset($this->buildParameters[$name])) { + return true; + } $name = $this->normalizeParameterName($name); return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); @@ -415,6 +423,9 @@ class ProjectServiceContainer extends Container foreach ($this->loadedDynamicParameters as $name => $loaded) { $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } $this->parameterBag = new FrozenParameterBag($parameters); } @@ -485,6 +496,10 @@ if (!\class_exists(ProjectServiceContainer::class, false)) { \class_alias(\Container%s\ProjectServiceContainer::class, ProjectServiceContainer::class, false); } -return new \Container%s\ProjectServiceContainer(); +return new \Container%s\ProjectServiceContainer(array( + 'container.build_hash' => '%s', + 'container.build_id' => '%s', + 'container.build_time' => %d, +)); ) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php index 0040f7bc1aa51..9475c923068f2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php @@ -83,7 +83,7 @@ protected function getTestServiceSubscriberService() */ protected function getFooServiceService() { - return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(\call_user_func(array(new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () { + return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () { $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'}); }, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () { $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'}); @@ -91,7 +91,7 @@ protected function getFooServiceService() $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'}); }, 'baz' => function () { $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'}); - })), 'withContext'), 'foo_service', $this)); + })))->withContext('foo_service', $this)); } /**