GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Menu   C
last analyzed

Complexity

Total Complexity 58

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 3
Bugs 0 Features 2
Metric Value
wmc 58
c 3
b 0
f 2
lcom 1
cbo 2
dl 0
loc 265
rs 6.3005

3 Methods

Rating   Name   Duplication   Size   Complexity  
C renderDeepestMenu() 0 51 14
F renderNormalMenu() 0 110 32
C htmlify() 0 59 12

How to fix   Complexity   

Complex Class

Complex classes like Menu often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Menu, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Menu Navigation view helper styled for Bootstrap 3.
5
 *
6
 * @author     Leandro Silva <[email protected]>
7
 *
8
 * @category   LosUi
9
 *
10
 * @license    https://github.com/Lansoweb/LosUi/blob/master/LICENSE MIT License
11
 *
12
 * @link       http://github.com/LansoWeb/LosUi
13
 * @link       http://getbootstrap.com/components/#navbar-default
14
 */
15
namespace LosUi\View\Helper\Navigation;
16
17
use LosUi\Navigation\Page\Divider;
18
use RecursiveIteratorIterator;
19
use Zend\Navigation\AbstractContainer;
20
use Zend\Navigation\Page\AbstractPage;
21
use Zend\View\Helper\Navigation\Menu as ZendMenu;
22
23
/**
24
 * Menu Navigation view helper styled for Bootstrap 3.
25
 *
26
 * @author     Leandro Silva <[email protected]>
27
 *
28
 * @category   LosUi
29
 *
30
 * @license    https://github.com/Lansoweb/LosUi/blob/master/LICENSE MIT License
31
 *
32
 * @link       http://github.com/LansoWeb/LosUi
33
 * @link       http://getbootstrap.com/components/#navbar-default
34
 * @codeCoverageIgnore
35
 */
36
class Menu extends ZendMenu
37
{
38
    protected $ulClass = 'nav navbar-nav';
39
40
    /**
41
     * (non-PHPdoc).
42
     *
43
     * @see \Zend\View\Helper\Navigation\Menu::renderDeepestMenu()
44
     * @param AbstractContainer $container
45
     * @param $ulClass
46
     * @param $indent
47
     * @param $minDepth
48
     * @param $maxDepth
49
     * @param $escapeLabels
50
     * @param $addClassToListItem
51
     * @param null $liActiveClass
52
     * @return string
53
     */
54
    protected function renderDeepestMenu(
55
        AbstractContainer $container,
56
        $ulClass,
57
        $indent,
58
        $minDepth,
59
        $maxDepth,
60
        $escapeLabels,
61
        $addClassToListItem,
62
        $liActiveClass = null
63
    ) {
64
        if (! $active = $this->findActive($container, $minDepth - 1, $maxDepth)) {
65
            return '';
66
        }
67
68
        if ($active['depth'] < $minDepth) {
69
            if (! $active['page']->hasPages()) {
70
                return '';
71
            }
72
        } elseif (! $active['page']->hasPages()) {
73
            $active['page'] = $active['page']->getParent();
74
        } elseif (is_int($maxDepth) && $active['depth'] + 1 > $maxDepth) {
75
            $active['page'] = $active['page']->getParent();
76
        }
77
78
        $ulClass = $ulClass ? ' class="'.$ulClass.'"' : '';
79
        $html = $indent.'<ul'.$ulClass.'>'.PHP_EOL;
80
81
        foreach ($active['page'] as $subPage) {
82
            if (! $this->accept($subPage)) {
83
                continue;
84
            }
85
86
            $liClasses = [];
87
            if ($subPage->isActive(true)) {
88
                $liClasses[] = 'active';
89
            }
90
91
            if ($addClassToListItem && $subPage->getClass()) {
92
                $liClasses[] = $subPage->getClass();
93
            }
94
            $liClass = empty($liClasses) ? '' : ' class="'.implode(' ', $liClasses).'"';
95
96
            $html .= $indent.'    <li'.$liClass.'>'.PHP_EOL;
97
            $html .= $indent.'        '.$this->htmlify($subPage, $escapeLabels, $addClassToListItem).PHP_EOL;
98
            $html .= $indent.'    </li>'.PHP_EOL;
99
        }
100
101
        $html .= $indent.'</ul>';
102
103
        return $html;
104
    }
105
106
    /**
107
     * (non-PHPdoc).
108
     *
109
     * @see \Zend\View\Helper\Navigation\Menu::renderNormalMenu()
110
     * @param AbstractContainer $container
111
     * @param $ulClass
112
     * @param $indent
113
     * @param $minDepth
114
     * @param $maxDepth
115
     * @param $onlyActive
116
     * @param $escapeLabels
117
     * @param $addClassToListItem
118
     * @param null $liActiveClass
119
     * @return string
120
     */
121
    protected function renderNormalMenu(
122
        AbstractContainer $container,
123
        $ulClass,
124
        $indent,
125
        $minDepth,
126
        $maxDepth,
127
        $onlyActive,
128
        $escapeLabels,
129
        $addClassToListItem,
130
        $liActiveClass = null
131
    ) {
132
        $html = '';
133
134
        $found = $this->findActive($container, $minDepth, $maxDepth);
135
        if (! empty($found)) {
136
            $foundPage = $found['page'];
137
            $foundDepth = $found['depth'];
138
        } else {
139
            $foundPage = null;
140
            $foundDepth = 0;
141
        }
142
143
        // Since bootstrap doesn't support more than one level, we set maxDepth to minDeph plus one
144
        $maxDepth = $minDepth + 1;
145
146
        $iterator = new RecursiveIteratorIterator($container, RecursiveIteratorIterator::SELF_FIRST);
147
        if (is_int($maxDepth)) {
148
            $iterator->setMaxDepth($maxDepth);
149
        }
150
151
        $prevDepth = -1;
152
        foreach ($iterator as $page) {
153
            $depth = $iterator->getDepth();
154
            $isActive = $page->isActive(true);
155
            if ($depth < $minDepth || ! $this->accept($page)) {
156
                continue;
157
            } elseif ($onlyActive && ! $isActive) {
158
                $accept = false;
159
                if ($foundPage) {
160
                    if ($foundPage->hasPage($page)) {
161
                        $accept = true;
162
                    } elseif ($foundPage->getParent()->hasPage($page)) {
163
                        if (! $foundPage->hasPages() || is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
164
                            $accept = true;
165
                        }
166
                    }
167
                }
168
169
                if (! $accept) {
170
                    continue;
171
                }
172
            }
173
174
            $depth -= $minDepth;
175
            $myIndent = $indent.str_repeat('        ', $depth);
176
177
            if ($depth > $prevDepth) {
178
                if ($ulClass && $depth == 0) {
179
                    $ulClass = ' class="'.$ulClass.'"';
180
                } elseif ($page->getParent()) {
181
                    $ulClass = ' class="dropdown-menu"';
182
                } else {
183
                    $ulClass = '';
184
                }
185
                $html .= $myIndent.'<ul'.$ulClass.'>'.PHP_EOL;
186
            } elseif ($prevDepth > $depth) {
187
                for ($i = $prevDepth; $i > $depth; --$i) {
188
                    $ind = $indent.str_repeat('        ', $i);
189
                    $html .= $ind.'    </li>'.PHP_EOL;
190
                    $html .= $ind.'</ul>'.PHP_EOL;
191
                }
192
                $html .= $myIndent.'    </li>'.PHP_EOL;
193
            } else {
194
                $html .= $myIndent.'    </li>'.PHP_EOL;
195
            }
196
197
            $liClasses = [];
198
            if ($isActive) {
199
                $liClasses[] = 'active';
200
            }
201
202
            if ($page->hasPages() && (! isset($maxDepth) || $depth < $maxDepth)) {
203
                if (! isset($page->dropdown) || $page->dropdown === true) {
204
                    $liClasses[] = 'dropdown';
205
                    $page->isDropdown = true;
206
                }
207
            }
208
209
            if ($addClassToListItem && $page->getClass()) {
210
                $liClasses[] = $page->getClass();
211
            }
212
            $liClass = empty($liClasses) ? '' : ' class="'.implode(' ', $liClasses).'"';
213
214
            $html .= $myIndent .
215
                '    <li'.$liClass.'>'.PHP_EOL.$myIndent.'        ' .
216
                $this->htmlify($page, $escapeLabels, $addClassToListItem).PHP_EOL;
217
218
            $prevDepth = $depth;
219
        }
220
221
        if ($html) {
222
            for ($i = $prevDepth + 1; $i > 0; --$i) {
223
                $myIndent = $indent.str_repeat('        ', $i - 1);
224
                $html .= $myIndent.'    </li>'.PHP_EOL.$myIndent.'</ul>'.PHP_EOL;
225
            }
226
            $html = rtrim($html, PHP_EOL);
227
        }
228
229
        return $html;
230
    }
231
232
    /**
233
     * (non-PHPdoc).
234
     *
235
     * @see \Zend\View\Helper\Navigation\Menu::htmlify()
236
     * @param AbstractPage $page
237
     * @param bool $escapeLabel
238
     * @param bool $addClassToListItem
239
     * @return string
240
     */
241
    public function htmlify(AbstractPage $page, $escapeLabel = true, $addClassToListItem = false)
242
    {
243
        if ($page instanceof Divider) {
244
            return '<li class="divider"></li>';
245
        }
246
247
        $label = $page->getLabel();
248
        $title = $page->getTitle();
249
250
        if (null !== ($translator = $this->getTranslator())) {
251
            $textDomain = $this->getTranslatorTextDomain();
252
            if (is_string($label) && ! empty($label)) {
253
                $label = $translator->translate($label, $textDomain);
254
            }
255
            if (is_string($title) && ! empty($title)) {
256
                $title = $translator->translate($title, $textDomain);
257
            }
258
        }
259
260
        $element = 'a';
261
        $extended = '';
262
        $attribs = [
263
            'id' => $page->getId(),
264
            'title' => $title,
265
            'href' => '#',
266
        ];
267
268
        $class = [];
269
        if ($addClassToListItem === false) {
270
            $class[] = $page->getClass();
271
        }
272
        if ($page->isDropdown) {
273
            $attribs['data-toggle'] = 'dropdown';
274
            $class[] = 'dropdown-toggle';
275
            $extended = ' <b class="caret"></b>';
276
        }
277
        if (count($class) > 0) {
278
            $attribs['class'] = implode(' ', $class);
279
        }
280
281
        $href = $page->getHref();
282
        if ($href) {
283
            $attribs['href'] = $href;
284
            $attribs['target'] = $page->getTarget();
285
        }
286
287
        $html = '<'.$element.$this->htmlAttribs($attribs).'>';
288
        if ($escapeLabel === true) {
289
            $escaper = $this->view->plugin('escapeHtml');
290
            $html .= $escaper($label);
291
        } else {
292
            $html .= $label;
293
        }
294
295
        $html .= $extended;
296
        $html .= '</'.$element.'>';
297
298
        return $html;
299
    }
300
}
301