]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/Extension/Core/EventListener/MergeCollectionListener.php
twig implementation
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / Extension / Core / EventListener / MergeCollectionListener.php
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\Form\Extension\Core\EventListener;
13
14 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15 use Symfony\Component\Form\FormEvents;
16 use Symfony\Component\Form\FormEvent;
17 use Symfony\Component\Form\Exception\UnexpectedTypeException;
18
19 /**
20 * @author Bernhard Schussek <bschussek@gmail.com>
21 */
22 class MergeCollectionListener implements EventSubscriberInterface
23 {
24 /**
25 * Whether elements may be added to the collection
26 * @var Boolean
27 */
28 private $allowAdd;
29
30 /**
31 * Whether elements may be removed from the collection
32 * @var Boolean
33 */
34 private $allowDelete;
35
36 /**
37 * Creates a new listener.
38 *
39 * @param Boolean $allowAdd Whether values might be added to the
40 * collection.
41 * @param Boolean $allowDelete Whether values might be removed from the
42 * collection.
43 */
44 public function __construct($allowAdd = false, $allowDelete = false)
45 {
46 $this->allowAdd = $allowAdd;
47 $this->allowDelete = $allowDelete;
48 }
49
50 public static function getSubscribedEvents()
51 {
52 return array(
53 FormEvents::SUBMIT => 'onSubmit',
54 );
55 }
56
57 public function onSubmit(FormEvent $event)
58 {
59 $dataToMergeInto = $event->getForm()->getNormData();
60 $data = $event->getData();
61
62 if (null === $data) {
63 $data = array();
64 }
65
66 if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) {
67 throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
68 }
69
70 if (null !== $dataToMergeInto && !is_array($dataToMergeInto) && !($dataToMergeInto instanceof \Traversable && $dataToMergeInto instanceof \ArrayAccess)) {
71 throw new UnexpectedTypeException($dataToMergeInto, 'array or (\Traversable and \ArrayAccess)');
72 }
73
74 // If we are not allowed to change anything, return immediately
75 if ((!$this->allowAdd && !$this->allowDelete) || $data === $dataToMergeInto) {
76 $event->setData($dataToMergeInto);
77
78 return;
79 }
80
81 if (!$dataToMergeInto) {
82 // No original data was set. Set it if allowed
83 if ($this->allowAdd) {
84 $dataToMergeInto = $data;
85 }
86 } else {
87 // Calculate delta
88 $itemsToAdd = is_object($data) ? clone $data : $data;
89 $itemsToDelete = array();
90
91 foreach ($dataToMergeInto as $beforeKey => $beforeItem) {
92 foreach ($data as $afterKey => $afterItem) {
93 if ($afterItem === $beforeItem) {
94 // Item found, next original item
95 unset($itemsToAdd[$afterKey]);
96 continue 2;
97 }
98 }
99
100 // Item not found, remember for deletion
101 $itemsToDelete[] = $beforeKey;
102 }
103
104 // Remove deleted items before adding to free keys that are to be
105 // replaced
106 if ($this->allowDelete) {
107 foreach ($itemsToDelete as $key) {
108 unset($dataToMergeInto[$key]);
109 }
110 }
111
112 // Add remaining items
113 if ($this->allowAdd) {
114 foreach ($itemsToAdd as $key => $item) {
115 if (!isset($dataToMergeInto[$key])) {
116 $dataToMergeInto[$key] = $item;
117 } else {
118 $dataToMergeInto[] = $item;
119 }
120 }
121 }
122 }
123
124 $event->setData($dataToMergeInto);
125 }
126
127 /**
128 * Alias of {@link onSubmit()}.
129 *
130 * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
131 * {@link onSubmit()} instead.
132 */
133 public function onBind(FormEvent $event)
134 {
135 $this->onSubmit($event);
136 }
137 }