editor ) && $elementor->editor->is_edit_mode() ) || ( isset( $elementor->preview ) && $elementor->preview->is_preview_mode() ) ) { return true; } } if ( class_exists( 'FLBuilderModel' ) && FLBuilderModel::is_builder_active() ) { return true; } if ( function_exists( 'vc_is_inline' ) && vc_is_inline() ) { return true; } if ( function_exists( 'bricks_is_builder' ) && bricks_is_builder() ) { return true; } if ( function_exists( 'bricks_is_builder_iframe' ) && bricks_is_builder_iframe() ) { return true; } if ( function_exists( '\\Breakdance\\Editor\\isEditor' ) && \Breakdance\Editor\isEditor() ) { return true; } if ( function_exists( 'themify_builder_is_frontend_editor' ) && themify_builder_is_frontend_editor() ) { return true; } if ( defined( 'SHOW_CT_BUILDER' ) && SHOW_CT_BUILDER ) { return true; } $preview_keys = array( 'elementor-preview', 'elementor_library', 'ct_builder', 'ct_inner', 'oxygen_iframe', 'brizy-edit-iframe', 'brizy-edit', 'fl_builder', 'fl_builder_ui', 'bricks', 'brickspreview', 'breakdance', 'breakdance_iframe', 'vc_editable', 'vcv-action', 'tve', 'tve_editor', 'tb-preview', 'themify_builder_infinite_scroll', ); foreach ( $preview_keys as $key ) { // Read-only detection of page-builder editor modes; no data is changed. if ( isset( $_REQUEST[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return true; } } return (bool) apply_filters( 'amber_mega_menu_is_builder_preview', false ); } public static function init() { add_shortcode( 'amber_mega_menu', array( __CLASS__, 'shortcode' ) ); // Backward-compatible aliases for embeds created by earlier versions. add_shortcode( 'category_mega_menu', array( __CLASS__, 'shortcode' ) ); add_shortcode( 'smm_mega_menu', array( __CLASS__, 'shortcode' ) ); add_action( 'wp_enqueue_scripts', array( __CLASS__, 'register_assets' ) ); } public static function register_assets() { wp_register_style( 'smm-frontend', AMBER_MEGA_MENU_URL . 'assets/frontend.css', array(), AMBER_MEGA_MENU_VERSION ); wp_register_script( 'smm-frontend', AMBER_MEGA_MENU_URL . 'assets/frontend.js', array(), AMBER_MEGA_MENU_VERSION, true ); // Visual builders can inject shortcode HTML after wp_head has already run. // Load the lightweight stylesheet up front so their live canvas never shows // an unstyled menu while a shortcode preview is being refreshed. wp_enqueue_style( 'smm-frontend' ); } /** English defaults, optionally replaced per menu by the premium text module. */ protected static function frontend_text( $settings ) { $text = array( 'panel_title' => __( 'Categories', 'amber-mega-menu' ), 'search_label' => __( 'Search categories', 'amber-mega-menu' ), 'search_placeholder'=> __( 'Search categories…', 'amber-mega-menu' ), 'close_label' => __( 'Close categories', 'amber-mega-menu' ), 'cart_label' => __( 'View shopping cart', 'amber-mega-menu' ), 'empty_message' => __( 'There are currently no visible items in this menu.', 'amber-mega-menu' ), 'no_results' => __( 'No categories found.', 'amber-mega-menu' ), 'show_all' => __( 'Show all', 'amber-mega-menu' ), 'show_less' => __( 'Show less', 'amber-mega-menu' ), ); /** Premium distributions may replace any built-in message per menu. */ return apply_filters( 'amber_mega_menu_frontend_text', $text, $settings ); } public static function shortcode( $atts ) { $atts = shortcode_atts( array( 'id' => 0, 'layout' => '', 'display' => '', // adaptive | modal — overrides the saved desktop opening mode 'trigger' => '', 'columns' => '', 'depth' => '', 'open' => '', // "1" renders the panel always open (no trigger button) 'nav' => '', // "1" = panel only, opened by a WordPress nav menu item 'disable_link' => '', 'nav_for' => '', // key of the WordPress menu item link that opens this panel 'nav_item_id' => 0, ), $atts, 'amber_mega_menu' ); $post_id = (int) $atts['id']; if ( ! $post_id ) { $found = get_posts( array( 'post_type' => AMBER_MEGA_MENU_CPT, 'posts_per_page' => 1, 'fields' => 'ids', 'orderby' => 'ID', 'order' => 'ASC', ) ); $post_id = $found ? (int) $found[0] : 0; } if ( ! $post_id || AMBER_MEGA_MENU_CPT !== get_post_type( $post_id ) ) { return ''; } $s = Amber_Mega_Menu_Source::get_settings( $post_id ); if ( $atts['layout'] ) { $s['layout'] = ( 'sideways' === $atts['layout'] ) ? 'sideways' : 'columns'; } if ( $atts['display'] ) { $s['desktop_display'] = ( 'modal' === $atts['display'] ) ? 'modal' : 'adaptive'; } if ( '' !== $atts['trigger'] ) { $s['trigger'] = $atts['trigger']; } if ( $atts['columns'] ) { $s['columns'] = max( 2, min( 6, (int) $atts['columns'] ) ); } if ( '' !== (string) $atts['depth'] ) { // 0 = unlimited; anything higher is honoured up to a generous cap. $s['depth'] = max( 0, min( 20, (int) $atts['depth'] ) ); } $always_open = ( '1' === (string) $atts['open'] ); $nav_mode = ( '1' === (string) $atts['nav'] ); $nav_no_link = ( '1' === (string) $atts['disable_link'] ); $nav_for = sanitize_html_class( (string) $atts['nav_for'] ); $nav_item_id = absint( $atts['nav_item_id'] ); if ( $nav_mode ) { $always_open = false; } /** Final settings for this placement; premium modules may extend them. */ $s = apply_filters( 'smm_menu_settings', $s, $post_id, $atts ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- legacy 'smm_' prefix kept for compatibility between the free and premium distributions. $builder_preview = self::is_builder_preview(); if ( $builder_preview ) { // Render the real configured panel in place. The builder preview must show // the selected source, layout, depth, tabs and visual settings—not a proxy. $always_open = true; $nav_mode = false; $s['show_cart'] = 0; } $tree = self::visible( Amber_Mega_Menu_Source::merged_tree( $post_id, $s ), $s ); $empty_tree = empty( $tree ); wp_enqueue_style( 'smm-frontend' ); wp_enqueue_script( 'smm-frontend' ); /** Premium distributions enqueue their own assets for this placement. */ do_action( 'amber_mega_menu_enqueue_assets', $s, $post_id ); $uid = 'smm-' . $post_id . '-' . wp_rand( 1000, 9999 ); $text = self::frontend_text( $s ); ob_start(); ?>