xref: /webtrees/app/Menu.php (revision f60bdb82d4dd2cd0b37ee9598ec6e772e3935798)
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 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees;
21
22/**
23 * System for generating menus.
24 */
25class Menu
26{
27    /** @var string The text to be displayed in the mneu */
28    private $label;
29
30    /** @var string The target URL or href */
31    private $link;
32
33    /** @var string The CSS class used to style this menu item */
34    private $class;
35
36    /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */
37    private $attrs;
38
39    /** @var Menu[] An optional list of sub-menus. */
40    private $submenus;
41
42    /**
43     * Constructor for the menu class
44     *
45     * @param string   $label    The label for the menu item
46     * @param string   $link     The target URL
47     * @param string   $class    A CSS class
48     * @param string[] $attrs    Optional attributes, such as onclick or data-xxx
49     * @param Menu[]   $submenus Any submenus
50     */
51    public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = [])
52    {
53        $this
54            ->setLabel($label)
55            ->setLink($link)
56            ->setClass($class)
57            ->setAttrs($attrs)
58            ->setSubmenus($submenus);
59    }
60
61    /**
62     * Render this menu using Bootstrap4 markup
63     *
64     * @return string
65     */
66    public function bootstrap4(): string
67    {
68        if ($this->submenus !== []) {
69            $submenus = '';
70            foreach ($this->submenus as $submenu) {
71                $attrs = '';
72                foreach ($submenu->attrs as $key => $value) {
73                    $attrs .= ' ' . $key . '="' . e($value) . '"';
74                }
75
76                $class = trim('dropdown-item ' . $submenu->class);
77                $submenus .= '<a class="' . $class . '" href="' . e($submenu->link) . '"' . $attrs . '>' . $submenu->label . '</a>';
78            }
79
80            $class = trim('nav-item dropdown ' . $this->class);
81
82            return
83                '<li class="' . $class . '">' .
84                '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
85                $this->label .
86                '<span class="caret"></span></a>' .
87                '<div class="dropdown-menu" role="menu">' .
88                $submenus .
89                '</div>' .
90                '</li>';
91        }
92
93        $attrs = '';
94        foreach ($this->attrs as $key => $value) {
95            $attrs .= ' ' . $key . '="' . e($value) . '"';
96        }
97
98        $class = trim('nav-item ' . $this->class);
99
100        return '<li class="' . $class . '"><a class="nav-link" href="' . e($this->link) . '"' . $attrs . '>' . $this->label . '</a></li>';
101    }
102
103    /**
104     * Get the optional attributes.
105     *
106     * @return string[]
107     */
108    public function getAttrs(): array
109    {
110        return $this->attrs;
111    }
112
113    /**
114     * Set the optional attributes.
115     *
116     * @param string[] $attrs
117     *
118     * @return $this
119     */
120    public function setAttrs(array $attrs): self
121    {
122        $this->attrs = $attrs;
123
124        return $this;
125    }
126
127    /**
128     * Get the class.
129     *
130     * @return string
131     */
132    public function getClass(): string
133    {
134        return $this->class;
135    }
136
137    /**
138     * Set the class.
139     *
140     * @param string $class
141     *
142     * @return $this
143     */
144    public function setClass($class): self
145    {
146        $this->class = $class;
147
148        return $this;
149    }
150
151    /**
152     * Get the label.
153     *
154     * @return string
155     */
156    public function getLabel(): string
157    {
158        return $this->label;
159    }
160
161    /**
162     * Set the label.
163     *
164     * @param string $label
165     *
166     * @return $this
167     */
168    public function setLabel($label): self
169    {
170        $this->label = $label;
171
172        return $this;
173    }
174
175    /**
176     * Get the link.
177     *
178     * @return string
179     */
180    public function getLink(): string
181    {
182        return $this->link;
183    }
184
185    /**
186     * Set the link.
187     *
188     * @param string $link
189     *
190     * @return $this
191     */
192    public function setLink($link): self
193    {
194        $this->link = $link;
195
196        return $this;
197    }
198
199    /**
200     * Add a submenu to this menu
201     *
202     * @param Menu $menu
203     *
204     * @return $this
205     */
206    public function addSubmenu($menu): self
207    {
208        $this->submenus[] = $menu;
209
210        return $this;
211    }
212
213    /**
214     * Get the sub-menus.
215     *
216     * @return Menu[]
217     */
218    public function getSubmenus(): array
219    {
220        return $this->submenus;
221    }
222
223    /**
224     * Set the sub-menus.
225     *
226     * @param Menu[] $submenus
227     *
228     * @return $this
229     */
230    public function setSubmenus(array $submenus): self
231    {
232        $this->submenus = $submenus;
233
234        return $this;
235    }
236}
237