diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md
index 21db4d1ed6..de430ca547 100644
--- a/UPGRADE-3.4.md
+++ b/UPGRADE-3.4.md
@@ -4,7 +4,7 @@ UPGRADE FROM 3.3 to 3.4
DependencyInjection
-------------------
- * Top-level anonymous services in XML are deprecated and will throw an exception in Symfony 4.0.
+ * Top-level anonymous services in XML are deprecated and will throw an exception in Symfony 4.0.
Finder
------
@@ -13,6 +13,38 @@ Finder
deprecated and will be removed in 4.0 as it used to fix a bug which existed
before version 5.5.23/5.6.7.
+FrameworkBundle
+---------------
+
+ * The `doctrine/cache` dependency has been removed; require it via `composer
+ require doctrine/cache` if you are using Doctrine cache in your project.
+
+ * The `validator.mapping.cache.doctrine.apc` service has been deprecated.
+
+ * The `symfony/stopwatch` dependency has been removed, require it via `composer
+ require symfony/stopwatch` in your `dev` environment.
+
+ * Using the `KERNEL_DIR` environment variable or the automatic guessing based
+ on the `phpunit.xml` / `phpunit.xml.dist` file location is deprecated since 3.4.
+ Set the `KERNEL_CLASS` environment variable to the fully-qualified class name
+ of your Kernel instead. Not setting the `KERNEL_CLASS` environment variable
+ will throw an exception on 4.0 unless you override the `KernelTestCase::createKernel()`
+ or `KernelTestCase::getKernelClass()` method.
+
+ * The `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()`
+ methods are deprecated since 3.4 and will be removed in 4.0.
+
+Process
+-------
+
+ * The `Symfony\Component\Process\ProcessBuilder` class has been deprecated,
+ use the `Symfony\Component\Process\Process` class directly instead.
+
+SecurityBundle
+--------------
+
+ * `FirewallContext::getListeners()` now returns `\Traversable|array`
+
Validator
---------
diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md
index 9bf6e0bda0..f6547fd0a0 100644
--- a/UPGRADE-4.0.md
+++ b/UPGRADE-4.0.md
@@ -227,6 +227,8 @@ Form
FrameworkBundle
---------------
+ * The `validator.mapping.cache.doctrine.apc` service has been removed.
+
* The `cache:clear` command does not warmup the cache anymore. Warmup should
be done via the `cache:warmup` command.
@@ -330,6 +332,15 @@ FrameworkBundle
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ValidateWorkflowsPass` class
has been removed. Use the `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass`
class instead.
+
+ * Using the `KERNEL_DIR` environment variable and the automatic guessing based
+ on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()`
+ method implementation. Set the `KERNEL_CLASS` environment variable to the
+ fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()`
+ or `KernelTestCase::getKernelClass()` method instead.
+
+ * The methods `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()`
+ have been removed.
* The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory` class has been removed.
Use `Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead.
@@ -411,6 +422,9 @@ Ldap
Process
-------
+ * The `Symfony\Component\Process\ProcessBuilder` class has been removed,
+ use the `Symfony\Component\Process\Process` class directly instead.
+
* The `ProcessUtils::escapeArgument()` method has been removed, use a command line array or give env vars to the `Process::start/run()` method instead.
* Environment variables are always inherited in sub-processes.
diff --git a/composer.json b/composer.json
index 527cbb16d1..6c4347ccaa 100644
--- a/composer.json
+++ b/composer.json
@@ -94,8 +94,7 @@
"symfony/phpunit-bridge": "~3.2",
"symfony/polyfill-apcu": "~1.1",
"symfony/security-acl": "~2.8|~3.0",
- "phpdocumentor/reflection-docblock": "^3.0",
- "sensio/framework-extra-bundle": "^3.0.2"
+ "phpdocumentor/reflection-docblock": "^3.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0",
diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php
index 2dad6ef009..c11fde9526 100644
--- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php
+++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php
@@ -18,53 +18,53 @@ use PHPUnit\Framework\Warning;
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListener', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener');
-
- return;
-}
-
-/**
- * Collects and replays skipped tests.
- *
- * @author Nicolas Grekas
- *
- * @final
- */
-class SymfonyTestsListener extends BaseTestListener
-{
- private $trait;
-
- public function __construct(array $mockedNamespaces = array())
+// Using an early return instead of a else does not work when using the PHPUnit phar due to some weird PHP behavior (the class
+// gets defined without executing the code before it and so the definition is not properly conditional)
+} else {
+ /**
+ * Collects and replays skipped tests.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+ class SymfonyTestsListener extends BaseTestListener
{
- $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces);
- }
+ private $trait;
- public function globalListenerDisabled()
- {
- $this->trait->globalListenerDisabled();
- }
+ public function __construct(array $mockedNamespaces = array())
+ {
+ $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces);
+ }
- public function startTestSuite(TestSuite $suite)
- {
- return $this->trait->startTestSuite($suite);
- }
+ public function globalListenerDisabled()
+ {
+ $this->trait->globalListenerDisabled();
+ }
- public function addSkippedTest(Test $test, \Exception $e, $time)
- {
- return $this->trait->addSkippedTest($test, $e, $time);
- }
+ public function startTestSuite(TestSuite $suite)
+ {
+ return $this->trait->startTestSuite($suite);
+ }
- public function startTest(Test $test)
- {
- return $this->trait->startTest($test);
- }
+ public function addSkippedTest(Test $test, \Exception $e, $time)
+ {
+ return $this->trait->addSkippedTest($test, $e, $time);
+ }
- public function addWarning(Test $test, Warning $e, $time)
- {
- return $this->trait->addWarning($test, $e, $time);
- }
+ public function startTest(Test $test)
+ {
+ return $this->trait->startTest($test);
+ }
- public function endTest(Test $test, $time)
- {
- return $this->trait->endTest($test, $time);
+ public function addWarning(Test $test, Warning $e, $time)
+ {
+ return $this->trait->addWarning($test, $e, $time);
+ }
+
+ public function endTest(Test $test, $time)
+ {
+ return $this->trait->endTest($test, $time);
+ }
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
index 3fd2c62269..44d39a9d66 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
@@ -18,6 +18,18 @@ CHANGELOG
* Removed class parameters related to routing
* Removed absolute template paths support in the template name parser
+3.4.0
+-----
+
+ * Removed `doctrine/cache` from the list of required dependencies in `composer.json`
+ * Deprecated `validator.mapping.cache.doctrine.apc` service
+ * Deprecated using the `KERNEL_DIR` environment variable with `KernelTestCase::getKernelClass()`.
+ * Deprecated the `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` methods.
+ * The `symfony/stopwatch` dependency has been removed, require it via `composer
+ require symfony/stopwatch` in your `dev` environment.
+ * Deprecated using the `KERNEL_DIR` environment variable with `KernelTestCase::getKernelClass()`.
+ * Deprecated the `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` methods.
+
3.3.0
-----
@@ -65,7 +77,7 @@ CHANGELOG
`Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass` instead
* Deprecated `ValidateWorkflowsPass`, use
`Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` instead
- * Deprecated `ConstraintValidatorFactory`, use
+ * Deprecated `ConstraintValidatorFactory`, use
`Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead.
3.2.0
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index e4fed3d17d..5661182096 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -628,7 +628,18 @@ class Configuration implements ConfigurationInterface
->info('validation configuration')
->{!class_exists(FullStack::class) && class_exists(Validation::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->children()
- ->scalarNode('cache')->end()
+ ->scalarNode('cache')
+ ->beforeNormalization()
+ // Can be removed in 4.0, when validator.mapping.cache.doctrine.apc is removed
+ ->ifString()->then(function ($v) {
+ if ('validator.mapping.cache.doctrine.apc' === $v && !class_exists('Doctrine\Common\Cache\ApcCache')) {
+ throw new LogicException('Doctrine APC cache for the validator cannot be enabled as the Doctrine Cache package is not installed.');
+ }
+
+ return $v;
+ })
+ ->end()
+ ->end()
->booleanNode('enable_annotations')->{!class_exists(FullStack::class) && class_exists(Annotation::class) ? 'defaultTrue' : 'defaultFalse'}()->end()
->arrayNode('static_method')
->defaultValue(array('loadValidatorMetadata'))
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index a06858343a..48466239d8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -15,6 +15,7 @@ use Doctrine\Common\Annotations\Reader;
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Config\FileLocator;
@@ -46,6 +47,8 @@ use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
+use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
@@ -56,6 +59,7 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\ObjectInitializerInterface;
use Symfony\Component\WebLink\HttpHeaderSerializer;
@@ -571,9 +575,14 @@ class FrameworkExtension extends Extension
{
$loader->load('debug_prod.xml');
+ if (class_exists(Stopwatch::class)) {
+ $container->register('debug.stopwatch', Stopwatch::class);
+ $container->setAlias(Stopwatch::class, 'debug.stopwatch');
+ }
+
$debug = $container->getParameter('kernel.debug');
- if ($debug) {
+ if ($debug && class_exists(Stopwatch::class)) {
$loader->load('debug.xml');
}
@@ -620,6 +629,29 @@ class FrameworkExtension extends Extension
$container->setParameter('request_listener.http_port', $config['http_port']);
$container->setParameter('request_listener.https_port', $config['https_port']);
+
+ if ($this->annotationsConfigEnabled) {
+ $container->register('routing.loader.annotation', AnnotatedRouteControllerLoader::class)
+ ->setPublic(false)
+ ->addTag('routing.loader', array('priority' => -10))
+ ->addArgument(new Reference('annotation_reader'));
+
+ $container->register('routing.loader.annotation.directory', AnnotationDirectoryLoader::class)
+ ->setPublic(false)
+ ->addTag('routing.loader', array('priority' => -10))
+ ->setArguments(array(
+ new Reference('file_locator'),
+ new Reference('routing.loader.annotation'),
+ ));
+
+ $container->register('routing.loader.annotation.file', AnnotationFileLoader::class)
+ ->setPublic(false)
+ ->addTag('routing.loader', array('priority' => -10))
+ ->setArguments(array(
+ new Reference('file_locator'),
+ new Reference('routing.loader.annotation'),
+ ));
+ }
}
/**
@@ -753,7 +785,7 @@ class FrameworkExtension extends Extension
$container->setParameter('templating.helper.form.resources', $config['form']['resources']);
- if ($container->getParameter('kernel.debug')) {
+ if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class)) {
$loader->load('templating_debug.xml');
$container->setDefinition('templating.engine.php', $container->findDefinition('debug.templating.engine.php'));
@@ -1084,6 +1116,10 @@ class FrameworkExtension extends Extension
$loader->load('annotations.xml');
if ('none' !== $config['cache']) {
+ if (!class_exists('Doctrine\Common\Cache\CacheProvider')) {
+ throw new LogicException('Annotations cannot be enabled as the Doctrine Cache library is not installed.');
+ }
+
$cacheService = $config['cache'];
if ('php_array' === $config['cache']) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
index 60635b3c00..fc4efe4e02 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
@@ -23,9 +23,6 @@
true
-
-
-
%debug.file_link_format%
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml
index 5f505e859c..aa472d380c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml
@@ -57,6 +57,7 @@
+ The "%service_id%" service is deprecated since Symfony 3.4 and will be removed in 4.0. Use a Psr6 cache like "validator.mapping.cache.symfony" instead.
diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/AnnotatedRouteControllerLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/AnnotatedRouteControllerLoader.php
new file mode 100644
index 0000000000..f5777af95a
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Routing/AnnotatedRouteControllerLoader.php
@@ -0,0 +1,52 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Routing;
+
+use Symfony\Component\Routing\Loader\AnnotationClassLoader;
+use Symfony\Component\Routing\Route;
+
+/**
+ * AnnotatedRouteControllerLoader is an implementation of AnnotationClassLoader
+ * that sets the '_controller' default based on the class and method names.
+ *
+ * @author Fabien Potencier
+ */
+class AnnotatedRouteControllerLoader extends AnnotationClassLoader
+{
+ /**
+ * Configures the _controller default parameter of a given Route instance.
+ *
+ * @param mixed $annot The annotation class instance
+ */
+ protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot)
+ {
+ $route->setDefault('_controller', $class->getName().'::'.$method->getName());
+ }
+
+ /**
+ * Makes the default route name more sane by removing common keywords.
+ *
+ * @return string
+ */
+ protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
+ {
+ return preg_replace(array(
+ '/(bundle|controller)_/',
+ '/action(_\d+)?$/',
+ '/__/',
+ ), array(
+ '_',
+ '\\1',
+ '_',
+ ), parent::getDefaultRouteName($class, $method));
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
index 26781cdf22..802259eedb 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
@@ -39,9 +39,13 @@ abstract class KernelTestCase extends TestCase
* @return string The directory where phpunit.xml(.dist) is stored
*
* @throws \RuntimeException
+ *
+ * @deprecated since 3.4 and will be removed in 4.0.
*/
protected static function getPhpUnitXmlDir()
{
+ @trigger_error(sprintf('The %s() method is deprecated since 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
+
if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) {
throw new \RuntimeException('You must override the KernelTestCase::createKernel() method.');
}
@@ -72,9 +76,13 @@ abstract class KernelTestCase extends TestCase
* the last configuration argument.
*
* @return string The value of the PHPUnit CLI configuration option
+ *
+ * @deprecated since 3.4 and will be removed in 4.0.
*/
private static function getPhpUnitCliConfigArgument()
{
+ @trigger_error(sprintf('The %s() method is deprecated since 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
+
$dir = null;
$reversedArgs = array_reverse($_SERVER['argv']);
foreach ($reversedArgs as $argIndex => $testArg) {
@@ -112,6 +120,8 @@ abstract class KernelTestCase extends TestCase
}
return $class;
+ } else {
+ @trigger_error(sprintf('Using the KERNEL_DIR environment variable or the automatic guessing based on the phpunit.xml / phpunit.xml.dist file location is deprecated since 3.4. Set the KERNEL_CLASS environment variable to the fully-qualified class name of your Kernel instead. Not setting the KERNEL_CLASS environment variable will throw an exception on 4.0 unless you override the %1$::createKernel() or %1$::getKernelClass() method.', static::class), E_USER_DEPRECATED);
}
if (isset($_SERVER['KERNEL_DIR'])) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php
index f3290d7728..a73987bcc9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php
@@ -11,10 +11,8 @@
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
-use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
return array(
new FrameworkBundle(),
new TestBundle(),
- new SensioFrameworkExtraBundle(),
);
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index 3d61ffd684..e1693a10db 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -27,11 +27,10 @@
"symfony/polyfill-mbstring": "~1.0",
"symfony/filesystem": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
- "symfony/routing": "~3.4|~4.0",
- "symfony/stopwatch": "~3.4|~4.0",
- "doctrine/cache": "~1.0"
+ "symfony/routing": "~3.4|~4.0"
},
"require-dev": {
+ "doctrine/cache": "~1.0",
"fig/link-util": "^1.0",
"symfony/asset": "~3.4|~4.0",
"symfony/browser-kit": "~3.4|~4.0",
@@ -46,6 +45,7 @@
"symfony/security-core": "~3.4|~4.0",
"symfony/security-csrf": "~3.4|~4.0",
"symfony/serializer": "~3.4|~4.0",
+ "symfony/stopwatch": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/templating": "~3.4|~4.0",
"symfony/validator": "~3.4|~4.0",
@@ -56,8 +56,7 @@
"symfony/web-link": "~3.4|~4.0",
"doctrine/annotations": "~1.0",
"phpdocumentor/reflection-docblock": "^3.0",
- "twig/twig": "~1.34|~2.4",
- "sensio/framework-extra-bundle": "^3.0.2"
+ "twig/twig": "~1.34|~2.4"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0",
diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
index d484dab08f..e7bd98893f 100644
--- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md
@@ -9,6 +9,11 @@ CHANGELOG
* made the first `UserPasswordEncoderCommand::_construct()` argument mandatory
* `UserPasswordEncoderCommand` does not extend `ContainerAwareCommand` anymore
+3.4.0
+-----
+
+ * [BC BREAK] `FirewallContext::getListeners()` now returns `\Traversable|array`
+
3.3.0
-----
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index e1843ca1c1..0a1ba11008 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -243,7 +243,7 @@ class SecurityExtension extends Extension
$contextId = 'security.firewall.map.context.'.$name;
$context = $container->setDefinition($contextId, new ChildDefinition('security.firewall.context'));
$context
- ->replaceArgument(0, $listeners)
+ ->replaceArgument(0, new IteratorArgument($listeners))
->replaceArgument(1, $exceptionListener)
->replaceArgument(2, new Reference($configId))
;
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
index 4b7dba5e45..79435ff5d4 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
@@ -19,7 +19,7 @@
%security.access.always_authenticate_before_granting%
-
+
@@ -59,7 +59,7 @@
-
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
index 073d0d869d..9cd6ec4d78 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
@@ -222,7 +222,7 @@
{% for voter in collector.voters %}
{{ loop.index }} |
- {{ voter }} |
+ {{ profiler_dump(voter) }} |
{% endfor %}
diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php
index 18e006ee9f..2122d69607 100644
--- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php
+++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php
@@ -25,7 +25,12 @@ class FirewallContext
private $exceptionListener;
private $config;
- public function __construct(array $listeners, ExceptionListener $exceptionListener = null, FirewallConfig $config = null)
+ /**
+ * @param \Traversable|array $listeners
+ * @param ExceptionListener|null $exceptionListener
+ * @param FirewallConfig|null $firewallConfig
+ */
+ public function __construct($listeners, ExceptionListener $exceptionListener = null, FirewallConfig $config = null)
{
$this->listeners = $listeners;
$this->exceptionListener = $exceptionListener;
@@ -37,6 +42,9 @@ class FirewallContext
return $this->config;
}
+ /**
+ * @return \Traversable|array
+ */
public function getListeners()
{
return $this->listeners;
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
index 6ef0e305ec..220e39b09a 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
@@ -72,7 +72,7 @@ abstract class CompleteConfigurationTest extends TestCase
foreach (array_keys($arguments[1]->getValues()) as $contextId) {
$contextDef = $container->getDefinition($contextId);
$arguments = $contextDef->getArguments();
- $listeners[] = array_map('strval', $arguments['index_0']);
+ $listeners[] = array_map('strval', $arguments['index_0']->getValues());
$configDef = $container->getDefinition((string) $arguments['index_2']);
$configs[] = array_values($configDef->getArguments());
diff --git a/src/Symfony/Bundle/WebServerBundle/WebServer.php b/src/Symfony/Bundle/WebServerBundle/WebServer.php
index b65cec1cb7..8edbe2bf56 100644
--- a/src/Symfony/Bundle/WebServerBundle/WebServer.php
+++ b/src/Symfony/Bundle/WebServerBundle/WebServer.php
@@ -13,7 +13,6 @@ namespace Symfony\Bundle\WebServerBundle;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
-use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Process\Exception\RuntimeException;
/**
@@ -151,11 +150,11 @@ class WebServer
throw new \RuntimeException('Unable to find the PHP binary.');
}
- $builder = new ProcessBuilder(array($binary, '-S', $config->getAddress(), $config->getRouter()));
- $builder->setWorkingDirectory($config->getDocumentRoot());
- $builder->setTimeout(null);
+ $process = new Process(array($binary, '-S', $config->getAddress(), $config->getRouter()));
+ $process->setWorkingDirectory($config->getDocumentRoot());
+ $process->setTimeout(null);
- return $builder->getProcess();
+ return $process;
}
private function getDefaultPidFile()
diff --git a/src/Symfony/Component/Console/Helper/ProcessHelper.php b/src/Symfony/Component/Console/Helper/ProcessHelper.php
index 2c46a2c39d..82935baeaa 100644
--- a/src/Symfony/Component/Console/Helper/ProcessHelper.php
+++ b/src/Symfony/Component/Console/Helper/ProcessHelper.php
@@ -15,7 +15,6 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
-use Symfony\Component\Process\ProcessBuilder;
/**
* The ProcessHelper class provides helpers to run external processes.
@@ -44,9 +43,7 @@ class ProcessHelper extends Helper
$formatter = $this->getHelperSet()->get('debug_formatter');
- if (is_array($cmd)) {
- $process = ProcessBuilder::create($cmd)->getProcess();
- } elseif ($cmd instanceof Process) {
+ if ($cmd instanceof Process) {
$process = $cmd;
} else {
$process = new Process($cmd);
diff --git a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
index 8069bcccc9..eb619539ee 100644
--- a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
@@ -17,7 +17,6 @@ use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Process\Process;
-use Symfony\Component\Process\ProcessBuilder;
class ProcessHelperTest extends TestCase
{
@@ -85,8 +84,8 @@ EOT;
EOT;
$errorMessage = 'An error occurred';
- $args = new ProcessBuilder(array('php', '-r', 'echo 42;'));
- $args = $args->getProcess()->getCommandLine();
+ $args = new Process(array('php', '-r', 'echo 42;'));
+ $args = $args->getCommandLine();
$successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug);
return array(
diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json
index e370f91eae..f32fd949d8 100644
--- a/src/Symfony/Component/Console/composer.json
+++ b/src/Symfony/Component/Console/composer.json
@@ -36,7 +36,8 @@
"psr/log": "For using the console logger"
},
"conflict": {
- "symfony/dependency-injection": "<3.4"
+ "symfony/dependency-injection": "<3.4",
+ "symfony/process": "<3.3"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Console\\": "" },
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php
index 2444e441ee..69d48d9ef2 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php
@@ -65,10 +65,14 @@ class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass
if (isset($changes['file'])) {
$value->setFile($this->bag->resolveValue($value->getFile()));
}
- $value->setProperties($this->bag->resolveValue($value->getProperties()));
- $value->setMethodCalls($this->bag->resolveValue($value->getMethodCalls()));
}
- return parent::processValue($value, $isRoot);
+ $value = parent::processValue($value, $isRoot);
+
+ if ($value && is_array($value)) {
+ $value = array_combine($this->bag->resolveValue(array_keys($value)), $value);
+ }
+
+ return $value;
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
index 50be82d741..b9459729e2 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php
@@ -41,12 +41,12 @@ class ResolveParameterPlaceHoldersPassTest extends TestCase
public function testArgumentParametersShouldBeResolved()
{
- $this->assertSame(array('bar', 'baz'), $this->fooDefinition->getArguments());
+ $this->assertSame(array('bar', array('bar' => 'baz')), $this->fooDefinition->getArguments());
}
public function testMethodCallParametersShouldBeResolved()
{
- $this->assertSame(array(array('foobar', array('bar', 'baz'))), $this->fooDefinition->getMethodCalls());
+ $this->assertSame(array(array('foobar', array('bar', array('bar' => 'baz')))), $this->fooDefinition->getMethodCalls());
}
public function testPropertyParametersShouldBeResolved()
@@ -71,7 +71,7 @@ class ResolveParameterPlaceHoldersPassTest extends TestCase
$containerBuilder->setParameter('foo.class', 'Foo');
$containerBuilder->setParameter('foo.factory.class', 'FooFactory');
$containerBuilder->setParameter('foo.arg1', 'bar');
- $containerBuilder->setParameter('foo.arg2', 'baz');
+ $containerBuilder->setParameter('foo.arg2', array('%foo.arg1%' => 'baz'));
$containerBuilder->setParameter('foo.method', 'foobar');
$containerBuilder->setParameter('foo.property.name', 'bar');
$containerBuilder->setParameter('foo.property.value', 'baz');
@@ -80,7 +80,7 @@ class ResolveParameterPlaceHoldersPassTest extends TestCase
$fooDefinition = $containerBuilder->register('foo', '%foo.class%');
$fooDefinition->setFactory(array('%foo.factory.class%', 'getFoo'));
- $fooDefinition->setArguments(array('%foo.arg1%', '%foo.arg2%'));
+ $fooDefinition->setArguments(array('%foo.arg1%', array('%foo.arg1%' => 'baz')));
$fooDefinition->addMethodCall('%foo.method%', array('%foo.arg1%', '%foo.arg2%'));
$fooDefinition->setProperty('%foo.property.name%', '%foo.property.value%');
$fooDefinition->setFile('%foo.file%');
diff --git a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
index 4029883dd9..f7b0273e15 100644
--- a/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
+++ b/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
@@ -15,7 +15,6 @@ use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\VarDumper\Caster\ClassStub;
-use Symfony\Component\VarDumper\Cloner\VarCloner;
/**
* @author Fabien Potencier
@@ -30,8 +29,7 @@ class WrappedListener
private $dispatcher;
private $pretty;
private $stub;
-
- private static $cloner;
+ private static $hasClassStub;
public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
{
@@ -58,8 +56,8 @@ class WrappedListener
$this->name = $name;
}
- if (null === self::$cloner) {
- self::$cloner = class_exists(ClassStub::class) ? new VarCloner() : false;
+ if (null === self::$hasClassStub) {
+ self::$hasClassStub = class_exists(ClassStub::class);
}
}
@@ -86,7 +84,7 @@ class WrappedListener
public function getInfo($eventName)
{
if (null === $this->stub) {
- $this->stub = false === self::$cloner ? $this->pretty.'()' : new ClassStub($this->pretty.'()', $this->listener);
+ $this->stub = self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->listener) : $this->pretty.'()';
}
return array(
diff --git a/src/Symfony/Component/Process/CHANGELOG.md b/src/Symfony/Component/Process/CHANGELOG.md
index bb719be711..7193c498d4 100644
--- a/src/Symfony/Component/Process/CHANGELOG.md
+++ b/src/Symfony/Component/Process/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+3.4.0
+-----
+
+ * deprecated the ProcessBuilder class
+
3.3.0
-----
diff --git a/src/Symfony/Component/Process/ProcessBuilder.php b/src/Symfony/Component/Process/ProcessBuilder.php
index 2a5bb2bc3f..5a54689875 100644
--- a/src/Symfony/Component/Process/ProcessBuilder.php
+++ b/src/Symfony/Component/Process/ProcessBuilder.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Process;
+@trigger_error(sprintf('The %s class is deprecated since version 3.4 and will be removed in 4.0. Use the Process class instead.', ProcessBuilder::class), E_USER_DEPRECATED);
+
use Symfony\Component\Process\Exception\InvalidArgumentException;
use Symfony\Component\Process\Exception\LogicException;
@@ -18,6 +20,8 @@ use Symfony\Component\Process\Exception\LogicException;
* Process builder.
*
* @author Kris Wallsmith
+ *
+ * @deprecated since version 3.4, to be removed in 4.0. Use the Process class instead.
*/
class ProcessBuilder
{
@@ -120,13 +124,9 @@ class ProcessBuilder
* @param bool $inheritEnv
*
* @return $this
- *
- * @deprecated since version 3.3, to be removed in 4.0.
*/
public function inheritEnvironmentVariables($inheritEnv = true)
{
- @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-
$this->inheritEnv = $inheritEnv;
return $this;
@@ -221,13 +221,9 @@ class ProcessBuilder
* @param string $value The option value
*
* @return $this
- *
- * @deprecated since version 3.3, to be removed in 4.0.
*/
public function setOption($name, $value)
{
- @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-
$this->options[$name] = $value;
return $this;
diff --git a/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php b/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php
index 34bb373272..c1a67afa18 100644
--- a/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php
+++ b/src/Symfony/Component/Process/Tests/ProcessBuilderTest.php
@@ -14,11 +14,11 @@ namespace Symfony\Component\Process\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ProcessBuilder;
+/**
+ * @group legacy
+ */
class ProcessBuilderTest extends TestCase
{
- /**
- * @group legacy
- */
public function testInheritEnvironmentVars()
{
$proc = ProcessBuilder::create()
diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md
index 206c1ccf61..d68060de3a 100644
--- a/src/Symfony/Component/Routing/CHANGELOG.md
+++ b/src/Symfony/Component/Routing/CHANGELOG.md
@@ -7,6 +7,11 @@ CHANGELOG
* dropped support for using UTF-8 route patterns without using the `utf8` option
* dropped support for using UTF-8 route requirements without using the `utf8` option
+3.4.0
+-----
+
+ * Added support for prioritized routing loaders.
+
3.3.0
-----
@@ -25,7 +30,7 @@ CHANGELOG
* Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations.
* Added support for UTF-8 requirements
-
+
2.8.0
-----
diff --git a/src/Symfony/Component/Routing/DependencyInjection/RoutingResolverPass.php b/src/Symfony/Component/Routing/DependencyInjection/RoutingResolverPass.php
index 73a8f8511d..4af0a5a286 100644
--- a/src/Symfony/Component/Routing/DependencyInjection/RoutingResolverPass.php
+++ b/src/Symfony/Component/Routing/DependencyInjection/RoutingResolverPass.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Routing\DependencyInjection;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
/**
* Adds tagged routing.loader services to routing.resolver service.
@@ -22,6 +23,8 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
*/
class RoutingResolverPass implements CompilerPassInterface
{
+ use PriorityTaggedServiceTrait;
+
private $resolverServiceId;
private $loaderTag;
@@ -39,7 +42,7 @@ class RoutingResolverPass implements CompilerPassInterface
$definition = $container->getDefinition($this->resolverServiceId);
- foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
+ foreach ($this->findAndSortTaggedServices($this->loaderTag, $container) as $id) {
$definition->addMethodCall('addLoader', array(new Reference($id)));
}
}
diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
index cf94b1af93..e57d04065b 100644
--- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
@@ -425,7 +425,7 @@ return function (root, x) {
if (this.isEmpty()) {
return this.current();
}
- this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : this.idx;
+ this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0;
return this.current();
},
@@ -433,7 +433,7 @@ return function (root, x) {
if (this.isEmpty()) {
return this.current();
}
- this.idx = this.idx > 0 ? this.idx - 1 : this.idx;
+ this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1);
return this.current();
},
@@ -507,7 +507,7 @@ return function (root, x) {
return;
}
- var xpathResult = doc.evaluate('//pre[@id="' + root.id + '"]//span[@class="sf-dump-str" or @class="sf-dump-key" or @class="sf-dump-public" or @class="sf-dump-protected" or @class="sf-dump-private"][contains(child::text(), ' + xpathString(searchQuery) + ')]', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+ var xpathResult = doc.evaluate('//pre[@id="' + root.id + '"]//span[@class="sf-dump-str" or @class="sf-dump-key" or @class="sf-dump-public" or @class="sf-dump-protected" or @class="sf-dump-private"][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
while (node = xpathResult.iterateNext()) state.nodes.push(node);
diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php
index d1c16d0758..8bf8f2ae6f 100644
--- a/src/Symfony/Component/Yaml/Inline.php
+++ b/src/Symfony/Component/Yaml/Inline.php
@@ -440,7 +440,7 @@ class Inline
if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags)) {
$evaluatedKey = self::evaluateScalar($key, $flags, $references);
- if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey)) {
+ if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey) && !is_int($evaluatedKey)) {
throw new ParseException('Non-string mapping keys are not supported. Pass the Yaml::PARSE_KEYS_AS_STRINGS flag to cast them to strings.', self::$parsedLineNumber + 1, $mapping);
}
}
diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php
index 5b8d1b3748..c19ebbd17b 100644
--- a/src/Symfony/Component/Yaml/Parser.php
+++ b/src/Symfony/Component/Yaml/Parser.php
@@ -187,7 +187,7 @@ class Parser
throw $e;
}
- if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags) && !is_string($key)) {
+ if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags) && !is_string($key) && !is_int($key)) {
throw new ParseException('Non-string mapping keys are not supported. Pass the Yaml::PARSE_KEYS_AS_STRINGS flag to cast them to strings.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}