Completed
Push — master ( 2c86a7...690ed0 )
by
unknown
36:26 queued 28:50
created

WidgetMapBundle/Manager/WidgetMapManager.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
use Victoire\Bundle\WidgetMapBundle\Helper\WidgetMapHelper;
11
12
class WidgetMapManager
13
{
14
    private $em;
15
    private $builder;
16
17
    public function __construct(EntityManager $em, WidgetMapBuilder $builder)
18
    {
19
        $this->em = $em;
20
        $this->builder = $builder;
21
    }
22
23
    /**
24
     * Insert a WidgetMap in a view at given position.
25
     *
26
     * @param string $slotId
27
     */
28
    public function insert(Widget $widget, View $view, $slotId, $position, $widgetReference)
29
    {
30
        $quantum = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->findOneBy([
31
            'view'     => $view,
32
            'slot'     => $slotId,
33
            'position' => $position,
34
            'parent'   => $widgetReference,
35
            'action' => [
36
                WidgetMap::ACTION_CREATE,
37
                WidgetMap::ACTION_OVERWRITE
38
            ]
39
        ]);
40
41
        if ($quantum) {
42
            $widget->setWidgetMap($quantum);
43
            $view->addWidgetMap($quantum);
44
        } else {
45
            $parent = null;
46
            if ($widgetReference) {
47
                $parent = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find($widgetReference);
48
            }
49
            //create the new widget map
50
            $widgetMapEntry = new WidgetMap();
51
            $widgetMapEntry->setAction(WidgetMap::ACTION_CREATE);
52
            $widgetMapEntry->setSlot($slotId);
53
            $widgetMapEntry->setPosition($position);
54
            $widgetMapEntry->setParent($parent);
55
            $widget->setWidgetMap($widgetMapEntry);
56
57
            $view->addWidgetMap($widgetMapEntry);
58
        }
59
    }
60
61
    /**
62
     * moves a widget in a view.
63
     *
64
     * @param View  $view
65
     * @param array $sortedWidget
66
     *
67
     * @return void
68
     */
69
    public function move(View $view, $sortedWidget)
70
    {
71
        /** @var WidgetMap $parentWidgetMap */
72
        $parentWidgetMap = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['parentWidgetMap']);
73
        $position = $sortedWidget['position'];
74
        $slot = $sortedWidget['slot'];
75
        /** @var WidgetMap $widgetMap */
76
        $widgetMap = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['widgetMap']);
77
78
        $originalParent = $widgetMap->getParent();
79
        $originalPosition = $widgetMap->getPosition();
80
81
        $children = $widgetMap->getChildren($view);
82
        $beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null;
83
        $afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null;
84
85
        $parentWidgetMapChildren = $this->getChildrenByView($parentWidgetMap);
86
87
        $widgetMap = $this->moveWidgetMap($view, $widgetMap, $parentWidgetMap, $position, $slot);
88
89
        // If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side
90
        // and find the first place after the before widgetMap hierarchy to place the after widgetMap.
91
        $this->moveChildren($view, $beforeChild, $afterChild, $originalParent, $originalPosition);
92
93
        foreach ($parentWidgetMapChildren['views'] as $_view) {
94
            if ($_view !== $view) {
95 View Code Duplication
                if (isset($parentWidgetMapChildren['before'][$_view->getId()]) && $parentWidgetMapChildren['before'][$_view->getId()]->getPosition() == $widgetMap->getPosition()) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
                    $parentWidgetMapChildren['before'][$_view->getId()]->setParent($widgetMap);
97
                }
98 View Code Duplication
                if (isset($parentWidgetMapChildren['after'][$_view->getId()]) && $parentWidgetMapChildren['after'][$_view->getId()]->getPosition() == $widgetMap->getPosition()) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
                    $parentWidgetMapChildren['after'][$_view->getId()]->setParent($widgetMap);
100
                }
101
            }
102
        }
103
    }
104
105
    /**
106
     * Delete the widget from the view.
107
     *
108
     * @param View   $view
109
     * @param Widget $widget
110
     *
111
     * @throws \Exception Widget map does not exists
112
     */
113
    public function delete(View $view, Widget $widget)
114
    {
115
        $this->builder->build($view);
116
117
        $widgetMap = WidgetMapHelper::getWidgetMapByWidgetAndView($widget, $view);
118
        $slot = $widgetMap->getSlot();
119
120
        $originalParent = $widgetMap->getParent();
121
        $originalPosition = $widgetMap->getPosition();
122
123
        $children = $widgetMap->getChildren($view);
124
        $beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null;
125
        $afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null;
126
127
        //we remove the widget from the current view
128
        if ($widgetMap->getView() === $view) {
129
            // If the widgetMap has substitutes, delete them or transform them in create mode
130
            if (count($widgetMap->getSubstitutes()) > 0) {
131
                foreach ($widgetMap->getSubstitutes() as $substitute) {
132
                    if ($substitute->getAction() === WidgetMap::ACTION_OVERWRITE) {
133
                        $substitute->setAction(WidgetMap::ACTION_CREATE);
134
                        $substitute->setReplaced(null);
135
                    } else {
136
                        $view->removeWidgetMap($widgetMap);
137
                    }
138
                }
139
            }
140
            //remove the widget map from the slot
141
            $view->removeWidgetMap($widgetMap);
142
        } else {
143
            //the widget is owned by another view (a parent)
144
            //so we add a new widget map that indicates we delete this widget
145
            $replaceWidgetMap = new WidgetMap();
146
            $replaceWidgetMap->setAction(WidgetMap::ACTION_DELETE);
147
            $replaceWidgetMap->setWidget($widget);
148
            $replaceWidgetMap->setSlot($slot);
149
            $replaceWidgetMap->setReplaced($widgetMap);
150
151
            $view->addWidgetMap($replaceWidgetMap);
152
        }
153
154
        $this->moveChildren($view, $beforeChild, $afterChild, $originalParent, $originalPosition);
155
    }
156
157
    /**
158
     * the widget is owned by another view (a parent)
159
     * so we add a new widget map that indicates we delete this widget.
160
     *
161
     * @param View      $view
162
     * @param WidgetMap $originalWidgetMap
163
     * @param Widget    $widgetCopy
164
     *
165
     * @throws \Exception
166
     */
167
    public function overwrite(View $view, WidgetMap $originalWidgetMap, Widget $widgetCopy)
168
    {
169
        $widgetMap = new WidgetMap();
170
        $widgetMap->setAction(WidgetMap::ACTION_OVERWRITE);
171
        $widgetMap->setReplaced($originalWidgetMap);
172
        $widgetCopy->setWidgetMap($widgetMap);
173
        $widgetMap->setSlot($originalWidgetMap->getSlot());
174
        $widgetMap->setPosition($originalWidgetMap->getPosition());
175
        $widgetMap->setParent($originalWidgetMap->getParent());
176
177
        $view->addWidgetMap($widgetMap);
178
    }
179
180
    /**
181
     * If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side
182
     * and find the first place after the before widgetMap hierarchy to place the after widgetMap.
183
     *
184
     * @param View $view
185
     * @param $beforeChild
186
     * @param $afterChild
187
     * @param $originalParent
188
     * @param $originalPosition
189
     */
190
    public function moveChildren(View $view, $beforeChild, $afterChild, $originalParent, $originalPosition)
191
    {
192
        if ($beforeChild && $afterChild) {
193
            $this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition);
194
195
            $child = $beforeChild;
196
            while ($child->getChild(WidgetMap::POSITION_AFTER)) {
197
                $child = $child->getChild(WidgetMap::POSITION_AFTER);
198
            }
199
            if ($afterChild->getId() !== $child->getId()) {
200
                $this->moveWidgetMap($view, $afterChild, $child);
201
            }
202
        } elseif ($beforeChild) {
203
            $this->moveWidgetMap($view, $beforeChild, $originalParent, $originalPosition);
204
        } elseif ($afterChild) {
205
            $this->moveWidgetMap($view, $afterChild, $originalParent, $originalPosition);
206
        }
207
    }
208
209
    /**
210
     * Create a copy of a WidgetMap in "overwrite" mode and insert it in the given view.
211
     *
212
     * @param WidgetMap $widgetMap
213
     * @param View      $view
214
     *
215
     * @throws \Exception
216
     *
217
     * @return WidgetMap
218
     */
219
    protected function cloneWidgetMap(WidgetMap $widgetMap, View $view)
220
    {
221
        $originalWidgetMap = $widgetMap;
222
        $widgetMap = clone $widgetMap;
223
        $widgetMap->setId(null);
224
        $widgetMap->setAction(WidgetMap::ACTION_OVERWRITE);
225
        $widgetMap->setReplaced($originalWidgetMap);
226
        $widgetMap->setView($view);
227
        $view->addWidgetMap($widgetMap);
228
        $this->em->persist($widgetMap);
229
230
        return $widgetMap;
231
    }
232
233
    /**
234
     * Move given WidgetMap as a child of given parent at given position and slot.
235
     *
236
     * @param View      $view
237
     * @param WidgetMap $widgetMap
238
     * @param bool      $parent
239
     * @param bool      $position
240
     * @param bool      $slot
241
     *
242
     * @return WidgetMap
243
     */
244
    protected function moveWidgetMap(View $view, WidgetMap $widgetMap, $parent = false, $position = false, $slot = false)
245
    {
246
        if ($widgetMap->getView() !== $view) {
247
            $widgetMap = $this->cloneWidgetMap($widgetMap, $view);
248
        }
249
250
        if ($parent !== false) {
251
            if ($oldParent = $widgetMap->getParent()) {
252
                $oldParent->removeChild($widgetMap);
253
            }
254
            $widgetMap->setParent($parent);
255
            if ($parent) {
256
                $parent->addChild($widgetMap);
257
            }
258
        }
259
        if ($position !== false) {
260
            $widgetMap->setPosition($position);
261
        }
262
        if ($slot !== false) {
263
            $widgetMap->setSlot($slot);
264
        }
265
266
        return $widgetMap;
267
    }
268
269
    /**
270
     * Find return all the given WidgetMap children for each view where it's related.
271
     *
272
     * @param WidgetMap $widgetMap
273
     *
274
     * @return mixed
275
     */
276
    protected function getChildrenByView(WidgetMap $widgetMap)
277
    {
278
        $beforeChilds = $widgetMap->getChilds(WidgetMap::POSITION_BEFORE);
279
        $afterChilds = $widgetMap->getChilds(WidgetMap::POSITION_AFTER);
280
281
        $childrenByView['views'] = [];
282
        $childrenByView['before'] = [];
283
        $childrenByView['after'] = [];
284
        foreach ($beforeChilds as $beforeChild) {
285
            $view = $beforeChild->getView();
286
            $childrenByView['views'][] = $view;
287
            $childrenByView['before'][$view->getId()] = $beforeChild;
288
        }
289
        foreach ($afterChilds as $afterChild) {
290
            $view = $afterChild->getView();
291
            $childrenByView['views'][] = $view;
292
            $childrenByView['after'][$view->getId()] = $afterChild;
293
        }
294
295
        return $childrenByView;
296
    }
297
}
298