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, [] ) );
?>
__( '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' );
}
}
}
}
}