diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
index 952ef3aec1..8f790fdd19 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
@@ -114,6 +114,20 @@
{%- endblock percent_widget %}
+{% block file_widget -%}
+
+ <{{ element|default('div') }} class="custom-file">
+ {%- set type = type|default('file') -%}
+ {{- block('form_widget_simple') -}}
+
+ {{ element|default('div') }}>
+
+{% endblock %}
+
{% block form_widget_simple -%}
{% if type is not defined or type != 'hidden' %}
{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? ' custom-file-input' : ' form-control'))|trim}) -%}
@@ -186,8 +200,6 @@
{%- if compound is defined and compound -%}
{%- set element = 'legend' -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
- {% elseif type is defined and type == 'file' %}
- {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%}
{%- else -%}
{%- set label_attr = label_attr|merge({for: id}) -%}
{%- endif -%}
@@ -269,15 +281,6 @@
{{ element|default('div') }}>
{%- endblock form_row %}
-{% block file_row -%}
-
- <{{ element|default('div') }} class="custom-file">
- {{- form_widget(form) -}}
- {{- form_label(form) -}}
- {{ element|default('div') }}>
-
-{% endblock %}
-
{# Errors #}
{% block form_errors -%}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 8590873439..c25aa2b4b5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -268,7 +268,7 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertInstanceOf(Reference::class, $markingStoreRef);
$this->assertEquals('workflow_service', (string) $markingStoreRef);
- $this->assertTrue($container->hasDefinition('workflow.registry', 'Workflow registry is registered as a service'));
+ $this->assertTrue($container->hasDefinition('workflow.registry'), 'Workflow registry is registered as a service');
$registryDefinition = $container->getDefinition('workflow.registry');
$this->assertGreaterThan(0, count($registryDefinition->getMethodCalls()));
}
@@ -313,8 +313,8 @@ abstract class FrameworkExtensionTest extends TestCase
{
$container = $this->createContainerFromFile('workflow_with_multiple_transitions_with_same_name');
- $this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service'));
- $this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service'));
+ $this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service');
+ $this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service');
$workflowDefinition = $container->getDefinition('workflow.article.definition');
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 ebce1aad4c..33ca8b4fb2 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig
@@ -292,6 +292,7 @@ div.sf-toolbar .sf-toolbar-block a:hover {
border-width: 0;
position: relative;
top: 8px;
+ vertical-align: baseline;
}
.sf-toolbar-block .sf-toolbar-icon img + span,
diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php
index edeabdbf25..14276ba317 100644
--- a/src/Symfony/Component/Console/Input/ArgvInput.php
+++ b/src/Symfony/Component/Console/Input/ArgvInput.php
@@ -301,7 +301,7 @@ class ArgvInput extends Input
while (0 < count($tokens)) {
$token = array_shift($tokens);
if ($onlyParams && '--' === $token) {
- return false;
+ return $default;
}
foreach ($values as $value) {
diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php
index 4d9797ba1a..595a8a0e8c 100644
--- a/src/Symfony/Component/Console/Input/ArrayInput.php
+++ b/src/Symfony/Component/Console/Input/ArrayInput.php
@@ -81,7 +81,7 @@ class ArrayInput extends Input
foreach ($this->parameters as $k => $v) {
if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) {
- return false;
+ return $default;
}
if (is_int($k)) {
diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
index 61d1723e08..4cd7ab478f 100644
--- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
+++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
@@ -395,25 +395,26 @@ class ArgvInputTest extends TestCase
/**
* @dataProvider provideGetParameterOptionValues
*/
- public function testGetParameterOptionEqualSign($argv, $key, $onlyParams, $expected)
+ public function testGetParameterOptionEqualSign($argv, $key, $default, $onlyParams, $expected)
{
$input = new ArgvInput($argv);
- $this->assertEquals($expected, $input->getParameterOption($key, false, $onlyParams), '->getParameterOption() returns the expected value');
+ $this->assertEquals($expected, $input->getParameterOption($key, $default, $onlyParams), '->getParameterOption() returns the expected value');
}
public function provideGetParameterOptionValues()
{
return array(
- array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', false, 'dev'),
- array(array('app/console', 'foo:bar', '--env=dev'), '--env', false, 'dev'),
- array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), false, 'dev'),
- array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), false, 'dev'),
- array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), false, '1'),
- array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), false, '1'),
- array(array('app/console', 'foo:bar', '--env', 'val'), '--env', false, 'val'),
- array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', false, 'val'),
- array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev'),
- array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', true, false),
+ array(array('app/console', 'foo:bar'), '-e', 'default', false, 'default'),
+ array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'default', false, 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'default', false, 'dev'),
+ array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'default', false, 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'default', false, 'dev'),
+ array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), 'default', false, '1'),
+ array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), 'default', false, '1'),
+ array(array('app/console', 'foo:bar', '--env', 'val'), '--env', 'default', false, 'val'),
+ array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', 'default', false, 'val'),
+ array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', false, 'dev'),
+ array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', true, 'default'),
);
}
diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
index 6b443e0b2a..34b67ac7f5 100644
--- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
+++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
@@ -47,14 +47,14 @@ class ArrayInputTest extends TestCase
{
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
- $this->assertFalse($input->getParameterOption('--bar'), '->getParameterOption() returns the default if an option is not present in the passed parameters');
+ $this->assertEquals('default', $input->getParameterOption('--bar', 'default'), '->getParameterOption() returns the default value if an option is not present in the passed parameters');
$input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
$input = new ArrayInput(array('--foo', '--', '--bar' => 'woop'));
$this->assertEquals('woop', $input->getParameterOption('--bar'), '->getParameterOption() returns the correct value if an option is present in the passed parameters');
- $this->assertFalse($input->getParameterOption('--bar', false, true), '->getParameterOption() returns false if an option is present in the passed parameters after an end of options signal');
+ $this->assertEquals('default', $input->getParameterOption('--bar', 'default', true), '->getParameterOption() returns the default value if an option is present in the passed parameters after an end of options signal');
}
public function testParseArguments()
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 3aa0e55af1..dad23cf3bb 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -608,10 +608,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* the parameters passed to the container constructor to have precedence
* over the loaded ones.
*
- * $container = new ContainerBuilder(array('foo' => 'bar'));
+ * $container = new ContainerBuilder(new ParameterBag(array('foo' => 'bar')));
* $loader = new LoaderXXX($container);
* $loader->load('resource_name');
- * $container->register('foo', new stdClass());
+ * $container->register('foo', 'stdClass');
*
* In the above example, even if the loaded resource defines a foo
* parameter, the value will still be 'bar' as defined in the ContainerBuilder
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
index 9a6e9f6dcd..af92cf92d6 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
@@ -237,6 +237,18 @@ class ValidateEnvPlaceholdersPassTest extends TestCase
$this->addToAssertionCount(1);
}
+ public function testEmptyConfigFromMoreThanOneSource()
+ {
+ $container = new ContainerBuilder();
+ $container->registerExtension(new EnvExtension(new ConfigurationWithArrayNodeRequiringOneElement()));
+ $container->loadFromExtension('env_extension', array());
+ $container->loadFromExtension('env_extension', array());
+
+ $this->doProcess($container);
+
+ $this->addToAssertionCount(1);
+ }
+
public function testDiscardedEnvInConfig(): void
{
$container = new ContainerBuilder();
@@ -315,6 +327,24 @@ class EnvConfigurationWithoutRootNode implements ConfigurationInterface
}
}
+class ConfigurationWithArrayNodeRequiringOneElement implements ConfigurationInterface
+{
+ public function getConfigTreeBuilder()
+ {
+ $treeBuilder = new TreeBuilder();
+ $treeBuilder->root('env_extension')
+ ->children()
+ ->arrayNode('nodes')
+ ->isRequired()
+ ->requiresAtLeastOneElement()
+ ->scalarPrototype()->end()
+ ->end()
+ ->end();
+
+ return $treeBuilder;
+ }
+}
+
class EnvExtension extends Extension
{
private $configuration;
@@ -337,6 +367,10 @@ class EnvExtension extends Extension
public function load(array $configs, ContainerBuilder $container)
{
+ if (!array_filter($configs)) {
+ return;
+ }
+
try {
$this->config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs);
} catch (TreeWithoutRootNodeException $e) {
diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
index 3b6e7cc393..8d851623fb 100644
--- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
+++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
@@ -217,6 +217,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
public function reset()
{
$this->called = array();
+ $this->orphanedEvents = array();
}
/**
diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
index 2521f741ea..ab3b33e377 100644
--- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
+++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
@@ -271,6 +271,17 @@ class TraceableEventDispatcherTest extends TestCase
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
}
+
+ public function testClearOrphanedEvents()
+ {
+ $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
+ $tdispatcher->dispatch('foo');
+ $events = $tdispatcher->getOrphanedEvents();
+ $this->assertCount(1, $events);
+ $tdispatcher->reset();
+ $events = $tdispatcher->getOrphanedEvents();
+ $this->assertCount(0, $events);
+ }
}
class EventSubscriber implements EventSubscriberInterface
diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php
index 9e7a9b579e..06bc48f303 100644
--- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php
+++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Extension\DataCollector;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Validator\ConstraintViolationInterface;
+use Symfony\Component\VarDumper\Caster\CutStub;
/**
* Default implementation of {@link FormDataExtractorInterface}.
@@ -144,6 +145,10 @@ class FormDataExtractor implements FormDataExtractorInterface
);
foreach ($view->vars as $varName => $value) {
+ // Removing redundant variable from view variables
+ if ('form' === $varName) {
+ $value = new CutStub($value);
+ }
$data['view_vars'][$varName] = $value;
}
diff --git a/src/Symfony/Component/Form/FormConfigBuilder.php b/src/Symfony/Component/Form/FormConfigBuilder.php
index 7ac98b1cf2..e3660e19ad 100644
--- a/src/Symfony/Component/Form/FormConfigBuilder.php
+++ b/src/Symfony/Component/Form/FormConfigBuilder.php
@@ -138,7 +138,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
private $data;
/**
- * @var string
+ * @var string|null
*/
private $dataClass;
@@ -181,7 +181,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
* Creates an empty form configuration.
*
* @param string|int $name The form name
- * @param string $dataClass The class of the form's data
+ * @param string|null $dataClass The class of the form's data
* @param EventDispatcherInterface $dispatcher The event dispatcher
* @param array $options The form options
*
diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
index 28b3111c4a..283757080b 100644
--- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
@@ -940,9 +940,42 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
{
$form = $this->factory->createNamed('name', FileType::class);
- $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')),
-'/input
- [@type="file"]
+ $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'n/a', 'attr' => array('class' => 'my&class form-control-file')),
+'/div
+ [@class="form-group"]
+ [
+ ./div
+ [@class="custom-file"]
+ [
+ ./input
+ [@type="file"]
+ [@name="name"]
+ /following-sibling::label
+ [@for="name"]
+ ]
+ ]
+'
+ );
+ }
+
+ public function testFileWithPlaceholder()
+ {
+ $form = $this->factory->createNamed('name', FileType::class);
+
+ $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'n/a', 'attr' => array('class' => 'my&class form-control-file', 'placeholder' => 'Custom Placeholder')),
+'/div
+ [@class="form-group"]
+ [
+ ./div
+ [@class="custom-file"]
+ [
+ ./input
+ [@type="file"]
+ [@name="name"]
+ /following-sibling::label
+ [@for="name" and text() = "[trans]Custom Placeholder[/trans]"]
+ ]
+ ]
'
);
}
diff --git a/src/Symfony/Component/HttpFoundation/HeaderBag.php b/src/Symfony/Component/HttpFoundation/HeaderBag.php
index 7026732fe7..d11887fb61 100644
--- a/src/Symfony/Component/HttpFoundation/HeaderBag.php
+++ b/src/Symfony/Component/HttpFoundation/HeaderBag.php
@@ -101,11 +101,11 @@ class HeaderBag implements \IteratorAggregate, \Countable
/**
* Returns a header value by name.
*
- * @param string $key The header name
- * @param string|string[] $default The default value
- * @param bool $first Whether to return the first value or all header values
+ * @param string $key The header name
+ * @param string|string[]|null $default The default value
+ * @param bool $first Whether to return the first value or all header values
*
- * @return string|string[] The first header value or default value if $first is true, an array of values otherwise
+ * @return string|string[]|null The first header value or default value if $first is true, an array of values otherwise
*/
public function get($key, $default = null, $first = true)
{
diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php
index 19b57762a6..dd7a7fad82 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php
@@ -124,7 +124,13 @@ class NamespacedAttributeBag extends AttributeBag
foreach ($parts as $part) {
if (null !== $array && !array_key_exists($part, $array)) {
- $array[$part] = $writeContext ? array() : null;
+ if (!$writeContext) {
+ $null = null;
+
+ return $null;
+ }
+
+ $array[$part] = array();
}
$array = &$array[$part];
diff --git a/src/Symfony/Component/HttpFoundation/StreamedResponse.php b/src/Symfony/Component/HttpFoundation/StreamedResponse.php
index a7c2150252..2519f874cc 100644
--- a/src/Symfony/Component/HttpFoundation/StreamedResponse.php
+++ b/src/Symfony/Component/HttpFoundation/StreamedResponse.php
@@ -141,4 +141,16 @@ class StreamedResponse extends Response
{
return false;
}
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function setNotModified()
+ {
+ $this->setCallback(function () {});
+
+ return parent::setNotModified();
+ }
}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php
index b4af82ddf6..a51b954fa0 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php
@@ -126,7 +126,7 @@ class ResponseTest extends ResponseTestCase
public function testSetNotModified()
{
- $response = new Response();
+ $response = new Response('foo');
$modified = $response->setNotModified();
$this->assertObjectHasAttribute('headers', $modified);
$this->assertObjectHasAttribute('content', $modified);
@@ -135,6 +135,11 @@ class ResponseTest extends ResponseTestCase
$this->assertObjectHasAttribute('statusText', $modified);
$this->assertObjectHasAttribute('charset', $modified);
$this->assertEquals(304, $modified->getStatusCode());
+
+ ob_start();
+ $modified->sendContent();
+ $string = ob_get_clean();
+ $this->assertEmpty($string);
}
public function testIsSuccessful()
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php
index f074ce1b26..ec4cd5ad1a 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php
@@ -82,6 +82,17 @@ class NamespacedAttributeBagTest extends TestCase
$this->assertEquals($exists, $this->bag->has($key));
}
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testHasNoSideEffect($key, $value, $expected)
+ {
+ $expected = json_encode($this->bag->all());
+ $this->bag->has($key);
+
+ $this->assertEquals($expected, json_encode($this->bag->all()));
+ }
+
/**
* @dataProvider attributesProvider
*/
@@ -96,6 +107,17 @@ class NamespacedAttributeBagTest extends TestCase
$this->assertEquals('default', $this->bag->get('user2.login', 'default'));
}
+ /**
+ * @dataProvider attributesProvider
+ */
+ public function testGetNoSideEffect($key, $value, $expected)
+ {
+ $expected = json_encode($this->bag->all());
+ $this->bag->get($key);
+
+ $this->assertEquals($expected, json_encode($this->bag->all()));
+ }
+
/**
* @dataProvider attributesProvider
*/
diff --git a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php
index c2ded996fa..699222e379 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php
@@ -123,4 +123,22 @@ class StreamedResponseTest extends TestCase
$this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
}
+
+ public function testSetNotModified()
+ {
+ $response = new StreamedResponse(function () { echo 'foo'; });
+ $modified = $response->setNotModified();
+ $this->assertObjectHasAttribute('headers', $modified);
+ $this->assertObjectHasAttribute('content', $modified);
+ $this->assertObjectHasAttribute('version', $modified);
+ $this->assertObjectHasAttribute('statusCode', $modified);
+ $this->assertObjectHasAttribute('statusText', $modified);
+ $this->assertObjectHasAttribute('charset', $modified);
+ $this->assertEquals(304, $modified->getStatusCode());
+
+ ob_start();
+ $modified->sendContent();
+ $string = ob_get_clean();
+ $this->assertEmpty($string);
+ }
}
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
index a5e4bd696a..491c62bcc4 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
@@ -76,14 +76,7 @@ abstract class AbstractToken implements TokenInterface
}
/**
- * Sets the user in the token.
- *
- * The user can be a UserInterface instance, or an object implementing
- * a __toString method or the username as a regular string.
- *
- * @param string|object $user The user
- *
- * @throws \InvalidArgumentException
+ * {@inheritdoc}
*/
public function setUser($user)
{
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php
index bb5711ee89..bcf6fbdd94 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php
@@ -47,17 +47,22 @@ interface TokenInterface extends \Serializable
/**
* Returns a user representation.
*
- * @return mixed Can be a UserInterface instance, an object implementing a __toString method,
- * or the username as a regular string
+ * @return string|object Can be a UserInterface instance, an object implementing a __toString method,
+ * or the username as a regular string
*
* @see AbstractToken::setUser()
*/
public function getUser();
/**
- * Sets a user.
+ * Sets the user in the token.
*
- * @param mixed $user
+ * The user can be a UserInterface instance, or an object implementing
+ * a __toString method or the username as a regular string.
+ *
+ * @param string|object $user The user
+ *
+ * @throws \InvalidArgumentException
*/
public function setUser($user);
diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
index 6c9098528b..77c98377ee 100644
--- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php
@@ -142,11 +142,16 @@ class ObjectNormalizer extends AbstractObjectNormalizer
return false;
}
- if (null !== $this->classDiscriminatorResolver && null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForMappedObject($classOrObject)) {
- $allowedAttributes[] = $attributesAsString ? $discriminatorMapping->getTypeProperty() : new AttributeMetadata($discriminatorMapping->getTypeProperty());
+ if (null !== $this->classDiscriminatorResolver) {
+ $class = \is_object($classOrObject) ? \get_class($classOrObject) : $classOrObject;
+ if (null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForMappedObject($classOrObject)) {
+ $allowedAttributes[] = $attributesAsString ? $discriminatorMapping->getTypeProperty() : new AttributeMetadata($discriminatorMapping->getTypeProperty());
+ }
- foreach ($discriminatorMapping->getTypesMapping() as $class) {
- $allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($class, $context, $attributesAsString));
+ if (null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForClass($class)) {
+ foreach ($discriminatorMapping->getTypesMapping() as $mappedClass) {
+ $allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($mappedClass, $context, $attributesAsString));
+ }
}
}
diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php
index 060c10dd79..3b828e50bf 100644
--- a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php
+++ b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php
@@ -11,9 +11,15 @@
namespace Symfony\Component\Serializer\Tests\Fixtures;
+use Symfony\Component\Serializer\Annotation\Groups;
+
/**
* @author Samuel Roze
*/
class DummyMessageNumberTwo implements DummyMessageInterface
{
+ /**
+ * @Groups({"two"})
+ */
+ public $three;
}