8000 [Form] Use `form.post_set_data` in `ResizeFormListener` · symfony/symfony@7422f04 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7422f04

Browse files
committed
[Form] Use form.post_set_data in ResizeFormListener
1 parent 0ba946a commit 7422f04

File tree

4 files changed

+105
-6
lines changed

4 files changed

+105
-6
lines changed

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ CHANGELOG
88
`model_timezone` option in `DateType`, `DateTimeType`, and `TimeType`
99
* Deprecate `PostSetDataEvent::setData()`, use `PreSetDataEvent::setData()` instead
1010
* Deprecate `PostSubmitEvent::setData()`, use `PreSubmitDataEvent::setData()` or `SubmitDataEvent::setData()` instead
11+
* Use `form.post_set_data` instead of `form.pre_set_data` in `ResizeFormListener`
12+
* Change the priority of `DataCollectorListener` from 255 to -255
1113

1214
6.3
1315
---

src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Core\EventListener;
1313

1414
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\Form\Event\PostSetDataEvent;
1516
use Symfony\Component\Form\Exception\UnexpectedTypeException;
1617
use Symfony\Component\Form\FormEvent;
1718
use Symfony\Component\Form\FormEvents;
@@ -32,6 +33,10 @@ class ResizeFormListener implements EventSubscriberInterface
3233

3334
private \Closure|bool $deleteEmpty;
3435

36+
// BC, to be removed in 7.0
37+
private bool $overridden = true;
38+
private bool $usePreSetData = false;
39+
3540
public function __construct(string $type, array $options = [], bool $allowAdd = false, bool $allowDelete = false, bool|callable $deleteEmpty = false, array $prototypeOptions = null)
3641
{
3742
$this->type = $type;
@@ -45,18 +50,52 @@ public function __construct(string $type, array $options = [], bool $allowAdd =
4550
public static function getSubscribedEvents(): array
4651
{
4752
return [
48-
FormEvents::PRE_SET_DATA => 'preSetData',
53+
FormEvents::PRE_SET_DATA => 'preSetData', // deprecated
54+
FormEvents::POST_SET_DATA => ['postSetData', 255], // as early as possible
4955
FormEvents::PRE_SUBMIT => 'preSubmit',
5056
// (MergeCollectionListener, MergeDoctrineCollectionListener)
5157
FormEvents::SUBMIT => ['onSubmit', 50],
5258
];
5359
}
5460

5561
/**
62+
* @deprecated Since 6.4, use {@see postSetData()} instead.
63+
*
5664
* @return void
5765
*/
5866
public function preSetData(FormEvent $event)
5967
{
68+
if (__CLASS__ === static::class
69+
|| __CLASS__ === (new \ReflectionClass($this))->getMethod('preSetData')->getDeclaringClass()->name
70+
) {
71+
// not a child class, or child class does not overload PRE_SET_DATA
72+
return;
73+
}
74+
75+
trigger_deprecation('symfony/form', '6.4', 'Calling "%s()" is deprecated, use "%s::postSetData()" instead.', __METHOD__, __CLASS__);
76+
// parent::preSetData() has been called
77+
$this->overridden = false;
78+
$this->postSetData($event);
79+
$this->usePreSetData = true;
80+
}
81+
82+
// Remove FormEvent type hint in 7.0
83+
final public function postSetData(FormEvent|PostSetDataEvent $event): void
84+
{
85+
if (__CLASS__ !== static::class) {
86+
if ($this->overridden) {
87+
trigger_deprecation('symfony/form', '6.4', 'Calling "%s::preSetData()" is deprecated, use "%s::postSetData()" instead.', static::class, __CLASS__);
88+
// parent::preSetData() has not been called, noop
89+
90+
return;
91+
}
92+
93+
if ($this->usePreSetData) {
94+
// nothing else to do
95+
return;
96+
}
97+
}
98+
6099
$form = $event->getForm();
61100
$data = $event->getData() ?? [];
62101

src/Symfony/Component/Form/Extension/DataCollector/EventListener/DataCollectorListener.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public function __construct(FormDataCollectorInterface $dataCollector)
3434
public static function getSubscribedEvents(): array
3535
{
3636
return [
37-
// High priority in order to be called as soon as possible
38-
FormEvents::POST_SET_DATA => ['postSetData', 255],
37+
// Low priority in order to be called as late as possible
38+
FormEvents::POST_SET_DATA => ['postSetData', -255],
3939
// Low priority in order to be called as late as possible
4040
FormEvents::POST_SUBMIT => ['postSubmit', -255],
4141
];

src/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,40 +48,98 @@ protected function getForm($name = 'name')
4848
return $this->getBuilder($name)->getForm();
4949
}
5050

51+
/**
52+
* @group legacy
53+
*/
5154
public function testPreSetDataResizesForm()
5255
{
5356
$this->form->add($this->getForm('0'));
5457
$this->form->add($this->getForm('1'));
5558

5659
$data = [1 => 'string', 2 => 'string'];
5760
$event = new FormEvent($this->form, $data);
58-
$listener = new ResizeFormListener(TextType::class, ['attr' => ['maxlength' => 10]], false, false);
61+
$listener = new class(TextType::class, ['attr' => ['maxlength' => 10]], false, false) extends ResizeFormListener {
62+
public function preSetData(FormEvent $event)
63+
{
64+
parent::preSetData($event);
65+
}
66+
};
5967
$listener->preSetData($event);
6068

6169
$this->assertFalse($this->form->has('0'));
6270
$this->assertTrue($this->form->has('1'));
6371
$this->assertTrue($this->form->has('2'));
6472
}
6573

74+
public function testPostSetDataResizesForm()
75+
{
76+
$this->form->add($this->getForm('0'));
77+
$this->form->add($this->getForm('1'));
78+
79+
$data = [1 => 'string', 2 => 'string'];
80+
$event = new FormEvent($this->form, $data);
81+
$listener = new ResizeFormListener(TextType::class, ['attr' => ['maxlength' => 10]], false, false);
82+
$listener->postSetData($event);
83+
84+
$this->assertFalse($this->form->has('0'));
85+
$this->assertTrue($this->form->has('1'));
86+
$this->assertTrue($this->form->has('2'));
87+
}
88+
89+
/**
90+
* @group legacy
91+
*/
6692
public function testPreSetDataRequiresArrayOrTraversable()
6793
{
6894
$this->expectException(UnexpectedTypeException::class);
6995
$data = 'no array or traversable';
7096
$event = new FormEvent($this->form, $data);
71-
$listener = new ResizeFormListener('text', [], false, false);
97+
$listener = new class('text', [], false, false) extends ResizeFormListener {
98+
public function preSetData(FormEvent $event)
99+
{
100+
parent::preSetData($event);
101+
}
102+
};
72103
$listener->preSetData($event);
73104
}
74105

106+
public function testPostSetDataRequiresArrayOrTraversable()
107+
{
108+
$this->expectException(UnexpectedTypeException::class);
109+
$data = 'no array or traversable';
110+
$event = new FormEvent($this->form, $data);
111+
$listener = new ResizeFormListener('text', [], false, false);
112+
$listener->postSetData($event);
113+
}
114+
115+
/**
116+
* @group legacy
117+
*/
75118
public function testPreSetDataDealsWithNullData()
76119
{
77120
$data = null;
78121
$event = new FormEvent($this->form, $data);
79-
$listener = new ResizeFormListener(TextType::class, [], false, false);
122+
$listener = new class(TextType::class, [], false, false) extends ResizeFormListener {
123+
public function preSetData(FormEvent $event)
124+
{
125+
parent::preSetData($event);
126+
}
127+
};
80128
$listener->preSetData($event);
81129

82130
$this->assertSame(0, $this->form->count());
83131
}
84132

133+
public function testPostSetDataDealsWithNullData()
134+
{
135+
$data = null;
136+
$event = new FormEvent($this->form, $data);
137+
$listener = new ResizeFormListener(TextType::class, [], false, false);
138+
$listener->postSetData($event);
139+
140+
$this->assertSame(0, $this->form->count());
141+
}
142+
85143
public function testPreSubmitResizesUpIfAllowAdd()
86144
{
87145
$this->form->add($this->getForm('0'));

0 commit comments

Comments
 (0)
0