Merge branch '4.1'
* 4.1: fixed typo [FrameworkBundle] fixed brackets position in method calls Add placeholder support in bootstrap 4 file fields [Form] Improve rendering of `file` field in bootstrap 4 [Form] Fix PHPDoc for FormConfigBuilder $dataClass argument [Security] Update user phpdoc on tokens [WebProfilerBundle] Fixed icon alignment issue using Bootstrap 4.1.2 suppress side effects in 'get' or 'has' methods of NamespacedAttributeBag [HttpFoundation] reset callback on StreamedResponse when setNotModified() is called [HttpFoundation] Fixed phpdoc for get method of HeaderBag fix typo in ContainerBuilder docblock [Form/Profiler] Massively reducing memory footprint of form profiling pages by removing redundant 'form' variable from view variables. [Console] correctly return parameter's default value on "--" [DependencyInjection] add missing test for #27710 [EventDispatcher] Clear orphaned events on TraceableEventDispatcher::reset Fix serialization of abstract items with groups across multiple entities
This commit is contained in:
commit
18ba2a81a7
@ -114,6 +114,20 @@
|
|||||||
</div>
|
</div>
|
||||||
{%- endblock percent_widget %}
|
{%- endblock percent_widget %}
|
||||||
|
|
||||||
|
{% block file_widget -%}
|
||||||
|
<div class="form-group">
|
||||||
|
<{{ element|default('div') }} class="custom-file">
|
||||||
|
{%- set type = type|default('file') -%}
|
||||||
|
{{- block('form_widget_simple') -}}
|
||||||
|
<label for="{{ form.vars.id }}" class="custom-file-label">
|
||||||
|
{%- if attr.placeholder is defined -%}
|
||||||
|
{{- translation_domain is same as(false) ? attr.placeholder : attr.placeholder|trans({}, translation_domain) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
</label>
|
||||||
|
</{{ element|default('div') }}>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block form_widget_simple -%}
|
{% block form_widget_simple -%}
|
||||||
{% if type is not defined or type != 'hidden' %}
|
{% 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}) -%}
|
{%- 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 -%}
|
{%- if compound is defined and compound -%}
|
||||||
{%- set element = 'legend' -%}
|
{%- set element = 'legend' -%}
|
||||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
|
{%- 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 -%}
|
{%- else -%}
|
||||||
{%- set label_attr = label_attr|merge({for: id}) -%}
|
{%- set label_attr = label_attr|merge({for: id}) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
@ -269,15 +281,6 @@
|
|||||||
</{{ element|default('div') }}>
|
</{{ element|default('div') }}>
|
||||||
{%- endblock form_row %}
|
{%- endblock form_row %}
|
||||||
|
|
||||||
{% block file_row -%}
|
|
||||||
<div class="form-group">
|
|
||||||
<{{ element|default('div') }} class="custom-file">
|
|
||||||
{{- form_widget(form) -}}
|
|
||||||
{{- form_label(form) -}}
|
|
||||||
</{{ element|default('div') }}>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{# Errors #}
|
{# Errors #}
|
||||||
|
|
||||||
{% block form_errors -%}
|
{% block form_errors -%}
|
||||||
|
@ -268,7 +268,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$this->assertInstanceOf(Reference::class, $markingStoreRef);
|
$this->assertInstanceOf(Reference::class, $markingStoreRef);
|
||||||
$this->assertEquals('workflow_service', (string) $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');
|
$registryDefinition = $container->getDefinition('workflow.registry');
|
||||||
$this->assertGreaterThan(0, count($registryDefinition->getMethodCalls()));
|
$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');
|
$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'), '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.definition'), 'Workflow definition is registered as a service');
|
||||||
|
|
||||||
$workflowDefinition = $container->getDefinition('workflow.article.definition');
|
$workflowDefinition = $container->getDefinition('workflow.article.definition');
|
||||||
|
|
||||||
|
@ -292,6 +292,7 @@ div.sf-toolbar .sf-toolbar-block a:hover {
|
|||||||
border-width: 0;
|
border-width: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-toolbar-block .sf-toolbar-icon img + span,
|
.sf-toolbar-block .sf-toolbar-icon img + span,
|
||||||
|
@ -301,7 +301,7 @@ class ArgvInput extends Input
|
|||||||
while (0 < count($tokens)) {
|
while (0 < count($tokens)) {
|
||||||
$token = array_shift($tokens);
|
$token = array_shift($tokens);
|
||||||
if ($onlyParams && '--' === $token) {
|
if ($onlyParams && '--' === $token) {
|
||||||
return false;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
|
@ -81,7 +81,7 @@ class ArrayInput extends Input
|
|||||||
|
|
||||||
foreach ($this->parameters as $k => $v) {
|
foreach ($this->parameters as $k => $v) {
|
||||||
if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) {
|
if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) {
|
||||||
return false;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_int($k)) {
|
if (is_int($k)) {
|
||||||
|
@ -395,25 +395,26 @@ class ArgvInputTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider provideGetParameterOptionValues
|
* @dataProvider provideGetParameterOptionValues
|
||||||
*/
|
*/
|
||||||
public function testGetParameterOptionEqualSign($argv, $key, $onlyParams, $expected)
|
public function testGetParameterOptionEqualSign($argv, $key, $default, $onlyParams, $expected)
|
||||||
{
|
{
|
||||||
$input = new ArgvInput($argv);
|
$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()
|
public function provideGetParameterOptionValues()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', false, 'dev'),
|
array(array('app/console', 'foo:bar'), '-e', 'default', false, 'default'),
|
||||||
array(array('app/console', 'foo:bar', '--env=dev'), '--env', false, 'dev'),
|
array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'default', false, 'dev'),
|
||||||
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), false, 'dev'),
|
array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'default', false, 'dev'),
|
||||||
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), false, 'dev'),
|
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'default', false, 'dev'),
|
||||||
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), false, '1'),
|
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'), 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', false, 'val'),
|
array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), 'default', false, '1'),
|
||||||
array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', false, 'val'),
|
array(array('app/console', 'foo:bar', '--env', 'val'), '--env', 'default', false, 'val'),
|
||||||
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev'),
|
array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', 'default', false, 'val'),
|
||||||
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', true, false),
|
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', false, 'dev'),
|
||||||
|
array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', true, 'default'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +47,14 @@ class ArrayInputTest extends TestCase
|
|||||||
{
|
{
|
||||||
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
|
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
|
||||||
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
|
$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'));
|
$input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
|
||||||
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
|
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
|
||||||
|
|
||||||
$input = new ArrayInput(array('--foo', '--', '--bar' => 'woop'));
|
$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->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()
|
public function testParseArguments()
|
||||||
|
@ -608,10 +608,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
* the parameters passed to the container constructor to have precedence
|
* the parameters passed to the container constructor to have precedence
|
||||||
* over the loaded ones.
|
* over the loaded ones.
|
||||||
*
|
*
|
||||||
* $container = new ContainerBuilder(array('foo' => 'bar'));
|
* $container = new ContainerBuilder(new ParameterBag(array('foo' => 'bar')));
|
||||||
* $loader = new LoaderXXX($container);
|
* $loader = new LoaderXXX($container);
|
||||||
* $loader->load('resource_name');
|
* $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
|
* In the above example, even if the loaded resource defines a foo
|
||||||
* parameter, the value will still be 'bar' as defined in the ContainerBuilder
|
* parameter, the value will still be 'bar' as defined in the ContainerBuilder
|
||||||
|
@ -237,6 +237,18 @@ class ValidateEnvPlaceholdersPassTest extends TestCase
|
|||||||
$this->addToAssertionCount(1);
|
$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
|
public function testDiscardedEnvInConfig(): void
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$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
|
class EnvExtension extends Extension
|
||||||
{
|
{
|
||||||
private $configuration;
|
private $configuration;
|
||||||
@ -337,6 +367,10 @@ class EnvExtension extends Extension
|
|||||||
|
|
||||||
public function load(array $configs, ContainerBuilder $container)
|
public function load(array $configs, ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
|
if (!array_filter($configs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs);
|
$this->config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs);
|
||||||
} catch (TreeWithoutRootNodeException $e) {
|
} catch (TreeWithoutRootNodeException $e) {
|
||||||
|
@ -217,6 +217,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
public function reset()
|
public function reset()
|
||||||
{
|
{
|
||||||
$this->called = array();
|
$this->called = array();
|
||||||
|
$this->orphanedEvents = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,6 +271,17 @@ class TraceableEventDispatcherTest extends TestCase
|
|||||||
|
|
||||||
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
|
$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
|
class EventSubscriber implements EventSubscriberInterface
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Extension\DataCollector;
|
|||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\Validator\ConstraintViolationInterface;
|
use Symfony\Component\Validator\ConstraintViolationInterface;
|
||||||
|
use Symfony\Component\VarDumper\Caster\CutStub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of {@link FormDataExtractorInterface}.
|
* Default implementation of {@link FormDataExtractorInterface}.
|
||||||
@ -144,6 +145,10 @@ class FormDataExtractor implements FormDataExtractorInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
foreach ($view->vars as $varName => $value) {
|
foreach ($view->vars as $varName => $value) {
|
||||||
|
// Removing redundant variable from view variables
|
||||||
|
if ('form' === $varName) {
|
||||||
|
$value = new CutStub($value);
|
||||||
|
}
|
||||||
$data['view_vars'][$varName] = $value;
|
$data['view_vars'][$varName] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
private $data;
|
private $data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
private $dataClass;
|
private $dataClass;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
* Creates an empty form configuration.
|
* Creates an empty form configuration.
|
||||||
*
|
*
|
||||||
* @param string|int $name The form name
|
* @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 EventDispatcherInterface $dispatcher The event dispatcher
|
||||||
* @param array $options The form options
|
* @param array $options The form options
|
||||||
*
|
*
|
||||||
|
@ -940,9 +940,42 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
{
|
{
|
||||||
$form = $this->factory->createNamed('name', FileType::class);
|
$form = $this->factory->createNamed('name', FileType::class);
|
||||||
|
|
||||||
$this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')),
|
$this->assertWidgetMatchesXpath($form->createView(), array('id' => 'n/a', 'attr' => array('class' => 'my&class form-control-file')),
|
||||||
'/input
|
'/div
|
||||||
|
[@class="form-group"]
|
||||||
|
[
|
||||||
|
./div
|
||||||
|
[@class="custom-file"]
|
||||||
|
[
|
||||||
|
./input
|
||||||
[@type="file"]
|
[@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]"]
|
||||||
|
]
|
||||||
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -102,10 +102,10 @@ class HeaderBag implements \IteratorAggregate, \Countable
|
|||||||
* Returns a header value by name.
|
* Returns a header value by name.
|
||||||
*
|
*
|
||||||
* @param string $key The header name
|
* @param string $key The header name
|
||||||
* @param string|string[] $default The default value
|
* @param string|string[]|null $default The default value
|
||||||
* @param bool $first Whether to return the first value or all header values
|
* @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)
|
public function get($key, $default = null, $first = true)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,13 @@ class NamespacedAttributeBag extends AttributeBag
|
|||||||
|
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
if (null !== $array && !array_key_exists($part, $array)) {
|
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];
|
$array = &$array[$part];
|
||||||
|
@ -141,4 +141,16 @@ class StreamedResponse extends Response
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setNotModified()
|
||||||
|
{
|
||||||
|
$this->setCallback(function () {});
|
||||||
|
|
||||||
|
return parent::setNotModified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ class ResponseTest extends ResponseTestCase
|
|||||||
|
|
||||||
public function testSetNotModified()
|
public function testSetNotModified()
|
||||||
{
|
{
|
||||||
$response = new Response();
|
$response = new Response('foo');
|
||||||
$modified = $response->setNotModified();
|
$modified = $response->setNotModified();
|
||||||
$this->assertObjectHasAttribute('headers', $modified);
|
$this->assertObjectHasAttribute('headers', $modified);
|
||||||
$this->assertObjectHasAttribute('content', $modified);
|
$this->assertObjectHasAttribute('content', $modified);
|
||||||
@ -135,6 +135,11 @@ class ResponseTest extends ResponseTestCase
|
|||||||
$this->assertObjectHasAttribute('statusText', $modified);
|
$this->assertObjectHasAttribute('statusText', $modified);
|
||||||
$this->assertObjectHasAttribute('charset', $modified);
|
$this->assertObjectHasAttribute('charset', $modified);
|
||||||
$this->assertEquals(304, $modified->getStatusCode());
|
$this->assertEquals(304, $modified->getStatusCode());
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$modified->sendContent();
|
||||||
|
$string = ob_get_clean();
|
||||||
|
$this->assertEmpty($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsSuccessful()
|
public function testIsSuccessful()
|
||||||
|
@ -82,6 +82,17 @@ class NamespacedAttributeBagTest extends TestCase
|
|||||||
$this->assertEquals($exists, $this->bag->has($key));
|
$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
|
* @dataProvider attributesProvider
|
||||||
*/
|
*/
|
||||||
@ -96,6 +107,17 @@ class NamespacedAttributeBagTest extends TestCase
|
|||||||
$this->assertEquals('default', $this->bag->get('user2.login', 'default'));
|
$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
|
* @dataProvider attributesProvider
|
||||||
*/
|
*/
|
||||||
|
@ -123,4 +123,22 @@ class StreamedResponseTest extends TestCase
|
|||||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
|
$this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders());
|
||||||
$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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,14 +76,7 @@ abstract class AbstractToken implements TokenInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the user in the token.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* 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)
|
public function setUser($user)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ interface TokenInterface extends \Serializable
|
|||||||
/**
|
/**
|
||||||
* Returns a user representation.
|
* Returns a user representation.
|
||||||
*
|
*
|
||||||
* @return mixed Can be a UserInterface instance, an object implementing a __toString method,
|
* @return string|object Can be a UserInterface instance, an object implementing a __toString method,
|
||||||
* or the username as a regular string
|
* or the username as a regular string
|
||||||
*
|
*
|
||||||
* @see AbstractToken::setUser()
|
* @see AbstractToken::setUser()
|
||||||
@ -55,9 +55,14 @@ interface TokenInterface extends \Serializable
|
|||||||
public function getUser();
|
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);
|
public function setUser($user);
|
||||||
|
|
||||||
|
@ -142,11 +142,16 @@ class ObjectNormalizer extends AbstractObjectNormalizer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->classDiscriminatorResolver && null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForMappedObject($classOrObject)) {
|
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());
|
$allowedAttributes[] = $attributesAsString ? $discriminatorMapping->getTypeProperty() : new AttributeMetadata($discriminatorMapping->getTypeProperty());
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($discriminatorMapping->getTypesMapping() as $class) {
|
if (null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForClass($class)) {
|
||||||
$allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($class, $context, $attributesAsString));
|
foreach ($discriminatorMapping->getTypesMapping() as $mappedClass) {
|
||||||
|
$allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($mappedClass, $context, $attributesAsString));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,15 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Serializer\Tests\Fixtures;
|
namespace Symfony\Component\Serializer\Tests\Fixtures;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Samuel Roze <samuel.roze@gmail.com>
|
* @author Samuel Roze <samuel.roze@gmail.com>
|
||||||
*/
|
*/
|
||||||
class DummyMessageNumberTwo implements DummyMessageInterface
|
class DummyMessageNumberTwo implements DummyMessageInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @Groups({"two"})
|
||||||
|
*/
|
||||||
|
public $three;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user