Completed
Pull Request — master (#325)
by Paul
08:28
created

WidgetMapBuilder   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 10
Bugs 1 Features 1
Metric Value
wmc 32
c 10
b 1
f 1
lcom 1
cbo 3
dl 0
loc 177
rs 9.6

6 Methods

Rating   Name   Duplication   Size   Complexity  
C build() 0 43 8
C getAvailablePosition() 0 28 7
A orderizeWidgetMap() 0 18 4
B removeOverwritedWidgetMaps() 0 21 6
A removeDeletedWidgetMaps() 0 10 4
A findRootWidgetMap() 0 12 3
1
<?php
2
3
namespace Victoire\Bundle\WidgetMapBundle\Builder;
4
5
use Doctrine\ORM\EntityManager;
6
use Victoire\Bundle\CoreBundle\Entity\View;
7
use Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap;
8
9
/**
10
 * View WidgetMap builder.
11
 *
12
 * ref: victoire_widget_map.builder
13
 */
14
class WidgetMapBuilder
15
{
16
    /**
17
     * This method build widgetmaps relativly to given view and it's templates
18
     *
19
     * @param View          $view
20
     * @param EntityManager $em
21
     * @param bool          $updatePage
22
     *
23
     * @return array
24
     */
25
    public function build(View $view, EntityManager $em = null, $updatePage = true)
0 ignored issues
show
Unused Code introduced by
The parameter $em is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
26
    {
27
        // populate a $widgetmaps array with widgetmaps of given view + widgetmaps of it's templates
28
        $widgetMaps = $view->getWidgetMaps()->toArray();
29
        $template = clone $view;
30
        $builtWidgetMap = [];
31
32
        while (null !== $template = $template->getTemplate()) {
33
            foreach ($template->getWidgetMaps()->toArray() as $item) {
34
                $widgetMaps[] = $item;
35
            }
36
        }
37
38
        $slots = $this->removeOverwritedWidgetMaps($widgetMaps);
39
40
        $this->removeDeletedWidgetMaps($slots);
41
42
        foreach ($slots as $slot => $widgetMaps) {
43
            $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...
44
            $builtWidgetMap[$slot] = [];
45
46
            $rootWidgetMap = $this->findRootWidgetMap($widgetMaps);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $rootWidgetMap is correct as $this->findRootWidgetMap($widgetMaps) (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...
47
48
            if ($rootWidgetMap) {
49
                $builtWidgetMap[$slot][] = $rootWidgetMap;
50
                $builtWidgetMap = $this->orderizeWidgetMap($rootWidgetMap, $builtWidgetMap, $slot, $widgetMaps, $view);
51
            }
52
        }
53
        $_builtWidgetMap = $builtWidgetMap;
54
        $builtWidgetMap = [];
55
        foreach ($_builtWidgetMap as $slot => $__builtWidgetMap) {
56
            foreach ($__builtWidgetMap as $key => $item) {
57
                // store each widgetmap in an array with the widget id as key to make the "View::getWidgetMapByWidgetAndView"
58
                // method more efficient
59
                $builtWidgetMap[$slot][$item->getWidget()->getId()] = $item;
60
            }
61
        }
62
        if ($updatePage) {
63
            $view->setBuiltWidgetMap($builtWidgetMap);
0 ignored issues
show
Documentation introduced by
$builtWidgetMap is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

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