Skip to content
/ form Public

Commit 4bc8440

Browse files
Merge branch '6.4' into 7.3
* 6.4: [Cache] Fix DSN auth not passed to clusters in RedisTrait do not parse "scalar" as an object [Form] Fix OrderedHashMap auto-increment logic with mixed keys don't skip custom view transformers while normalizing submitted newlines [Serializer] Fix is/has/can accessor naming regression while preserving collision detection
2 parents e6b4024 + b758162 commit 4bc8440

File tree

6 files changed

+93
-162
lines changed

6 files changed

+93
-162
lines changed

Extension/Core/EventListener/CrlfNormalizerListener.php

Lines changed: 0 additions & 37 deletions
This file was deleted.

Extension/Core/Type/TextareaType.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212
namespace Symfony\Component\Form\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\AbstractType;
15-
use Symfony\Component\Form\Extension\Core\EventListener\CrlfNormalizerListener;
15+
use Symfony\Component\Form\DataTransformerInterface;
1616
use Symfony\Component\Form\FormBuilderInterface;
1717
use Symfony\Component\Form\FormInterface;
1818
use Symfony\Component\Form\FormView;
19+
use Symfony\Component\Form\Util\StringUtil;
1920

20-
class TextareaType extends AbstractType
21+
class TextareaType extends AbstractType implements DataTransformerInterface
2122
{
2223
public function buildForm(FormBuilderInterface $builder, array $options): void
2324
{
24-
$builder->addEventSubscriber(new CrlfNormalizerListener());
25+
$builder->addViewTransformer($this);
2526
}
2627

2728
public function buildView(FormView $view, FormInterface $form, array $options): void
@@ -39,4 +40,26 @@ public function getBlockPrefix(): string
3940
{
4041
return 'textarea';
4142
}
43+
44+
public function transform(mixed $value): mixed
45+
{
46+
if (null === $value) {
47+
return '';
48+
}
49+
50+
return $value;
51+
}
52+
53+
public function reverseTransform(mixed $value): mixed
54+
{
55+
if (!\is_string($value)) {
56+
return $value;
57+
}
58+
59+
if ('' === $value) {
60+
return null;
61+
}
62+
63+
return StringUtil::normalizeNewlines($value);
64+
}
4265
}

Tests/Extension/Core/EventListener/CrlfNormalizerListenerTest.php

Lines changed: 0 additions & 112 deletions
This file was deleted.

Tests/Extension/Core/Type/TextareaTypeTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
1313

14+
use Symfony\Component\Form\CallbackTransformer;
1415
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
1516

1617
class TextareaTypeTest extends BaseTypeTestCase
@@ -86,4 +87,33 @@ public function testWithTrimEnabled()
8687

8788
$this->assertSame("Line 1\nLine 2", $form->getData());
8889
}
90+
91+
public function testCustomViewTransformerTakesPrecedence()
92+
{
93+
$form = $this->factory->createBuilder(static::TESTED_TYPE)
94+
->addViewTransformer(new CallbackTransformer(
95+
static function (?string $value) {
96+
if (null === $value) {
97+
return null;
98+
}
99+
100+
return str_replace(';', "\r\n", $value);
101+
},
102+
static function (?string $value) {
103+
if (null === $value) {
104+
return null;
105+
}
106+
107+
return str_replace("\r\n", ';', $value);
108+
}
109+
))
110+
->getForm();
111+
$form->setData('foo;bar');
112+
113+
$this->assertSame("foo\r\nbar", $form->getViewData());
114+
115+
$form->submit("bar\r\nbaz");
116+
117+
$this->assertSame('bar;baz', $form->getData());
118+
}
89119
}

Tests/Util/OrderedHashMapTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,4 +524,36 @@ public function testCount()
524524

525525
$this->assertCount(2, $map);
526526
}
527+
528+
public function testAppendDoesNotOverwriteExistingNumericKeysWhenStringKeysExist()
529+
{
530+
$map = new OrderedHashMap();
531+
$map[0] = 'zero';
532+
$map[1] = 'one';
533+
$map['foo'] = 'bar';
534+
$map[] = 'new';
535+
536+
$this->assertSame('one', $map[1]);
537+
$this->assertSame('new', $map[2]);
538+
}
539+
540+
public function testUpdateNullValueDoesNotChangeElementPosition()
541+
{
542+
$map = new OrderedHashMap();
543+
$map['first'] = null;
544+
$map['second'] = 2;
545+
$map['first'] = null;
546+
547+
$this->assertSame(['first' => null, 'second' => 2], iterator_to_array($map));
548+
}
549+
550+
public function testUpdateFromNullValueDoesNotChangeElementPosition()
551+
{
552+
$map = new OrderedHashMap();
553+
$map['first'] = null;
554+
$map['second'] = 2;
555+
$map['first'] = 1;
556+
557+
$this->assertSame(['first' => 1, 'second' => 2], iterator_to_array($map));
558+
}
527559
}

Util/OrderedHashMap.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,11 @@ public function offsetGet(mixed $key): mixed
113113

114114
public function offsetSet(mixed $key, mixed $value): void
115115
{
116-
if (null === $key || !isset($this->elements[$key])) {
117-
if (null === $key) {
118-
$key = [] === $this->orderedKeys
119-
// If the array is empty, use 0 as key
120-
? 0
121-
// Imitate PHP behavior of generating a key that equals
122-
// the highest existing integer key + 1
123-
: 1 + (int) max($this->orderedKeys);
124-
}
125-
116+
if (null === $key) {
117+
$this->elements[] = $value;
118+
$key = array_key_last($this->elements);
119+
$this->orderedKeys[] = (string) $key;
120+
} elseif (!\array_key_exists($key, $this->elements)) {
126121
$this->orderedKeys[] = (string) $key;
127122
}
128123

0 commit comments

Comments
 (0)