Navbar::createMenuWithSubMenus()   F
last analyzed

Complexity

Conditions 19
Paths 8

Size

Total Lines 102

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 380

Importance

Changes 0
Metric Value
dl 0
loc 102
ccs 0
cts 54
cp 0
rs 3.6133
c 0
b 0
f 0
cc 19
nc 8
nop 1
crap 380

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Anax\Navigation;
4
5
use Anax\Commons\ContainerInjectableInterface;
6
use Anax\Commons\ContainerInjectableTrait;
7
8
/**
9
 * Helper to create a navbar for sites by reading its configuration from file
10
 * and then applying some code while rendering the resultning navbar.
11
 *
12
 */
13
class Navbar
14
{
15
    use ContainerInjectableTrait;
16
17
18
19
    /**
20
     * Create an url.
21
     *
22
     * @param: string $url where to create the url.
23
     *
24
     * @return string as the url create.
25
     */
26
    public function url($url)
27
    {
28
        return $this->di->get("url")->create($url);
29
    }
30
31
32
33
    /**
34
     * Callback tracing the current selected menu item base on scriptname.
35
     *
36
     * @param: string $url to check for.
37
     *
38
     * @return boolean true if item is selected, else false.
39
     */
40
    public function check($url)
41
    {
42
        if ($this->url($url) == $this->di->get("request")->getCurrentUrl(false)) {
43
            return true;
44
        }
45
    }
46
47
48
49
    /**
50
     * Create an url.
51
     *
52
     * @param: string $url where to create the url.
53
     *
54
     * @return string as the url create.
55
     */
56
    public function isParent($parent)
57
    {
58
        $route = $this->di->get("request")->getRoute();
59
        return !substr_compare($parent, $route, 0, strlen($parent));
60
    }
61
62
63
64
    /**
65
     * Create a navigation bar/menu, with submenus.
66
     *
67
     * @param array $config with configuration for the menu.
68
     *
69
     * @return string with html for the menu.
70
     *
71
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
72
     * @SuppressWarnings(PHPMD.NPathComplexity)
73
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
74
     */
75
    public function createMenuWithSubMenus(array $config): string
76
    {
77
        $default = [
78
            "id"      => null,
79
            "class"   => null,
80
            "wrapper" => "nav",
81
        ];
82
        $menu = array_replace_recursive($default, $config);
83
        //$menu = array_replace_recursive($menu, $menus[$menuName]);
84
85
        // Create the ul li menu from the array, use an anonomous recursive
86
        // function that returns an array of values.
87
        $createMenu = function (
88
            $items,
89
            $ulId = null,
90
            $ulClass = null
91
        ) use (
92
            &$createMenu
93
        ) {
94
95
            $html = null;
96
            $hasItemIsSelected = false;
97
98
            foreach ($items as $item) {
99
                // has submenu, call recursivly and keep track on if the submenu has a selected item in it.
100
                $subMenu        = null;
101
                $subMenuButton  = null;
102
                $subMenuClass   = null;
103
                $selectedParent = null;
104
105
                if (isset($item["submenu"])) {
106
                    list($subMenu, $selectedParent) = $createMenu($item["submenu"]["items"]);
107
                    $selectedParent = $selectedParent
108
                        ? "selected-parent "
109
                        : null;
110
                    $subMenuButton = "<a class=\"rm-submenu-button\" href=\"#\"></a>";
111
                    $subMenuClass = "rm-submenu";
112
                }
113
114
                // Check if the current menuitem is selected
115
                if (!isset($item["url"])) {
116
                    var_dump($item);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($item); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
117
                }
118
                $selected = $this->check($item["url"])
119
                    ? "selected "
120
                    : null;
121
122
                // Check if the menuitem is a parent of current page, /controller for /controller/action
123
                $isParent = null;
124
                if (isset($item["mark-if-parent"]) && $item["mark-if-parent"] == true) {
125
                    $isParent = $this->isParent($item["url"])
126
                        ? "selected-parent "
127
                        : null;
128
                }
129
130
                // Is there a class set for this item, then use it
131
                $class = isset($item["class"]) && ! is_null($item["class"])
132
                    ? $item["class"]
133
                    : null;
134
135
                // Prepare the class-attribute, if used
136
                $class = ($selected || $selectedParent || $isParent || $class)
0 ignored issues
show
Bug Best Practice introduced by
The expression $selected of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $selectedParent of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $isParent of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
137
                    ? " class=\"{$selected}{$selectedParent}{$isParent}{$class}{$subMenuClass}\" "
138
                    : null;
139
140
                // Add the menu item
141
                // $url = $menu["create_url"]($item["url"]);
142
                $url = $this->url($item["url"]);
143
                $html .= "\n<li{$class}>{$subMenuButton}<a href='{$url}' title='{$item['title']}'>{$item['text']}</a>{$subMenu}</li>\n";
144
145
                // To remember there is selected children when going up the menu hierarchy
146
                if ($selected) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $selected of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
147
                    $hasItemIsSelected = true;
148
                }
149
            }
150
151
            // Return the menu
152
            return array("\n<ul$ulId$ulClass>$html</ul>\n", $hasItemIsSelected);
153
        };
154
155
        // Call the anonomous function to create the menu, and submenues if any.
156
        $id = isset($menu["id"])
157
            ? " id=\"{$menu["id"]}\""
158
            : null;
159
        $class = isset($menu["class"])
160
            ? " class=\"{$menu["class"]}\""
161
            : null;
162
163
        list($html) = $createMenu(
164
            $menu["items"],
165
            $id,
166
            $class
167
        );
168
169
        // Set the id & class element, only if it exists in the menu-array
170
        $wrapper = $menu["wrapper"];
171
        if ($wrapper) {
172
            $html = "<{$wrapper}>{$html}</{$wrapper}>";
173
        }
174
175
        return "\n{$html}\n";
176
    }
177
}
178