diff --git a/UPGRADE-3.3.md b/UPGRADE-3.3.md index ae1985740f..c068b378f5 100644 --- a/UPGRADE-3.3.md +++ b/UPGRADE-3.3.md @@ -244,6 +244,10 @@ FrameworkBundle class has been deprecated and will be removed in 4.0. Use the `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` class instead. + * Passing an array of validators or validator aliases as the second argument of + `ConstraintValidatorFactory::__construct()` is deprecated since 3.3 and will + be removed in 4.0. Use the service locator instead. + HttpFoundation -------------- @@ -262,7 +266,7 @@ HttpKernel * Deprecated the `Kernel::getRootDir()` method. Use the new `Kernel::getProjectDir()` method instead. - * The `Extension::addClassesToCompile()` method has been deprecated and will be removed in 4.0. + * The `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` methods have been deprecated and will be removed in 4.0. * The `Psr6CacheClearer::addPool()` method has been deprecated. Pass an array of pools indexed by name to the constructor instead. diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index e4d9df88d6..70c6f8e7e6 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -301,6 +301,10 @@ FrameworkBundle * Extending `ConstraintValidatorFactory` is not supported anymore. + * Passing an array of validators or validator aliases as the second argument of + `ConstraintValidatorFactory::__construct()` has been removed. + Use the service locator instead. + * Class parameters related to routing have been removed * router.options.generator_class * router.options.generator_base_class @@ -374,7 +378,7 @@ HttpKernel * Removed the `Kernel::getRootDir()` method. Use the `Kernel::getProjectDir()` method instead. - * The `Extension::addClassesToCompile()` method has been removed. + * The `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` methods have been removed. * Possibility to pass non-scalar values as URI attributes to the ESI and SSI renderers has been removed. The inline fragment renderer should be used with diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index daaa369e49..1cb07da782 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -8,3 +8,9 @@ CHANGELOG deprecated, use the `@group legacy` notation instead * using the `Legacy` prefix in class names to mark a test as legacy is deprecated, use the `@group legacy` notation instead + +3.1.0 +----- + + * passing a numerically indexed array to the constructor of the `SymfonyTestsListenerTrait` + is deprecated, pass an array of namespaces indexed by the mocked feature instead diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt index 7bbda8775d..7e9c6f8ed7 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt @@ -17,6 +17,8 @@ require PHPUNIT_COMPOSER_INSTALL; require_once __DIR__.'/../../bootstrap.php'; require __DIR__.'/fake_vendor/autoload.php'; require __DIR__.'/fake_vendor/acme/lib/deprecation_riddled.php'; + +?> --EXPECTF-- Unsilenced deprecation notices (2) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 82d52706d9..51e13a8430 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -79,7 +79,7 @@ {{- block('choice_widget_options') -}} {%- else -%} - + {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%} @@ -259,7 +259,7 @@ {% set label = name|humanize %} {%- endif -%} {%- endif -%} - {{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }} + {{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }} {%- endif -%} {%- endblock form_label -%} diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index df80163243..b7473b5812 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -49,6 +49,7 @@ CHANGELOG `Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass` instead * Deprecated `ValidateWorkflowsPass`, use `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` instead + * Deprecated `ConstraintValidatorFactory::__construct()` second argument. 3.2.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php index 76705f08d5..6db6da85e0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php @@ -46,7 +46,6 @@ class AboutCommand extends ContainerAwareCommand /** @var $kernel KernelInterface */ $kernel = $this->getContainer()->get('kernel'); - $baseDir = realpath($kernel->getRootDir().DIRECTORY_SEPARATOR.'..'); $io->table(array(), array( array('Symfony'), @@ -62,9 +61,9 @@ class AboutCommand extends ContainerAwareCommand array('Environment', $kernel->getEnvironment()), array('Debug', $kernel->isDebug() ? 'true' : 'false'), array('Charset', $kernel->getCharset()), - array('Root directory', self::formatPath($kernel->getRootDir(), $baseDir)), - array('Cache directory', self::formatPath($kernel->getCacheDir(), $baseDir).' ('.self::formatFileSize($kernel->getCacheDir()).')'), - array('Log directory', self::formatPath($kernel->getLogDir(), $baseDir).' ('.self::formatFileSize($kernel->getLogDir()).')'), + array('Root directory', self::formatPath($kernel->getRootDir(), $kernel->getProjectDir())), + array('Cache directory', self::formatPath($kernel->getCacheDir(), $kernel->getProjectDir()).' ('.self::formatFileSize($kernel->getCacheDir()).')'), + array('Log directory', self::formatPath($kernel->getLogDir(), $kernel->getProjectDir()).' ('.self::formatFileSize($kernel->getLogDir()).')'), new TableSeparator(), array('PHP'), new TableSeparator(), diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index feb966d850..136b1c21fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -82,9 +82,7 @@ EOT $targetArg = rtrim($input->getArgument('target'), '/'); if (!is_dir($targetArg)) { - $appRoot = $this->getContainer()->getParameter('kernel.root_dir').'/..'; - - $targetArg = $appRoot.'/'.$targetArg; + $targetArg = $this->getContainer()->getParameter('kernel.project_dir').'/'.$targetArg; if (!is_dir($targetArg)) { throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 49284270e6..02aad425c2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -201,6 +201,7 @@ EOF { $cacheDir = var_export($warmupDir, true); $rootDir = var_export(realpath($parent->getRootDir()), true); + $projectDir = var_export(realpath($parent->getProjectDir()), true); $logDir = var_export(realpath($parent->getLogDir()), true); // the temp kernel class name must have the same length than the real one // to avoid the many problems in serialized resources files @@ -224,6 +225,11 @@ namespace $namespace return $rootDir; } + public function getProjectDir() + { + return $projectDir; + } + public function getLogDir() { return $logDir; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php index 6cf9574ece..38a1190ade 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php @@ -14,7 +14,10 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Validator; use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory; use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; +use Symfony\Component\Validator\ConstraintValidator; class ConstraintValidatorFactoryTest extends TestCase { @@ -41,6 +44,38 @@ class ConstraintValidatorFactoryTest extends TestCase } public function testGetInstanceReturnsService() + { + $service = 'validator_constraint_service'; + $validator = $this->getMockForAbstractClass(ConstraintValidator::class); + + // mock ContainerBuilder b/c it implements TaggedContainerInterface + $container = $this->getMockBuilder(ContainerBuilder::class)->setMethods(array('get', 'has'))->getMock(); + $container + ->expects($this->once()) + ->method('get') + ->with($service) + ->willReturn($validator); + $container + ->expects($this->once()) + ->method('has') + ->with($service) + ->willReturn(true); + + $constraint = $this->getMockBuilder(Constraint::class)->getMock(); + $constraint + ->expects($this->once()) + ->method('validatedBy') + ->will($this->returnValue($service)); + + $factory = new ConstraintValidatorFactory($container); + $this->assertSame($validator, $factory->getInstance($constraint)); + } + + /** + * @group legacy + * @expectedDeprecation Passing an array of validators or validator aliases as the second argument of "Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory::__construct" is deprecated since 3.3 and will be removed in 4.0. Use the service locator instead. + */ + public function testGetInstanceReturnsServiceWithAlias() { $service = 'validator_constraint_service'; $alias = 'validator_constraint_alias'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php b/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php index aba02e0944..49cd5fe113 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php +++ b/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php @@ -45,15 +45,16 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface protected $container; protected $validators; - /** - * Constructor. - * - * @param ContainerInterface $container The service container - * @param array $validators An array of validators - */ - public function __construct(ContainerInterface $container, array $validators = array()) + public function __construct(ContainerInterface $container, array $validators = null) { $this->container = $container; + + if (null !== $validators) { + @trigger_error(sprintf('Passing an array of validators or validator aliases as the second argument of "%s" is deprecated since 3.3 and will be removed in 4.0. Use the service locator instead.', __METHOD__), E_USER_DEPRECATED); + } else { + $validators = array(); + } + $this->validators = $validators; } @@ -82,6 +83,7 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface $this->validators[$name] = new $name(); } } elseif (is_string($this->validators[$name])) { + // To be removed in 4.0 $this->validators[$name] = $this->container->get($this->validators[$name]); } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index a54244d67c..4191506f1e 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -98,11 +98,11 @@ class SecurityExtension extends Extension if ($config['encoders']) { $this->createEncoders($config['encoders'], $container); + } - if (class_exists(Application::class)) { - $loader->load('console.xml'); - $container->getDefinition('security.console.user_password_encoder_command')->replaceArgument(1, array_keys($config['encoders'])); - } + if (class_exists(Application::class)) { + $loader->load('console.xml'); + $container->getDefinition('security.console.user_password_encoder_command')->replaceArgument(1, array_keys($config['encoders'])); } // load ACL diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index bfa0f1b877..6ef0e305ec 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -345,6 +345,11 @@ abstract class CompleteConfigurationTest extends TestCase $this->assertEquals('security.user_checker', $this->getContainer('container1')->getAlias('security.user_checker.secure')); } + public function testUserPasswordEncoderCommandIsRegistered() + { + $this->assertTrue($this->getContainer('remember_me_options')->has('security.console.user_password_encoder_command')); + } + protected function getContainer($file) { $file = $file.'.'.$this->getFileExtension(); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig index ea73c8bde7..28e3a3c838 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -107,8 +107,8 @@ {% if profile.parent %} -

- Sub-Request {{ profile.getcollector('request').requestattributes.get('_controller') }} +

+ Sub-Request {{ profiler_dump(profile.getcollector('request').requestattributes.get('_controller')) }} {{ collector.events.__section__.duration }} ms Return to parent request diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index 4092f7547a..3a8f6e0fba 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -382,6 +382,9 @@ .sf-toolbar-block-dump pre.sf-dump:last-child { margin-bottom: 0; } +.sf-toolbar-block-dump pre.sf-dump .sf-dump-search-wrapper { + margin-bottom: 5px; +} .sf-toolbar-block-dump pre.sf-dump span.sf-dump-search-count { color: #333; font-size: 12px; diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerCommand.php index 40a0da6e08..1df81a68a1 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerCommand.php @@ -17,6 +17,8 @@ use Symfony\Component\Console\Command\Command; * Base methods for commands related to a local web server. * * @author Christian Flothmann + * + * @internal */ abstract class ServerCommand extends Command { diff --git a/src/Symfony/Bundle/WebServerBundle/Resources/config/webserver.xml b/src/Symfony/Bundle/WebServerBundle/Resources/config/webserver.xml index c45fff0a23..2815c6d2cf 100644 --- a/src/Symfony/Bundle/WebServerBundle/Resources/config/webserver.xml +++ b/src/Symfony/Bundle/WebServerBundle/Resources/config/webserver.xml @@ -8,13 +8,13 @@ - %kernel.root_dir%/../web + %kernel.project_dir%/web %kernel.environment% - %kernel.root_dir%/../web + %kernel.project_dir%/web %kernel.environment% diff --git a/src/Symfony/Bundle/WebServerBundle/composer.json b/src/Symfony/Bundle/WebServerBundle/composer.json index cf6222295c..601b5073f7 100644 --- a/src/Symfony/Bundle/WebServerBundle/composer.json +++ b/src/Symfony/Bundle/WebServerBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.5.9", "symfony/console": "~2.8.8|~3.0.8|~3.1.2|~3.2|~4.0.0", - "symfony/http-kernel": "~2.8|~3.0|~4.0.0", + "symfony/http-kernel": "~3.3|~4.0.0", "symfony/process": "~2.8|~3.0|~4.0.0" }, "autoload": { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowireExceptionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowireExceptionPass.php index 31e407cd63..2ee9427a15 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowireExceptionPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowireExceptionPass.php @@ -21,16 +21,30 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; class AutowireExceptionPass implements CompilerPassInterface { private $autowirePass; + private $inlineServicePass; - public function __construct(AutowirePass $autowirePass) + public function __construct(AutowirePass $autowirePass, InlineServiceDefinitionsPass $inlineServicePass) { $this->autowirePass = $autowirePass; + $this->inlineServicePass = $inlineServicePass; } public function process(ContainerBuilder $container) { - foreach ($this->autowirePass->getAutowiringExceptions() as $exception) { - if ($container->hasDefinition($exception->getServiceId())) { + // the pass should only be run once + if (null === $this->autowirePass || null === $this->inlineServicePass) { + return; + } + + $inlinedIds = $this->inlineServicePass->getInlinedServiceIds(); + $exceptions = $this->autowirePass->getAutowiringExceptions(); + + // free up references + $this->autowirePass = null; + $this->inlineServicePass = null; + + foreach ($exceptions as $exception) { + if ($container->hasDefinition($exception->getServiceId()) || in_array($exception->getServiceId(), $inlinedIds)) { throw $exception; } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index cec68cbb57..b084d7e4dc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -23,6 +23,7 @@ use Symfony\Component\DependencyInjection\Reference; class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface { private $repeatedPass; + private $inlinedServiceIds = array(); /** * {@inheritdoc} @@ -32,6 +33,16 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe $this->repeatedPass = $repeatedPass; } + /** + * Returns an array of all services inlined by this pass. + * + * @return array Service id strings + */ + public function getInlinedServiceIds() + { + return $this->inlinedServiceIds; + } + /** * {@inheritdoc} */ @@ -46,6 +57,7 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe if ($this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) { $this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId)); + $this->inlinedServiceIds[] = $id; if ($definition->isShared()) { return $definition; diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php index 1e80a6060a..5ee8f98851 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php @@ -73,11 +73,11 @@ class PassConfig new RemoveAbstractDefinitionsPass(), new RepeatedPass(array( new AnalyzeServiceReferencesPass(), - new InlineServiceDefinitionsPass(), + $inlinedServicePass = new InlineServiceDefinitionsPass(), new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass(), )), - new AutowireExceptionPass($autowirePass), + new AutowireExceptionPass($autowirePass, $inlinedServicePass), new CheckExceptionOnInvalidReferenceBehaviorPass(), )); } diff --git a/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php b/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php index 30911d3a5e..30cbdef0a6 100644 --- a/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php +++ b/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php @@ -17,6 +17,8 @@ use Symfony\Component\DependencyInjection\Definition; * Null dumper, negates any proxy code generation for any given service definition. * * @author Marco Pivetta + * + * @final since version 3.3 */ class NullDumper implements DumperInterface { @@ -31,7 +33,7 @@ class NullDumper implements DumperInterface /** * {@inheritdoc} */ - public function getProxyFactoryCode(Definition $definition, $id) + public function getProxyFactoryCode(Definition $definition, $id, $methodName = null) { return ''; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowireExceptionPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowireExceptionPassTest.php index 4859db3a64..092b6401c4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowireExceptionPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowireExceptionPassTest.php @@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Compiler\AutowireExceptionPass; use Symfony\Component\DependencyInjection\Compiler\AutowirePass; +use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; @@ -29,10 +30,45 @@ class AutowireExceptionPassTest extends TestCase ->method('getAutowiringExceptions') ->will($this->returnValue(array($autowireException))); + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->will($this->returnValue(array())); + $container = new ContainerBuilder(); $container->register('foo_service_id'); - $pass = new AutowireExceptionPass($autowirePass); + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); + + try { + $pass->process($container); + $this->fail('->process() should throw the exception if the service id exists'); + } catch (\Exception $e) { + $this->assertSame($autowireException, $e); + } + } + + public function testThrowExceptionIfServiceInlined() + { + $autowirePass = $this->getMockBuilder(AutowirePass::class) + ->getMock(); + + $autowireException = new AutowiringFailedException('foo_service_id', 'An autowiring exception message'); + $autowirePass->expects($this->any()) + ->method('getAutowiringExceptions') + ->will($this->returnValue(array($autowireException))); + + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->will($this->returnValue(array('foo_service_id'))); + + // don't register the foo_service_id service + $container = new ContainerBuilder(); + + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); try { $pass->process($container); @@ -52,9 +88,15 @@ class AutowireExceptionPassTest extends TestCase ->method('getAutowiringExceptions') ->will($this->returnValue(array($autowireException))); + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->will($this->returnValue(array())); + $container = new ContainerBuilder(); - $pass = new AutowireExceptionPass($autowirePass); + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); $pass->process($container); // mark the test as passed diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php index c5e7272235..d241758b04 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php @@ -252,6 +252,30 @@ class InlineServiceDefinitionsPassTest extends TestCase $this->assertSame('inline', (string) $values[0]); } + public function testGetInlinedServiceIds() + { + $container = new ContainerBuilder(); + $container + ->register('inlinable.service') + ->setPublic(false) + ; + $container + ->register('non_inlinable.service') + ->setPublic(true) + ; + + $container + ->register('service') + ->setArguments(array(new Reference('inlinable.service'))) + ; + + $inlinePass = new InlineServiceDefinitionsPass(); + $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), $inlinePass)); + $repeatedPass->process($container); + + $this->assertEquals(array('inlinable.service'), $inlinePass->getInlinedServiceIds()); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass())); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 68fd01cf84..717dcdc52e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -88,7 +88,7 @@ class DummyProxyDumper implements ProxyDumper return false; } - public function getProxyFactoryCode(Definition $definition, $id) + public function getProxyFactoryCode(Definition $definition, $id, $methodName = null) { return ''; } diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index b963960fe0..061f61d172 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -10,7 +10,7 @@ CHANGELOG * deprecated the special `SYMFONY__` environment variables * added the possibility to change the query string parameter used by `UriSigner` * deprecated `LazyLoadingFragmentHandler::addRendererService()` - * deprecated `Extension::addClassesToCompile()` + * deprecated `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` * deprecated `Psr6CacheClearer::addPool()` 3.2.0 diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php b/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php index 99ae0d4b90..573e1b4e6b 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/Extension.php @@ -27,9 +27,15 @@ abstract class Extension extends BaseExtension * Gets the classes to cache. * * @return array An array of classes + * + * @deprecated since version 3.3, to be removed in 4.0. */ public function getClassesToCompile() { + if (PHP_VERSION_ID >= 70000) { + @trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED); + } + return $this->classes; } diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index a709f4a61d..fb12d393ab 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -320,7 +320,7 @@ class Process implements \IteratorAggregate } if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $this->options['bypass_shell'] = true; - $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup); + $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $env); } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild $descriptors[3] = array('pipe', 'w'); @@ -1627,7 +1627,7 @@ class Process implements \IteratorAggregate return true; } - private function prepareWindowsCommandLine($cmd, array &$envBackup) + private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env = null) { $uid = uniqid('', true); $varCount = 0; @@ -1640,7 +1640,7 @@ class Process implements \IteratorAggregate [^"%!^]*+ )++ )"/x', - function ($m) use (&$envBackup, &$varCache, &$varCount, $uid) { + function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) { if (isset($varCache[$m[0]])) { return $varCache[$m[0]]; } @@ -1652,10 +1652,15 @@ class Process implements \IteratorAggregate } $value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value); - $value = preg_replace('/(\\\\*)"/', '$1$1\\"', $value); - + $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"'; $var = $uid.++$varCount; - putenv("$var=\"$value\""); + + if (null === $env) { + putenv("$var=$value"); + } else { + $env[$var] = $value; + } + $envBackup[$var] = false; return $varCache[$m[0]] = '!'.$var.'!'; diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 642df9c4a3..ade11138e3 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -1465,6 +1465,19 @@ class ProcessTest extends TestCase $this->assertSame($arg, $p->getOutput()); } + /** + * @dataProvider provideEscapeArgument + * @group legacy + */ + public function testEscapeArgumentWhenInheritEnvDisabled($arg) + { + $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg), null, array('BAR' => 'BAZ')); + $p->inheritEnvironmentVariables(false); + $p->run(); + + $this->assertSame($arg, $p->getOutput()); + } + public function provideEscapeArgument() { yield array('a"b%c%'); diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml b/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml index e8d07350b7..dbc72e46dd 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml +++ b/src/Symfony/Component/Routing/Tests/Fixtures/validpattern.xml @@ -11,14 +11,5 @@ context.getMethod() == "GET" - - MyBundle:Blog:show - GET|POST|put|OpTiOnS - hTTps - \w+ - - context.getMethod() == "GET" - - diff --git a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php index e8e24fde58..d24ec79a79 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php @@ -70,7 +70,7 @@ class XmlFileLoaderTest extends TestCase $routeCollection = $loader->load('validresource.xml'); $routes = $routeCollection->all(); - $this->assertCount(3, $routes, 'Two routes are loaded'); + $this->assertCount(2, $routes, 'Two routes are loaded'); $this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); foreach ($routes as $route) { diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index 8b82c51d11..cf94b1af93 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -655,17 +655,17 @@ pre.sf-dump code { border: 1px solid #ffa500; border-radius: 3px; } -.sf-dump-search-hidden { +pre.sf-dump .sf-dump-search-hidden { display: none; } -.sf-dump-search-wrapper { +pre.sf-dump .sf-dump-search-wrapper { float: right; font-size: 0; white-space: nowrap; max-width: 100%; text-align: right; } -.sf-dump-search-wrapper > * { +pre.sf-dump .sf-dump-search-wrapper > * { vertical-align: top; box-sizing: border-box; height: 21px; @@ -675,7 +675,7 @@ pre.sf-dump code { color: #757575; border: 1px solid #BBB; } -.sf-dump-search-wrapper > input.sf-dump-search-input { +pre.sf-dump .sf-dump-search-wrapper > input.sf-dump-search-input { padding: 3px; height: 21px; font-size: 12px; @@ -685,25 +685,25 @@ pre.sf-dump code { border-bottom-left-radius: 3px; color: #000; } -.sf-dump-search-wrapper > .sf-dump-search-input-next, -.sf-dump-search-wrapper > .sf-dump-search-input-previous { +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next, +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous { background: #F2F2F2; outline: none; border-left: none; font-size: 0; line-height: 0; } -.sf-dump-search-wrapper > .sf-dump-search-input-next { +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } -.sf-dump-search-wrapper > .sf-dump-search-input-next > svg, -.sf-dump-search-wrapper > .sf-dump-search-input-previous > svg { +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next > svg, +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous > svg { pointer-events: none; width: 12px; height: 12px; } -.sf-dump-search-wrapper > .sf-dump-search-count { +pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-count { display: inline-block; padding: 0 5px; margin: 0; diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index dcedd899bc..52cd1867ef 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -368,7 +368,11 @@ class Parser foreach ($this->lines as $line) { try { - $parsedLine = Inline::parse($line, $flags, $this->refs); + if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { + $parsedLine = $line; + } else { + $parsedLine = Inline::parse($line, $flags, $this->refs); + } if (!is_string($parsedLine)) { $parseError = true; diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index f64d7589d8..c8f4a7d40e 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -1561,8 +1561,18 @@ EOT; $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz")); } - public function testParseMultiLineMappingValue() + /** + * @dataProvider multiLineDataProvider + */ + public function testParseMultiLineMappingValue($yaml, $expected, $parseError) { + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function multiLineDataProvider() + { + $tests = array(); + $yaml = <<<'EOF' foo: - bar: @@ -1579,7 +1589,43 @@ EOF; ), ); - $this->assertEquals($expected, $this->parser->parse($yaml)); + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar +"foo" +EOF; + $expected = 'bar "foo"'; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar +"foo +EOF; + $expected = 'bar "foo'; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar + +'foo' +EOF; + $expected = "bar\n'foo'"; + + $tests[] = array($yaml, $expected, false); + + $yaml = <<<'EOF' +bar + +foo' +EOF; + $expected = "bar\nfoo'"; + + $tests[] = array($yaml, $expected, false); + + return $tests; } public function testTaggedInlineMapping()