Completed
Push — master ( 8d79fb...5cde88 )
by Cheren
12:20
created

NavHelper::render()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 35
rs 8.8571
cc 3
eloc 23
nc 3
nop 4
1
<?php
2
/**
3
 * CakeCMS Core
4
 *
5
 * This file is part of the of the simple cms based on CakePHP 3.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package   Core
10
 * @license   MIT
11
 * @copyright MIT License http://www.opensource.org/licenses/mit-license.php
12
 * @link      https://github.com/CakeCMS/Core".
13
 * @author    Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace Core\View\Helper;
17
18
use JBZoo\Utils\FS;
19
use Cake\Utility\Hash;
20
21
/**
22
 * Class NavHelper
23
 *
24
 * @package Core\View\Helper
25
 */
26
class NavHelper extends AppHelper
27
{
28
29
    /**
30
     * Default menu params.
31
     *
32
     * @var array
33
     */
34
    protected $_default = [
35
        'menuAttr' => [
36
            'class'   => 'menu',
37
            'element' => 'Core.Nav/menu'
38
        ],
39
        'childMenuAttr' => [
40
            'class'   => 'child-menu',
41
            'element' => 'Core.Nav/menu_child'
42
        ],
43
        'itemElement' => 'Core.Nav/item',
44
    ];
45
46
    /**
47
     * Render menu.
48
     *
49
     * @param string $key
50
     * @param array $items
51
     * @param array $options
52
     * @param int $level
53
     * @return string
54
     * @SuppressWarnings(PHPMD.ShortVariable)
55
     */
56
    public function render($key, array $items = [], array $options = [], $level = 1)
57
    {
58
        $i = 0;
59
        $output    = [];
60
        $options   = Hash::merge($this->_default, $options);
61
        $sorted    = Hash::sort($items, '{s}.weight', 'ASC');
62
        $itemCount = count($sorted);
63
64
        foreach ($sorted as $item) {
65
            $i++;
66
            $item = $this->_setFirstLast($i, $itemCount, $item);
67
68
            $children = false;
69
            if (count($item['children']) > 0) {
70
                $children = $this->render($key, $item['children'], $options, $level + 1);
71
            }
72
73
            $itemOutput = $this->_View->element($options['itemElement'], [
74
                'options'  => $options,
75
                'item'     => $item,
76
                'count'    => $i,
77
                'children' => $children,
78
                'level'    => $level,
79
            ]);
80
81
            $output[] = $itemOutput;
82
        }
83
84
        $element = $this->_getCurrentMenuElement($options, $level);
85
86
        return $this->_View->element($element, [
87
            'content' => $output,
88
            'options' => $options,
89
        ]);
90
    }
91
92
    /**
93
     * Get current menu element.
94
     *
95
     * @param array $options
96
     * @param int $level
97
     * @return string
98
     */
99
    protected function _getCurrentMenuElement(array $options = [], $level = 1)
100
    {
101
        if ($level > 1) {
102
            $levelElement = $this->_getLevelElement($options, $level);
103
            if ($this->_View->elementExists($levelElement)) {
104
                return $levelElement;
105
            }
106
107
            return $options['childMenuAttr']['element'];
108
        }
109
110
        return $options['menuAttr']['element'];
111
    }
112
113
    /**
114
     * Get current menu level element.
115
     *
116
     * @param array $options
117
     * @param int $level
118
     * @return string
119
     */
120
    protected function _getLevelElement(array $options, $level)
121
    {
122
        $levelElement = 'menu_child_' . $level;
123
        $element      = $options['childMenuAttr']['element'];
124
125
        list($plugin, $path) = $this->_View->pluginSplit($element);
126
        $path    = FS::clean($path, '/');
127
        $details = explode('/', $path);
128
        array_pop($details);
129
130
        $path = implode('/', $details);
131
132
        return $plugin . '.' . $path . '/' . $levelElement;
133
    }
134
135
    /**
136
     * Setup first last item params.
137
     *
138
     * @param int $i
139
     * @param int $itemCount
140
     * @param array $item
141
     * @return array
142
     * @SuppressWarnings(PHPMD.ShortVariable)
143
     */
144
    protected function _setFirstLast($i, $itemCount, array $item = [])
145
    {
146
        $item = array_merge(['last' => false, 'first' => false], $item);
147
        if ($i == 1) {
148
            $item['first'] = true;
149
        }
150
151
        if ($i == $itemCount) {
152
            $item['last'] = true;
153
        }
154
155
        return $item;
156
    }
157
}
158