WidgetMapBuilder::findRootWidgetMap()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
3
namespace Victoire\Bundle\WidgetMapBundle\Builder;
4
5
use Victoire\Bundle\CoreBundle\Entity\View;
6
use Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap;
7
use Victoire\Bundle\WidgetMapBundle\Resolver\WidgetMapChildrenResolver;
8
use Victoire\Bundle\WidgetMapBundle\Warmer\ContextualViewWarmer;
9
10
/**
11
 * View WidgetMap builder.
12
 *
13
 * ref: victoire_widget_map.builder
14
 */
15
class WidgetMapBuilder
16
{
17
    private $contextualViewWarmer;
18
    private $resolver;
19
20
    /**
21
     * WidgetMapBuilder constructor.
22
     *
23
     * @param ContextualViewWarmer      $contextualViewWarmer
24
     * @param WidgetMapChildrenResolver $resolver
25
     */
26
    public function __construct(
27
        ContextualViewWarmer $contextualViewWarmer,
28
        WidgetMapChildrenResolver $resolver
29
    ) {
30
        $this->contextualViewWarmer = $contextualViewWarmer;
31
        $this->resolver = $resolver;
32
    }
33
34
    /**
35
     * This method build widgetmaps relativly to given view and it's templates.
36
     *
37
     * @param View $view
38
     * @param bool $updatePage
39
     *
40
     * @return array
41
     */
42
    public function build(View $view, $updatePage = true)
43
    {
44
        $builtWidgetMap = [];
45
46
        $widgetMaps = $this->contextualViewWarmer->warm($view);
47
48
        $slots = $this->removeOverwritedWidgetMaps($widgetMaps);
49
50
        $this->removeDeletedWidgetMaps($slots);
51
52
        foreach ($slots as $slot => $slotWidgetMaps) {
53
            $mainWidgetMap = null;
0 ignored issues
show
Unused Code introduced by
$mainWidgetMap is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
54
            $builtWidgetMap[$slot] = [];
55
56
            $rootWidgetMap = $this->findRootWidgetMap($slotWidgetMaps);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $rootWidgetMap is correct as $this->findRootWidgetMap($slotWidgetMaps) (which targets Victoire\Bundle\WidgetMa...er::findRootWidgetMap()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
57
58
            if ($rootWidgetMap) {
59
                $builtWidgetMap[$slot][] = $rootWidgetMap;
60
                $builtWidgetMap = $this->orderizeWidgetMap($rootWidgetMap, $builtWidgetMap, $slot, $slotWidgetMaps, $view);
61
            }
62
        }
63
64
        if ($updatePage) {
65
            $view->setBuiltWidgetMap($builtWidgetMap);
66
        }
67
68
        return $builtWidgetMap;
69
    }
70
71
    /**
72
     * This method takes the builtWidgetMap for view and creates an array that indicate, for
73
     * each widgetmap, if the position "after" and "before" are available.
74
     *
75
     * @param View $view
76
     *
77
     * @return array
78
     */
79
    public function getAvailablePosition(View $view)
80
    {
81
        $widgetMaps = $view->getBuiltWidgetMap();
82
83
        $availablePositions = [];
84
        foreach ($widgetMaps as $slot => $widgetMap) {
85
            foreach ($widgetMap as $_widgetMap) {
86
                $availablePositions[$slot][$_widgetMap->getId()]['id'] = $_widgetMap->getId();
87
                $availablePositions[$slot][$_widgetMap->getId()][WidgetMap::POSITION_BEFORE] = true;
88
                $availablePositions[$slot][$_widgetMap->getId()][WidgetMap::POSITION_AFTER] = true;
89
                if ($_widgetMap->getReplaced()) {
90
                    $availablePositions[$slot][$_widgetMap->getId()]['replaced'] = $_widgetMap->getReplaced()->getId();
91
                }
92
            }
93
            /** @var WidgetMap $_widgetMap */
94
            foreach ($widgetMap as $_widgetMap) {
95
                if ($_widgetMap->getParent()) {
96
                    if ($substitute = $_widgetMap->getParent()->getSubstituteForView($view)) {
97
                        $availablePositions[$slot][$substitute->getId()][$_widgetMap->getPosition()] = false;
98
                    } else {
99
                        $availablePositions[$slot][$_widgetMap->getParent()->getId()][$_widgetMap->getPosition()] = false;
100
                    }
101
                }
102
            }
103
        }
104
105
        return $availablePositions;
106
    }
107
108
    /**
109
     * Get the children of given WidgetMap and place them recursively in the "builtWidgetMap" array at the right place
110
     * depending of the children parents and positions.
111
     *
112
     * @param WidgetMap $currentWidgetMap
113
     * @param $builtWidgetMap
114
     * @param $slot
115
     * @param $slotWidgetMaps
116
     * @param View $view
117
     *
118
     * @return mixed
119
     */
120
    protected function orderizeWidgetMap(WidgetMap $currentWidgetMap, $builtWidgetMap, $slot, $slotWidgetMaps, View $view)
121
    {
122
        $children = $this->resolver->getChildren($currentWidgetMap, $view);
123
        foreach ($children as $child) {
124
            // check if the founded child belongs to the view
125
            if (in_array($child, $slotWidgetMaps, true)) {
126
                // Find the position of the "currentWidgetMap" inside the builtWidgetMap,
127
                // add "1" to this position if wanted position is "after", 0 is it's before.
128
                $offset = array_search($currentWidgetMap, $builtWidgetMap[$slot]) + ($child->getPosition() == WidgetMap::POSITION_AFTER ? 1 : 0);
129
                // insert the child in builtWidgetMap at offset position
130
                array_splice($builtWidgetMap[$slot], $offset, 0, [$child]);
131
                // call myself with child
132
                $builtWidgetMap = $this->orderizeWidgetMap($child, $builtWidgetMap, $slot, $slotWidgetMaps, $view);
133
            }
134
        }
135
136
        return $builtWidgetMap;
137
    }
138
139
    /**
140
     * Create a $slot array that'll contain, for each slot, a widgetmap id as key and a widgetmap as value
141
     * Do not keeps widgetMaps that are overwrited.
142
     *
143
     * @param $widgetMaps
144
     *
145
     * @return array
146
     */
147
    protected function removeOverwritedWidgetMaps($widgetMaps)
148
    {
149
        $slots = [];
150
        /** @var WidgetMap $widgetMapItem */
151
        foreach ($widgetMaps as $widgetMapItem) {
152
            $id = $widgetMapItem->getId();
153
            // If the widgetmap replace one (has a "replaced"), use the replaced id as key
154
            if ($widgetMapItem->getReplaced()) {
155
                $id = $widgetMapItem->getReplaced()->getId();
156
            }
157
            // If "id" is not present in slot array or
158
            if (empty($slots[$widgetMapItem->getSlot()][$id])
159
                // or if the id exists AND the inserted widgetmap is overwrite|delete, then erase the initial widget by it
160
                || !empty($slots[$widgetMapItem->getSlot()][$id])
161
                && $widgetMapItem->getAction() !== WidgetMap::ACTION_CREATE) {
162
                $slots[$widgetMapItem->getSlot()][$id] = $widgetMapItem;
163
            }
164
        }
165
166
        return $slots;
167
    }
168
169
    /**
170
     * If "delete" widgetmaps are found, remove it because they're not rendered.
171
     *
172
     * @param $slots
173
     */
174
    protected function removeDeletedWidgetMaps(&$slots)
175
    {
176
        foreach ($slots as $slot => $widgetMaps) {
177
            foreach ($widgetMaps as $key => $widgetMap) {
178
                if ($widgetMap->getAction() == WidgetMap::ACTION_DELETE) {
179
                    unset($slots[$slot][$key]);
180
                }
181
            }
182
        }
183
    }
184
185
    /**
186
     * Find the "root" widgetmap (the one that has no parent).
187
     *
188
     * @param $widgetMaps
189
     *
190
     * @return WidgetMap|null
191
     */
192
    private function findRootWidgetMap($widgetMaps)
193
    {
194
        $rootWidgetMap = null;
195
        foreach ($widgetMaps as $_widgetMap) {
196
            if (!$_widgetMap->getParent()) {
197
                $rootWidgetMap = $_widgetMap;
198
                break;
199
            }
200
        }
201
202
        return $rootWidgetMap;
203
    }
204
}
205