4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Form\Extension\Core\EventListener
;
14 use Symfony\Component\Form\FormEvents
;
15 use Symfony\Component\Form\FormEvent
;
16 use Symfony\Component\Form\Exception\UnexpectedTypeException
;
17 use Symfony\Component\EventDispatcher\EventSubscriberInterface
;
20 * Resize a collection form element based on the data sent from the client.
22 * @author Bernhard Schussek <bschussek@gmail.com>
24 class ResizeFormListener
implements EventSubscriberInterface
37 * Whether children could be added to the group
43 * Whether children could be removed from the group
46 protected $allowDelete;
48 public function __construct($type, array $options = array(), $allowAdd = false, $allowDelete = false)
51 $this->allowAdd
= $allowAdd;
52 $this->allowDelete
= $allowDelete;
53 $this->options
= $options;
56 public static function getSubscribedEvents()
59 FormEvents
::PRE_SET_DATA
=> 'preSetData',
60 FormEvents
::PRE_SUBMIT
=> 'preSubmit',
61 // (MergeCollectionListener, MergeDoctrineCollectionListener)
62 FormEvents
::SUBMIT
=> array('onSubmit', 50),
66 public function preSetData(FormEvent
$event)
68 $form = $event->getForm();
69 $data = $event->getData();
75 if (!is_array($data) && !($data instanceof \Traversable
&& $data instanceof \ArrayAccess
)) {
76 throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
79 // First remove all rows
80 foreach ($form as $name => $child) {
84 // Then add all rows again in the correct order
85 foreach ($data as $name => $value) {
86 $form->add($name, $this->type
, array_replace(array(
87 'property_path' => '['.$name.']',
92 public function preSubmit(FormEvent
$event)
94 $form = $event->getForm();
95 $data = $event->getData();
97 if (null === $data || '' === $data) {
101 if (!is_array($data) && !($data instanceof \Traversable
&& $data instanceof \ArrayAccess
)) {
102 throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
105 // Remove all empty rows
106 if ($this->allowDelete
) {
107 foreach ($form as $name => $child) {
108 if (!isset($data[$name])) {
109 $form->remove($name);
114 // Add all additional rows
115 if ($this->allowAdd
) {
116 foreach ($data as $name => $value) {
117 if (!$form->has($name)) {
118 $form->add($name, $this->type
, array_replace(array(
119 'property_path' => '['.$name.']',
126 public function onSubmit(FormEvent
$event)
128 $form = $event->getForm();
129 $data = $event->getData();
131 if (null === $data) {
135 if (!is_array($data) && !($data instanceof \Traversable
&& $data instanceof \ArrayAccess
)) {
136 throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
139 // The data mapper only adds, but does not remove items, so do this
141 if ($this->allowDelete
) {
142 foreach ($data as $name => $child) {
143 if (!$form->has($name)) {
149 $event->setData($data);
153 * Alias of {@link preSubmit()}.
155 * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
156 * {@link preSubmit()} instead.
158 public function preBind(FormEvent
$event)
160 $this->preSubmit($event);
164 * Alias of {@link onSubmit()}.
166 * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
167 * {@link onSubmit()} instead.
169 public function onBind(FormEvent
$event)
171 $this->onSubmit($event);