Navbar::createMenuWithSubMenus()   D
last analyzed

Complexity

Conditions 19
Paths 8

Size

Total Lines 101
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 20.6722

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 19
eloc 60
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 101
ccs 45
cts 54
cp 0.8333
crap 20.6722
rs 4.5166

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 2
    public function url($url)
27
    {
28 2
        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 2
    public function check($url)
41
    {
42 2
        if ($url == $this->di->get("request")->getCurrentUrl(false)) {
43
            return true;
44
        }
45 2
    }
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));
0 ignored issues
show
Bug Best Practice introduced by
The expression return ! substr_compare(...te, 0, strlen($parent)) returns the type boolean which is incompatible with the documented return type string.
Loading history...
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 2
    public function createMenuWithSubMenus($config)
76
    {
77
        $default = [
78 2
            "id"      => null,
79
            "class"   => null,
80
            "wrapper" => "nav",
81
        ];
82 2
        $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 2
            &$createMenu
93
        ) {
94
95 2
            $html = null;
96 2
            $hasItemIsSelected = false;
97
98 2
            foreach ($items as $item) {
99
                // has submenu, call recursivly and keep track on if the submenu has a selected item in it.
100 2
                $subMenu        = null;
101 2
                $subMenuButton  = null;
102 2
                $subMenuClass   = null;
103 2
                $selectedParent = null;
104
105 2
                if (isset($item["submenu"])) {
106 2
                    list($subMenu, $selectedParent) = $createMenu($item["submenu"]["items"]);
107 2
                    $selectedParent = $selectedParent
108
                        ? "selected-parent "
109 2
                        : null;
110 2
                    $subMenuButton = "<a class=\"rm-submenu-button\" href=\"#\"></a>";
111 2
                    $subMenuClass = "rm-submenu";
112
                }
113
114
                // Check if the current menuitem is selected
115 2
                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?
Loading history...
117
                }
118 2
                $selected = $this->check($item["url"])
119
                    ? "selected "
120 2
                    : null;
121
122
                // Check if the menuitem is a parent of current page, /controller for /controller/action
123 2
                $isParent = null;
124 2
                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 2
                $class = isset($item["class"]) && ! is_null($item["class"])
132
                    ? $item["class"]
133 2
                    : null;
134
135
                // Prepare the class-attribute, if used
136 2
                $class = ($selected || $selectedParent || $isParent || $class)
137
                    ? " class=\"{$selected}{$selectedParent}{$isParent}{$class}{$subMenuClass}\" "
138 2
                    : null;
139
140
                // Add the menu item
141
                // $url = $menu["create_url"]($item["url"]);
142 2
                $url = $this->url($item["url"]);
143 2
                $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 2
                if ($selected) {
147 2
                    $hasItemIsSelected = true;
148
                }
149
            }
150
151
            // Return the menu
152 2
            return array("\n<ul$ulId$ulClass>$html</ul>\n", $hasItemIsSelected);
153 2
        };
154
155
        // Call the anonomous function to create the menu, and submenues if any.
156 2
        $id = isset($menu["id"])
157 2
            ? " id=\"{$menu["id"]}\""
158 2
            : null;
159 2
        $class = isset($menu["class"])
160 2
            ? " class=\"{$menu["class"]}\""
161 2
            : null;
162
163 2
        list($html) = $createMenu(
164 2
            $menu["items"],
165 2
            $id,
166 2
            $class
167
        );
168
169
        // Set the id & class element, only if it exists in the menu-array
170 2
        $wrapper = $menu["wrapper"];
171 2
        if ($wrapper) {
172
            $html = "<{$wrapper}>{$html}</{$wrapper}>";
173
        }
174
175 2
        return "\n{$html}\n";
176
    }
177
}
178