PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.1.9
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.1.9
3.2.2 3.2.3 3.2.1 3.2.0 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.9 trunk 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.3 1.1.4 1.1.5 All 174 releases
master-addons / inc / modules / display / mega-menu / inc / walker-nav-menu.php

walker-nav-menu.php in Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits 3.1.9, at inc/modules/display/mega-menu/inc/walker-nav-menu.php

419 lines 19.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace MasterAddons\Modules\Display\MegaMenu;
4
5 use MasterAddons\Modules\Display\MegaMenu\JLTMA_Megamenu_Options;
6 use MasterAddons\Inc\Classes\Helper;
7 // use \Walker_Nav_Menu;
8
9 class Megamenu_Nav_Walker extends \Walker_Nav_Menu
10 {
11
12 private $currentItem;
13 private static $_instance = null;
14 public $menu_Settings;
15
16 // Get Item Custom Method
17 public function get_item_meta($menu_item_id)
18 {
19 $meta_key = Megamenu_Options::$jltma_menuitem_settings_key;
20 $data = get_post_meta($menu_item_id, $meta_key, true);
21 $data = (array) json_decode($data);
22
23 $format = [
24 "menu_id" => null,
25 "menu_has_child" => '',
26 "menu_enable" => 0,
27 "menu_trigger_effect" => 'hover',
28 "menu_icon" => '',
29 "menu_disable_description" => 0,
30 "menu_label_enable" => 0,
31 "menu_icon_color" => '',
32 "menu_width_type" => 'default',
33 "menu_width_size" => '1000px',
34 "menu_transition" => '',
35 "menu_badge_text" => '',
36 "menu_badge_color" => '',
37 "menu_badge_background" => '',
38 "menu_mobile_submenu_content_type" => 'builder_content'
39 ];
40
41 return array_merge($format, $data);
42 }
43
44 public function is_megamenu($menu_slug)
45 {
46 $menu_slug = (((gettype($menu_slug) == 'object') && isset($menu_slug->slug)) ? $menu_slug->slug : $menu_slug);
47
48 $cache_key = 'master_megamenu_data_' . $menu_slug;
49 $cached = wp_cache_get($cache_key);
50 if (false !== $cached) {
51 return $cached;
52 }
53
54 $return = 0;
55 $settings = Megamenu_Options::get_instance()->get_option(Megamenu_Options::$jltma_menu_settings_key, []);
56 $term = get_term_by('slug', $menu_slug, 'nav_menu');
57
58 if (
59 isset($term->term_id)
60 && isset($settings['menu_location_' . $term->term_id])
61 && $settings['menu_location_' . $term->term_id]['is_enabled'] == '1'
62 ) {
63
64 $return = 1;
65 }
66
67 wp_cache_set($cache_key, $return);
68 return $return;
69 }
70
71 public function is_megamenu_item($item_meta, $menu)
72 {
73 if ($this->is_megamenu($menu) == 1 && $item_meta['menu_enable'] == 1 && class_exists('Elementor\Plugin')) {
74 return true;
75 }
76 return false;
77 }
78
79 /**
80 * Starts the list before the elements are added.
81 */
82 public function start_lvl(&$output, $depth = 0, $args = array())
83 {
84 $indent = str_repeat("\t", $depth);
85
86 $output .= "\n$indent<ul class=\"jltma-dropdown jltma-sub-menu dropdown-menu\">\n";
87 }
88 /**
89 * Ends the list of after the elements are added.
90 *
91 * @see Walker::end_lvl()
92 * @since 3.0.0
93 * @param string $output Passed by reference. Used to append additional content.
94 * @param int $depth Depth of menu item. Used for padding.
95 * @param array $args An array of arguments. @see wp_nav_menu()
96 */
97 public function end_lvl(&$output, $depth = 0, $args = array())
98 {
99 $indent = str_repeat("\t", $depth);
100 $output .= "$indent</ul>\n";
101 }
102 /**
103 * Start the element output.
104 * @see Walker::start_el()
105 * @param int $id Current item ID.
106 */
107 public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
108 {
109 $this->currentItem = $item;
110
111 $indent = ($depth) ? str_repeat("\t", $depth) : '';
112 $classes = empty($item->classes) ? array() : (array) $item->classes;
113 $classes[] = 'menu-item-' . $item->ID;
114
115
116 /**
117 * Filter the CSS class(es) applied to a menu item's list item element.
118 */
119 $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args, $depth));
120
121 $class_names .= ' nav-item';
122 $item_meta = $this->get_item_meta($item->ID);
123
124 $menu_obj = wp_get_nav_menu_object($args->menu);
125 $is_megamenu_item = $this->is_megamenu_item($item_meta, $menu_obj);
126 $data_menu_width_type = '';
127 if (in_array('menu-item-has-children', $classes) || $is_megamenu_item == true) {
128 $class_names .= ' jltma-menu-has-children';
129 $data_menu_width_type = ' data-menu-type="'.$item_meta['menu_width_type'].'"';
130 if ($is_megamenu_item == true) {
131 if ($item_meta['menu_mobile_submenu_content_type'] == 'submenu_list') {
132 $class_names .= ' jltma-default-submenu';
133 }
134 $class_names .= ' jltma-has-megamenu ';
135 }else{
136 $class_names .= ' jltma-default-submenu';
137 }
138 }
139
140 // if ($depth === 0 && in_array('menu-item-has-children', $classes)) {
141 // $class_names .= ' dropdown';
142 // }
143
144 if (in_array('menu-item-has-children', $classes)) {
145 $class_names .= ' dropdown';
146 }
147
148 if ($item_meta['menu_trigger_effect'] != "") {
149 $class_names .= ' jltma-megamenu-' . $item_meta['menu_trigger_effect'];
150 }
151
152 if ($item_meta['menu_transition'] != "") {
153 $class_names .= ' ' . $item_meta['menu_transition'];
154 }
155
156
157 if ($item_meta['menu_mobile_submenu_content_type'] == 'builder_content') {
158 $class_names .= ' jltma-mobile-builder-content';
159 }
160
161 if (in_array('current-menu-item', $classes)) {
162 $class_names .= ' active';
163 }
164
165 $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';
166
167 /**
168 * Filter the ID applied to a menu item's list item element.
169 */
170 $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth);
171 $id = $id ? ' id="' . esc_attr($id) . '"' : '';
172
173 $output .= $indent . '<li' . $id . $class_names . $data_menu_width_type . '>';
174 $atts = array();
175 $atts['title'] = !empty($item->attr_title) ? $item->attr_title : '';
176
177 $atts['target'] = !empty($item->target) ? $item->target : '';
178 $atts['rel'] = !empty($item->xfn) ? $item->xfn : '';
179 $atts['href'] = !empty($item->url) ? $item->url : '';
180
181 $submenu_indicator = '';
182
183 // New
184 if ($depth === 0) {
185 $atts['class'] = 'jltma-menu-nav-link nav-link';
186 }
187
188 if (in_array('menu-item-has-children', $classes) || $is_megamenu_item == true) {
189 $atts['data-toggle'] = 'dropdown';
190 $atts['class'] .= ' jltma-menu-dropdown-toggle';
191 }
192
193 // Build submenu indicator with mega menu icon if set
194 if (in_array('menu-item-has-children', $classes) || $is_megamenu_item == true) {
195 $indicator_icon = '';
196 // Check if mega menu has icon set
197 if ($this->is_megamenu($menu_obj) == 1 && !empty($item_meta['menu_icon'])) {
198 // Only apply color style if explicitly set (not default brand color)
199 $icon_style = '';
200 if (!empty($item_meta['menu_icon_color']) && $item_meta['menu_icon_color'] !== '#6814cd') {
201 $icon_style = 'color:' . $item_meta['menu_icon_color'] . ';';
202 }
203 $v = explode('|', $item_meta['menu_icon']);
204 $menu_icon_class = isset($v[1]) ? $v[0] . ' ' . $v[1] : $item_meta['menu_icon'];
205 if (!empty($icon_style)) {
206 $indicator_icon = '<i class="' . esc_attr($menu_icon_class) . '" style="' . esc_attr($icon_style) . '"></i>';
207 } else {
208 $indicator_icon = '<i class="' . esc_attr($menu_icon_class) . '"></i>';
209 }
210 }
211 $submenu_indicator = '<span class="jltma-submenu-indicator">' . $indicator_icon . '</span>';
212 }
213 if ($depth > 0) {
214 $manual_class = array_values($classes)[0] . ' ' . 'dropdown-item';
215 $atts['class'] = $manual_class;
216 }
217 if (in_array('current-menu-item', $item->classes)) {
218 $atts['class'] .= ' active';
219 }
220
221 /**
222 * Filter the HTML attributes applied to a menu item's anchor element.
223 */
224 $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args, $depth);
225 $attributes = '';
226 foreach ($atts as $attr => $value) {
227 if (!empty($value)) {
228 $value = ('href' === $attr) ? esc_url($value) : esc_attr($value);
229 $attributes .= ' ' . $attr . '="' . $value . '"';
230 }
231 }
232 $item_output = $args->before;
233
234 $item_output .= '<a' . $attributes . '>';
235 $menu_obj = wp_get_nav_menu_object($args->menu);
236
237 if ($this->is_megamenu($menu_obj) == 1) {
238
239 // add badge text
240 if ($item_meta['menu_badge_text'] != '') {
241 $badge_style = 'background:' . $item_meta['menu_badge_background'] . '; color:' . $item_meta['menu_badge_color'];
242 $badge_carret_style = 'border-top-color:' . $item_meta['menu_badge_background'];
243 $item_output .= '<span style="' . $badge_style . '; padding: 0px 7px;font-size: 10px;border-radius: 10px;position: absolute;right: 3px;top: -7px;" class="jltma-menu-badge">' . $item_meta['menu_badge_text'] . '<i style="' . $badge_carret_style . '" class="jltma-menu-badge-arrow"></i></span>';
244 }
245
246 if ($item_meta['menu_disable_description'] == "1") {
247 $item_output .= (!empty($item->description) and 0 == $depth)
248 ? '<small class="jltma-menu-description">' . esc_attr($item->description) . '</small>' : '';
249 }
250 }
251
252
253 /** This filter is documented in wp-includes/post-template.php */
254 $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
255
256 if ($item_meta['menu_label_enable'] == "1") {
257 $item_output .= '<span class="jltma-menu-label">' . $item->attr_title . '</span>';
258 }
259
260 $item_output .= $submenu_indicator . '</a>';
261 $item_output .= $args->after;
262 /**
263 * Filter a menu item's starting output.
264 *
265 */
266 $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
267 }
268 /**
269 * Ends the element output
270 */
271 public function end_el(&$output, $item, $depth = 0, $args = array())
272 {
273 if ($depth === 0) {
274 $menu_obj = wp_get_nav_menu_object($args->menu);
275 if ($this->is_megamenu($menu_obj) == 1) {
276
277 $item_meta = $this->get_item_meta($item->ID);
278
279 $menu_transition = 'fade-up';
280 if ($item_meta['menu_transition'] != "") {
281 $menu_transition = $item_meta['menu_transition'];
282 }
283
284 if ($item_meta['menu_enable'] == 1 && class_exists('Elementor\Plugin')) {
285 $width = 'max-content';
286 if( $item_meta['menu_width_type'] == 'custom_width' ){
287 if( $item_meta['menu_width_size'] != '' ){
288 $width = $item_meta['menu_width_size'];
289 }
290 }
291 if( $item_meta['menu_width_type'] == 'full_width' ){
292 $width = '100%';
293 }
294
295 $builder_post_title = 'mastermega-content-megamenu-menuitem' . $item->ID;
296 $builder_post = Helper::get_page_by_title( $builder_post_title, 'mastermega_content' );
297
298 // Get Elementor page settings for background
299 $megamenu_style = 'width:'.$width.';';
300 if ($builder_post != null) {
301 $page_settings = get_post_meta($builder_post->ID, '_elementor_page_settings', true);
302 if (!empty($page_settings) && is_array($page_settings)) {
303 // Handle background color
304 if (!empty($page_settings['background_background'])) {
305 if ($page_settings['background_background'] === 'classic' && !empty($page_settings['background_color'])) {
306 $megamenu_style .= 'background-color:' . esc_attr($page_settings['background_color']) . ';';
307 }
308 // Handle gradient background
309 if ($page_settings['background_background'] === 'gradient') {
310 $gradient_color = !empty($page_settings['background_color']) ? $page_settings['background_color'] : '#fff';
311 $gradient_color_b = !empty($page_settings['background_color_b']) ? $page_settings['background_color_b'] : '#000';
312 $gradient_type = !empty($page_settings['background_gradient_type']) ? $page_settings['background_gradient_type'] : 'linear';
313 $gradient_angle = !empty($page_settings['background_gradient_angle']['size']) ? $page_settings['background_gradient_angle']['size'] : 180;
314 $gradient_position = !empty($page_settings['background_gradient_position']) ? $page_settings['background_gradient_position'] : 'center center';
315
316 if ($gradient_type === 'linear') {
317 $megamenu_style .= 'background:linear-gradient(' . esc_attr($gradient_angle) . 'deg, ' . esc_attr($gradient_color) . ', ' . esc_attr($gradient_color_b) . ');';
318 } else {
319 $megamenu_style .= 'background:radial-gradient(at ' . esc_attr($gradient_position) . ', ' . esc_attr($gradient_color) . ', ' . esc_attr($gradient_color_b) . ');';
320 }
321 }
322 }
323 // Handle background image
324 if (!empty($page_settings['background_image']['url'])) {
325 $megamenu_style .= 'background-image:url(' . esc_url($page_settings['background_image']['url']) . ');';
326 if (!empty($page_settings['background_position'])) {
327 $megamenu_style .= 'background-position:' . esc_attr($page_settings['background_position']) . ';';
328 }
329 if (!empty($page_settings['background_size'])) {
330 $megamenu_style .= 'background-size:' . esc_attr($page_settings['background_size']) . ';';
331 }
332 if (!empty($page_settings['background_repeat'])) {
333 $megamenu_style .= 'background-repeat:' . esc_attr($page_settings['background_repeat']) . ';';
334 }
335 }
336 // Handle padding
337 if (!empty($page_settings['padding'])) {
338 $padding = $page_settings['padding'];
339 if (!empty($padding['top']) || !empty($padding['right']) || !empty($padding['bottom']) || !empty($padding['left'])) {
340 $unit = !empty($padding['unit']) ? $padding['unit'] : 'px';
341 $megamenu_style .= 'padding:' .
342 (isset($padding['top']) ? $padding['top'] : '0') . $unit . ' ' .
343 (isset($padding['right']) ? $padding['right'] : '0') . $unit . ' ' .
344 (isset($padding['bottom']) ? $padding['bottom'] : '0') . $unit . ' ' .
345 (isset($padding['left']) ? $padding['left'] : '0') . $unit . ';';
346 }
347 }
348 }
349 }
350
351 $output .= '<ul class="dropdown-menu jltma-megamenu ' . esc_attr($menu_transition) . '" style="' . esc_attr($megamenu_style) . '">';
352 if ($builder_post != null) {
353 $elementor = \Elementor\Plugin::instance();
354 // Pass $with_css = true so the mega menu content's Elementor CSS is
355 // printed inline with the markup. The walker runs in <body> after
356 // wp_head has fired, so the external post-{id}.css enqueue is too late;
357 // inline CSS keeps styling correct on every render regardless of cache state.
358 $output .= $elementor->frontend->get_builder_content_for_display($builder_post->ID, true);
359
360 // Register this mega menu content post with Elementor's Atomic Widgets
361 // styles manager. Atomic Elements render class-based CSS as external
362 // file handles enqueued on `elementor/frontend/after_enqueue_post_styles`,
363 // collecting post IDs from `elementor/post/render`. Elementor fires both
364 // only for the main queried post -- never for mega menu CPT posts. We are
365 // already in the exact scope of an active, rendered mega menu item, so we
366 // register it here (no global scan) and trigger the styles pass once in
367 // the footer (see queue_megamenu_styles()).
368 do_action('elementor/post/render', $builder_post->ID);
369 self::queue_megamenu_styles();
370 } else {
371 $output .= esc_html__('Menu content not found', 'master-addons' );
372 }
373
374 $output .= '</ul>';
375 }
376 }
377 $output .= "</li>\n";
378 }
379 }
380
381
382 /**
383 * Trigger Elementor's Atomic Widgets styles pass for the mega menu content
384 * posts collected via `elementor/post/render` during the walk.
385 *
386 * The walker runs in <body>, after Elementor's head-time styles pass
387 * (wp_enqueue_scripts priority 20) has already fired -- too late to enqueue
388 * into <head>. So we re-fire `after_enqueue_post_styles` once on wp_footer
389 * at priority 5, before WordPress prints late styles (wp_print_footer_scripts
390 * at priority 20). The atomic styles manager renders the collected posts'
391 * class-based CSS and enqueues it as late styles. No FOUC: the mega menu
392 * dropdown is display:none until hover, so the CSS lands before any reveal.
393 *
394 * Hooked once per request, and only when an active mega menu actually
395 * rendered -- pages without a mega menu do zero extra work.
396 */
397 private static $styles_queued = false;
398
399 private static function queue_megamenu_styles()
400 {
401 if (self::$styles_queued) {
402 return;
403 }
404 self::$styles_queued = true;
405
406 add_action('wp_footer', function () {
407 do_action('elementor/frontend/after_enqueue_post_styles');
408 }, 5);
409 }
410
411 public static function get_instance()
412 {
413 if (is_null(self::$_instance)) {
414 self::$_instance = new self();
415 }
416 return self::$_instance;
417 }
418 }
419