Completed
Push — master ( 36b244...7a8808 )
by Travis
09:14
created

Container::updateActive()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 1
nop 0
crap 2
1
<?php namespace NukaCode\Menu;
2
3
use Illuminate\Support\Collection;
4
5
/**
6
 * Class Container
7
 *
8
 * @package NukaCode\Menu
9
 */
10
class Container extends Collection
11
{
12
13
    /**
14
     * The slug to set to active during render
15
     *
16
     * @var string
17
     */
18
    private $active;
19
20
    /**
21
     * Get a menu you have created.
22
     *
23
     * @param $menuName
24
     *
25
     * @return mixed
26
     */
27 12
    public function getMenu($menuName)
28
    {
29 12
        $menu = $this->getMenuObject($menuName);
30 12
        if ($menu) {
31 1
            return $menu;
32
        } else {
33 12
            return $this->add($menuName);
34
        }
35
    }
36
37
    /**
38
     * Add a new menu.
39
     *
40
     * @param $menuName
41
     *
42
     * @return Menu
43
     */
44 12
    private function add($menuName)
45
    {
46 12
        return $this->items[] = new Menu($this->snakeName($menuName));
47
    }
48
49
    /**
50
     * Check if a menu exists.
51
     *
52
     * @param $menuName
53
     *
54
     * @return bool
55
     */
56 2
    public function exists($menuName)
57
    {
58 2
        return (bool)$this->getMenuObject($menuName);
59
    }
60
61
    /**
62
     * Check if a menu is empty
63
     *
64
     * @param $menuName
65
     *
66
     * @return bool
67
     */
68 2
    public function hasLinks($menuName)
69
    {
70 2
        return (count($this->getMenuObject($menuName)->links) > 0);
71
    }
72
73
    /**
74
     * Update the active and order values and then return the object.
75
     *
76
     * @param $menuName
77
     *
78
     * @return Menu
79
     * @throws \Exception
80
     */
81 4
    public function render($menuName)
82
    {
83
        // We set active at the last possible moment.
84 4
        $this->updateActive();
85
86 4
        $menu = $this->getMenuObject($menuName);
87
88 4
        if (! $menu) {
89 1
            throw new \Exception("Menu {$menuName} not found.");
90
        }
91
92 3
        return $menu;
93
    }
94
95
    /**
96
     * Sanitize the menus names for safe use in array keys.
97
     *
98
     * @param $name
99
     *
100
     * @return string
101
     */
102 14
    public function snakeName($name)
103
    {
104 14
        return e(snake_case($name));
105
    }
106
107
    /**
108
     * Get the menu object
109
     *
110
     * @param $menuName
111
     *
112
     * @return mixed|null
113
     */
114 14
    private function getMenuObject($menuName)
115
    {
116 14
        return $this->where('name', $this->snakeName($menuName))->first();
117
    }
118
119
    /**
120
     * Get the active link by slug.
121
     *
122
     * @return string
123
     */
124 1
    public function getActive()
125
    {
126 1
        return $this->active;
127
    }
128
129
    /**
130
     * Set the active link by slug.
131
     *
132
     * @param $slug
133
     */
134 3
    public function setActive($slug)
135
    {
136 3
        $this->active = $slug;
137 3
    }
138
139
    /**
140
     * Use the active param and set the link to active
141
     */
142
    private function updateActive()
143
    {
144 4
        $this->each(function ($item) {
145
            if (isset($item->links)) {
146
                $this->makeActive($item);
147 3
            }
148
        });
149 3
    }
150 1
151 1
    /**
152
     * Loop through the links and check for active.
153 3
     * Sets the item and it's parents as active when told to.
154 1
     */
155 1
    private function makeActive($item, $parent = null)
156 1
    {
157 1
        $item->links->each(function ($link) use ($item, $parent) {
158 1
            if ($link->slug == $this->active) {
159 1
                $this->makeParentActive($parent);
160 1
                $this->makeParentActive($item);
161 1
162 1
                $link->setActive(true);
163 3
            }
164 3
165 4
            if (isset($link->links)) {
166 4
                $this->makeActive($link, $item);
167
            }
168
        });
169
    }
170
171
    /**
172
     * Set the parent item as active if able to do so.
173
     */
174
    private function makeParentActive($parent)
175
    {
176
        if (! is_null($parent)
177
            && method_exists($parent, 'activeParentage')
178
            && $parent->activeParentage()
179
        ) {
180
            $parent->setActive(true);
181
        }
182
    }
183
}
184