diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 3432439481..9cf36e6beb 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -70,9 +70,9 @@ Symfony is the result of the work of many people who made the code better
- Deni
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
+ - Jáchym Toušek (enumag)
- Titouan Galopin (tgalopin)
- Douglas Greenshields (shieldo)
- - Jáchym Toušek (enumag)
- Konstantin Myakshin (koc)
- Lee McDermott
- Brandon Turner
@@ -99,11 +99,12 @@ Symfony is the result of the work of many people who made the code better
- Baptiste Clavié (talus)
- Vladimir Reznichenko (kalessil)
- marc.weistroff
+ - Yonel Ceruto González (yonelceruto)
- lenar
- Włodzimierz Gajda (gajdaw)
- - Yonel Ceruto González (yonelceruto)
- Alexander Schwenn (xelaris)
- Jacob Dreesen (jdreesen)
+ - Tobias Nyholm (tobias)
- Florian Voutzinos (florianv)
- Colin Frei
- Adrien Brault (adrienbrault)
@@ -111,7 +112,6 @@ Symfony is the result of the work of many people who made the code better
- Peter Kokot (maastermedia)
- David Buchmann (dbu)
- excelwebzone
- - Tobias Nyholm (tobias)
- Tomáš Votruba (tomas_votruba)
- Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler)
@@ -133,12 +133,15 @@ Symfony is the result of the work of many people who made the code better
- Guilherme Blanco (guilhermeblanco)
- Pablo Godel (pgodel)
- Jérémie Augustin (jaugustin)
+ - Dany Maillard (maidmaid)
- Andréia Bohner (andreia)
- Rafael Dohms (rdohms)
- Arnaud Kleinpeter (nanocom)
- jwdeitch
+ - David Maicher (dmaicher)
- Mikael Pajunen
- Joel Wurtz (brouznouf)
+ - Grégoire Paris (greg0ire)
- Philipp Wahala (hifi)
- Vyacheslav Pavlov
- Richard van Laak (rvanlaak)
@@ -147,11 +150,9 @@ Symfony is the result of the work of many people who made the code better
- Thomas Rabaix (rande)
- Rouven Weßling (realityking)
- Teoh Han Hui (teohhanhui)
- - David Maicher (dmaicher)
- Jérôme Vasseur (jvasseur)
- Clemens Tolboom
- Helmer Aaviksoo
- - Grégoire Paris (greg0ire)
- Hiromi Hishida (77web)
- Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa)
@@ -236,7 +237,6 @@ Symfony is the result of the work of many people who made the code better
- Arjen Brouwer (arjenjb)
- Katsuhiro OGAWA
- Patrick McDougle (patrick-mcdougle)
- - Dany Maillard (maidmaid)
- Alif Rachmawadi
- Kristen Gilden (kgilden)
- Pierre-Yves LEBECQ (pylebecq)
@@ -622,6 +622,7 @@ Symfony is the result of the work of many people who made the code better
- develop
- ReenExe
- Mark Sonnabaum
+ - Maxime Veber (nek-)
- Richard Quadling
- jochenvdv
- Arturas Smorgun (asarturas)
@@ -644,6 +645,7 @@ Symfony is the result of the work of many people who made the code better
- Trent Steel (trsteel88)
- Yuen-Chi Lian
- Besnik Br
+ - Jose Gonzalez
- Dariusz Ruminski
- Joshua Nye
- Claudio Zizza
@@ -1083,7 +1085,6 @@ Symfony is the result of the work of many people who made the code better
- Max Summe
- WedgeSama
- Felds Liscia
- - Maxime Veber (nek-)
- Sullivan SENECHAL
- Tadcka
- Beth Binkovitz
@@ -1094,12 +1095,12 @@ Symfony is the result of the work of many people who made the code better
- Tomaz Ahlin
- Marcus Stöhr (dafish)
- Emmanuel Vella (emmanuel.vella)
+ - Adam Szaraniec (mimol)
- Carsten Nielsen (phreaknerd)
- Mathieu Rochette
- Jay Severson
- René Kerner
- Nathaniel Catchpole
- - Jose Gonzalez
- Adrien Samson (adriensamson)
- Samuel Gordalina (gordalina)
- Max Romanovsky (maxromanovsky)
@@ -1260,6 +1261,7 @@ Symfony is the result of the work of many people who made the code better
- Aarón Nieves Fernández
- Mike Meier
- Kirill Saksin
+ - Julien Pauli
- Koalabaerchen
- michalmarcinkowski
- Warwick
@@ -1307,6 +1309,7 @@ Symfony is the result of the work of many people who made the code better
- klemens
- dened
- Dmitry Korotovsky
+ - mcorteel
- Michael van Tricht
- Sam Ward
- Walther Lalk
@@ -1337,6 +1340,7 @@ Symfony is the result of the work of many people who made the code better
- Jan Marek (janmarek)
- Mark de Haan (markdehaan)
- Dan Patrick (mdpatrick)
+ - Pedro Magalhães (pmmaga)
- Rares Vlaseanu (raresvla)
- tante kinast (tante)
- Vincent LEFORT (vlefort)
@@ -1544,6 +1548,7 @@ Symfony is the result of the work of many people who made the code better
- Abdulkadir N. A.
- Yevgen Kovalienia
- Lebnik
+ - Shude
- Ondřej Führer
- Sema
- Elan Ruusamäe
diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md
index 46200360d4..90b2a84498 100644
--- a/UPGRADE-4.0.md
+++ b/UPGRADE-4.0.md
@@ -587,10 +587,6 @@ Validator
}
```
- * The default value of the strict option of the `Choice` Constraint has been
- changed to `true` as of 4.0. If you need the previous behaviour ensure to
- set the option to `false`.
-
* Setting the `checkDNS` option of the `Url` constraint to `true` is dropped
in favor of `Url::CHECK_DNS_TYPE_*` constants values.
diff --git a/composer.json b/composer.json
index 698c283d14..fa1c0e7a31 100644
--- a/composer.json
+++ b/composer.json
@@ -17,6 +17,7 @@
],
"require": {
"php": "^7.1.3",
+ "ext-xml": "*",
"doctrine/common": "~2.4",
"fig/link-util": "^1.0",
"twig/twig": "~1.34|~2.4",
diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
index 90b515ee32..0dad40cfa0 100644
--- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
@@ -72,6 +72,13 @@ class HttpFoundationExtension extends AbstractExtension
$port = ':'.$this->requestContext->getHttpsPort();
}
+ if ('#' === $path[0]) {
+ $queryString = $this->requestContext->getQueryString();
+ $path = $this->requestContext->getPathInfo().($queryString ? '?'.$queryString : '').$path;
+ } elseif ('?' === $path[0]) {
+ $path = $this->requestContext->getPathInfo().$path;
+ }
+
if ('/' !== $path[0]) {
$path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path;
}
@@ -82,6 +89,12 @@ class HttpFoundationExtension extends AbstractExtension
return $path;
}
+ if ('#' === $path[0]) {
+ $path = $request->getRequestUri().$path;
+ } elseif ('?' === $path[0]) {
+ $path = $request->getPathInfo().$path;
+ }
+
if (!$path || '/' !== $path[0]) {
$prefix = $request->getPathInfo();
$last = strlen($prefix) - 1;
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
index 8f0c66ad78..fcff0c0e1b 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php
@@ -42,6 +42,15 @@ class HttpFoundationExtensionTest extends TestCase
array('http://example.com/baz', 'http://example.com/baz', '/'),
array('https://example.com/baz', 'https://example.com/baz', '/'),
array('//example.com/baz', '//example.com/baz', '/'),
+
+ array('http://localhost/foo/bar?baz', '?baz', '/foo/bar'),
+ array('http://localhost/foo/bar?baz=1', '?baz=1', '/foo/bar?foo=1'),
+ array('http://localhost/foo/baz?baz=1', 'baz?baz=1', '/foo/bar?foo=1'),
+
+ array('http://localhost/foo/bar#baz', '#baz', '/foo/bar'),
+ array('http://localhost/foo/bar?0#baz', '#baz', '/foo/bar?0'),
+ array('http://localhost/foo/bar?baz=1#baz', '?baz=1#baz', '/foo/bar?foo=1'),
+ array('http://localhost/foo/baz?baz=1#baz', 'baz?baz=1#baz', '/foo/bar?foo=1'),
);
}
diff --git a/src/Symfony/Bundle/DebugBundle/composer.json b/src/Symfony/Bundle/DebugBundle/composer.json
index ccfe8d6788..c469f93518 100644
--- a/src/Symfony/Bundle/DebugBundle/composer.json
+++ b/src/Symfony/Bundle/DebugBundle/composer.json
@@ -17,6 +17,7 @@
],
"require": {
"php": "^7.1.3",
+ "ext-xml": "*",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/twig-bridge": "~3.4|~4.0",
"symfony/var-dumper": "~3.4|~4.0"
diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
index caa5a2228b..cd4312f923 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
@@ -108,7 +108,8 @@ CHANGELOG
* Deprecated using core form types without dependencies as services
* Added `Symfony\Component\HttpHernel\DataCollector\RequestDataCollector::onKernelResponse()`
* Added `Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector`
- * Deprecated service `serializer.mapping.cache.apc` (use `serializer.mapping.cache.doctrine.apc` instead)
+ * The `framework.serializer.cache` option and the service `serializer.mapping.cache.apc` have been
+ deprecated. APCu should now be automatically used when available.
3.0.0
-----
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
index e4a86dc6ef..967c6133f4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
@@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -72,7 +73,7 @@ class CachePoolPass implements CompilerPassInterface
}
$i = 0;
foreach ($attributes as $attr) {
- if (isset($tags[0][$attr])) {
+ if (isset($tags[0][$attr]) && ('namespace' !== $attr || ArrayAdapter::class !== $adapter->getClass())) {
$pool->replaceArgument($i++, $tags[0][$attr]);
}
unset($tags[0][$attr]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php b/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
index b083bb7ba8..6072061dba 100644
--- a/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
+++ b/src/Symfony/Bundle/FrameworkBundle/EventListener/ResolveControllerNameSubscriber.php
@@ -33,7 +33,7 @@ class ResolveControllerNameSubscriber implements EventSubscriberInterface
public function onKernelRequest(GetResponseEvent $event)
{
$controller = $event->getRequest()->attributes->get('_controller');
- if ($controller && false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
+ if (is_string($controller) && false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
// controller in the a:b:c notation then
$event->getRequest()->attributes->set('_controller', $this->parser->parse($controller));
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
index 713cd4eaca..4619301b6e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php
@@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
@@ -49,6 +50,24 @@ class CachePoolPassTest extends TestCase
$this->assertSame('D07rhFx97S', $cachePool->getArgument(0));
}
+ public function testNamespaceArgumentIsNotReplacedIfArrayAdapterIsUsed()
+ {
+ $container = new ContainerBuilder();
+ $container->setParameter('kernel.environment', 'prod');
+ $container->setParameter('kernel.name', 'app');
+ $container->setParameter('kernel.root_dir', 'foo');
+
+ $container->register('cache.adapter.array', ArrayAdapter::class)->addArgument(0);
+
+ $cachePool = new ChildDefinition('cache.adapter.array');
+ $cachePool->addTag('cache.pool');
+ $container->setDefinition('app.cache_pool', $cachePool);
+
+ $this->cachePoolPass->process($container);
+
+ $this->assertCount(0, $container->getDefinition('app.cache_pool')->getArguments());
+ }
+
public function testArgsAreReplaced()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/ResolveControllerNameSubscriberTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/ResolveControllerNameSubscriberTest.php
index e5cc6d28a4..338c1ec81a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/ResolveControllerNameSubscriberTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/EventListener/ResolveControllerNameSubscriberTest.php
@@ -37,7 +37,10 @@ class ResolveControllerNameSubscriberTest extends TestCase
$this->assertEquals('App\\Final\\Format::methodName', $request->attributes->get('_controller'));
}
- public function testSkipsOtherControllerFormats()
+ /**
+ * @dataProvider provideSkippedControllers
+ */
+ public function testSkipsOtherControllerFormats($controller)
{
$parser = $this->getMockBuilder(ControllerNameParser::class)->disableOriginalConstructor()->getMock();
$parser->expects($this->never())
@@ -45,10 +48,16 @@ class ResolveControllerNameSubscriberTest extends TestCase
$httpKernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = new Request();
- $request->attributes->set('_controller', 'Other:format');
+ $request->attributes->set('_controller', $controller);
$subscriber = new ResolveControllerNameSubscriber($parser);
$subscriber->onKernelRequest(new GetResponseEvent($httpKernel, $request, HttpKernelInterface::MASTER_REQUEST));
- $this->assertEquals('Other:format', $request->attributes->get('_controller'));
+ $this->assertEquals($controller, $request->attributes->get('_controller'));
+ }
+
+ public function provideSkippedControllers()
+ {
+ yield array('Other:format');
+ yield array(function () {});
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php
index fb5395ea6d..438ca2538d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php
@@ -33,7 +33,7 @@ class RedirectableUrlMatcherTest extends TestCase
'scheme' => null,
'httpPort' => $context->getHttpPort(),
'httpsPort' => $context->getHttpsPort(),
- '_route' => null,
+ '_route' => 'foo',
),
$matcher->match('/foo')
);
diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json
index 8dc6271b0c..a0ac75fd80 100644
--- a/src/Symfony/Bundle/SecurityBundle/composer.json
+++ b/src/Symfony/Bundle/SecurityBundle/composer.json
@@ -17,6 +17,7 @@
],
"require": {
"php": "^7.1.3",
+ "ext-xml": "*",
"symfony/security": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0"
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd
index 3314091a08..61b57798b2 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd
@@ -9,6 +9,8 @@
+
+
@@ -26,6 +28,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php
new file mode 100644
index 0000000000..630a9a9edc
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php
@@ -0,0 +1,14 @@
+loadFromExtension('twig', array(
+ 'date' => array(
+ 'format' => 'Y-m-d',
+ 'interval_format' => '%d',
+ 'timezone' => 'Europe/Berlin',
+ ),
+ 'number_format' => array(
+ 'decimals' => 2,
+ 'decimal_point' => ',',
+ 'thousands_separator' => '.',
+ ),
+));
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml
new file mode 100644
index 0000000000..1ab39e4922
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml
new file mode 100644
index 0000000000..290921630f
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml
@@ -0,0 +1,9 @@
+twig:
+ date:
+ format: Y-m-d
+ interval_format: '%d'
+ timezone: Europe/Berlin
+ number_format:
+ decimals: 2
+ decimal_point: ','
+ thousands_separator: .
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
index 2de7fd10a4..e38bf53906 100644
--- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
@@ -116,6 +116,26 @@ class TwigExtensionTest extends TestCase
$this->assertEquals('name', $options['autoescape']);
}
+ /**
+ * @dataProvider getFormats
+ */
+ public function testLoadCustomDateFormats($fileFormat)
+ {
+ $container = $this->createContainer();
+ $container->registerExtension(new TwigExtension());
+ $this->loadFromFile($container, 'formats', $fileFormat);
+ $this->compileContainer($container);
+
+ $environmentConfigurator = $container->getDefinition('twig.configurator.environment');
+
+ $this->assertSame('Y-m-d', $environmentConfigurator->getArgument(0));
+ $this->assertSame('%d', $environmentConfigurator->getArgument(1));
+ $this->assertSame('Europe/Berlin', $environmentConfigurator->getArgument(2));
+ $this->assertSame(2, $environmentConfigurator->getArgument(3));
+ $this->assertSame(',', $environmentConfigurator->getArgument(4));
+ $this->assertSame('.', $environmentConfigurator->getArgument(5));
+ }
+
public function testGlobalsWithDifferentTypesAndValues()
{
$globals = array(
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
index 37f47df6a6..7ebd04b574 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
+++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php
@@ -128,34 +128,6 @@ class ProfilerController
)), 200, array('Content-Type' => 'text/html'));
}
- /**
- * Displays information page.
- *
- * @param Request $request The current HTTP Request
- * @param string $about The about message
- *
- * @return Response A Response instance
- *
- * @throws NotFoundHttpException
- */
- public function infoAction(Request $request, $about)
- {
- if (null === $this->profiler) {
- throw new NotFoundHttpException('The profiler must be enabled.');
- }
-
- $this->profiler->disable();
-
- if (null !== $this->cspHandler) {
- $this->cspHandler->disableCsp();
- }
-
- return new Response($this->twig->render('@WebProfiler/Profiler/info.html.twig', array(
- 'about' => $about,
- 'request' => $request,
- )), 200, array('Content-Type' => 'text/html'));
- }
-
/**
* Renders the Web Debug Toolbar.
*
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml
index 1a4bd39c62..0be717b19d 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/routing/profiler.xml
@@ -16,10 +16,6 @@
web_profiler.controller.profiler:searchBarAction
-
- web_profiler.controller.profiler:infoAction
-
-
web_profiler.controller.profiler:phpinfoAction
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig
index ef381fe4a7..0227532e12 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/info.html.twig
@@ -1,25 +1,10 @@
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
{% set messages = {
- 'purge' : {
- status: 'success',
- title: 'The profiler database was purged successfully',
- message: 'Now you need to browse some pages with the Symfony Profiler enabled to collect data.'
- },
'no_token' : {
status: 'error',
title: (token|default('') == 'latest') ? 'There are no profiles' : 'Token not found',
message: (token|default('') == 'latest') ? 'No profiles found in the database.' : 'Token "' ~ token|default('') ~ '" was not found in the database.'
- },
- 'upload_error' : {
- status: 'error',
- title: 'A problem occurred when uploading the data',
- message: 'No file given or the file was not uploaded successfully.'
- },
- 'already_exists' : {
- status: 'error',
- title: 'A problem occurred when uploading the data',
- message: 'The token already exists in the database.'
}
} %}
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 d3a8e7bc2e..ad87620e3e 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig
@@ -570,3 +570,10 @@
padding: 5px 0;
margin-right: 10px;
}
+
+/***** Media query print: Do not print the Toolbar. *****/
+@media print {
+ .sf-toolbar {
+ display: none;
+ }
+}
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
index 7ebc36f0a5..6cad6135cf 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache\Tests\Adapter;
+use Psr\Log\NullLogger;
use Symfony\Component\Cache\Adapter\ApcuAdapter;
class ApcuAdapterTest extends AdapterTestCase
@@ -23,9 +24,14 @@ class ApcuAdapterTest extends AdapterTestCase
public function createCachePool($defaultLifetime = 0)
{
- if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) {
+ if (!function_exists('apcu_fetch') || !ini_get('apc.enabled')) {
$this->markTestSkipped('APCu extension is required.');
}
+ if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) {
+ if ('testWithCliSapi' !== $this->getName()) {
+ $this->markTestSkipped('APCu extension is required.');
+ }
+ }
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Fails transiently on Windows.');
}
@@ -70,4 +76,24 @@ class ApcuAdapterTest extends AdapterTestCase
$this->assertFalse($item->isHit());
$this->assertNull($item->get());
}
+
+ public function testWithCliSapi()
+ {
+ try {
+ // disable PHPUnit error handler to mimic a production environment
+ $isCalled = false;
+ set_error_handler(function () use (&$isCalled) {
+ $isCalled = true;
+ });
+ $pool = new ApcuAdapter(str_replace('\\', '.', __CLASS__));
+ $pool->setLogger(new NullLogger());
+
+ $item = $pool->getItem('foo');
+ $item->isHit();
+ $pool->save($item->set('bar'));
+ $this->assertFalse($isCalled);
+ } finally {
+ restore_error_handler();
+ }
+ }
}
diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php
index 9984418fa6..f5051cdc6a 100644
--- a/src/Symfony/Component/Dotenv/Dotenv.php
+++ b/src/Symfony/Component/Dotenv/Dotenv.php
@@ -352,7 +352,7 @@ final class Dotenv
}
$name = $matches[3];
- $value = isset($this->values[$name]) ? $this->values[$name] : (isset($_ENV[$name]) ? isset($_ENV[$name]) : (string) getenv($name));
+ $value = isset($this->values[$name]) ? $this->values[$name] : (isset($_ENV[$name]) ? $_ENV[$name] : (string) getenv($name));
if (!$matches[2] && isset($matches[4])) {
$value .= '}';
diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
index a7f211ecd6..47598030a8 100644
--- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
+++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php
@@ -63,6 +63,7 @@ class DotenvTest extends TestCase
public function getEnvData()
{
putenv('LOCAL=local');
+ $_ENV['REMOTE'] = 'remote';
$tests = array(
// spaces
@@ -134,6 +135,7 @@ class DotenvTest extends TestCase
array('FOO=" \\$ "', array('FOO' => ' $ ')),
array('FOO=" $ "', array('FOO' => ' $ ')),
array('BAR=$LOCAL', array('BAR' => 'local')),
+ array('BAR=$REMOTE', array('BAR' => 'remote')),
array('FOO=$NOTDEFINED', array('FOO' => '')),
);
diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php
index 23b35ef8ce..7cf6e5f82e 100644
--- a/src/Symfony/Component/Filesystem/Filesystem.php
+++ b/src/Symfony/Component/Filesystem/Filesystem.php
@@ -37,7 +37,8 @@ class Filesystem
*/
public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
{
- if (stream_is_local($originFile) && !is_file($originFile)) {
+ $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
+ if ($originIsLocal && !is_file($originFile)) {
throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
}
@@ -68,11 +69,13 @@ class Filesystem
throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
}
- // Like `cp`, preserve executable permission bits
- @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
+ if ($originIsLocal) {
+ // Like `cp`, preserve executable permission bits
+ @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
- if (stream_is_local($originFile) && $bytesCopied !== ($bytesOrigin = filesize($originFile))) {
- throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
+ if ($bytesCopied !== $bytesOrigin = filesize($originFile)) {
+ throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
+ }
}
}
}
diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md
index d68060de3a..3fe6602c43 100644
--- a/src/Symfony/Component/Routing/CHANGELOG.md
+++ b/src/Symfony/Component/Routing/CHANGELOG.md
@@ -11,6 +11,7 @@ CHANGELOG
-----
* Added support for prioritized routing loaders.
+ * Add matched and default parameters to redirect responses
3.3.0
-----
diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
index 8eae68c4c2..cfe8459f4a 100644
--- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
+++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -333,10 +333,35 @@ EOF;
}
}
+ // the offset where the return value is appended below, with indendation
+ $retOffset = 12 + strlen($code);
+
+ // optimize parameters array
+ if ($matches || $hostMatches) {
+ $vars = array();
+ if ($hostMatches) {
+ $vars[] = '$hostMatches';
+ }
+ if ($matches) {
+ $vars[] = '$matches';
+ }
+ $vars[] = "array('_route' => '$name')";
+
+ $code .= sprintf(
+ " \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n",
+ implode(', ', $vars),
+ str_replace("\n", '', var_export($route->getDefaults(), true))
+ );
+ } elseif ($route->getDefaults()) {
+ $code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
+ } else {
+ $code .= sprintf(" \$ret = array('_route' => '%s');\n", $name);
+ }
+
if ($hasTrailingSlash) {
$code .= <<redirect(\$pathinfo.'/', '$name');
+ return array_replace(\$ret, \$this->redirect(\$pathinfo.'/', '$name'));
}
@@ -351,33 +376,17 @@ EOF;
$code .= <<redirect(\$pathinfo, '$name', key(\$requiredSchemes));
+ return array_replace(\$ret, \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes)));
}
EOF;
}
- // optimize parameters array
- if ($matches || $hostMatches) {
- $vars = array();
- if ($hostMatches) {
- $vars[] = '$hostMatches';
- }
- if ($matches) {
- $vars[] = '$matches';
- }
- $vars[] = "array('_route' => '$name')";
-
- $code .= sprintf(
- " return \$this->mergeDefaults(array_replace(%s), %s);\n",
- implode(', ', $vars),
- str_replace("\n", '', var_export($route->getDefaults(), true))
- );
- } elseif ($route->getDefaults()) {
- $code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
+ if ($hasTrailingSlash || $schemes) {
+ $code .= " return \$ret;\n";
} else {
- $code .= sprintf(" return array('_route' => '%s');\n", $name);
+ $code = substr_replace($code, 'return', $retOffset, 6);
}
$code .= " }\n";
diff --git a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
index 900c59fa37..3770a9c24c 100644
--- a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
+++ b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php
@@ -32,9 +32,9 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
}
try {
- parent::match($pathinfo.'/');
+ $parameters = parent::match($pathinfo.'/');
- return $this->redirect($pathinfo.'/', null);
+ return array_replace($parameters, $this->redirect($pathinfo.'/', isset($parameters['_route']) ? $parameters['_route'] : null));
} catch (ResourceNotFoundException $e2) {
throw $e;
}
diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
index c646723b3a..df80226cc4 100644
--- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
+++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php
@@ -163,15 +163,11 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
- if (self::ROUTE_MATCH === $status[0]) {
- return $status[1];
- }
-
if (self::REQUIREMENT_MISMATCH === $status[0]) {
continue;
}
- return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
+ return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array()));
}
}
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php
index 91ec47899e..efab3dba7e 100644
--- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php
@@ -87,22 +87,24 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// baz3
if ('/test/baz3' === $trimmedPathinfo) {
+ $ret = array('_route' => 'baz3');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'baz3');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'baz3'));
}
- return array('_route' => 'baz3');
+ return $ret;
}
}
// baz4
if (preg_match('#^/test/(?P[^/]++)/?$#s', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'baz4');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'baz4'));
}
- return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
+ return $ret;
}
// baz5
@@ -181,11 +183,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// hey
if ('/multi/hey' === $trimmedPathinfo) {
+ $ret = array('_route' => 'hey');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'hey');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'hey'));
}
- return array('_route' => 'hey');
+ return $ret;
}
// overridden2
@@ -326,22 +329,24 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
// secure
if ('/secure' === $pathinfo) {
+ $ret = array('_route' => 'secure');
$requiredSchemes = array ( 'https' => 0,);
if (!isset($requiredSchemes[$scheme])) {
- return $this->redirect($pathinfo, 'secure', key($requiredSchemes));
+ return array_replace($ret, $this->redirect($pathinfo, 'secure', key($requiredSchemes)));
}
- return array('_route' => 'secure');
+ return $ret;
}
// nonsecure
if ('/nonsecure' === $pathinfo) {
+ $ret = array('_route' => 'nonsecure');
$requiredSchemes = array ( 'http' => 0,);
if (!isset($requiredSchemes[$scheme])) {
- return $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes));
+ return array_replace($ret, $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes)));
}
- return array('_route' => 'nonsecure');
+ return $ret;
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php
index 1e6824b341..42258149f5 100644
--- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php
@@ -61,29 +61,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a')) {
// a_fourth
if ('/a/44' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fourth');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'a_fourth');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fourth'));
}
- return array('_route' => 'a_fourth');
+ return $ret;
}
// a_fifth
if ('/a/55' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_fifth');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'a_fifth');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fifth'));
}
- return array('_route' => 'a_fifth');
+ return $ret;
}
// a_sixth
if ('/a/66' === $trimmedPathinfo) {
+ $ret = array('_route' => 'a_sixth');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'a_sixth');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'a_sixth'));
}
- return array('_route' => 'a_sixth');
+ return $ret;
}
}
@@ -96,29 +99,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/nested/group')) {
// nested_a
if ('/nested/group/a' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_a');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'nested_a');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_a'));
}
- return array('_route' => 'nested_a');
+ return $ret;
}
// nested_b
if ('/nested/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_b');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'nested_b');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_b'));
}
- return array('_route' => 'nested_b');
+ return $ret;
}
// nested_c
if ('/nested/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'nested_c');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'nested_c');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_c'));
}
- return array('_route' => 'nested_c');
+ return $ret;
}
}
@@ -126,29 +132,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/slashed/group')) {
// slashed_a
if ('/slashed/group' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_a');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'slashed_a');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_a'));
}
- return array('_route' => 'slashed_a');
+ return $ret;
}
// slashed_b
if ('/slashed/group/b' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_b');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'slashed_b');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_b'));
}
- return array('_route' => 'slashed_b');
+ return $ret;
}
// slashed_c
if ('/slashed/group/c' === $trimmedPathinfo) {
+ $ret = array('_route' => 'slashed_c');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'slashed_c');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_c'));
}
- return array('_route' => 'slashed_c');
+ return $ret;
}
}
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php
index 876a90f2da..4548bcf52d 100644
--- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php
@@ -38,11 +38,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/trailing/simple')) {
// simple_trailing_slash_no_methods
if ('/trailing/simple/no-methods' === $trimmedPathinfo) {
+ $ret = array('_route' => 'simple_trailing_slash_no_methods');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods'));
}
- return array('_route' => 'simple_trailing_slash_no_methods');
+ return $ret;
}
// simple_trailing_slash_GET_method
@@ -52,11 +53,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
goto not_simple_trailing_slash_GET_method;
}
+ $ret = array('_route' => 'simple_trailing_slash_GET_method');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method'));
}
- return array('_route' => 'simple_trailing_slash_GET_method');
+ return $ret;
}
not_simple_trailing_slash_GET_method:
@@ -67,11 +69,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
goto not_simple_trailing_slash_HEAD_method;
}
+ $ret = array('_route' => 'simple_trailing_slash_HEAD_method');
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method'));
}
- return array('_route' => 'simple_trailing_slash_HEAD_method');
+ return $ret;
}
not_simple_trailing_slash_HEAD_method:
@@ -91,11 +94,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
// regex_trailing_slash_no_methods
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P[^/]++)/?$#s', $pathinfo, $matches)) {
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods'));
}
- return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
+ return $ret;
}
// regex_trailing_slash_GET_method
@@ -105,11 +109,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
goto not_regex_trailing_slash_GET_method;
}
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method'));
}
- return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
+ return $ret;
}
not_regex_trailing_slash_GET_method:
@@ -120,11 +125,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
goto not_regex_trailing_slash_HEAD_method;
}
+ $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
if (substr($pathinfo, -1) !== '/') {
- return $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method');
+ return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method'));
}
- return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
+ return $ret;
}
not_regex_trailing_slash_HEAD_method:
diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php
index ba4c6e972f..ddd2133e96 100644
--- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php
+++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php
@@ -24,7 +24,7 @@ class RedirectableUrlMatcherTest extends TestCase
$coll->add('foo', new Route('/foo/'));
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
- $matcher->expects($this->once())->method('redirect');
+ $matcher->expects($this->once())->method('redirect')->will($this->returnValue(array()));
$matcher->match('/foo');
}
@@ -65,8 +65,37 @@ class RedirectableUrlMatcherTest extends TestCase
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
$matcher
->expects($this->never())
- ->method('redirect')
- ;
+ ->method('redirect');
$matcher->match('/foo');
}
+
+ public function testSchemeRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https')));
+
+ $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz', 'foo', 'https')
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
+
+ public function testSlashRedirectWithParams()
+ {
+ $coll = new RouteCollection();
+ $coll->add('foo', new Route('/foo/{bar}/'));
+
+ $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
+ $matcher
+ ->expects($this->once())
+ ->method('redirect')
+ ->with('/foo/baz/', 'foo', null)
+ ->will($this->returnValue(array('redirect' => 'value')))
+ ;
+ $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz'));
+ }
}
diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
index 4e4b99245d..25f5fffdc2 100644
--- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
@@ -13,7 +13,6 @@ namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
@@ -54,8 +53,6 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
/**
* {@inheritdoc}
- *
- * @throws CircularReferenceException
*/
public function normalize($object, $format = null, array $context = array())
{
diff --git a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
index 817fe5111a..4f79f4f50e 100644
--- a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
@@ -33,8 +33,6 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer
/**
* {@inheritdoc}
- *
- * @throws UnexpectedValueException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
diff --git a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php
index 988a491b7c..9e5af130d0 100644
--- a/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/DataUriNormalizer.php
@@ -79,9 +79,6 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
* Regex adapted from Brian Grinstead code.
*
* @see https://gist.github.com/bgrins/6194623
- *
- * @throws InvalidArgumentException
- * @throws UnexpectedValueException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
index 23df4829a8..2b3b206287 100644
--- a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
@@ -11,6 +11,13 @@
namespace Symfony\Component\Serializer\Normalizer;
+use Symfony\Component\Serializer\Exception\BadMethodCallException;
+use Symfony\Component\Serializer\Exception\ExtraAttributesException;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
+use Symfony\Component\Serializer\Exception\LogicException;
+use Symfony\Component\Serializer\Exception\RuntimeException;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
+
/**
* Defines the interface of denormalizers.
*
@@ -27,6 +34,13 @@ interface DenormalizerInterface
* @param array $context options available to the denormalizer
*
* @return object
+ *
+ * @throws BadMethodCallException Occurs when the normalizer is not called in an expected context
+ * @throws InvalidArgumentException Occurs when the arguments are not coherent or not supported
+ * @throws UnexpectedValueException Occurs when the item cannot be hydrated with the given data
+ * @throws ExtraAttributesException Occurs when the item doesn't have attribute to receive given data
+ * @throws LogicException Occurs when the normalizer is not supposed to denormalize
+ * @throws RuntimeException Occurs if the class cannot be instantiated
*/
public function denormalize($data, $class, $format = null, array $context = array());
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
index f7007840da..2779053f74 100644
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
@@ -11,6 +11,10 @@
namespace Symfony\Component\Serializer\Normalizer;
+use Symfony\Component\Serializer\Exception\CircularReferenceException;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
+use Symfony\Component\Serializer\Exception\LogicException;
+
/**
* Defines the interface of normalizers.
*
@@ -26,6 +30,11 @@ interface NormalizerInterface
* @param array $context Context options for the normalizer
*
* @return array|scalar
+ *
+ * @throws InvalidArgumentException Occurs when the object given is not an attempted type for the normalizer
+ * @throws CircularReferenceException Occurs when the normalizer detects a circular reference when no circular
+ * reference handler can fix it
+ * @throws LogicException Occurs when the normalizer is not called in an expected context
*/
public function normalize($object, $format = null, array $context = array());