diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000000000..6eaec7c81da9a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,13 @@
+| Q | A
+| ---------------- | -----
+| Bug report? | yes/no
+| Feature request? | yes/no
+| BC Break report? | yes/no
+| RFC? | yes/no
+| Symfony version | x.y.z
+
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 99ba8e00213af..216a2ba4e5625 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,11 +1,19 @@
| Q | A
| ------------- | ---
-| Branch? | "master" for new features / 2.7, 2.8 or 3.1 for fixes
+| Branch? | master / 2.7, 2.8, 3.1 or 3.2
| Bug fix? | yes/no
| New feature? | yes/no
| BC breaks? | yes/no
| Deprecations? | yes/no
| Tests pass? | yes/no
-| Fixed tickets | comma-separated list of tickets fixed by the PR, if any
+| Fixed tickets | #...
| License | MIT
-| Doc PR | reference to the documentation PR, if any
+| Doc PR | symfony/symfony-docs#...
+
+
diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md
index c892ebb6755b7..39dd7fa8598f5 100644
--- a/CHANGELOG-3.2.md
+++ b/CHANGELOG-3.2.md
@@ -7,6 +7,52 @@ in 3.2 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.2.0...v3.2.1
+* 3.2.1 (2016-12-13)
+
+ * bug #20891 Add support for REDIS_URL environment variables. (robinvdvleuten)
+ * bug #20724 [WebProfilerBundle] Fix AJAX panel with fetch requests (OnekO)
+ * bug #20883 Don’t compile when Opcache is not enabled on CLI (ruudk)
+ * bug #20877 DateIntervalType: 'invert' should not inherit the 'required' option (galeaspablo)
+ * bug #20886 [Form] DateIntervalType: Do not try to translate choices (ogizanagi)
+ * bug #20855 [Yaml] do not trigger deprecations for valid YAML (xabbuh)
+ * bug #20714 [FrameworkBundle] Fix unresolved parameters from default configs in debug:config (chalasr)
+ * bug #20862 Allow simple-phpunit to be used with an HTTP proxy (Cydonia7)
+ * bug #20882 [TwigBridge] fix constructor args check (xabbuh)
+ * bug #20860 [WebProfilerBundle] Fix a web profiler form issue with fields added to the form after the form was built (tgalopin)
+ * bug #20442 [FrameworkBundle] Bundle commands are not available via find() (julienfalque)
+ * bug #20840 [WebProfilerBundle] add dependency on Twig (xabbuh)
+ * bug #20833 [HttpKernel] Fix open_basedir compat in DataCollector (nicolas-grekas)
+ * bug #20828 [Validator] Fix init of YamlFileLoader::$classes for empty files (nicolas-grekas)
+ * bug #20688 [FrameworkBundle] Resolve env params in debug:config command (nicolas-grekas)
+ * bug #20725 [HttpKernel] Fix annotation cache warmer with failing or missing classes (nicolas-grekas)
+ * bug #20830 [FrameworkBundle] Fix validation cache warmer with failing or missing classes (nicolas-grekas)
+ * bug #20760 [FrameworkBundle] [Workflow] Fix service marking store configuration (fduch)
+ * bug #20745 [Validator] add class name to the cache key (Simperfit)
+ * bug #20530 [Serializer] Remove AbstractObjectNormalizer::isAttributeToNormalize (dunglas)
+ * bug #19141 Throw less misleading exception when property access not found (bramtweedegolf)
+ * bug #20539 Cast result to int before adding to it (alcaeus)
+ * bug #20831 [Twig] Fix deprecations with Twig 1.29 (nicolas-grekas)
+ * bug #20701 Ignore missing 'debug.file_link_formatter' service in Debug and Twig bundles (mbabker)
+ * bug #20816 [FrameworkBundle] Removed kernel.debug from the cache pool namespace seed (Sander Toonen)
+ * bug #20769 [Bridge\Twig] Trigger deprecation when using FormExtension::$renderer (nicolas-grekas)
+ * bug #20646 Maintain the selected panel when redirecting to another profile (javiereguiluz)
+ * bug #20767 [Cache] Fix dumping SplDoublyLinkedList iter mode (nicolas-grekas)
+ * bug #20690 [Serializer] Fix argument object denormalization (ogizanagi)
+ * bug #20762 [Form] Fix FormDataCollector (nicolas-grekas, Padam87)
+ * bug #20747 [HttpKernel] Fixed RequestDataCollector handling of null header values. (Gabriel Moreira)
+ * bug #20727 [TwigBundle] Inject project root path into twig filesystem loader (4rthem)
+ * bug #20736 [Console] fixed PHP7 Errors when not using Dispatcher (keradus)
+ * bug #20756 [HttpKernel] Regression test for missing controller arguments (iltar)
+ * bug #20755 [HttpKernel] Regression test for missing controller arguments (iltar)
+ * bug #20732 fix the inline level for dumped multi-line strings (xabbuh)
+ * bug #20418 [Form][DX] FileType "multiple" fixes (yceruto)
+ * bug #19902 [DependencyInjection] PhpDumper.php: hasReference() shouldn't search references in lazy service. (antanas-arvasevicius)
+ * bug #20704 [Console] Fix wrong handling of multiline arg/opt descriptions (ogizanagi)
+ * bug #20700 [WebProfilerBundle][Translator] Fix TranslationDataCollector should use cloneVar (ogizanagi)
+ * bug #20712 [TwigBundle] Fix twig loader registered twice (ogizanagi)
+ * bug #20716 [WebProfilerBundle] Fix dump block is unfairly restrained (ogizanagi)
+ * bug #20717 Fix hide button in toolbar (nicolasdewez)
+
* 3.2.0 (2016-11-30)
* bug #20687 [FrameworkBundle] Forbid env parameters in routing configuration (nicolas-grekas)
diff --git a/UPGRADE-3.1.md b/UPGRADE-3.1.md
index b9163cfff369e..58ce838cfb714 100644
--- a/UPGRADE-3.1.md
+++ b/UPGRADE-3.1.md
@@ -111,6 +111,10 @@ Serializer
deprecated and will not be supported in Symfony 4.0. You should use the
`CacheClassMetadataFactory` class instead.
+ * The `AbstractObjectNormalizer::isAttributeToNormalize()` method has been removed
+ because it was initially added by mistake, has never been used and is not tested
+ nor documented.
+
Translation
-----------
diff --git a/UPGRADE-3.2.md b/UPGRADE-3.2.md
index f4b043c754c66..e977a845cf045 100644
--- a/UPGRADE-3.2.md
+++ b/UPGRADE-3.2.md
@@ -6,28 +6,6 @@ BrowserKit
* Client HTTP user agent has been changed to 'Symfony BrowserKit' (was 'Symfony2 BrowserKit' before).
-FrameworkBundle
----------------
-
- * The `doctrine/annotations` dependency has been removed; require it via `composer
- require doctrine/annotations` if you are using annotations in your project
- * The `symfony/security-core` and `symfony/security-csrf` dependencies have
- been removed; require them via `composer require symfony/security-core
- symfony/security-csrf` if you depend on them and don't already depend on
- `symfony/symfony`
- * The `symfony/templating` dependency has been removed; require it via `composer
- require symfony/templating` if you depend on it and don't already depend on
- `symfony/symfony`
- * The `symfony/translation` dependency has been removed; require it via `composer
- require symfony/translation` if you depend on it and don't already depend on
- `symfony/symfony`
- * The `symfony/asset` dependency has been removed; require it via `composer
- require symfony/asset` if you depend on it and don't already depend on
- `symfony/symfony`
- * The `Resources/public/images/*` files have been removed.
- * The `Resources/public/css/*.css` files have been removed (they are now inlined
- in TwigBundle).
-
Console
-------
@@ -72,27 +50,27 @@ Form
FrameworkBundle
---------------
+ * The `doctrine/annotations` dependency has been removed; require it via `composer
+ require doctrine/annotations` if you are using annotations in your project
+ * The `symfony/security-core` and `symfony/security-csrf` dependencies have
+ been removed; require them via `composer require symfony/security-core
+ symfony/security-csrf` if you depend on them and don't already depend on
+ `symfony/symfony`
+ * The `symfony/templating` dependency has been removed; require it via `composer
+ require symfony/templating` if you depend on it and don't already depend on
+ `symfony/symfony`
+ * The `symfony/translation` dependency has been removed; require it via `composer
+ require symfony/translation` if you depend on it and don't already depend on
+ `symfony/symfony`
+ * The `symfony/asset` dependency has been removed; require it via `composer
+ require symfony/asset` if you depend on it and don't already depend on
+ `symfony/symfony`
+ * The `Resources/public/images/*` files have been removed.
+ * The `Resources/public/css/*.css` files have been removed (they are now inlined
+ in TwigBundle).
* The service `serializer.mapping.cache.doctrine.apc` is deprecated. APCu should now
be automatically used when available.
-HttpKernel
-----------
-
- * `DataCollector::varToString()` is deprecated and will be removed in Symfony
- 4.0. Use the `cloneVar()` method instead.
-
- * Surrogate name in a `Surrogate-Capability` HTTP request header has been changed to 'symfony'.
-
- Before:
- ```
- Surrogate-Capability: symfony2="ESI/1.0"
- ```
-
- After:
- ```
- Surrogate-Capability: symfony="ESI/1.0"
- ```
-
HttpFoundation
---------------
@@ -116,6 +94,37 @@ HttpFoundation
- `isInvalid`/`isSuccessful`/`isRedirection`/`isClientError`/`isServerError`
- `isOk`/`isForbidden`/`isNotFound`/`isRedirect`/`isEmpty`
+HttpKernel
+----------
+
+ * `DataCollector::varToString()` is deprecated and will be removed in Symfony
+ 4.0. Use the `cloneVar()` method instead.
+
+ * Surrogate name in a `Surrogate-Capability` HTTP request header has been changed to 'symfony'.
+
+ Before:
+ ```
+ Surrogate-Capability: symfony2="ESI/1.0"
+ ```
+
+ After:
+ ```
+ Surrogate-Capability: symfony="ESI/1.0"
+ ```
+
+Router
+------
+
+ * `UrlGenerator` now generates URLs in compliance with [`RFC 3986`](https://www.ietf.org/rfc/rfc3986.txt),
+ which means spaces will be percent encoded (%20) inside query strings.
+
+Serializer
+----------
+
+ * Method `AbstractNormalizer::instantiateObject()` will have a 6th
+ `$format = null` argument in Symfony 4.0. Not defining it when overriding
+ the method is deprecated.
+
TwigBridge
----------
diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md
index 483b7e6ed1447..76b6b51bd7b3c 100644
--- a/UPGRADE-4.0.md
+++ b/UPGRADE-4.0.md
@@ -170,6 +170,10 @@ Serializer
* The ability to pass a Doctrine `Cache` instance to the `ClassMetadataFactory`
class has been removed. You should use the `CacheClassMetadataFactory` class
instead.
+
+ * Not defining the 6th argument `$format = null` of the
+ `AbstractNormalizer::instantiateObject()` method when overriding it is not
+ supported anymore.
Translation
-----------
@@ -182,6 +186,42 @@ TwigBridge
* The possibility to inject the Form Twig Renderer into the form extension
has been removed. Inject it into the `TwigRendererEngine` instead.
+Validator
+---------
+
+ * The `DateTimeValidator::PATTERN` constant was removed.
+
+ * `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in
+ favor of `Test\ConstraintValidatorTestCase`.
+
+ Before:
+
+ ```php
+ // ...
+ use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
+
+ class MyCustomValidatorTest extends AbstractConstraintValidatorTest
+ {
+ // ...
+ }
+ ```
+
+ After:
+
+ ```php
+ // ...
+ use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
+
+ class MyCustomValidatorTest extends ConstraintValidatorTestCase
+ {
+ // ...
+ }
+ ```
+
+ * The default value of the strict option of the `Choice` Constraint has been
+ changed to `true` as of 4.0. If you need the the previous behaviour ensure to
+ set the option to `false`.
+
Yaml
----
@@ -273,39 +313,3 @@ Yaml
the `!php/object` tag.
* Duplicate mapping keys lead to a `ParseException`.
-
-Validator
----------
-
- * The `DateTimeValidator::PATTERN` constant was removed.
-
- * `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in
- favor of `Test\ConstraintValidatorTestCase`.
-
- Before:
-
- ```php
- // ...
- use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
-
- class MyCustomValidatorTest extends AbstractConstraintValidatorTest
- {
- // ...
- }
- ```
-
- After:
-
- ```php
- // ...
- use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
-
- class MyCustomValidatorTest extends ConstraintValidatorTestCase
- {
- // ...
- }
- ```
-
- * The default value of the strict option of the `Choice` Constraint has been
- changed to `true` as of 4.0. If you need the the previous behaviour ensure to
- set the option to `false`.
diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
index 9f846a3ecbaae..a832b68b48e6e 100755
--- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
+++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
@@ -37,7 +37,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
if (file_exists("phpunit-$PHPUNIT_VERSION")) {
passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION"));
}
- if (extension_loaded('openssl') && ini_get('allow_url_fopen')) {
+ if (extension_loaded('openssl') && ini_get('allow_url_fopen') && !isset($_SERVER['http_proxy']) && !isset($_SERVER['https_proxy'])) {
stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb'));
} else {
@unlink("$PHPUNIT_VERSION.zip");
diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php
index 016e6a9586c97..81a8683c35b97 100644
--- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php
@@ -13,6 +13,7 @@
use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
use Symfony\Bridge\Twig\Form\TwigRendererInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
/**
@@ -23,12 +24,17 @@
*/
class FormExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface
{
+ /**
+ * @deprecated since version 3.2, to be removed in 4.0 alongside with magic methods below
+ */
private $renderer;
- public function __construct(TwigRendererInterface $renderer = null)
+ public function __construct($renderer = null)
{
- if (null !== $this->renderer) {
+ if ($renderer instanceof TwigRendererInterface) {
@trigger_error(sprintf('Passing a Twig Form Renderer to the "%s" constructor is deprecated since version 3.2 and won\'t be possible in 4.0. Pass the Twig_Environment to the TwigRendererEngine constructor instead.', static::class), E_USER_DEPRECATED);
+ } elseif (null !== $renderer && !(is_array($renderer) && isset($renderer[0], $renderer[1]) && $renderer[0] instanceof ContainerInterface)) {
+ throw new \InvalidArgumentException(sprintf('Passing any arguments the constructor of %s is reserved for internal use.', __CLASS__));
}
$this->renderer = $renderer;
}
@@ -40,8 +46,10 @@ public function __construct(TwigRendererInterface $renderer = null)
*/
public function initRuntime(\Twig_Environment $environment)
{
- if (null !== $this->renderer) {
+ if ($this->renderer instanceof TwigRendererInterface) {
$this->renderer->setEnvironment($environment);
+ } elseif (null !== $this->renderer) {
+ $this->renderer[2] = $environment;
}
}
@@ -94,6 +102,62 @@ public function getTests()
);
}
+ /**
+ * @internal
+ */
+ public function __get($name)
+ {
+ if ('renderer' === $name) {
+ @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+
+ if (is_array($this->renderer)) {
+ $renderer = $this->renderer[0]->get($this->renderer[1]);
+ if (isset($this->renderer[2])) {
+ $renderer->setEnvironment($this->renderer[2]);
+ }
+ $this->renderer = $renderer;
+ }
+ }
+
+ return $this->$name;
+ }
+
+ /**
+ * @internal
+ */
+ public function __set($name, $value)
+ {
+ if ('renderer' === $name) {
+ @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+ }
+
+ $this->$name = $value;
+ }
+
+ /**
+ * @internal
+ */
+ public function __isset($name)
+ {
+ if ('renderer' === $name) {
+ @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+ }
+
+ return isset($this->$name);
+ }
+
+ /**
+ * @internal
+ */
+ public function __unset($name)
+ {
+ if ('renderer' === $name) {
+ @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
+ }
+
+ unset($this->$name);
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php b/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php
index 5e7c4ce5216d0..23869da436d68 100644
--- a/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php
@@ -72,8 +72,7 @@ public function getExtractData()
}
/**
- * @expectedException \Twig_Error
- * @expectedExceptionMessageRegExp /Unclosed "block" in ".*extractor(\/|\\)syntax_error\.twig" at line 1/
+ * @expectedException \Twig_Error
* @dataProvider resourcesWithSyntaxErrorsProvider
*/
public function testExtractSyntaxError($resources)
@@ -82,7 +81,19 @@ public function testExtractSyntaxError($resources)
$twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface')));
$extractor = new TwigExtractor($twig);
- $extractor->extract($resources, new MessageCatalogue('en'));
+
+ try {
+ $extractor->extract($resources, new MessageCatalogue('en'));
+ } catch (\Twig_Error $e) {
+ if (method_exists($e, 'getSourceContext')) {
+ $this->assertSame(dirname(__DIR__).strtr('/Fixtures/extractor/syntax_error.twig', '/', DIRECTORY_SEPARATOR), $e->getFile());
+ $this->assertSame(1, $e->getLine());
+ $this->assertSame('Unclosed "block".', $e->getMessage());
+ } else {
+ $this->expectExceptionMessageRegExp('/Unclosed "block" in ".*extractor(\\/|\\\\)syntax_error\\.twig" at line 1/');
+ }
+ throw $e;
+ }
}
/**
diff --git a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php
index 950c4d0810db0..35995dbd64518 100644
--- a/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php
+++ b/src/Symfony/Bridge/Twig/Translation/TwigExtractor.php
@@ -61,10 +61,14 @@ public function extract($resource, MessageCatalogue $catalogue)
try {
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
} catch (\Twig_Error $e) {
- if ($file instanceof SplFileInfo) {
- $e->setTemplateName($file->getRelativePathname());
- } elseif ($file instanceof \SplFileInfo) {
- $e->setTemplateName($file->getRealPath() ?: $file->getPathname());
+ if ($file instanceof \SplFileInfo) {
+ $path = $file->getRealPath() ?: $file->getPathname();
+ $name = $file instanceof SplFileInfo ? $file->getRelativePathname() : $path;
+ if (method_exists($e, 'setSourceContext')) {
+ $e->setSourceContext(new \Twig_Source('', $name, $path));
+ } else {
+ $e->setTemplateName($name);
+ }
}
throw $e;
diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml
index aada03eff87cf..655d0ae5c7e89 100644
--- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml
+++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml
@@ -14,7 +14,7 @@
-
+
%kernel.charset%
null
diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php
index 6d044676eb012..2c0a435617d4a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php
@@ -66,9 +66,19 @@ public function warmUp($cacheDir)
$arrayPool = new ArrayAdapter(0, false);
$reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayPool));
-
- foreach ($annotatedClasses as $class) {
- $this->readAllComponents($reader, $class);
+ $throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); };
+ spl_autoload_register($throwingAutoloader);
+
+ try {
+ foreach ($annotatedClasses as $class) {
+ try {
+ $this->readAllComponents($reader, $class);
+ } catch (\ReflectionException $e) {
+ // ignore failing reflection
+ }
+ }
+ } finally {
+ spl_autoload_unregister($throwingAutoloader);
}
$values = $arrayPool->getValues();
diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php
index ce5104dc41cc5..d450cc1f85237 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php
@@ -66,12 +66,23 @@ public function warmUp($cacheDir)
$loaders = $this->validatorBuilder->getLoaders();
$metadataFactory = new LazyLoadingMetadataFactory(new LoaderChain($loaders), new Psr6Cache($arrayPool));
- foreach ($this->extractSupportedLoaders($loaders) as $loader) {
- foreach ($loader->getMappedClasses() as $mappedClass) {
- if ($metadataFactory->hasMetadataFor($mappedClass)) {
- $metadataFactory->getMetadataFor($mappedClass);
+ $throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); };
+ spl_autoload_register($throwingAutoloader);
+
+ try {
+ foreach ($this->extractSupportedLoaders($loaders) as $loader) {
+ foreach ($loader->getMappedClasses() as $mappedClass) {
+ try {
+ if ($metadataFactory->hasMetadataFor($mappedClass)) {
+ $metadataFactory->getMetadataFor($mappedClass);
+ }
+ } catch (\ReflectionException $e) {
+ // ignore failing reflection
+ }
}
}
+ } finally {
+ spl_autoload_unregister($throwingAutoloader);
}
$values = $arrayPool->getValues();
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
index 22811c6558894..33073b0a91044 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php
@@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->validateConfiguration($extension, $configuration);
- $configs = $container->getParameterBag()->resolveValue($configs);
+ $configs = $container->resolveEnvPlaceholders($container->getParameterBag()->resolveValue($configs));
$processor = new Processor();
$config = $processor->processConfiguration($configuration, $configs);
@@ -105,7 +105,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$io->title(sprintf('Current configuration for "%s.%s"', $extensionAlias, $path));
- $io->writeln(Yaml::dump($config, 10));
+ $io->writeln(Yaml::dump($container->getParameterBag()->resolveValue($config), 10));
}
private function compileContainer()
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
index 981df241cd3a1..c9d0e419e290e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php
@@ -19,6 +19,7 @@
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\Config\FileLocator;
/**
@@ -96,7 +97,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
$object = $this->getContainerBuilder();
if ($input->getOption('parameters')) {
- $object = $object->getParameterBag();
+ $parameters = array();
+ foreach ($object->getParameterBag()->all() as $k => $v) {
+ $parameters[$k] = $object->resolveEnvPlaceholders($v);
+ }
+ $object = new ParameterBag($parameters);
$options = array();
} elseif ($parameter = $input->getOption('parameter')) {
$options = array('parameter' => $parameter);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
index 40604e3d809db..0287f42a8ed4d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php
@@ -17,7 +17,6 @@
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;
use Symfony\Component\Workflow\Marking;
-use Symfony\Component\Workflow\Workflow;
/**
* @author Grégoire Pineau
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
index 5dfe21357f46a..da28fc0294af2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php
@@ -80,6 +80,16 @@ public function doRun(InputInterface $input, OutputInterface $output)
return parent::doRun($input, $output);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function find($name)
+ {
+ $this->registerCommands();
+
+ return parent::find($name);
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
index da809aea8df63..95c9324662490 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
@@ -57,7 +57,7 @@ public function describe(OutputInterface $output, $object, array $options = arra
$this->describeContainerService($this->resolveServiceDefinition($object, $options['id']), $options);
break;
case $object instanceof ContainerBuilder && isset($options['parameter']):
- $this->describeContainerParameter($object->getParameter($options['parameter']), $options);
+ $this->describeContainerParameter($object->resolveEnvPlaceholders($object->getParameter($options['parameter'])), $options);
break;
case $object instanceof ContainerBuilder:
$this->describeContainerServices($object, $options);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
index 1dbf54b5adf9d..90daa3eeadd00 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
@@ -137,7 +137,7 @@ protected function json($data, $status = 200, $headers = array(), $context = arr
protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
{
$response = new BinaryFileResponse($file);
- $response->setContentDisposition($disposition, $fileName === null ? $response->getFile()->getFileName() : $fileName);
+ $response->setContentDisposition($disposition, $fileName === null ? $response->getFile()->getFilename() : $fileName);
return $response;
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
index 593b7782c66b0..df02d65259a8d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
@@ -34,7 +34,7 @@ public function process(ContainerBuilder $container)
} else {
$seed = '_'.$container->getParameter('kernel.root_dir');
}
- $seed .= '.'.$container->getParameter('kernel.name').'.'.$container->getParameter('kernel.environment').'.'.$container->getParameter('kernel.debug');
+ $seed .= '.'.$container->getParameter('kernel.name').'.'.$container->getParameter('kernel.environment');
$aliases = $container->getAliases();
$attributes = array(
@@ -96,7 +96,9 @@ private function getNamespace($seed, $id)
*/
public static function getServiceProvider(ContainerBuilder $container, $name)
{
- if (0 === strpos($name, 'redis://')) {
+ $container->resolveEnvPlaceholders($name, null, $usedEnvs);
+
+ if (0 === strpos($name, 'redis://') || $usedEnvs) {
$dsn = $name;
if (!$container->hasDefinition($name = md5($dsn))) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 5c6208e6e46f2..adb825b7c3dfd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -268,7 +268,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
->thenInvalid('"type" and "service" cannot be used together.')
->end()
->validate()
- ->ifTrue(function ($v) { return isset($v['arguments']) && isset($v['service']); })
+ ->ifTrue(function ($v) { return !empty($v['arguments']) && isset($v['service']); })
->thenInvalid('"arguments" and "service" cannot be used together.')
->end()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
index fc0e7654db2ca..a944da863f6d0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php
@@ -32,8 +32,7 @@ public function testBundleInterfaceImplementation()
public function testBundleCommandsAreRegistered()
{
- $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
- $bundle->expects($this->once())->method('registerCommands');
+ $bundle = $this->createBundleMock(array());
$kernel = $this->getKernel(array($bundle), true);
@@ -46,8 +45,7 @@ public function testBundleCommandsAreRegistered()
public function testBundleCommandsAreRetrievable()
{
- $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
- $bundle->expects($this->once())->method('registerCommands');
+ $bundle = $this->createBundleMock(array());
$kernel = $this->getKernel(array($bundle));
@@ -60,47 +58,41 @@ public function testBundleCommandsAreRetrievable()
public function testBundleSingleCommandIsRetrievable()
{
- $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
- $bundle->expects($this->once())->method('registerCommands');
+ $command = new Command('example');
+
+ $bundle = $this->createBundleMock(array($command));
$kernel = $this->getKernel(array($bundle));
$application = new Application($kernel);
- $command = new Command('example');
- $application->add($command);
-
$this->assertSame($command, $application->get('example'));
}
public function testBundleCommandCanBeFound()
{
- $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
- $bundle->expects($this->once())->method('registerCommands');
+ $command = new Command('example');
+
+ $bundle = $this->createBundleMock(array($command));
$kernel = $this->getKernel(array($bundle));
$application = new Application($kernel);
- $command = new Command('example');
- $application->add($command);
-
$this->assertSame($command, $application->find('example'));
}
public function testBundleCommandCanBeFoundByAlias()
{
- $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
- $bundle->expects($this->once())->method('registerCommands');
+ $command = new Command('example');
+ $command->setAliases(array('alias'));
+
+ $bundle = $this->createBundleMock(array($command));
$kernel = $this->getKernel(array($bundle));
$application = new Application($kernel);
- $command = new Command('example');
- $command->setAliases(array('alias'));
- $application->add($command);
-
$this->assertSame($command, $application->find('alias'));
}
@@ -167,4 +159,18 @@ private function getKernel(array $bundles, $useDispatcher = false)
return $kernel;
}
+
+ private function createBundleMock(array $commands)
+ {
+ $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle');
+ $bundle
+ ->expects($this->once())
+ ->method('registerCommands')
+ ->will($this->returnCallback(function (Application $application) use ($commands) {
+ $application->addCommands($commands);
+ }))
+ ;
+
+ return $bundle;
+ }
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
index 192e1493d0c38..25a706c3a4f81 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
@@ -45,7 +45,7 @@ public function testNamespaceArgumentIsReplaced()
$this->cachePoolPass->process($container);
- $this->assertSame('C42Pcl9VBJ', $cachePool->getArgument(0));
+ $this->assertSame('D07rhFx97S', $cachePool->getArgument(0));
}
public function testArgsAreReplaced()
@@ -69,7 +69,7 @@ public function testArgsAreReplaced()
$this->assertInstanceOf(Reference::class, $cachePool->getArgument(0));
$this->assertSame('foobar', (string) $cachePool->getArgument(0));
- $this->assertSame('KO3xHaFEZU', $cachePool->getArgument(1));
+ $this->assertSame('itantF+pIq', $cachePool->getArgument(1));
$this->assertSame(3, $cachePool->getArgument(2));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/cache_env_var.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/cache_env_var.php
new file mode 100644
index 0000000000000..b93ade8f4c816
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/cache_env_var.php
@@ -0,0 +1,9 @@
+setParameter('env(REDIS_URL)', 'redis://paas.com');
+
+$container->loadFromExtension('framework', array(
+ 'cache' => array(
+ 'default_redis_provider' => '%env(REDIS_URL)%',
+ ),
+));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php
index 854a858415e00..5ebfeeeb76e7a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php
@@ -88,5 +88,23 @@
),
),
),
+ 'service_marking_store_workflow' => array(
+ 'marking_store' => array(
+ 'service' => 'workflow_service',
+ ),
+ 'supports' => array(
+ FrameworkExtensionTest::class,
+ ),
+ 'places' => array(
+ 'first',
+ 'last',
+ ),
+ 'transitions' => array(
+ 'go' => array(
+ 'from' => 'first',
+ 'to' => 'last',
+ ),
+ ),
+ ),
),
));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/cache_env_var.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/cache_env_var.xml
new file mode 100644
index 0000000000000..8f03cb1784b35
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/cache_env_var.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ redis://paas.com
+
+
+
+
+ %env(REDIS_URL)%
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
index 924ff75111ca8..509bdd38fcc30 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
@@ -79,5 +79,16 @@
review
+
+
+
+ Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
+ first
+ last
+
+ first
+ last
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/cache_env_var.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/cache_env_var.yml
new file mode 100644
index 0000000000000..1d9ce5f7f02f7
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/cache_env_var.yml
@@ -0,0 +1,6 @@
+parameters:
+ env(REDIS_URL): redis://paas.com
+
+framework:
+ cache:
+ default_redis_provider: "%env(REDIS_URL)%"
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
index a933db5100fc8..00cd4b55a897f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
@@ -63,3 +63,17 @@ framework:
reopen:
from: closed
to: review
+ service_marking_store_workflow:
+ marking_store:
+ service: workflow_service
+ supports:
+ - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
+ places:
+ - first
+ - last
+ transitions:
+ go:
+ from:
+ - first
+ to:
+ - last
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index c1ee84685654f..26792c6b1c1d9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -20,7 +20,6 @@
use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -165,6 +164,12 @@ public function testWorkflows()
$this->assertSame(array('workflow.definition' => array(array('name' => 'pull_request', 'type' => 'state_machine', 'marking_store' => 'single_state'))), $stateMachineDefinition->getTags());
$this->assertCount(9, $stateMachineDefinition->getArgument(1));
$this->assertSame('start', $stateMachineDefinition->getArgument(2));
+
+ $serviceMarkingStoreWorkflowDefinition = $container->getDefinition('workflow.service_marking_store_workflow');
+ /** @var Reference $markingStoreRef */
+ $markingStoreRef = $serviceMarkingStoreWorkflowDefinition->getArgument(1);
+ $this->assertInstanceOf(Reference::class, $markingStoreRef);
+ $this->assertEquals('workflow_service', (string) $markingStoreRef);
}
/**
@@ -692,6 +697,34 @@ public function testPropertyInfoEnabled()
$this->assertTrue($container->has('property_info'));
}
+ public function testCacheDefaultRedisProvider()
+ {
+ $container = $this->createContainerFromFile('cache');
+
+ $redisUrl = 'redis://localhost';
+ $providerId = md5($redisUrl);
+
+ $this->assertTrue($container->hasDefinition($providerId));
+
+ $url = $container->getDefinition($providerId)->getArgument(0);
+
+ $this->assertSame($redisUrl, $url);
+ }
+
+ public function testCacheDefaultRedisProviderWithEnvVar()
+ {
+ $container = $this->createContainerFromFile('cache_env_var');
+
+ $redisUrl = 'redis://paas.com';
+ $providerId = md5($redisUrl);
+
+ $this->assertTrue($container->hasDefinition($providerId));
+
+ $url = $container->getDefinition($providerId)->getArgument(0);
+
+ $this->assertSame($redisUrl, $url);
+ }
+
public function testCachePoolServices()
{
$container = $this->createContainerFromFile('cache');
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php
new file mode 100644
index 0000000000000..a1ecee6d0b375
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php
@@ -0,0 +1,8 @@
+
-
-
+
+
other
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
index 603cbe8e22ef1..184acc72e0106 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
@@ -12,6 +12,7 @@
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
use Symfony\Component\Config\Resource\ClassExistenceResource;
+use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
@@ -64,13 +65,17 @@ public function process(ContainerBuilder $container)
$container->getDefinition('twig.extension.debug')->addTag('twig.extension');
}
+ $composerRootDir = $this->getComposerRootDir($container->getParameter('kernel.root_dir'));
+ $loader = $container->getDefinition('twig.loader.filesystem');
+ $loader->replaceArgument(2, $composerRootDir);
+
if (!$container->has('templating')) {
$loader = $container->getDefinition('twig.loader.native_filesystem');
- $loader->replaceArgument(1, $this->getComposerRootDir($container->getParameter('kernel.root_dir')));
+ $loader->replaceArgument(1, $composerRootDir);
$loader->addTag('twig.loader');
$loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());
- $container->setDefinition('twig.loader.filesystem', $loader);
+ $container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
}
if ($container->has('assets.packages')) {
diff --git a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php
index 53fe300e29a62..0a9ac7a3ca19a 100644
--- a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php
+++ b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php
@@ -29,12 +29,13 @@ class FilesystemLoader extends \Twig_Loader_Filesystem
/**
* Constructor.
*
- * @param FileLocatorInterface $locator A FileLocatorInterface instance
- * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
+ * @param FileLocatorInterface $locator A FileLocatorInterface instance
+ * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
+ * @param string|null $rootPath The root path common to all relative paths (null for getcwd())
*/
- public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser)
+ public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser, $rootPath = null)
{
- parent::__construct(array());
+ parent::__construct(array(), $rootPath);
$this->locator = $locator;
$this->parser = $parser;
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index c82cbafbeb953..29d2c4390a13b 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -46,12 +46,13 @@
-
+
+
@@ -87,7 +88,7 @@
-
+
%kernel.root_dir%
%kernel.charset%
@@ -117,7 +118,12 @@
-
+
+
+
+ twig.form.renderer
+
+
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig
index f405f6473e8f5..b017420dd5c70 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig
+++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/exception.html.twig
@@ -9,9 +9,7 @@
“
-
- {{ exception.message|nl2br|format_file_from_text }}
-
+
{{ exception.message|nl2br|format_file_from_text }}
{{ status_code }} {{ status_text }} - {{ exception.class|abbr_class }}
diff --git a/src/Symfony/Bundle/TwigBundle/TwigEngine.php b/src/Symfony/Bundle/TwigBundle/TwigEngine.php
index 5fa22cfcbae06..76daad58a3188 100644
--- a/src/Symfony/Bundle/TwigBundle/TwigEngine.php
+++ b/src/Symfony/Bundle/TwigBundle/TwigEngine.php
@@ -52,7 +52,13 @@ public function render($name, array $parameters = array())
if ($name instanceof TemplateReference) {
try {
// try to get the real name of the template where the error occurred
- $e->setTemplateName(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateName()))));
+ $name = $e->getTemplateName();
+ $path = (string) $this->locator->locate($this->parser->parse($name));
+ if (method_exists($e, 'setSourceContext')) {
+ $e->setSourceContext(new \Twig_Source('', $name, $path));
+ } else {
+ $e->setTemplateName($path);
+ }
} catch (\Exception $e2) {
}
}
diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json
index fbb5f9bf8afd5..ecb5ed5917a17 100644
--- a/src/Symfony/Bundle/TwigBundle/composer.json
+++ b/src/Symfony/Bundle/TwigBundle/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.5.9",
- "symfony/twig-bridge": "~3.2",
+ "symfony/twig-bridge": "^3.2.1",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0",
"twig/twig": "~1.28|~2.0"
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig
index 35ed14da04739..e88a33ab967e1 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig
@@ -9,7 +9,7 @@
padding-bottom: 2px;
}
.sf-reset .traces li {
- ccolor: #222;
+ color: #222;
font-size: 14px;
padding: 5px 0;
list-style-type: decimal;
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig
index 3b79db20a6a60..628e87dec1cb7 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig
@@ -457,7 +457,7 @@
{% import _self as tree %}
- {{ name|default('(no name)') }} ({{ profiler_dump(data.type_class) }})
+ {{ name|default('(no name)') }} {% if data.type_class is defined %}({{ profiler_dump(data.type_class) }}){% endif %}
{% if data.errors is defined and data.errors|length > 0 %}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
index 0be04e76117d8..f5ff17680a236 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig
@@ -183,8 +183,7 @@
{% for parameters in message.parameters %}
- {{ profiler_dump(parameters) }}
- {% if not loop.last %} {% endif %}
+ {{ profiler_dump(parameters, maxDepth=1) }}
{% endfor %}
{% endif %}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
index bfbbc8a102aa8..c31fb19d4459f 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
@@ -243,16 +243,29 @@
var oldFetch = window.fetch;
window.fetch = function () {
var promise = oldFetch.apply(this, arguments);
- if (!arguments[0].match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
+ var url = arguments[0];
+ var params = arguments[1];
+ var paramType = Object.prototype.toString.call(arguments[0]);
+ if (paramType === '[object Request]') {
+ url = arguments[0].url;
+ params = {
+ method: arguments[0].method,
+ credentials: arguments[0].credentials,
+ headers: arguments[0].headers,
+ mode: arguments[0].mode,
+ redirect: arguments[0].redirect
+ };
+ }
+ if (!url.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
var method = 'GET';
- if (arguments[1] && arguments[1].method !== undefined) {
- method = arguments[1].method;
+ if (params && params.method !== undefined) {
+ method = params.method;
}
var stackElement = {
loading: true,
error: false,
- url: arguments[0],
+ url: url,
method: method,
type: 'fetch',
start: new Date()
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig
index b037a260148c5..9a201aa189de9 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig
@@ -39,7 +39,7 @@
{%- else -%}
{{ redirect_route }}
{%- endif %}
- (
{{ redirect.token }} )
+ (
{{ redirect.token }} )
{%- endif %}
@@ -113,9 +113,11 @@