PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.3
Tutor LMS – eLearning and online course solution v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / components / Nav.php
tutor / components Last commit date
Constants 3 weeks ago Accordion.php 1 week ago Alert.php 1 week ago AttachmentCard.php 1 week ago Avatar.php 1 week ago Badge.php 1 week ago BaseComponent.php 3 weeks ago Button.php 1 week ago ConfirmationModal.php 1 week ago CourseFilter.php 1 week ago DateFilter.php 1 week ago DropdownFilter.php 1 week ago EmptyState.php 1 week ago FileUploader.php 1 week ago InputField.php 1 week ago Modal.php 1 week ago Nav.php 1 week ago Pagination.php 1 week ago Popover.php 1 week ago PreviewTrigger.php 1 week ago Progress.php 1 week ago SearchFilter.php 1 week ago Sorting.php 1 week ago StarRating.php 1 week ago StarRatingInput.php 1 week ago StatusSelect.php 1 week ago SvgIcon.php 1 week ago Table.php 1 week ago Tabs.php 1 week ago Tooltip.php 1 week ago WPEditor.php 1 week ago
Nav.php
389 lines
1 <?php
2 /**
3 * Nav Component Class.
4 *
5 * @package Tutor\Components
6 * @author Themeum
7 * @link https://themeum.com
8 * @since 4.0.0
9 */
10
11 namespace Tutor\Components;
12
13 defined( 'ABSPATH' ) || exit;
14
15 use Tutor\Components\Constants\Color;
16 use Tutor\Components\Constants\InputType;
17 use Tutor\Components\Constants\Size;
18 use Tutor\Components\Constants\Variant;
19 use TUTOR\Icon;
20
21 /**
22 * Class Nav
23 *
24 * Responsible for rendering the nav component.
25 *
26 *
27 * Example Usage:
28 *
29 * ```php
30 * // Simple link-only nav (primary, medium)
31 * $items = array(
32 * array( 'type' => 'link', 'label' => 'Dashboard', 'icon' => Icon::DASHBOARD, 'url' => '/dashboard', 'active' => true ),
33 * array( 'type' => 'link', 'label' => 'My Courses', 'icon' => Icon::BOOK, 'url' => '/my-courses' ),
34 * array( 'type' => 'link', 'label' => 'Wishlist', 'icon' => Icon::WISHLIST, 'url' => '/wishlist' ),
35 * );
36 *
37 * Nav::make()
38 * ->items( $items )
39 * ->render();
40 *
41 * // Nav with a dropdown item
42 * $items = array(
43 * array(
44 * 'type' => 'dropdown',
45 * 'active' => true,
46 * 'options' => array(
47 * array( 'label' => 'Active', 'count' => 4, 'icon' => Icon::PLAY_LINE, 'url' => '?status=active', 'active' => true ),
48 * array( 'label' => 'Enrolled', 'count' => 2, 'icon' => Icon::ENROLLED, 'url' => '?status=enrolled' ),
49 * array( 'label' => 'Wishlist', 'count' => 1, 'icon' => Icon::WISHLIST, 'url' => '?status=wishlist' ),
50 * ),
51 * ),
52 * array( 'type' => 'link', 'label' => 'Reviews', 'url' => '/reviews' ),
53 * );
54 *
55 * Nav::make()
56 * ->items( $items )
57 * ->size( Size::SMALL )
58 * ->variant( Variant::SECONDARY )
59 * ->render();
60 *
61 * // Nav with count displayed on link items
62 * $items = array(
63 * array( 'type' => 'link', 'label' => 'Students', 'count' => 42, 'url' => '/students', 'active' => true ),
64 * array( 'type' => 'link', 'label' => 'Reviews', 'count' => 8, 'url' => '/reviews' ),
65 * );
66 *
67 * Nav::make()
68 * ->items( $items )
69 * ->size( Size::LARGE )
70 * ->render();
71 *
72 * // Extra attributes on the wrapper
73 * Nav::make()
74 * ->items( $items )
75 * ->attr( 'id', 'student-nav' )
76 * ->render();
77 *
78 * // Retrieve HTML without echoing
79 * $html = Nav::make()->items( $items )->get();
80 * ```
81 *
82 * @since 4.0.0
83 */
84 class Nav extends BaseComponent {
85
86 /**
87 * The nav variant.
88 *
89 * @var string
90 */
91 protected $nav_variant = Variant::PRIMARY;
92
93 /**
94 * The nav size.
95 *
96 * @var string
97 */
98 protected $nav_size = Size::MEDIUM;
99
100 /**
101 * The nav items.
102 *
103 * @var array
104 */
105 protected $nav_items = array();
106
107 /**
108 * Nav attributes.
109 *
110 * @since 4.0.0
111 *
112 * @var array
113 */
114 protected $attributes = array();
115
116 /**
117 * Set the nav variant.
118 *
119 * @since 4.0.0
120 *
121 * @param string $variant the nav variant to set.
122 *
123 * @return self
124 */
125 public function variant( $variant = Variant::PRIMARY ): self {
126 $allowed_variants = array( Variant::PRIMARY, Variant::SECONDARY );
127 $this->nav_variant = in_array( $variant, $allowed_variants, true ) ? $variant : Variant::PRIMARY;
128 return $this;
129 }
130
131 /**
132 * Set the nav size.
133 *
134 * @since 4.0.0
135 *
136 * @param string $size the nav size.
137 *
138 * @return self
139 */
140 public function size( $size = Size::MEDIUM ): self {
141 $allowed_sizes = array( Size::MEDIUM, Size::SMALL, Size::LARGE );
142 $this->nav_size = in_array( $size, $allowed_sizes, true ) ? $size : Size::MEDIUM;
143
144 return $this;
145 }
146
147 /**
148 * Set the nav items.
149 *
150 * @since 4.0.0
151 *
152 * @param array $items the nav items.
153 *
154 * @return self
155 */
156 public function items( $items = array() ): self {
157 $this->nav_items = $items;
158 return $this;
159 }
160
161 /**
162 * Get icon size for item size.
163 *
164 * @since 4.0.0
165 *
166 * @param string $size the item size.
167 *
168 * @return integer
169 */
170 protected function get_icon_size( $size ): int {
171 $icon_sizes = array(
172 Size::SMALL => 20,
173 Size::MEDIUM => 20,
174 Size::LARGE => 24,
175 );
176
177 return $icon_sizes[ $size ];
178 }
179
180 /**
181 * Get the label of the active dropdown option.
182 *
183 * @since 4.0.0
184 *
185 * @param array $options Array of dropdown options.
186 *
187 * @return string The label of the active option, or the first option's label * if none are active.
188 */
189 protected function get_active_dropdown_label( array $options ): string {
190 if ( ! tutor_utils()->count( $options ) ) {
191 return '';
192 }
193
194 $active_option = $options[0];
195 foreach ( $options as $option ) {
196 if ( ! empty( $option['active'] ) ) {
197 $active_option = $option;
198 break;
199 }
200 }
201
202 $label = $active_option['label'] ?? '';
203 if ( isset( $active_option['count'] ) ) {
204 $label .= ' (' . $active_option['count'] . ')';
205 }
206
207 return $label;
208 }
209
210 /**
211 * Get the icon of the active dropdown option.
212 *
213 * @since 4.0.0
214 *
215 * @param array $options Array of dropdown options.
216 *
217 * @return string The icon of the active option, or the first option's icon if none are active.
218 */
219 protected function get_active_dropdown_icon( array $options ): string {
220 if ( ! tutor_utils()->count( $options ) ) {
221 return '';
222 }
223
224 $active_option = $options[0];
225 foreach ( $options as $option ) {
226 if ( ! empty( $option['active'] ) ) {
227 $active_option = $option;
228 break;
229 }
230 }
231
232 return $active_option['icon'] ?? '';
233 }
234
235 /**
236 * Render dropdown nav if it is selected.
237 *
238 * @since 4.0.0
239 *
240 * @param array $item the dropdown nav item.
241 *
242 * @return string
243 */
244 protected function render_dropdown_item( array $item ): string {
245 $dropdown = '';
246
247 if ( ! tutor_utils()->count( $item ) ) {
248 return '';
249 }
250
251 $options = $item['options'] ?? array();
252 $active_label = $this->get_active_dropdown_label( $options );
253 $icon_size = $this->get_icon_size( $this->nav_size );
254 $active_item = isset( $item['active'] ) && $item['active'] ? 'active' : '';
255 $active_icon = $this->get_active_dropdown_icon( $options );
256 $icon = $active_icon ? SvgIcon::make()->name( $active_icon )->size( $icon_size )->get() : '';
257 $dropdown_icon = SvgIcon::make()
258 ->name( Icon::CHEVRON_DOWN_2 )
259 ->size( $icon_size )
260 ->color( Color::SUBDUED )
261 ->get();
262
263 $dropdown_options = '';
264
265 if ( count( $options ) ) {
266 foreach ( $options as $option ) {
267 $option_icon = isset( $option['icon'] ) ? SvgIcon::make()->name( $option['icon'] )->size( $icon_size )->get() : '';
268 $is_active = isset( $option['active'] ) && $option['active'] ? 'active' : '';
269 $label = esc_html( $option['label'] );
270 $label = isset( $option['count'] ) ? $label . ' (' . esc_html( $option['count'] ) . ')' : $label;
271 $url = isset( $option['url'] ) ? esc_url( $option['url'] ) : '#';
272
273 $dropdown_options .= sprintf(
274 '<a href="%s" class="tutor-nav-dropdown-item %s">
275 %s
276 %s
277 </a>',
278 $url,
279 $is_active,
280 $option_icon,
281 $label
282 );
283 }
284 }
285
286 $dropdown = sprintf(
287 '<div x-data="tutorPopover({ placement: \'bottom-start\', offset: 4 })">
288 <button x-ref="trigger" @click="toggle()"
289 :aria-expanded="open.toString()"
290 aria-haspopup="true"
291 class="tutor-nav-item %s">
292 %s
293 %s
294 %s
295 </button>
296 <div x-ref="content" x-show="open" x-cloak @click.outside="handleClickOutside()" class="tutor-popover tutor-nav-dropdown" x-transition.origin.top.left>
297 %s
298 </div>
299 </div>',
300 $active_item,
301 $icon,
302 esc_html( $active_label ),
303 $dropdown_icon,
304 $dropdown_options
305 );
306
307 return $dropdown;
308 }
309
310 /**
311 * Render link nav item if it is selected.
312 *
313 * @since 4.0.0
314 *
315 * @param array $item the link nav item.
316 *
317 * @return string
318 */
319 protected function render_link_item( array $item ): string {
320 $dropdown = '';
321
322 if ( ! tutor_utils()->count( $item ) ) {
323 return '';
324 }
325
326 $active_item = isset( $item['active'] ) && $item['active'] ? 'active' : '';
327 $url = isset( $item['url'] ) ? esc_url( $item['url'] ) : '#';
328 $icon_size = $this->get_icon_size( $this->nav_size );
329 $label = esc_html( $item['label'] ?? '' );
330 $label = isset( $item['count'] ) ? $label . ' (' . esc_html( $item['count'] ) . ')' : $label;
331 $icon = isset( $item['icon'] ) ? SvgIcon::make()->name( $item['icon'] )->size( $icon_size )->get() : '';
332
333 $dropdown = sprintf(
334 '<a href="%s" class="tutor-nav-item %s">
335 %s
336 %s
337 </a>',
338 $url,
339 $active_item,
340 $icon,
341 $label
342 );
343
344 return $dropdown;
345 }
346
347 /**
348 * Get the HTML nav component.
349 *
350 * @since 4.0.0
351 *
352 * @return string
353 */
354 public function get(): string {
355 if ( ! count( $this->nav_items ) ) {
356 return '';
357 }
358
359 $nav_items = '';
360
361 foreach ( $this->nav_items as $nav_item ) {
362 if ( isset( $nav_item['type'] ) && InputType::DROPDOWN === $nav_item['type'] ) {
363 $nav_items .= $this->render_dropdown_item( $nav_item );
364 } else {
365 $nav_items .= $this->render_link_item( $nav_item );
366 }
367 }
368
369 $classes = sprintf(
370 'tutor-nav tutor-nav-%s tutor-nav-%s',
371 $this->nav_size,
372 $this->nav_variant,
373 );
374
375 // Merge with any custom class attribute.
376 $this->attributes['class'] = trim( "{$classes} " . ( $this->attributes['class'] ?? '' ) );
377
378 $attributes = $this->get_attributes_string();
379
380 return sprintf(
381 '<div %s>
382 %s
383 </div>',
384 $attributes,
385 $nav_items
386 );
387 }
388 }
389