settings_options = [ [ 'option_group' => MODULES_OPTION, 'option_name' => MODULES_OPTION, 'args' => [ 'sanitize_callback' => [ $this, 'sanitize_settings' ] ], ], ]; $settings_sections = apply_filters( 'adminoptimizer_settings_sections', [] ); if ( ! empty( $settings_sections ) ) { $this->settings_sections = $settings_sections; } $nav_tab = []; $nav_tab = apply_filters( 'adminoptimizer_settings_navtab', $nav_tab ); if ( ! empty( $nav_tab ) ) { $this->nav_tab = $nav_tab; } $this->setup(); } /** * Add submenu to WP Menu page * * @return void */ public function add_submenu_page() { add_submenu_page( ADMINOPTIMIZER_MODULES_MENU_SLUG, __( 'Admin Optimizer Modules', 'admin-optimizer' ), __( 'Modules', 'admin-optimizer' ), 'manage_options', ADMINOPTIMIZER_MODULES_MENU_SLUG, [ $this, 'render_menu_page' ] ); } /** * Render menu page * * @return void */ public function render_menu_page() { ?>

render_settings( MODULES_OPTION ); ?>
, total_active: int, total_all: int} */ private function compute_module_counts(): array { $sections = apply_filters( 'adminoptimizer_settings_sections', [] ); $options = (array) get_option( MODULES_OPTION, [] ); $counts = [ 'tabs' => [], 'total_active' => 0, 'total_all' => 0, ]; // Build a reverse map: menu_slug → nav_tab key, so sections that share a slug // (e.g. the three Disable Features sub-groups) are accumulated under the same tab. $slug_to_tab = []; foreach ( $this->nav_tab as $nav_key => $nav_args ) { if ( ! empty( $nav_args['slug'] ) ) { $slug_to_tab[ $nav_args['slug'] ] = $nav_key; } } foreach ( $sections as $key => $section ) { if ( empty( $section['fields'] ) || ! is_array( $section['fields'] ) ) { continue; } // Exclude the export/import section from module counts. if ( isset( $section['menu_slug'] ) && str_contains( $section['menu_slug'], 'export-import' ) ) { continue; } // Resolve which tab this section belongs to. $tab_key = isset( $section['menu_slug'], $slug_to_tab[ $section['menu_slug'] ] ) ? $slug_to_tab[ $section['menu_slug'] ] : $key; $total = 0; $active = 0; foreach ( $section['fields'] as $field ) { if ( empty( $field['name'] ) || ( isset( $field['type'] ) && 'html_message' === $field['type'] ) ) { continue; } ++$total; if ( ! empty( $options[ $field['name'] ] ) ) { ++$active; } } if ( $total > 0 ) { if ( isset( $counts['tabs'][ $tab_key ] ) ) { $counts['tabs'][ $tab_key ]['active'] += $active; $counts['tabs'][ $tab_key ]['total'] += $total; } else { $counts['tabs'][ $tab_key ] = [ 'active' => $active, 'total' => $total ]; } } $counts['total_active'] += $active; $counts['total_all'] += $total; } return $counts; } /** * Render Settings page * * @param string $section Settings section. * * @return void */ public function render_settings( $section ) { $counts = $this->compute_module_counts(); $is_first_run = empty( (array) get_option( MODULES_OPTION, [] ) ); ?>

nav_tab as $key => $args ) : if ( $tab === $key ) { $content_visibility = 'section-visible'; } else { $content_visibility = 'section-hidden'; } ?>
__( 'You do not have permission to update modules.', 'admin-optimizer' ) ], 403 ); } $posted_modules = isset( $_POST['modules'] ) ? wp_unslash( $_POST['modules'] ) : []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if ( ! is_array( $posted_modules ) ) { $posted_modules = []; } $allowed_keys = $this->get_allowed_module_keys(); $options = []; foreach ( $posted_modules as $key => $value ) { $key = sanitize_key( (string) $key ); if ( ! in_array( $key, $allowed_keys, true ) ) { continue; } if ( absint( $value ) > 0 ) { $options[ $key ] = 1; } } update_option( MODULES_OPTION, $this->sanitize_settings( $options ) ); wp_send_json_success( [ 'message' => __( 'Module settings saved.', 'admin-optimizer' ), 'counts' => $this->compute_module_counts(), ] ); } /** * Enqueue scripts * * @param string $hook_suffix Enqueue script only on specific page. * * @return void */ public function enqueue_scripts( $hook_suffix ) { wp_register_style( 'adminoptim-modules-pro-settings', ADMINOPTIMIZER_ADMIN_URI . 'assets/css/modules-pro-settings.min.css', [], ADMINOPTIMIZER_VERSION ); wp_register_style( 'adminoptim-module-settings', ADMINOPTIMIZER_ADMIN_URI . 'assets/css/module-settings.min.css', [], ADMINOPTIMIZER_VERSION ); if ( 'toplevel_page_' . ADMINOPTIMIZER_MODULES_MENU_SLUG === $hook_suffix ) { wp_enqueue_script( 'adminoptim-admin-settings', ADMINOPTIMIZER_ADMIN_URI . 'assets/js/settings.min.js', [], ADMINOPTIMIZER_VERSION, true ); wp_localize_script( 'adminoptim-admin-settings', 'adminoptimModules', [ 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'adminoptim_save_modules' ), 'optionName' => MODULES_OPTION, 'savingText' => __( 'Saving...', 'admin-optimizer' ), 'savedText' => __( 'Saved', 'admin-optimizer' ), 'errorText' => __( 'Unable to save. Please try again.', 'admin-optimizer' ), /* translators: 1: number of active modules, 2: total number of modules */ 'summaryText' => __( '%1$d of %2$d modules active', 'admin-optimizer' ), ] ); wp_enqueue_style( 'adminoptim-admin-settings', ADMINOPTIMIZER_ADMIN_URI . 'assets/css/settings.min.css', [], ADMINOPTIMIZER_VERSION ); do_action( 'ao_enqueue_toplevel_scripts' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- ao_ is this plugin's established short-form hook prefix. } } /** * Disable Action Scheduler schedule if a module is deactivated * * @param mixed $old_value The old option value. * @param mixed $value The new option value. * @param string $option_name Option name. * * @return void */ public function cleanup_as_schedule( $old_value, $value, $option_name ) { if ( MODULES_OPTION === $option_name && is_array( $value ) ) { // Check if Publish Missed Posts module has been deactivated. if ( empty( $value['enable_publish_missed_posts'] ) ) { if ( as_has_scheduled_action( 'adminoptim_publish_missed_post' ) ) { as_unschedule_action( 'adminoptim_publish_missed_post' ); } } // Check if database cleaner module has been deactivated. if ( empty( $value['enable_db_cleaner'] ) ) { if ( as_has_scheduled_action( 'adminoptim_database_cleanup' ) ) { as_unschedule_action( 'adminoptim_database_cleanup' ); } } // Check if redirect manager module has been deactivated. if ( empty( $value['enable_redirect_manager'] ) ) { if ( as_has_scheduled_action( 'adminoptim_redirect_manager_daily_cleanup' ) ) { as_unschedule_action( 'adminoptim_redirect_manager_daily_cleanup' ); } } } } }