* * 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:----I1rSmolFkNLneH4oRsvE9oQCSA9V31SCQOkbg3EpdDWjZaacc9srnLvl1dWab4nJFqdjj1JBtehSniFxB0WIKZKlGUNMsdsRmiQ7CIIWJysY+1j8pOsJ7F7/0SjqHTrnt4NBA0jDVZC7tU3yRnm450JmgW1c4S3XIp+WBJ5W+zQCQ1GGmN0x858BP60hSbPv6UsA3U/6bP1KybHILrQnenoxHq37W8d9dDGn8CbFm3x5ZI8q0N/nQL9Q74JdLbLII3bVITBIWGDTVTZdZjfbf79neqJ4LcrjEvzGHxtqXHq3Qt+jzlJPhL5yl275lisglkwQGeeQYF/MQKDVupGKohqZvkQrXPiY+i5vpGsTvHtvqQyMC/YHdlLi3p92A8DxguLlr0deOnUSVE6hsth5SIJAOI50Bs1zCloH9uKlYvWGuxgWGQxFjZ7u0eDmf6vDvk0yx4ZyM1d/8mHcMHHgTnDLquyOWGr7X6pLNGPJ8n0sOd8OwrJ3rT3XhOBZOMFdyu8l7bBRiVlgXOdrx/HUqHiZlLwhcQWjASJrXQu5+HUOnNyDN/lYUBvus5Nrf2Xj/G5S3Z3zV3E6OezghcWgO1zuBRRkGUC1QPSnKROfXN3fYD/2Oh3vv86wSZYDYEIL4F2nkL0QtwR7TPpgr0f81LpyOkDIjcx+A42LcsJEpEc=----ATTACHMENT:----OTY2Mzk2MDMxNTA1NTkzMyA1MDc0NjY3OTQ1ODkzNjIyIDI1MzU2ODgyNjkyNzM0OTU=