xref: /webtrees/app/Menu.php (revision ee4364da76be9b2651fd11a0b3dae7961849d2f3)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17declare(strict_types=1);
18
19namespace Fisharebest\Webtrees;
20
21/**
22 * System for generating menus.
23 */
24class Menu
25{
26    /** @var string The text to be displayed in the mneu */
27    private $label;
28
29    /** @var string The target URL or href */
30    private $link;
31
32    /** @var string The CSS class used to style this menu item */
33    private $class;
34
35    /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */
36    private $attrs;
37
38    /** @var Menu[] An optional list of sub-menus. */
39    private $submenus;
40
41    /**
42     * Constructor for the menu class
43     *
44     * @param string   $label    The label for the menu item
45     * @param string   $link     The target URL
46     * @param string   $class    A CSS class
47     * @param string[] $attrs    Optional attributes, such as onclick or data-xxx
48     * @param Menu[]   $submenus Any submenus
49     */
50    public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = [])
51    {
52        $this
53            ->setLabel($label)
54            ->setLink($link)
55            ->setClass($class)
56            ->setAttrs($attrs)
57            ->setSubmenus($submenus);
58    }
59
60    /**
61     * Render this menu using Bootstrap4 markup
62     *
63     * @return string
64     */
65    public function bootstrap4(): string
66    {
67        if (!empty($this->submenus)) {
68            $submenus = '';
69            foreach ($this->submenus as $submenu) {
70                $attrs = '';
71                foreach ($submenu->attrs as $key => $value) {
72                    $attrs .= ' ' . $key . '="' . e($value) . '"';
73                }
74
75                $class = trim('dropdown-item ' . $submenu->class);
76                $submenus .= '<a class="' . $class . '" href="' . e($submenu->link) . '"' . $attrs . '>' . $submenu->label . '</a>';
77            }
78
79            $class = trim('nav-item dropdown ' . $this->class);
80
81            return
82                '<li class="' . $class . '">' .
83                '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
84                $this->label .
85                '<span class="caret"></span></a>' .
86                '<div class="dropdown-menu" role="menu">' .
87                $submenus .
88                '</div>' .
89                '</li>';
90        }
91
92        $attrs = '';
93        foreach ($this->attrs as $key => $value) {
94            $attrs .= ' ' . $key . '="' . e($value) . '"';
95        }
96
97        $class = trim('nav-item ' . $this->class);
98
99        return '<li class="' . $class . '"><a class="nav-link" href="' . e($this->link) . '"' . $attrs . '>' . $this->label . '</a></li>';
100    }
101
102    /**
103     * Get the optional attributes.
104     *
105     * @return string[]
106     */
107    public function getAttrs(): array
108    {
109        return $this->attrs;
110    }
111
112    /**
113     * Set the optional attributes.
114     *
115     * @param string[] $attrs
116     *
117     * @return $this
118     */
119    public function setAttrs(array $attrs): self
120    {
121        $this->attrs = $attrs;
122
123        return $this;
124    }
125
126    /**
127     * Get the class.
128     *
129     * @return string
130     */
131    public function getClass(): string
132    {
133        return $this->class;
134    }
135
136    /**
137     * Set the class.
138     *
139     * @param string $class
140     *
141     * @return $this
142     */
143    public function setClass($class): self
144    {
145        $this->class = $class;
146
147        return $this;
148    }
149
150    /**
151     * Get the label.
152     *
153     * @return string
154     */
155    public function getLabel(): string
156    {
157        return $this->label;
158    }
159
160    /**
161     * Set the label.
162     *
163     * @param string $label
164     *
165     * @return $this
166     */
167    public function setLabel($label): self
168    {
169        $this->label = $label;
170
171        return $this;
172    }
173
174    /**
175     * Get the link.
176     *
177     * @return string
178     */
179    public function getLink(): string
180    {
181        return $this->link;
182    }
183
184    /**
185     * Set the link.
186     *
187     * @param string $link
188     *
189     * @return $this
190     */
191    public function setLink($link): self
192    {
193        $this->link = $link;
194
195        return $this;
196    }
197
198    /**
199     * Add a submenu to this menu
200     *
201     * @param Menu $menu
202     *
203     * @return $this
204     */
205    public function addSubmenu($menu): self
206    {
207        $this->submenus[] = $menu;
208
209        return $this;
210    }
211
212    /**
213     * Get the sub-menus.
214     *
215     * @return Menu[]
216     */
217    public function getSubmenus(): array
218    {
219        return $this->submenus;
220    }
221
222    /**
223     * Set the sub-menus.
224     *
225     * @param Menu[] $submenus
226     *
227     * @return $this
228     */
229    public function setSubmenus(array $submenus): self
230    {
231        $this->submenus = $submenus;
232
233        return $this;
234    }
235}
236