|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Victoire\Bundle\WidgetMapBundle\Manager; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\Orm\EntityManager; |
|
6
|
|
|
use Victoire\Bundle\CoreBundle\Entity\View; |
|
7
|
|
|
use Victoire\Bundle\WidgetBundle\Entity\Widget; |
|
8
|
|
|
use Victoire\Bundle\WidgetMapBundle\Builder\WidgetMapBuilder; |
|
9
|
|
|
use Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap; |
|
10
|
|
|
|
|
11
|
|
|
class WidgetMapManager |
|
12
|
|
|
{ |
|
13
|
|
|
private $em; |
|
14
|
|
|
private $builder; |
|
15
|
|
|
|
|
16
|
|
|
public function __construct(EntityManager $em, WidgetMapBuilder $builder) |
|
|
|
|
|
|
17
|
|
|
{ |
|
18
|
|
|
$this->em = $em; |
|
19
|
|
|
$this->builder = $builder; |
|
20
|
|
|
} |
|
21
|
|
|
|
|
22
|
|
|
public function insert(Widget $widget, View $view, $slotId, $position, $widgetReference) |
|
23
|
|
|
{ |
|
24
|
|
|
$parent = null; |
|
25
|
|
|
if ($widgetReference) { |
|
26
|
|
|
$parent = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find($widgetReference); |
|
27
|
|
|
} |
|
28
|
|
|
//create the new widget map |
|
29
|
|
|
$widgetMapEntry = new WidgetMap(); |
|
30
|
|
|
$widgetMapEntry->setAction(WidgetMap::ACTION_CREATE); |
|
31
|
|
|
$widgetMapEntry->setWidget($widget); |
|
32
|
|
|
$widgetMapEntry->setSlot($slotId); |
|
33
|
|
|
$widgetMapEntry->setPosition($position); |
|
34
|
|
|
$widgetMapEntry->setParent($parent); |
|
|
|
|
|
|
35
|
|
|
|
|
36
|
|
|
$view->addWidgetMap($widgetMapEntry); |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* moves a widget in a view. |
|
41
|
|
|
* |
|
42
|
|
|
* @param View $view |
|
43
|
|
|
* @param array $sortedWidget |
|
44
|
|
|
* |
|
45
|
|
|
* @returns void |
|
46
|
|
|
*/ |
|
47
|
|
|
public function move(View $view, $sortedWidget) |
|
48
|
|
|
{ |
|
49
|
|
|
/** @var WidgetMap $widgetMapReference */ |
|
50
|
|
|
$widgetMapReference = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['widgetMapReference']); |
|
51
|
|
|
$position = $sortedWidget['position']; |
|
52
|
|
|
$slot = $sortedWidget['slot']; |
|
53
|
|
|
/** @var WidgetMap $widgetMap */ |
|
54
|
|
|
$widgetMap = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['widgetMap']); |
|
55
|
|
|
|
|
56
|
|
|
$originalParent = $widgetMap->getParent(); |
|
57
|
|
|
$originalPosition = $widgetMap->getPosition(); |
|
58
|
|
|
|
|
59
|
|
|
$children = $widgetMap->getChildren($view); |
|
60
|
|
|
$beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null; |
|
61
|
|
|
$afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null; |
|
62
|
|
|
|
|
63
|
|
|
$widgetMapReferenceChildren = $this->getChildrenByView($widgetMapReference); |
|
64
|
|
|
|
|
65
|
|
|
$widgetMap = $this->moveWidgetMap($view, $widgetMap, $widgetMapReference, $position, $slot); |
|
|
|
|
|
|
66
|
|
|
|
|
67
|
|
|
// If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side |
|
68
|
|
|
// and find the first place after the before widgetMap hierarchy to place the after widgetMap. |
|
69
|
|
View Code Duplication |
if ($beforeChild && $afterChild) { |
|
|
|
|
|
|
70
|
|
|
$this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition); |
|
|
|
|
|
|
71
|
|
|
|
|
72
|
|
|
$child = $beforeChild; |
|
73
|
|
|
while ($child->getChild(WidgetMap::POSITION_AFTER)) { |
|
74
|
|
|
$child = $child->getChild(WidgetMap::POSITION_AFTER); |
|
75
|
|
|
} |
|
76
|
|
|
if ($afterChild->getId() !== $child->getId()) { |
|
77
|
|
|
$this->moveWidgetMap($view, $afterChild, $child); |
|
78
|
|
|
} |
|
79
|
|
|
} elseif ($beforeChild) { |
|
80
|
|
|
$this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition); |
|
|
|
|
|
|
81
|
|
|
} elseif ($afterChild) { |
|
82
|
|
|
$this->moveWidgetMap($view, $afterChild, $originalParent, $originalPosition); |
|
|
|
|
|
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
foreach ($widgetMapReferenceChildren['views'] as $_view) { |
|
86
|
|
|
if ($_view->getId() !== $view->getId()) { |
|
87
|
|
View Code Duplication |
if (isset($widgetMapReferenceChildren['before'][$_view->getId()])) { |
|
|
|
|
|
|
88
|
|
|
$widgetMapReferenceChildren['before'][$_view->getId()]->setParent($widgetMap); |
|
89
|
|
|
} |
|
90
|
|
View Code Duplication |
if (isset($widgetMapReferenceChildren['after'][$_view->getId()])) { |
|
|
|
|
|
|
91
|
|
|
$widgetMapReferenceChildren['after'][$_view->getId()]->setParent($widgetMap); |
|
92
|
|
|
} |
|
93
|
|
|
} |
|
94
|
|
|
} |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
/** |
|
98
|
|
|
* Delete the widget from the view. |
|
99
|
|
|
* |
|
100
|
|
|
* @param View $view |
|
101
|
|
|
* @param Widget $widget |
|
102
|
|
|
* |
|
103
|
|
|
* @throws \Exception Widget map does not exists |
|
104
|
|
|
*/ |
|
105
|
|
|
public function delete(View $view, Widget $widget) |
|
106
|
|
|
{ |
|
107
|
|
|
$this->builder->build($view); |
|
108
|
|
|
|
|
109
|
|
|
$widgetMap = $view->getWidgetMapByWidget($widget); |
|
110
|
|
|
$slot = $widgetMap->getSlot(); |
|
111
|
|
|
|
|
112
|
|
|
$originalParent = $widgetMap->getParent(); |
|
113
|
|
|
$originalPosition = $widgetMap->getPosition(); |
|
114
|
|
|
|
|
115
|
|
|
$children = $widgetMap->getChildren($view); |
|
116
|
|
|
$beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null; |
|
117
|
|
|
$afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null; |
|
118
|
|
|
|
|
119
|
|
|
//we remove the widget from the current view |
|
120
|
|
|
if ($widgetMap->getView() === $view) { |
|
121
|
|
|
//remove the widget map from the slot |
|
122
|
|
|
$view->removeWidgetMap($widgetMap); |
|
123
|
|
|
} else { |
|
124
|
|
|
//the widget is owned by another view (a parent) |
|
125
|
|
|
//so we add a new widget map that indicates we delete this widget |
|
126
|
|
|
$replaceWidgetMap = new WidgetMap(); |
|
127
|
|
|
$replaceWidgetMap->setAction(WidgetMap::ACTION_DELETE); |
|
128
|
|
|
$replaceWidgetMap->setWidget($widget); |
|
129
|
|
|
$replaceWidgetMap->setSlot($slot); |
|
130
|
|
|
$replaceWidgetMap->setReplaced($widgetMap); |
|
131
|
|
|
|
|
132
|
|
|
$view->addWidgetMap($replaceWidgetMap); |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
$this->moveChildren($view, $beforeChild, $afterChild, $originalParent, $originalPosition); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* the widget is owned by another view (a parent) |
|
140
|
|
|
* so we add a new widget map that indicates we delete this widget. |
|
141
|
|
|
* |
|
142
|
|
|
* @param View $view |
|
143
|
|
|
* @param WidgetMap $originalWidgetMap |
|
144
|
|
|
* @param Widget $widgetCopy |
|
145
|
|
|
* |
|
146
|
|
|
* @throws \Exception |
|
147
|
|
|
*/ |
|
148
|
|
|
public function overwrite(View $view, WidgetMap $originalWidgetMap, Widget $widgetCopy) |
|
149
|
|
|
{ |
|
150
|
|
|
$widgetMap = new WidgetMap(); |
|
151
|
|
|
$widgetMap->setAction(WidgetMap::ACTION_OVERWRITE); |
|
152
|
|
|
$widgetMap->setReplaced($originalWidgetMap); |
|
153
|
|
|
$widgetMap->setWidget($widgetCopy); |
|
154
|
|
|
$widgetMap->setView($view); |
|
155
|
|
|
$widgetMap->setSlot($originalWidgetMap->getSlot()); |
|
156
|
|
|
$widgetMap->setPosition($originalWidgetMap->getPosition()); |
|
157
|
|
|
$widgetMap->setAsynchronous($widgetCopy->isAsynchronous()); |
|
158
|
|
|
$widgetMap->setParent($originalWidgetMap->getParent()); |
|
159
|
|
|
|
|
160
|
|
|
$view->addWidgetMap($widgetMap); |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side |
|
165
|
|
|
* and find the first place after the before widgetMap hierarchy to place the after widgetMap. |
|
166
|
|
|
* |
|
167
|
|
|
* @param View $view |
|
168
|
|
|
* @param $beforeChild |
|
169
|
|
|
* @param $afterChild |
|
170
|
|
|
* @param $originalParent |
|
171
|
|
|
* @param $originalPosition |
|
172
|
|
|
*/ |
|
173
|
|
|
public function moveChildren(View $view, $beforeChild, $afterChild, $originalParent, $originalPosition) |
|
174
|
|
|
{ |
|
175
|
|
View Code Duplication |
if ($beforeChild && $afterChild) { |
|
|
|
|
|
|
176
|
|
|
$this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition); |
|
177
|
|
|
|
|
178
|
|
|
$child = $beforeChild; |
|
179
|
|
|
while ($child->getChild(WidgetMap::POSITION_AFTER)) { |
|
180
|
|
|
$child = $child->getChild(WidgetMap::POSITION_AFTER); |
|
181
|
|
|
} |
|
182
|
|
|
if ($afterChild->getId() !== $child->getId()) { |
|
183
|
|
|
$this->moveWidgetMap($view, $afterChild, $child); |
|
184
|
|
|
} |
|
185
|
|
|
} elseif ($beforeChild) { |
|
186
|
|
|
$this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition); |
|
187
|
|
|
} elseif ($afterChild) { |
|
188
|
|
|
$this->moveWidgetMap($view, $afterChild, $originalParent, $originalPosition); |
|
189
|
|
|
} |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
protected function cloneWidgetMap(WidgetMap $widgetMap, View $view) |
|
193
|
|
|
{ |
|
194
|
|
|
$originalWidgetMap = $widgetMap; |
|
195
|
|
|
$widgetMap = clone $widgetMap; |
|
196
|
|
|
$widgetMap->setId(null); |
|
197
|
|
|
$widgetMap->setAction(WidgetMap::ACTION_OVERWRITE); |
|
198
|
|
|
$widgetMap->setReplaced($originalWidgetMap); |
|
199
|
|
|
$originalWidgetMap->addSubstitute($widgetMap); |
|
200
|
|
|
$view->addWidgetMap($widgetMap); |
|
201
|
|
|
$this->em->persist($widgetMap); |
|
202
|
|
|
|
|
203
|
|
|
return $widgetMap; |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
protected function moveWidgetMap(View $view, WidgetMap $widgetMap, $parent = false, $position = false, $slot = false) |
|
207
|
|
|
{ |
|
208
|
|
|
if ($widgetMap->getView() !== $view) { |
|
209
|
|
|
$widgetMap = $this->cloneWidgetMap($widgetMap, $view); |
|
210
|
|
|
} |
|
211
|
|
|
|
|
212
|
|
|
if ($parent !== false) { |
|
213
|
|
|
if ($oldParent = $widgetMap->getParent()) { |
|
214
|
|
|
$oldParent->removeChild($widgetMap); |
|
215
|
|
|
} |
|
216
|
|
|
$widgetMap->setParent($parent); |
|
|
|
|
|
|
217
|
|
|
if ($parent) { |
|
218
|
|
|
$parent->addChild($widgetMap); |
|
|
|
|
|
|
219
|
|
|
} |
|
220
|
|
|
} |
|
221
|
|
|
if ($position !== false) { |
|
222
|
|
|
$widgetMap->setPosition($position); |
|
|
|
|
|
|
223
|
|
|
} |
|
224
|
|
|
if ($slot !== false) { |
|
225
|
|
|
$widgetMap->setSlot($slot); |
|
|
|
|
|
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
return $widgetMap; |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
public function getChildrenByView(WidgetMap $widgetMap) |
|
232
|
|
|
{ |
|
233
|
|
|
$beforeChilds = $widgetMap->getChilds(WidgetMap::POSITION_BEFORE); |
|
234
|
|
|
$afterChilds = $widgetMap->getChilds(WidgetMap::POSITION_AFTER); |
|
235
|
|
|
|
|
236
|
|
|
$childrenByView['views'] = []; |
|
|
|
|
|
|
237
|
|
|
$childrenByView['before'] = []; |
|
238
|
|
|
$childrenByView['after'] = []; |
|
239
|
|
|
foreach ($beforeChilds as $beforeChild) { |
|
240
|
|
|
$view = $beforeChild->getView(); |
|
241
|
|
|
$childrenByView['views'][] = $view; |
|
242
|
|
|
$childrenByView['before'][$view->getId()] = $beforeChild; |
|
243
|
|
|
} |
|
244
|
|
|
foreach ($afterChilds as $afterChild) { |
|
245
|
|
|
$view = $afterChild->getView(); |
|
246
|
|
|
$childrenByView['views'][] = $view; |
|
247
|
|
|
$childrenByView['after'][$view->getId()] = $afterChild; |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
return $childrenByView; |
|
251
|
|
|
} |
|
252
|
|
|
} |
|
253
|
|
|
|
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.