CNavbar::create()   F
last analyzed

Complexity

Conditions 19
Paths 16

Size

Total Lines 107

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 380

Importance

Changes 0
Metric Value
cc 19
nc 16
nop 1
dl 0
loc 107
ccs 0
cts 59
cp 0
crap 380
rs 3.6133
c 0
b 0
f 0

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
/**
6
 * Helper to create a navbar for sites by reading its configuration from file
7
 * and then applying some code while rendering the resultning navbar.
8
 *
9
 */
10
class CNavbar
11
{
12
    use \Anax\TConfigure,
13
        \Anax\DI\TInjectionAware;
14
15
16
17
    /**
18
     * Create a navigation bar / menu, with submenu.
19
     *
20
     * @param: string $menuName name of menu config to use.
21
     *
22
     * @return string with html for the menu.
23
     *
24
     * @link http://dbwebb.se/coachen/skapa-en-dynamisk-navbar-meny-med-undermeny-via-php
25
     */
26
    public function create($menuName = null)
27
    {
28
        // Keep default options in an array and merge with incoming options that can override the defaults.
29
        $default = array(
30
            "id"          => null,
31
            "class"       => null,
32
            "wrapper"     => "nav",
33
            "create_url"  => function ($url) {
34
                return $url;
35
            },
36
        );
37
        $menu = array_replace_recursive($default, $this->config);
38
        if (!is_null($menuName)) {
39
            $menu = array_replace_recursive($menu, $this->config[$menuName]);
40
        }
41
42
        // Create the ul li menu from the array, use an anonomous recursive
43
        // function that returns an array of values.
44
        $createMenu = function (
45
            $items,
46
            $callback,
47
            $ulId = null,
48
            $ulClass = null
49
        ) use (
50
            &$createMenu,
51
            $menu
52
        ) {
53
54
            $html = null;
55
            $hasItemIsSelected = false;
56
57
            foreach ($items as $item) {
58
                // has submenu, call recursivly and keep track on if the submenu has a selected item in it.
59
                $subMenu        = null;
60
                $subMenuButton  = null;
61
                $subMenuClass   = null;
62
                $selectedParent = null;
63
64
                if (isset($item["submenu"])) {
65
                    list($subMenu, $selectedParent) = $createMenu($item["submenu"]["items"], $callback);
66
                    $selectedParent = $selectedParent
67
                        ? "selected-parent "
68
                        : null;
69
                    $subMenuButton = "<a class=\"rm-submenu-button\" href=\"#\"></a>";
70
                    $subMenuClass = "rm-submenu";
71
                }
72
73
                // Check if the current menuitem is selected
74
                $selected = $callback($item["url"])
75
                    ? "selected "
76
                    : null;
77
78
                // Check if the menuitem is a parent of current page, /controller for /controller/action
79
                $isParent = null;
80
                if (isset($item["mark-if-parent"]) && $item["mark-if-parent"] == true) {
81
                    $isParent = $menu["is_parent"]($item["url"])
82
                        ? "selected-parent "
83
                        : null;
84
                }
85
86
                // Is there a class set for this item, then use it
87
                $class = isset($item["class"]) && ! is_null($item["class"])
88
                    ? $item["class"]
89
                    : null;
90
91
                // Prepare the class-attribute, if used
92
                $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...
93
                    ? " class=\"{$selected}{$selectedParent}{$isParent}{$class}{$subMenuClass}\" "
94
                    : null;
95
96
                // Add the menu item
97
                $url = $menu["create_url"]($item["url"]);
98
                $html .= "\n<li{$class}>{$subMenuButton}<a href='{$url}' title='{$item['title']}'>{$item['text']}</a>{$subMenu}</li>\n";
99
100
                // To remember there is selected children when going up the menu hierarchy
101
                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...
102
                    $hasItemIsSelected = true;
103
                }
104
            }
105
106
            // Return the menu
107
            return array("\n<ul$ulId$ulClass>$html</ul>\n", $hasItemIsSelected);
108
        };
109
110
        // Call the anonomous function to create the menu, and submenues if any.
111
        $id = isset($menu["id"])
112
            ? " id=\"{$menu["id"]}\""
113
            : null;
114
        $class = isset($menu["class"])
115
            ? " class=\"{$menu["class"]}\""
116
            : null;
117
118
        list($html) = $createMenu(
119
            $menu["items"],
120
            $menu["callback"],
121
            $id,
122
            $class
123
        );
124
125
        // Set the id & class element, only if it exists in the menu-array
126
        $wrapper = $menu["wrapper"];
127
        if ($wrapper) {
128
            $html = "<{$wrapper}>{$html}</{$wrapper}>";
129
        }
130
131
        return "\n{$html}\n";
132
    }
133
}
134