HEX
Server: Apache
System: Linux 244.240.109.208.host.secureserver.net 5.14.0-611.11.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Dec 3 09:47:37 EST 2025 x86_64
User: icsla (1002)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/icsla/public_html/wp-content/plugins/megamenu/classes/menu-item-manager.class.php
<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit; // disable direct access
}

if ( ! class_exists( 'Mega_Menu_Menu_Item_Manager' ) ) :

	/**
	 * Handles AJAX requests for menu item settings, including the lightbox
	 * editor, grid elements, and saving of menu item configuration.
	 *
	 * @since   1.4
	 * @package MegaMenu
	 */
	class Mega_Menu_Menu_Item_Manager {

		/**
		 * The ID of the current menu.
		 *
		 * @var int
		 */
		public $menu_id = 0;

		/**
		 * The ID of the current menu item.
		 *
		 * @var int
		 */
		public $menu_item_id = 0;

		/**
		 * The title of the current menu item.
		 *
		 * @var string
		 */
		public $menu_item_title = '';

		/**
		 * The depth of the current menu item (0 = top level).
		 *
		 * @var int
		 */
		public $menu_item_depth = 0;

		/**
		 * All menu item objects for the current menu.
		 *
		 * @var array
		 */
		public $menu_item_objects = [];

		/**
		 * Saved meta for the current menu item.
		 *
		 * @var array
		 */
		public $menu_item_meta = [];


		/**
		 * Constructor. Registers AJAX actions and menu item tab filters.
		 *
		 * @since 1.4
		 */
		public function __construct() {
			add_action( 'wp_ajax_megamenu_get_dialog_html', [ $this, 'ajax_get_dialog_html' ] );
			add_action( 'wp_ajax_megamenu_get_empty_grid_column', [ $this, 'ajax_get_empty_grid_column' ] );
			add_action( 'wp_ajax_megamenu_get_empty_grid_row', [ $this, 'ajax_get_empty_grid_row' ] );
			add_action( 'wp_ajax_megamenu_save_menu_item_settings', [ $this, 'ajax_save_menu_item_settings' ] );
			// Pro and older integrations still POST action=mm_save_menu_item_settings; admin-ajax returns 400 if no hook exists.
			add_action( 'wp_ajax_mm_save_menu_item_settings', [ $this, 'ajax_save_menu_item_settings' ] );

			add_filter( 'megamenu_tabs', [ $this, 'add_mega_menu_tab' ], 10, 5 );
			add_filter( 'megamenu_tabs', [ $this, 'add_general_settings_tab' ], 10, 5 );
			add_filter( 'megamenu_tabs', [ $this, 'add_icon_tab' ], 10, 5 );
		}


		/**
		 * Populates instance properties from the current AJAX POST request.
		 *
		 * @since 1.4
		 * @return void
		 */
		private function init() {
			if ( isset( $_POST['menu_item_id'] ) ) {
				$this->menu_item_id      = absint( $_POST['menu_item_id'] );
				$this->menu_id           = $this->get_menu_id_for_menu_item_id( $this->menu_item_id );
				$this->menu_item_objects = wp_get_nav_menu_items( $this->menu_id );
				$this->menu_item_title   = $this->get_title_for_menu_item_id( $this->menu_item_id, $this->menu_item_objects );
				$this->menu_item_depth   = $this->get_menu_item_depth( $this->menu_item_id, $this->menu_item_objects );
				$saved_settings          = array_filter( (array) get_post_meta( $this->menu_item_id, '_megamenu', true ) );
				$this->menu_item_meta    = array_merge( Mega_Menu_Nav_Menus::get_menu_item_defaults(), $saved_settings );
			}
		}

		/**
		 * Get the depth for a menu item ID.
		 *
		 * @since 2.7.7
		 * @param int   $menu_item_id      ID of the menu item.
		 * @param array $menu_item_objects All menu item objects for the menu.
		 * @return int Depth of the item: 0 = top level, 1 = second level, 2 = third level or deeper.
		 */
		public function get_menu_item_depth( $menu_item_id, $menu_item_objects ) {
			$parents = [];

			foreach ( $menu_item_objects as $key => $item ) {
				if ( $item->menu_item_parent == 0 ) {

					if ( $item->ID == $menu_item_id ) {
						return 0; // top level item
					}

					$parents[] = $item->ID;
				}
			}

			if ( count( $parents ) ) {
				foreach ( $menu_item_objects as $key => $item ) {
					if ( in_array( $item->menu_item_parent, $parents ) ) {
						if ( $item->ID == $menu_item_id ) {
							return 1; // second level item
						}
					}
				}
			}

			return 2; // third level item or above
		}


		/**
		 * Save custom menu item fields via AJAX.
		 *
		 * @since 1.4
		 * @return void
		 */
		public static function ajax_save_menu_item_settings() {

			check_ajax_referer( 'megamenu_edit' );

			$capability = apply_filters( 'megamenu_options_capability', 'edit_theme_options' );

			if ( ! current_user_can( $capability ) ) {
				return;
			}

			$submitted_settings = isset( $_POST['settings'] ) ? $_POST['settings'] : [];

			$menu_item_id = absint( $_POST['menu_item_id'] );

			if ( $menu_item_id > 0 && is_array( $submitted_settings ) ) {

				// only check the checkbox values if the general settings form was submitted
				if ( isset( $_POST['tab'] ) && $_POST['tab'] == 'general_settings' ) {

					$checkboxes = [ 'hide_text', 'disable_link', 'hide_arrow', 'hide_on_mobile', 'hide_on_desktop', 'close_after_click', 'hide_sub_menu_on_mobile', 'collapse_children' ];

					foreach ( $checkboxes as $checkbox ) {
						if ( ! isset( $submitted_settings[ $checkbox ] ) ) {
							$submitted_settings[ $checkbox ] = 'false';
						}
					}
				}

				$submitted_settings = apply_filters( 'megamenu_menu_item_submitted_settings', $submitted_settings, $menu_item_id );

				$existing_settings = get_post_meta( $menu_item_id, '_megamenu', true );

				if ( is_array( $existing_settings ) ) {

					$submitted_settings = array_merge( $existing_settings, $submitted_settings );

				}

				update_post_meta( $menu_item_id, '_megamenu', $submitted_settings );

				do_action( 'megamenu_save_menu_item_settings', $menu_item_id );

			}

			if ( isset( $_POST['clear_cache'] ) ) {

				do_action( 'megamenu_delete_cache' );

			}

			if ( ob_get_contents() ) {
				ob_clean(); // remove any warnings or output from other plugins which may corrupt the response
			}

			wp_send_json_success();

		}


		/**
		 * Returns the tab HTML for the menu item settings dialog via AJAX.
		 *
		 * @since 1.4
		 * @return void
		 */
		public function ajax_get_dialog_html() {

			check_ajax_referer( 'megamenu_edit' );

			$capability = apply_filters( 'megamenu_options_capability', 'edit_theme_options' );

			if ( ! current_user_can( $capability ) ) {
				return;
			}

			$this->init();

			$response = [];

			$response['title'] = $this->menu_item_title;

			$response['active_tab'] = 'mega_menu';

			if ( $this->menu_item_depth > 0 ) {
				$response['active_tab'] = 'general_settings';
			}

			$response = apply_filters( 'megamenu_tabs', $response, $this->menu_item_id, $this->menu_id, $this->menu_item_depth, $this->menu_item_meta );

			if ( ob_get_contents() ) {
				ob_clean(); // remove any warnings or output from other plugins which may corrupt the response
			}

			wp_send_json_success( json_encode( $response ) );
		}


		/**
		 * Returns the menu ID for a specified menu item ID.
		 *
		 * @since 2.7.5
		 * @param int $menu_item_id ID of the menu item.
		 * @return int The parent menu's term ID.
		 */
		public function get_menu_id_for_menu_item_id( $menu_item_id ) {
			$terms   = get_the_terms( $menu_item_id, 'nav_menu' );
			$menu_id = $terms[0]->term_id;
			return $menu_id;
		}


		/**
		 * Returns the title of a given menu item.
		 *
		 * @since 2.7.5
		 * @param int   $menu_item_id      ID of the menu item.
		 * @param array $menu_item_objects All menu item objects for the menu.
		 * @return string|false The menu item title, or false if not found.
		 */
		public function get_title_for_menu_item_id( $menu_item_id, $menu_item_objects ) {
			foreach ( $menu_item_objects as $key => $item ) {
				if ( $item->ID == $menu_item_id ) {
					return $item->title;
				}
			}

			return false;
		}

		/**
		 * Return the HTML to display in the 'Mega Menu' tab.
		 *
		 * @since 1.7
		 * @param array $tabs            Existing tabs array.
		 * @param int   $menu_item_id    ID of the menu item.
		 * @param int   $menu_id         ID of the menu.
		 * @param int   $menu_item_depth Depth of the menu item.
		 * @param array $menu_item_meta  Saved meta for the menu item.
		 * @return array Updated tabs array.
		 */
		public function add_mega_menu_tab( $tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta ) {
			if ( $menu_item_depth > 0 ) {
				$tabs['mega_menu'] = [
					'title'   => __( 'Sub Menu', 'megamenu' ),
					'content' => '<em>' . __( 'Mega Menus can only be created on top level menu items.', 'megamenu' ) . '</em>',
				];

				return $tabs;
			}

			$return  = $this->get_mega_submenu_toolbar_html( $menu_item_meta, $menu_item_depth );
			$return .= $this->get_megamenu_html( $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta );

			$return .= $this->get_megamenu_grid_html( $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta );

			$tabs['mega_menu'] = [
				'title'   => __( 'Mega Menu', 'megamenu' ),
				'content' => $return,
			];

			return $tabs;
		}


		/**
		 * Markup for sub menu type + panel options (`mm_*` ids, `mm_panel_options`), matching megamenu-pro.
		 * JS wraps this in `.mega-submenu-toolbar` when missing. Public for extensions.
		 *
		 * @since 3.9.0
		 * @param array $menu_item_meta   Saved mega menu meta for the menu item; must include `type`.
		 * @param int   $menu_item_depth  Item depth: 0 top level, 1 second level, 2 third level or deeper (@see get_menu_item_depth()).
		 * @return string HTML.
		 */
		public function get_mega_submenu_toolbar_html( $menu_item_meta, $menu_item_depth = 0 ) {
			$submenu_options = apply_filters(
				'megamenu_submenu_options',
				[
					'flyout'   => __( 'Flyout Menu', 'megamenu' ),
					'grid'     => __( 'Mega Menu - Grid Layout', 'megamenu' ),
					'megamenu' => __( 'Mega Menu - Standard Layout', 'megamenu' ),
				],
				$menu_item_meta,
				(int) $menu_item_depth
			);

			// Match megamenu-pro Tab Content / second-level markup (`mm_*` ids, `mm_panel_options`) so Pro + free share one DOM contract.
			$return  = "<label for='mm_enable_mega_menu'>" . esc_html__( 'Sub menu display mode', 'megamenu' ) . '</label>';
			$return .= "<select id='mm_enable_mega_menu' name='settings[type]'>";

			foreach ( $submenu_options as $type => $label ) {
				$return .= "<option id='{$type}' value='{$type}' " . selected( $menu_item_meta['type'], $type, false ) . ">{$label}</option>";
			}
			$return .= '</select>';

			$widget_manager = new Mega_Menu_Widget_Manager();

			$all_widgets = $widget_manager->get_available_widgets();

			$return .= "<div class='mm_panel_options'>";
			$return .= $this->get_panel_columns_select_markup( $menu_item_meta );
			$return .= "<select id='mm_widget_selector'>";
			$return .= "<option value='disabled'>" . esc_html__( 'Select a Widget to add to the panel', 'megamenu' ) . '</option>';

			foreach ( $all_widgets as $widget ) {
				$return .= "<option value='" . esc_attr( $widget['value'] ) . "'>" . esc_html( $widget['text'] ) . '</option>';
			}

			$return .= '</select>';
			$return .= '</div>';

			$return .= apply_filters( 'megamenu_submenu_toolbar_extra_html', '', $menu_item_meta, (int) $menu_item_depth );

			return $return;
		}


		/**
		 * Return the HTML for the grid layout mega menu builder.
		 *
		 * @since 2.4
		 * @param int   $menu_item_id    ID of the menu item.
		 * @param int   $menu_id         ID of the menu.
		 * @param int   $menu_item_depth Depth of the menu item.
		 * @param array $menu_item_meta  Saved meta for the menu item.
		 * @return string Grid layout HTML.
		 */
		public function get_megamenu_grid_html( $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta ) {

			$return = "<div id='megamenu-grid'>";

			$widget_manager = new Mega_Menu_Widget_Manager();

			$grid = $widget_manager->get_grid_widgets_and_menu_items_for_menu_id( $menu_item_id, $menu_id );

			if ( count( $grid ) ) {

				foreach ( $grid as $row => $row_data ) {

					$column_html = '';

					if ( isset( $row_data['columns'] ) && count( $row_data['columns'] ) ) {

						foreach ( $row_data['columns'] as $col => $col_data ) {
							$column_html .= $this->get_grid_column( $row_data, $col_data );
						}
					}

					$return .= $this->get_grid_row( $row_data, $column_html );

				}
			}

			$return .= "   <button class='button button-primary button-small mega-add-row'><span class='dashicons dashicons-plus'></span>" . __( 'Row', 'megamenu' ) . '</button>';
			$return .= '</div>';

			return $return;

		}

		/**
		 * Returns the HTML for an empty grid column via AJAX.
		 *
		 * @since 2.4
		 * @return void
		 */
		public function ajax_get_empty_grid_column() {

			check_ajax_referer( 'megamenu_edit' );

			$capability = apply_filters( 'megamenu_options_capability', 'edit_theme_options' );

			if ( ! current_user_can( $capability ) ) {
				return;
			}

			$return = $this->get_grid_column();

			if ( ob_get_contents() ) {
				ob_clean(); // remove any warnings or output from other plugins which may corrupt the response
			}

			wp_send_json_success( $return );
		}

		/**
		 * Returns the HTML for an empty grid row via AJAX.
		 *
		 * @since 2.4
		 * @return void
		 */
		public function ajax_get_empty_grid_row() {

			check_ajax_referer( 'megamenu_edit' );

			$capability = apply_filters( 'megamenu_options_capability', 'edit_theme_options' );

			if ( ! current_user_can( $capability ) ) {
				return;
			}

			$column_html = $this->get_grid_column();

			$return = $this->get_grid_row( false, $column_html );

			if ( ob_get_contents() ) {
				ob_clean(); // remove any warnings or output from other plugins which may corrupt the response
			}

			wp_send_json_success( $return );
		}

		/**
		 * Return the HTML for a single grid row.
		 *
		 * @since 2.4
		 * @param array|false  $row_data    Row meta data, or false for an empty row.
		 * @param string|false $column_html Pre-rendered column HTML, or false for empty.
		 * @return string Row HTML.
		 */
		public function get_grid_row( $row_data = false, $column_html = false ) {

			$hide_on_desktop_checked = 'false';
			$hide_on_desktop         = 'mega-enabled';

			if ( isset( $row_data['meta']['hide-on-desktop'] ) && $row_data['meta']['hide-on-desktop'] == 'true' ) {
				$hide_on_desktop         = 'mega-disabled';
				$hide_on_desktop_checked = 'true';
			}

			$hide_on_mobile_checked = 'false';
			$hide_on_mobile         = 'mega-enabled';

			if ( isset( $row_data['meta']['hide-on-mobile'] ) && $row_data['meta']['hide-on-mobile'] == 'true' ) {
				$hide_on_mobile         = 'mega-disabled';
				$hide_on_mobile_checked = 'true';
			}

			$row_columns = 12;

			if ( isset( $row_data['meta']['columns'] ) ) {
				$row_columns = (int) $row_data['meta']['columns'];
			}

			$desktop_tooltip_visible = __( 'Row', 'megamenu' ) . ': ' . __( 'Visible on desktop', 'megamenu' );
			$desktop_tooltip_hidden  = __( 'Row', 'megamenu' ) . ': ' . __( 'Hidden on desktop', 'megamenu' );
			$mobile_tooltip_visible  = __( 'Row', 'megamenu' ) . ': ' . __( 'Visible on mobile', 'megamenu' );
			$mobile_tooltip_hidden   = __( 'Row', 'megamenu' ) . ': ' . __( 'Hidden on mobile', 'megamenu' );

			$row_class = isset( $row_data['meta']['class'] ) ? $row_data['meta']['class'] : '';

			$row_tracks = (int) $row_columns;
			$return      = "<div class='mega-row' data-available-cols='" . esc_attr( (string) $row_tracks ) . "' style='" . esc_attr( '--row-tracks: ' . $row_tracks . ';' ) . "'>";
			$return .= "    <div class='mega-row-header'>";
			$return .= "        <div class='mega-row-actions' role='toolbar' aria-label='" . esc_attr__( 'Row toolbar', 'megamenu' ) . "'>";
			$return .= "            <button type='button' class='dashicons dashicons-admin-generic mega-row-header__action mega-row-header__action--settings' aria-expanded='false' aria-label='" . esc_attr__( 'Row settings', 'megamenu' ) . "'></button>";
			$return .= "            <button type='button' class='" . esc_attr( "{$hide_on_desktop} mega-row-header__action mega-row-header__action--desktop" ) . "' data-mega-tooltip data-mega-tooltip-enabled='" . esc_attr( $desktop_tooltip_visible ) . "' data-mega-tooltip-disabled='" . esc_attr( $desktop_tooltip_hidden ) . "' aria-label='" . esc_attr__( 'Toggle row visibility on desktop', 'megamenu' ) . "'><span class='dashicons dashicons-desktop' aria-hidden='true'></span></button>";
			$return .= "            <button type='button' class='" . esc_attr( "{$hide_on_mobile} mega-row-header__action mega-row-header__action--mobile" ) . "' data-mega-tooltip data-mega-tooltip-enabled='" . esc_attr( $mobile_tooltip_visible ) . "' data-mega-tooltip-disabled='" . esc_attr( $mobile_tooltip_hidden ) . "' aria-label='" . esc_attr__( 'Toggle row visibility on mobile', 'megamenu' ) . "'><span class='dashicons dashicons-smartphone' aria-hidden='true'></span></button>";
			$return .= "            <button type='button' class='dashicons dashicons-trash mega-row-header__action mega-row-header__action--delete' aria-label='" . esc_attr__( 'Delete row', 'megamenu' ) . "'></button>";
			$return .= '        </div>';
			$return .= "        <div class='mega-row-settings'>";
			$return .= "            <input name='mega-hide-on-mobile' type='hidden' value='{$hide_on_mobile_checked}' />";
			$return .= "            <input name='mega-hide-on-desktop' type='hidden' value='{$hide_on_desktop_checked}'/>";
			$return .= "            <div class='mega-settings-row'>";
			$return .= '                <label>' . __( 'Row class', 'megamenu' ) . '</label>';
			$return .= "                <input class='mega-row-class' type='text' value='{$row_class}' />";
			$return .= '            </div>';
			$return .= "            <div class='mega-settings-row'>";
			$return .= '                <label>' . __( 'Row columns', 'megamenu' ) . '</label>';
			$return .= "                <select class='mega-row-columns'>";
			$return .= "                    <option value='1' " . selected( $row_columns, 1, false ) . '>1 ' . __( 'column', 'megamenu' ) . '</option>';
			$return .= "                    <option value='2' " . selected( $row_columns, 2, false ) . '>2 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='3' " . selected( $row_columns, 3, false ) . '>3 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='4' " . selected( $row_columns, 4, false ) . '>4 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='5' " . selected( $row_columns, 5, false ) . '>5 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='6' " . selected( $row_columns, 6, false ) . '>6 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='7' " . selected( $row_columns, 7, false ) . '>7 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='8' " . selected( $row_columns, 8, false ) . '>8 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='9' " . selected( $row_columns, 9, false ) . '>9 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='10' " . selected( $row_columns, 10, false ) . '>10 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='11' " . selected( $row_columns, 11, false ) . '>11 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= "                    <option value='12' " . selected( $row_columns, 12, false ) . '>12 ' . __( 'columns', 'megamenu' ) . '</option>';
			$return .= '                </select>';
			$return .= '            </div>';
			$return .= '<p class="submit"><button type="submit" class="button button-primary button-small mega-save-row-settings">' . esc_html__( 'Save', 'megamenu' ) . '</button></p>';
			$return .= '        </div>';
			$return .= "        <button class='button button-primary button-small mega-add-column'><span class='dashicons dashicons-plus'></span>" . __( 'Column', 'megamenu' ) . '</button>';
			$return .= '    </div>';
			$return .= "    <div class='error notice is-dismissible mega-too-many-cols'>";
			$return .= '        <p>' . __( 'You should rearrange the content of this row so that all columns fit onto a single line.', 'megamenu' ) . '</p>';
			$return .= '    </div>';
			$return .= "    <div class='error notice is-dismissible mega-row-is-full'>";
			$return .= '        <p>' . __( 'There is not enough space on this row to add a new column.', 'megamenu' ) . '</p>';
			$return .= '    </div>';

			$return .= "    <div class='mega-row-cols'>";
			$return .= $column_html ? $column_html : '';
			$return .= '    </div>';

			$return .= '</div>';

			return $return;
		}

		/**
		 * Return the HTML for an individual grid column.
		 *
		 * @since 2.4
		 * @param array|false $row_data Row meta data, or false for a new empty row.
		 * @param array|false $col_data Column meta and widget data, or false for empty.
		 * @return string Column HTML.
		 */
		public function get_grid_column( $row_data = false, $col_data = false ) {

			$col_span    = 3;
			$row_columns = 12;

			if ( isset( $row_data['meta']['columns'] ) ) {
				$row_columns = (int) $row_data['meta']['columns'];
			}

			if ( isset( $col_data['meta']['span'] ) ) {
				$col_span = $col_data['meta']['span'];
			}

			$hide_on_desktop_checked = 'false';
			$hide_on_desktop         = 'mega-enabled';

			if ( isset( $col_data['meta']['hide-on-desktop'] ) && $col_data['meta']['hide-on-desktop'] == 'true' ) {
				$hide_on_desktop         = 'mega-disabled';
				$hide_on_desktop_checked = 'true';
			}

			$hide_on_mobile_checked = 'false';
			$hide_on_mobile         = 'mega-enabled';

			if ( isset( $col_data['meta']['hide-on-mobile'] ) && $col_data['meta']['hide-on-mobile'] == 'true' ) {
				$hide_on_mobile         = 'mega-disabled';
				$hide_on_mobile_checked = 'true';
			}

			$desktop_tooltip_visible = __( 'Column', 'megamenu' ) . ': ' . __( 'Visible on desktop', 'megamenu' );
			$desktop_tooltip_hidden  = __( 'Column', 'megamenu' ) . ': ' . __( 'Hidden on desktop', 'megamenu' );
			$mobile_tooltip_visible  = __( 'Column', 'megamenu' ) . ': ' . __( 'Visible on mobile', 'megamenu' );
			$mobile_tooltip_hidden   = __( 'Column', 'megamenu' ) . ': ' . __( 'Hidden on mobile', 'megamenu' );

			$col_class = isset( $col_data['meta']['class'] ) ? $col_data['meta']['class'] : '';

			$col_span_int = (int) $col_span;
			$total_blocks = ( is_array( $col_data ) && isset( $col_data['items'] ) && count( $col_data['items'] ) ) ? count( $col_data['items'] ) : 0;
			$return        = "<div class='mega-col' data-span='" . esc_attr( (string) $col_span_int ) . "' data-total-blocks='" . esc_attr( (string) $total_blocks ) . "' style='" . esc_attr( '--span: ' . $col_span_int . ';' ) . "'>";
			$return .= "    <div class='mega-col-wrap'>";
			$return .= "        <div class='mega-col-header'>";
			$return .= "            <div class='mega-col-actions' role='toolbar' aria-label='" . esc_attr__( 'Column toolbar', 'megamenu' ) . "'>";
			$return .= "                <button type='button' class='dashicons dashicons-admin-generic mega-col-header__action mega-col-header__action--settings' aria-expanded='false' aria-label='" . esc_attr__( 'Column settings', 'megamenu' ) . "'></button>";
			$return .= "                <button type='button' class='" . esc_attr( "{$hide_on_desktop} mega-col-header__action mega-col-header__action--desktop" ) . "' data-mega-tooltip data-mega-tooltip-enabled='" . esc_attr( $desktop_tooltip_visible ) . "' data-mega-tooltip-disabled='" . esc_attr( $desktop_tooltip_hidden ) . "' aria-label='" . esc_attr__( 'Toggle column visibility on desktop', 'megamenu' ) . "'><span class='dashicons dashicons-desktop' aria-hidden='true'></span></button>";
			$return .= "                <button type='button' class='" . esc_attr( "{$hide_on_mobile} mega-col-header__action mega-col-header__action--mobile" ) . "' data-mega-tooltip data-mega-tooltip-enabled='" . esc_attr( $mobile_tooltip_visible ) . "' data-mega-tooltip-disabled='" . esc_attr( $mobile_tooltip_hidden ) . "' aria-label='" . esc_attr__( 'Toggle column visibility on mobile', 'megamenu' ) . "'><span class='dashicons dashicons-smartphone' aria-hidden='true'></span></button>";
			$return .= "                <button type='button' class='dashicons dashicons-trash mega-col-header__action mega-col-header__action--delete' aria-label='" . esc_attr__( 'Delete column', 'megamenu' ) . "'></button>";
			$return .= '                <span class="mega-col-drag-handle" title="' . esc_attr__( 'Drag to reorder column', 'megamenu' ) . '"></span>';
			$return .= '            </div>';
			$return .= '            <div class="mega-col-span">';
			$return .= '<button type="button" class="mega-col-option mega-col-contract" aria-label="' . esc_attr__( 'Contract', 'megamenu' ) . '"><span class="dashicons dashicons-arrow-left-alt2" aria-hidden="true"></span></button>';
			$return .= "                <span class='mega-col-cols'><span class='mega-num-cols'>{$col_span_int}</span><span class='mega-of'>/</span><span class='mega-num-total-cols'>" . $row_columns . '</span></span>';
			$return .= '<button type="button" class="mega-col-options mega-col-expand" aria-label="' . esc_attr__( 'Expand', 'megamenu' ) . '"><span class="dashicons dashicons-arrow-right-alt2" aria-hidden="true"></span></button>';
			$return .= '            </div>';
			$return .= '        </div>';
			$return .= "        <div class='mega-col-settings'>";
			$return .= "            <input name='mega-hide-on-mobile' type='hidden' value='{$hide_on_mobile_checked}' />";
			$return .= "            <input name='mega-hide-on-desktop' type='hidden' value='{$hide_on_desktop_checked}'/>";
			$return .= '            <label>' . __( 'Column class', 'megamenu' ) . '</label>';
			$return .= "            <input class='mega-column-class' type='text' value='{$col_class}' />";
			$return .= '<p class="submit"><button type="submit" class="button button-primary button-small mega-save-column-settings">' . esc_html__( 'Save', 'megamenu' ) . '</button></p>';
			$return .= '        </div>';
			$return .= "        <div class='mega-col-widgets'>";

			if ( isset( $col_data['items'] ) && count( $col_data['items'] ) ) {
				foreach ( $col_data['items'] as $item ) {
					$return .= '<div class="mega-widget widget" id="' . esc_attr( $item['id'] ) . '" data-type="' . esc_attr( $item['type'] ) . '" data-id="' . esc_attr( $item['id'] ) . '">';
					$return .= '    <div class="mega-widget-top widget-top">';
					$return .= '        <div class="mega-widget-title widget-title">';
					$return .= '            <h4>' . esc_html( $item['title'] ) . '</h4>';
					$return .= '            <span class="mega-widget-desc widget-desc">' . esc_html( $item['description'] ) . '</span>';
					$return .= '        </div>';
					$return .= '        <div class="mega-widget-title-action widget-title-action">';
					$return .= '            <a class="mega-widget-option mega-widget-action widget-option widget-action" title="' . esc_attr( __( 'Edit', 'megamenu' ) ) . '"></a>';
					$return .= '        </div>';
					$return .= '    </div>';
					$return .= '    <div class="mega-widget-inner mega-widget-inside widget-inner widget-inside"></div>';
					$return .= '</div>';
				}
			}

			$add_widget_label = __( 'Add widget to this column', 'megamenu' );
			$return .= "            <button type='button' class='mega-col-add-widget' data-mega-tooltip='" . esc_attr( $add_widget_label ) . "' aria-label='" . esc_attr( $add_widget_label ) . "'>";
			$return .= "                <span class='dashicons dashicons-plus-alt2' aria-hidden='true'></span>";
			$return .= '            </button>';

			$return .= '        </div>';
			$return .= '    </div>';
			$return .= '</div>';

			return $return;
		}


		/**
		 * Return the HTML for the standard (non-grid) mega menu builder.
		 *
		 * @since 1.4
		 * @param int   $menu_item_id    ID of the menu item.
		 * @param int   $menu_id         ID of the menu.
		 * @param int   $menu_item_depth Depth of the menu item.
		 * @param array $menu_item_meta  Saved meta for the menu item.
		 * @return string Standard mega menu builder HTML.
		 */
		public function get_megamenu_html( $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta ) {

			$widget_manager = new Mega_Menu_Widget_Manager();

			$return = "<div id='megamenu-standard' data-columns='{$menu_item_meta['panel_columns']}'>";

			$items = $widget_manager->get_widgets_and_menu_items_for_menu_id( $menu_item_id, $menu_id );

			if ( count( $items ) ) {

				foreach ( $items as $item ) {
					$return .= '<div class="mega-widget widget" id="' . esc_attr( $item['id'] ) . '" data-columns="' . esc_attr( $item['columns'] ) . '" data-type="' . esc_attr( $item['type'] ) . '" data-id="' . esc_attr( $item['id'] ) . '">';
					$return .= '    <div class="mega-widget-top widget-top">';
					$return .= '        <div class="mega-widget-title widget-title">';
					$return .= '            <h4>' . esc_html( $item['title'] ) . '</h4>';
					$return .= '        </div>';
					$return .= '        <div class="mega-widget-title-action widget-title-action">';
					$return .= '            <div class="mega-col-span">';
					$return .= '<button type="button" class="mega-widget-option mega-widget-contract widget-option widget-contract" aria-label="' . esc_attr__( 'Contract', 'megamenu' ) . '"></button>';
					$return .= '            <span class="mega-widget-cols widget-cols"><span class="mega-widget-num-cols widget-num-cols">' . $item['columns'] . '</span><span class="mega-widget-of widget-of">/</span><span class="mega-widget-total-cols widget-total-cols">' . $menu_item_meta['panel_columns'] . '</span></span>';
					$return .= '<button type="button" class="mega-widget-option mega-widget-expand widget-option widget-expand" aria-label="' . esc_attr__( 'Expand', 'megamenu' ) . '"></button>';
					$return .= '            </div>';
					$return .= '            <a class="mega-widget-option mega-widget-action widget-option widget-action" title="' . esc_attr( __( 'Edit', 'megamenu' ) ) . '"></a>';
					$return .= '        </div>';
					$return .= '    </div>';
					$return .= '    <div class="mega-widget-inner mega-widget-inside widget-inner widget-inside"></div>';
					$return .= '</div>';
				}
			} else {
				$return .= "<p class='no_widgets'>" . __( 'No widgets found. Add a widget using the widget selector above.', 'megamenu' ) . '</p>';
			}

			$return .= '</div>';

			return $return;
		}


		/**
		 * &lt;select&gt; for settings[panel_columns] (shared option list; `mm_number_of_columns` matches megamenu-pro).
		 *
		 * @param array $menu_item_meta Menu item meta.
		 * @return string HTML.
		 */
		private function get_panel_columns_select_markup( array $menu_item_meta ) {
			$html  = "<select id='mm_number_of_columns' name='settings[panel_columns]' aria-label='" . esc_attr__( 'Number of columns', 'megamenu' ) . "'>";
			$html .= "        <option value='1' " . selected( $menu_item_meta['panel_columns'], 1, false ) . '>1 ' . __( 'column', 'megamenu' ) . '</option>';
			$html .= "        <option value='2' " . selected( $menu_item_meta['panel_columns'], 2, false ) . '>2 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='3' " . selected( $menu_item_meta['panel_columns'], 3, false ) . '>3 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='4' " . selected( $menu_item_meta['panel_columns'], 4, false ) . '>4 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='5' " . selected( $menu_item_meta['panel_columns'], 5, false ) . '>5 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='6' " . selected( $menu_item_meta['panel_columns'], 6, false ) . '>6 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='7' " . selected( $menu_item_meta['panel_columns'], 7, false ) . '>7 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='8' " . selected( $menu_item_meta['panel_columns'], 8, false ) . '>8 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='9' " . selected( $menu_item_meta['panel_columns'], 9, false ) . '>9 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='10' " . selected( $menu_item_meta['panel_columns'], 10, false ) . '>10 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='11' " . selected( $menu_item_meta['panel_columns'], 11, false ) . '>11 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= "        <option value='12' " . selected( $menu_item_meta['panel_columns'], 12, false ) . '>12 ' . __( 'columns', 'megamenu' ) . '</option>';
			$html .= '    </select>';

			return $html;
		}


		/**
		 * Pill toggle markup for menu item Settings tab checkboxes (same structure as location enable toggle).
		 *
		 * @since 3.8.2
		 * @param int    $menu_item_id Menu item post ID.
		 * @param string $setting_key   Key in the submitted settings array.
		 * @param string $current       Saved value, typically 'true' or 'false'.
		 * @return string HTML.
		 */
		private function render_menu_item_settings_pill( $menu_item_id, $setting_key, $current ) {
			$id = 'mmm-item-setting-' . sanitize_key( $setting_key ) . '-' . (int) $menu_item_id;

			$is_on           = ( 'true' === (string) $current );
			$toggle_classes  = 'components-form-toggle';
			$toggle_classes .= $is_on ? ' is-checked' : '';

			$html  = '<label class="mmm-settings-pill-field-label">';
			$html .= '<span class="' . esc_attr( $toggle_classes ) . '">';
			$html .= '<input type="checkbox" id="' . esc_attr( $id ) . '" class="components-form-toggle__input" role="switch" name="' . esc_attr( 'settings[' . $setting_key . ']' ) . '" value="true"';
			$html .= checked( $current, 'true', false );
			$html .= ' />';
			$html .= '<span class="components-form-toggle__track" aria-hidden="true"></span>';
			$html .= '<span class="components-form-toggle__thumb" aria-hidden="true"></span>';
			$html .= '</span></label>';

			return $html;
		}

		/**
		 * Return the HTML to display in the 'General Settings' tab.
		 *
		 * @since 1.7
		 * @param array $tabs            Existing tabs array.
		 * @param int   $menu_item_id    ID of the menu item.
		 * @param int   $menu_id         ID of the menu.
		 * @param int   $menu_item_depth Depth of the menu item.
		 * @param array $menu_item_meta  Saved meta for the menu item.
		 * @return array Updated tabs array.
		 */
		public function add_general_settings_tab( $tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta ) {

			$return  = '<form>';
			$return .= '    <input type="hidden" name="menu_item_id" value="' . esc_attr( $menu_item_id ) . '" />';
			$return .= '    <input type="hidden" name="action" value="megamenu_save_menu_item_settings" />';
			$return .= '    <input type="hidden" name="_wpnonce" value="' . wp_create_nonce( 'megamenu_edit' ) . '" />';
			$return .= '    <input type="hidden" name="tab" value="general_settings" />';
			$return .= '    <h4 class="first">' . __( 'Menu Item Settings', 'megamenu' ) . '</h4>';
			$return .= '    <table class="mmm-settings-table">';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Hide text', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'hide_text', $menu_item_meta['hide_text'] );
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Hide arrow', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'hide_arrow', $menu_item_meta['hide_arrow'] );
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Disable link', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'disable_link', $menu_item_meta['disable_link'] );
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Hide item on mobile', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'hide_on_mobile', $menu_item_meta['hide_on_mobile'] );
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Hide item on desktop', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'hide_on_desktop', $menu_item_meta['hide_on_desktop'] );
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Close sub menu when clicked', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'close_after_click', $menu_item_meta['close_after_click'] );
			$return .= '            <div class="mega-description">';
			$return .= __( 'Intended for use on anchor links (e.g. #about)', 'megamenu' );
			$return .= '            </div>';
			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr class="mega-menu-item-align">';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Menu item align', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value">';

			if ( $menu_item_depth == 0 ) {

				$item_align = $menu_item_meta['item_align'];

				$float_left_display = $item_align == 'float-left' ? 'block' : 'none';
				$left_display       = $item_align == 'left' ? 'block' : 'none';
				$right_display      = $item_align == 'right' ? 'block' : 'none';

				$return .= '            <select id="mega-item-align" name="settings[item_align]">';
				$return .= '                <option value="float-left" ' . selected( $menu_item_meta['item_align'], 'float-left', false ) . '>' . __( 'Left', 'megamenu' ) . '</option>';
				$return .= '                <option value="left" ' . selected( $menu_item_meta['item_align'], 'left', false ) . '>' . __( 'Default', 'megamenu' ) . '</option>';
				$return .= '                <option value="right" ' . selected( $menu_item_meta['item_align'], 'right', false ) . '>' . __( 'Right', 'megamenu' ) . '</option>';
				$return .= '            </select>';
				$return .= '            <div class="mega-description">';
				$return .= "                    <div class='float-left' style='display:{$float_left_display}'></div>";
				$return .= "                    <div class='left' style='display:{$left_display}'>" . __( "Item will be aligned based on the 'Menu Items Align' option set in the Theme Editor", 'megamenu' ) . '</div>';
				$return .= "                    <div class='right' style='display:{$right_display}'>" . __( 'Right aligned items will appear in reverse order on the right hand side of the menu bar', 'megamenu' ) . '</div>';
				$return .= '            </div>';
			} else {
				$return .= '<em>' . __( 'Option only available for top level menu items', 'megamenu' ) . '</em>';
			}

			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr class="mega-menu-icon-position">';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Icon position', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value">';
			$return .= '            <select name="settings[icon_position]">';
			$return .= '                <option value="left" ' . selected( $menu_item_meta['icon_position'], 'left', false ) . '>' . __( 'Left', 'megamenu' ) . '</option>';
			$return .= '                <option value="top" ' . selected( $menu_item_meta['icon_position'], 'top', false ) . '>' . __( 'Top', 'megamenu' ) . '</option>';
			$return .= '                <option value="right" ' . selected( $menu_item_meta['icon_position'], 'right', false ) . '>' . __( 'Right', 'megamenu' ) . '</option>';
			$return .= '            </select>';

			$return .= '            </td>';
			$return .= '        </tr>';

			$return .= apply_filters( 'megamenu_after_menu_item_settings', '', $tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta );

			$return .= '    </table>';

			$return .= '    <h4>' . __( 'Sub Menu Settings', 'megamenu' ) . '</h4>';

			$return .= '    <table class="mmm-settings-table">';
			$return .= '        <tr class="mega-sub-menu-align">';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Sub menu align', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value">';

			if ( $menu_item_depth == 0 ) {
				$return .= '            <select name="settings[align]">';
				$return .= '                <option value="bottom-left" ' . selected( $menu_item_meta['align'], 'bottom-left', false ) . '>' . __( 'Left edge of Parent', 'megamenu' ) . '</option>';
				$return .= '                <option value="bottom-right" ' . selected( $menu_item_meta['align'], 'bottom-right', false ) . '>' . __( 'Right edge of Parent', 'megamenu' ) . '</option>';
				$return .= '            </select>';
				$return .= '            <div class="mega-description">';
				$return .= __( 'Right aligned flyout menus will expand to the left', 'megamenu' );
				$return .= '            </div>';
			} else {
				$return .= '<em>' . __( 'Option only available for top level menu items', 'megamenu' ) . '</em>';
			}

			$return .= '            </td>';
			$return .= '        </tr>';
			$return .= '        <tr>';
			$return .= '            <td class="mega-name">';
			$return .= '<div class="mega-name-title">' . __( 'Hide sub menu on mobile', 'megamenu' ) . '</div>';
			$return .= '            </td>';
			$return .= '            <td class="mega-value mega-value--pill">';
			$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'hide_sub_menu_on_mobile', $menu_item_meta['hide_sub_menu_on_mobile'] );
			$return .= '            </td>';
			$return .= '        </tr>';

			if ( $menu_item_depth > 0 ) {
				$return .= '        <tr>';
				$return .= '            <td class="mega-name">';
				$return .= '<div class="mega-name-title">' . __( 'Collapse sub menu', 'megamenu' ) . '</div>';
				$return .= '            </td>';
				$return .= '            <td class="mega-value mega-value--pill">';
				$return .= $this->render_menu_item_settings_pill( $menu_item_id, 'collapse_children', $menu_item_meta['collapse_children'] );
				$return .= '                <em>' . __( 'Only applies to menu items displayed within mega sub menus.', 'megamenu' ) . '</em>';
				$return .= '            </td>';
				$return .= '        </tr>';
			}

			$return .= apply_filters( 'megamenu_after_menu_item_submenu_settings', '', $tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta );

			$return .= '    </table>';

			$return .= '<p class="submit"><button type="submit" name="submit" id="submit" class="button button-primary button-compact">' . esc_html__( 'Save Changes', 'default' ) . '</button></p>';
			$return .= '</form>';

			$tabs['general_settings'] = [
				'title'   => __( 'Settings', 'megamenu' ),
				'content' => $return,
			];

			return $tabs;

		}


		/**
		 * Returns the upgrade CTA anchor HTML for icon-tab upsell copy.
		 *
		 * @see WP_HTML_Tag_Processor
		 * @since 3.9.0
		 * @return string Markup for an external link to the Pro upgrade page.
		 */
		private function get_megamenu_icon_upgrade_link_html() {
			$url   = 'https://www.megamenu.com/upgrade/?utm_source=free&utm_medium=icon&utm_campaign=pro';
			$label = esc_html( __( 'Max Mega Menu Pro', 'megamenu' ) );

			$processor = new WP_HTML_Tag_Processor( '<a>' . $label . '</a>' );
			
			if ( $processor->next_tag( 'a' ) ) {
				$processor->set_attribute( 'href', $url );
				$processor->set_attribute( 'target', '_blank' );
				$processor->set_attribute( 'rel', 'noopener noreferrer' );
			}

			return $processor->get_updated_html();
		}


		/**
		 * Return the HTML to display in the 'Icon' tab.
		 *
		 * @since 1.7
		 * @param array $tabs            Existing tabs array.
		 * @param int   $menu_item_id    ID of the menu item.
		 * @param int   $menu_id         ID of the menu.
		 * @param int   $menu_item_depth Depth of the menu item.
		 * @param array $menu_item_meta  Saved meta for the menu item.
		 * @return array Updated tabs array.
		 */
		public function add_icon_tab( $tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta ) {

			$upgrade_link = $this->get_megamenu_icon_upgrade_link_html();

			$icon_tabs = [
				'fontawesome' => [
					'title'   => __( 'Font Awesome', 'megamenu' ),
					'active'  => false,
					'content' => '<p>' . sprintf(
						/* translators: %s: HTML link to upgrade to Max Mega Menu Pro. */
						__( 'Get access to over 400 Font Awesome Icons with %s', 'megamenu' ),
						$upgrade_link
					) . '</p>',
				],
				'custom'      => [
					'title'   => __( 'Custom Icon', 'megamenu' ),
					'active'  => false,
					'content' => '<p>' . sprintf(
						/* translators: %s: HTML link to upgrade to Max Mega Menu Pro. */
						__( 'Select icons from your media library with %s', 'megamenu' ),
						$upgrade_link
					) . '</p>',
				],
			];

			$icon_tabs = apply_filters( 'megamenu_icon_tabs', $icon_tabs, $menu_item_id, $menu_id, $menu_item_depth, $menu_item_meta );

			$return  = "<div class='menu_icon__header'>";
			$return .= "<h4 class='first'>" . __( 'Menu Item Icon', 'megamenu' ) . '</h4>';
			$return .= "<div class='megamenu_icon_tab_toolbar'>";
			$return .= "<ul class='megamenu_tabs horizontal'>";

			foreach ( $icon_tabs as $id => $icon_tab ) {

				$active = $icon_tab['active'] || count( $icon_tabs ) === 1 ? 'active' : '';

				$return .= "<li rel='megamenu_tab_{$id}' class='megamenu_tab_horizontal {$active}'>";
				$return .= esc_html( $icon_tab['title'] );
				$return .= '</li>';

			}

			$return .= '</ul>';
			$return .= "<input type='text' id='filter_icons' class='filter_icons' placeholder='" . esc_attr__( 'Search', 'megamenu' ) . "' />";
			$return .= '</div>';
			$return .= '</div>';

			foreach ( $icon_tabs as $id => $icon_tab ) {

				$display = $icon_tab['active'] ? 'block' : 'none';

				$before_form = isset( $icon_tab['before_form'] ) ? $icon_tab['before_form'] : '';

				$return .= "<div class='megamenu_tab_{$id}' style='display: {$display}'>";
				$return .= $before_form;
				$form_class = ( 'custom' === $id ) ? 'icon_selector_custom' : 'icon_selector icon_selector_' . $id;
				$return .= "    <form class='" . esc_attr( $form_class ) . "'>";
				$return .= "        <input type='hidden' name='_wpnonce' value='" . wp_create_nonce( 'megamenu_edit' ) . "' />";
				$return .= "        <input type='hidden' name='menu_item_id' value='" . esc_attr( $menu_item_id ) . "' />";
				$return .= "        <input type='hidden' name='action' value='megamenu_save_menu_item_settings' />";
				$return .= $icon_tab['content'];
				$return .= '    </form>';
				$return .= '</div>';

			}

			$icon_payload_merged = [];
			foreach ( $icon_tabs as $id => $icon_tab ) {
				if ( ! empty( $icon_tab['icon_payload'] ) && is_array( $icon_tab['icon_payload'] ) ) {
					foreach ( $icon_tab['icon_payload'] as $payload_key => $payload_val ) {
						$icon_payload_merged[ $payload_key ] = $payload_val;
					}
				}
			}

			// menu_icon may include icon_payload for lazy JS (Dashicons / Material). Pro tabs may be HTML-only with no icon_payload keys.
			$tabs['menu_icon'] = [
				'title'        => __( 'Icon', 'megamenu' ),
				'content'      => $return,
				'icon_payload' => array_merge(
					[
						'current_icon' => isset( $menu_item_meta['icon'] ) ? (string) $menu_item_meta['icon'] : 'disabled',
					],
					$icon_payload_merged
				),
			];

			return $tabs;

		}

		/**
		 * List of all available Dashicon classes.
		 *
		 * @since 1.0
		 * @return array Sorted map of hex code keys to Dashicon CSS class names.
		 */
		public function all_icons() {
			if ( class_exists( 'Mega_Menu_Dashicons' ) ) {
				return Mega_Menu_Dashicons::all_icons();
			}

			return [];
		}
	}

endif;