MergeCollectionListener.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. /*
  3. * This file is part of the Sonata Project package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Form\EventListener;
  11. use Sonata\AdminBundle\Model\ModelManagerInterface;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Form\FormEvent;
  14. use Symfony\Component\Form\FormEvents;
  15. /**
  16. * Class MergeCollectionListener.
  17. *
  18. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  19. */
  20. class MergeCollectionListener implements EventSubscriberInterface
  21. {
  22. /**
  23. * @var ModelManagerInterface
  24. */
  25. protected $modelManager;
  26. /**
  27. * @param ModelManagerInterface $modelManager
  28. */
  29. public function __construct(ModelManagerInterface $modelManager)
  30. {
  31. $this->modelManager = $modelManager;
  32. }
  33. /**
  34. * {@inheritdoc}
  35. */
  36. public static function getSubscribedEvents()
  37. {
  38. return array(
  39. FormEvents::SUBMIT => array('onBind', 10),
  40. );
  41. }
  42. /**
  43. * @param FormEvent $event
  44. */
  45. public function onBind(FormEvent $event)
  46. {
  47. $collection = $event->getForm()->getData();
  48. $data = $event->getData();
  49. // looks like there is no way to remove other listeners
  50. $event->stopPropagation();
  51. if (!$collection) {
  52. $collection = $data;
  53. } elseif (count($data) === 0) {
  54. $this->modelManager->collectionClear($collection);
  55. } else {
  56. // merge $data into $collection
  57. foreach ($collection as $entity) {
  58. if (!$this->modelManager->collectionHasElement($data, $entity)) {
  59. $this->modelManager->collectionRemoveElement($collection, $entity);
  60. } else {
  61. $this->modelManager->collectionRemoveElement($data, $entity);
  62. }
  63. }
  64. foreach ($data as $entity) {
  65. $this->modelManager->collectionAddElement($collection, $entity);
  66. }
  67. }
  68. $event->setData($collection);
  69. }
  70. }