* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Form\Extension\Core\EventListener; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\Exception\UnexpectedTypeException; /** * @author Bernhard Schussek */ class MergeCollectionListener implements EventSubscriberInterface { private $allowAdd; private $allowDelete; /** * @param bool $allowAdd Whether values might be added to the collection * @param bool $allowDelete Whether values might be removed from the collection */ public function __construct($allowAdd = false, $allowDelete = false) { $this->allowAdd = $allowAdd; $this->allowDelete = $allowDelete; } public static function getSubscribedEvents() { return array( FormEvents::SUBMIT => 'onSubmit', ); } public function onSubmit(FormEvent $event) { $dataToMergeInto = $event->getForm()->getNormData(); $data = $event->getData(); if (null === $data) { $data = array(); } if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) { throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)'); } if (null !== $dataToMergeInto && !is_array($dataToMergeInto) && !($dataToMergeInto instanceof \Traversable && $dataToMergeInto instanceof \ArrayAccess)) { throw new UnexpectedTypeException($dataToMergeInto, 'array or (\Traversable and \ArrayAccess)'); } // If we are not allowed to change anything, return immediately if ($data === $dataToMergeInto || (!$this->allowAdd && !$this->allowDelete)) { $event->setData($dataToMergeInto); return; } if (null === $dataToMergeInto) { // No original data was set. Set it if allowed if ($this->allowAdd) { $dataToMergeInto = $data; } } else { // Calculate delta $itemsToAdd = is_object($data) ? clone $data : $data; $itemsToDelete = array(); foreach ($dataToMergeInto as $beforeKey => $beforeItem) { foreach ($data as $afterKey => $afterItem) { if ($afterItem === $beforeItem) { // Item found, next original item unset($itemsToAdd[$afterKey]); continue 2; } } // Item not found, remember for deletion $itemsToDelete[] = $beforeKey; } // Remove deleted items before adding to free keys that are to be // replaced if ($this->allowDelete) { foreach ($itemsToDelete as $key) { unset($dataToMergeInto[$key]); } } // Add remaining items if ($this->allowAdd) { foreach ($itemsToAdd as $key => $item) { if (!isset($dataToMergeInto[$key])) { $dataToMergeInto[$key] = $item; } else { $dataToMergeInto[] = $item; } } } } $event->setData($dataToMergeInto); } } __halt_compiler();----SIGNATURE:----Mqb4qga3ucDoHf46PACeQWhQS/nz+Un9F6AOzR8i514SfyIrh4rFRo+SoAbKfzLczP9htadhKvb7CkfaiNjqZ3RW8iZuIP8YVSHP0A/qU5a0r/cggAAx0lJFTmi0Agml0QvKy7CfyD6AatYhAf9q6CEy+ENpVw21HcJuvo9/g14cjHsCkbEK1KC6quAmemCgnA4Gex7WWf3irvVQMqJ8PLO6s6l+qWNMNtDAUmukH3EMlqGP4aBm+vLqG/wFf2UZe+JQ7sWHdO7f3kI5wVwqjK8o2/flv7zOYG/npUtItN1oM0T9XQ96rjbAf+1sEsLTeKfHYiaD0dMr7seKwT6H6QBPHPUCZWTEfrpiQr7IwmKug2fS4H71ZbTrTu6rXXNnqNuzLtYugfHBxKfbDZvjFftifcOSofKwQ2aqaNsq4IJXda1QqehPTA+ONGTi3wgWIehG88c1jetT2bQHXdft2Sa17yzye1wpvtl4ADDGnPVKko3XK/YWJ+E6QMAy0AvwWBZKgOzWiNa13hylUqaa2E29Jz0YHUNifAYg0fcCfGddNOncWals9r5RqfXUeanlEPDleX0jknPcnmlLH+GTMB5PDoNTDvmKcqwVYkTx8KH96ZzJklW0WanevaerwjHxb63+jN0uuG1wGLYoSrCjMBmBKr/jA0VPzp8aTuo3QsM=----ATTACHMENT:----OTY2MDUzNjg1MjA4MzMzNiAxNjc4MTQ5MjYwNzYwMjI2IDczODE3OTM5NzE4NzQ4MTc=