fields = new Aha_Orbit_Testimonials_Settings_Fields( self::OPTION_GENERAL, array($this, 'get_settings') ); add_action('admin_menu', array($this, 'register_admin_menus')); add_action('admin_init', array($this, 'register_settings')); add_action('admin_init', array($this, 'maybe_save_uninstall_preference')); // The Uninstall tab is always last. Add-ons can insert their own tabs // (e.g. a Extra tab) at priority < 100 via this same filter. add_filter('aha_orbit_testimonials_settings_tabs', array($this, 'append_uninstall_tab'), 100); } /* ───────────────────────────────────────────────────────────────────────── Menu registration ───────────────────────────────────────────────────────────────────────── */ /** * Register the full admin menu structure: parent, Settings submenu, and Testimonials submenu. * All three are registered sequentially in the same hook to guarantee order and avoid * edge cases with the auto-generated duplicate first submenu. */ public function register_admin_menus() { // 1. Parent menu. add_menu_page( __('Aha Orbit Testimonials', 'aha-orbit-testimonials'), __('Aha Orbit', 'aha-orbit-testimonials'), 'manage_options', AHA_ORBIT_TESTIMONIALS_ADMIN_SLUG, array($this, 'render_page'), 'dashicons-format-quote', 57 ); // 2. Override the auto-generated first submenu (which duplicates the parent label) with "Settings". add_submenu_page( AHA_ORBIT_TESTIMONIALS_ADMIN_SLUG, __('Aha Orbit Testimonials – Settings', 'aha-orbit-testimonials'), __('Settings', 'aha-orbit-testimonials'), 'manage_options', AHA_ORBIT_TESTIMONIALS_ADMIN_SLUG, array($this, 'render_page') ); // 3. Link to the CPT post list. add_submenu_page( AHA_ORBIT_TESTIMONIALS_ADMIN_SLUG, __('Testimonials', 'aha-orbit-testimonials'), __('Testimonials', 'aha-orbit-testimonials'), 'edit_posts', 'edit.php?post_type=' . AHA_ORBIT_TESTIMONIALS_CPT ); } /* ───────────────────────────────────────────────────────────────────────── Settings API ───────────────────────────────────────────────────────────────────────── */ /** * Register options and fields for the General tab. */ public function register_settings() { // ── General ────────────────────────────────────────────────────────── register_setting( 'aha_orbit_testimonials_general_group', self::OPTION_GENERAL, array( 'sanitize_callback' => array($this, 'sanitize_general'), ) ); add_settings_section( 'aha_orbit_testimonials_status', __('Plugin Status', 'aha-orbit-testimonials'), array($this->fields, 'render_section_status'), 'aha-orbit-testimonials-general' ); add_settings_field( 'aha_orbit_testimonials_enabled', __('Enable all orbits', 'aha-orbit-testimonials'), array($this->fields, 'render_field_enabled'), 'aha-orbit-testimonials-general', 'aha_orbit_testimonials_status' ); } /** * Sanitize general settings input. * * @param mixed $input Raw input. * @return array */ public function sanitize_general($input) { if (!is_array($input)) { return $this->get_defaults(); } return array( 'enabled' => !empty($input['enabled']) ? 1 : 0, ); } /** * Default general settings. * * @return array */ public function get_defaults() { return array( 'enabled' => 1, ); } /** * Retrieve current general settings (merged with defaults). * * @return array */ public function get_settings() { return wp_parse_args(get_option(self::OPTION_GENERAL, array()), $this->get_defaults()); } /* ───────────────────────────────────────────────────────────────────────── Tabs filter ───────────────────────────────────────────────────────────────────────── */ /** * Append the Uninstall tab (always last, priority 100). * * Add-ons should use the same filter at a lower priority (e.g. 50) to * inject their own tabs before this one. * * Example: * add_filter( 'aha_orbit_testimonials_settings_tabs', function( $tabs ) { * $tabs['my_tab'] = __( 'My Tab', 'my-addon' ); * return $tabs; * }, 50 ); * * @param array $tabs Tab slug => label. * @return array */ public function append_uninstall_tab($tabs) { if (!is_array($tabs)) { $tabs = array(); } $tabs['uninstall'] = __('Uninstall', 'aha-orbit-testimonials'); return $tabs; } /* ───────────────────────────────────────────────────────────────────────── Uninstall preference ───────────────────────────────────────────────────────────────────────── */ /** * Save the "remove data on uninstall" preference from the Uninstall tab form. */ public function maybe_save_uninstall_preference() { if (!isset($_POST['aha_orbit_uninstall_prefs'])) { return; } if (!current_user_can('manage_options')) { wp_die(esc_html__('Permission denied.', 'aha-orbit-testimonials')); } check_admin_referer('aha_orbit_uninstall_prefs', 'aha_orbit_uninstall_prefs_nonce'); $erase = isset($_POST['aha_orbit_remove_data_on_uninstall']) ? '1' : '0'; update_option(AHA_ORBIT_TESTIMONIALS_UNINSTALL_DELETE_DATA_OPTION, $erase, false); wp_safe_redirect( add_query_arg( array( 'page' => AHA_ORBIT_TESTIMONIALS_ADMIN_SLUG, 'tab' => 'uninstall', 'aha_orbit_uninstall_saved' => '1', ), admin_url('admin.php') ) ); exit; } /* ───────────────────────────────────────────────────────────────────────── Page rendering ───────────────────────────────────────────────────────────────────────── */ /** * Render the full settings / dashboard page. */ public function render_page() { if (!current_user_can('manage_options')) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended if (isset($_GET['aha_orbit_uninstall_saved']) && '1' === $_GET['aha_orbit_uninstall_saved']) { echo '

' . esc_html__('Uninstall preferences saved successfully.', 'aha-orbit-testimonials') . '

'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $active_tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'general'; $tabs = array( 'general' => __('General', 'aha-orbit-testimonials'), 'shortcode' => __('Shortcode', 'aha-orbit-testimonials'), ); /** * Filter the dashboard tabs. * * @param array $tabs Tab slug => label. */ $tabs = apply_filters('aha_orbit_testimonials_settings_tabs', $tabs); if (!array_key_exists($active_tab, $tabs)) { $active_tab = 'general'; } ?>
render_uninstall_tab(); ?>
render_shortcode_tab(); ?>
render_coming_soon_section(); ?>
AHA_ORBIT_TESTIMONIALS_CPT), admin_url('edit.php'))); ?>

123) or in the Orbit Testimonials list.', 'aha-orbit-testimonials'), $orbits_url ), array( 'a' => array('href' => array()), 'strong' => array(), ) ); ?>

[aha_orbit id="1"]
[aha_orbit id="5"]
"); ?>

Orbit editor.', 'aha-orbit-testimonials'), $orbits_url ), array('a' => array('href' => array())) ); ?>