plugin_name = $plugin_name; $this->version = $version; } public function enqueue_styles() { wp_enqueue_style($this->plugin_name . '-admin', NEXUS_MENU_PLUGIN_URL . 'assets/css/admin.css', array(), $this->version, 'all'); // FontAwesome (Use Elementor's bundled version to avoid offloading error) $fa_url = defined('ELEMENTOR_ASSETS_URL') ? ELEMENTOR_ASSETS_URL . 'lib/font-awesome/css/all.min.css' : WP_PLUGIN_URL . '/elementor/assets/lib/font-awesome/css/all.min.css'; wp_enqueue_style('nexus-font-awesome', $fa_url, array(), '5.15.3'); wp_enqueue_style('dashicons'); } public function enqueue_scripts() { $screen = get_current_screen(); if (!$screen || 'nav-menus' !== $screen->base) { return; } wp_enqueue_media(); // For Image Upload wp_enqueue_script($this->plugin_name . '-admin', NEXUS_MENU_PLUGIN_URL . 'assets/js/admin.js', array('jquery'), $this->version, false); wp_enqueue_script($this->plugin_name . '-icons', NEXUS_MENU_PLUGIN_URL . 'assets/js/nexus-icon-library.js', array(), $this->version, false); // Localize script with menus for the dropdown $menus = wp_get_nav_menus(); $menu_options = array(); $menu_nonces = array(); $generic_duplicate_nonce = wp_create_nonce('nexus_duplicate_menu'); foreach ($menus as $menu) { $menu_options[] = array('id' => $menu->term_id, 'name' => $menu->name); $menu_nonces[$menu->term_id] = $generic_duplicate_nonce; } wp_localize_script($this->plugin_name . '-admin', 'nexus_menu_params', array( 'menus' => $menu_options, 'nonces' => $menu_nonces, 'create_menu_nonce' => wp_create_nonce('nexus_create_menu_nonce') )); } private function copy_menu_items($source_id, $target_id) { $menu_items = wp_get_nav_menu_items($source_id); if (!$menu_items) return; $rel_map = array(); foreach ($menu_items as $menu_item) { $args = array( // ... (standard args) 'menu-item-title' => $menu_item->title, 'menu-item-position' => $menu_item->menu_order, 'menu-item-description' => $menu_item->description, 'menu-item-attr-title' => $menu_item->attr_title, 'menu-item-target' => $menu_item->target, 'menu-item-classes' => implode(' ', $menu_item->classes), 'menu-item-xfn' => $menu_item->xfn, 'menu-item-status' => $menu_item->post_status, 'menu-item-type' => $menu_item->type, 'menu-item-object' => $menu_item->object, 'menu-item-object-id' => $menu_item->object_id, 'menu-item-parent-id' => isset($rel_map[$menu_item->menu_item_parent]) ? $rel_map[$menu_item->menu_item_parent] : 0, ); if ($menu_item->type === 'custom') { $args['menu-item-url'] = $menu_item->url; } $new_item_id = wp_update_nav_menu_item($target_id, 0, $args); if ($new_item_id && !is_wp_error($new_item_id)) { $rel_map[$menu_item->ID] = $new_item_id; $fields = array('nexus_icon_class', 'nexus_icon_type', 'nexus_icon_image_id', 'nexus_is_mega_menu', 'nexus_mega_menu_template_id', 'nexus_mega_menu_width_type', 'nexus_mega_menu_custom_width', 'nexus_mega_menu_container_width'); foreach ($fields as $field) { $val = get_post_meta($menu_item->ID, '_menu_item_' . $field, true); if ($val) { update_post_meta($new_item_id, '_menu_item_' . $field, $val); } } } } } public function handle_menu_creation_duplication($term_id, $menu_data) { if (!current_user_can('edit_theme_options')) { return; } // Verify specific nonce for menu creation duplication if (!isset($_POST['nexus_create_menu_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nexus_create_menu_nonce'])), 'nexus_create_menu_nonce')) { return; } if (!isset($_POST['nexus_source_menu_id']) || empty($_POST['nexus_source_menu_id'])) { return; } $source_id = absint($_POST['nexus_source_menu_id']); $this->copy_menu_items($source_id, $term_id); } public function setup_nav_menu_item($menu_item) { $fields = array('nexus_icon_class', 'nexus_icon_type', 'nexus_icon_image_id', 'nexus_is_mega_menu', 'nexus_mega_menu_template_id', 'nexus_mega_menu_width_type', 'nexus_mega_menu_custom_width', 'nexus_mega_menu_container_width'); foreach ($fields as $field) { $menu_item->$field = get_post_meta($menu_item->ID, '_menu_item_' . $field, true); } return $menu_item; } public function update_nav_menu_item($menu_id, $menu_item_db_id, $args) { // Verify Nonce if (!isset($_POST['nexus_menu_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nexus_menu_meta_nonce'])), 'nexus_menu_meta_nonce')) { return; } $fields = array('nexus_icon_class', 'nexus_icon_type', 'nexus_icon_image_id', 'nexus_is_mega_menu', 'nexus_mega_menu_template_id', 'nexus_mega_menu_width_type', 'nexus_mega_menu_custom_width', 'nexus_mega_menu_container_width'); foreach ($fields as $field) { if (isset($_POST['menu-item-' . $field][$menu_item_db_id])) { $value = sanitize_text_field(wp_unslash($_POST['menu-item-' . $field][$menu_item_db_id])); update_post_meta($menu_item_db_id, '_menu_item_' . $field, $value); } else { if ($field === 'nexus_is_mega_menu') { delete_post_meta($menu_item_db_id, '_menu_item_' . $field); } } } } public function add_custom_fields($item_id, $item, $depth, $args, $id = 0) { $nexus_icon_class = get_post_meta($item_id, '_menu_item_nexus_icon_class', true); $nexus_is_mega_menu = get_post_meta($item_id, '_menu_item_nexus_is_mega_menu', true); $nexus_mega_menu_template_id = get_post_meta($item_id, '_menu_item_nexus_mega_menu_template_id', true); $nexus_icon_type = get_post_meta($item_id, '_menu_item_nexus_icon_type', true); $nexus_icon_image_id = get_post_meta($item_id, '_menu_item_nexus_icon_image_id', true); $nexus_mega_menu_width_type = get_post_meta($item_id, '_menu_item_nexus_mega_menu_width_type', true); $nexus_mega_menu_custom_width = get_post_meta($item_id, '_menu_item_nexus_mega_menu_custom_width', true); $nexus_mega_menu_container_width = get_post_meta($item_id, '_menu_item_nexus_mega_menu_container_width', true); // Defaults if (empty($nexus_icon_type)) $nexus_icon_type = 'icon_class'; if (empty($nexus_mega_menu_width_type)) $nexus_mega_menu_width_type = 'full'; // Default to full width $templates = $this->get_elementor_templates(); ?>
'elementor_library', 'posts_per_page' => -1, 'post_status' => 'publish', )); } public function duplicate_menu() { if (!current_user_can('edit_theme_options')) { wp_die('No menu to duplicate or insufficient permissions.'); } // Verify nonce FIRST before touching $_GET or $_POST to satisfy security scanners check_admin_referer('nexus_duplicate_menu'); // Determine if menu ID is provided $menu_id = 0; if (isset($_GET['menu'])) { $menu_id = absint($_GET['menu']); } elseif (isset($_POST['menu'])) { $menu_id = absint($_POST['menu']); } if (!$menu_id) { wp_die('Invalid menu.'); } $menu_object = wp_get_nav_menu_object($menu_id); if (!$menu_object) { wp_die('Invalid menu.'); } $new_menu_name = $menu_object->name . ' (Copy)'; $new_menu_id = wp_create_nav_menu($new_menu_name); if (is_wp_error($new_menu_id)) { wp_die(esc_html($new_menu_id->get_error_message())); } // Reuse the centralized logic $this->copy_menu_items($menu_id, $new_menu_id); $redirect_url = add_query_arg(array('menu' => $new_menu_id), admin_url('nav-menus.php')); wp_safe_redirect($redirect_url); exit; } // JS Injection for the Duplicate button public function add_duplicate_link_to_admin() { // Handled via admin.js } public function add_plugin_admin_menu() { add_menu_page( 'Nexus Nav Settings', 'Nexus Nav', 'manage_options', 'nexus-menu-settings', array($this, 'display_plugin_setup_page'), 'dashicons-menu', 30 ); } public function display_plugin_setup_page() { ?>
"Nexus Nav Menu" to your Elementor editor.', 'advanced-menu-builder-for-elementor')); ?>