*/
class AIO_Tools_Admin {
/**
* The ID of this plugin.
*
* @since 1.0.0
* @access private
* @var string $plugin_name The ID of this plugin.
*/
private $plugin_name;
/**
* The version of this plugin.
*
* @since 1.0.0
* @access private
* @var string $version The current version of this plugin.
*/
private $version;
/**
* Initialize the class and set its properties.
*
* @param string $plugin_name The name of this plugin.
* @param string $version The version of this plugin.
*
* @since 1.0.0
*/
public function __construct( $plugin_name, $version ) {
$this->plugin_name = $plugin_name;
$this->version = $version;
$this->load_dependencies_frameworks();
add_filter( 'plugin_action_links_' . AIO_BASE_NAME, [ $this, 'aio_add_plugin_page_settings_link' ], 10, 2 );
add_action( 'admin_bar_menu', [ $this, 'aio_add_admin_bar_links' ], 90 );
add_action( 'admin_head', [ __CLASS__, 'output_admin_menu_icon_css' ] );
add_action( 'admin_footer', [ __CLASS__, 'output_admin_bar_ajax_script' ], 99 );
$this->create_settings_page();
add_action( 'wp_dashboard_setup', [ $this, 'aio_add_dashboard_widgets' ] );
add_action( 'wp_ajax_aio_get_settings', [ $this, 'aio_get_settings_ajax' ] );
add_action( 'wp_ajax_aio_update_settings', [ $this, 'aio_update_settings_ajax' ] );
add_action( 'wp_ajax_aio_get_system_status', [ $this, 'aio_get_system_status_ajax' ] );
add_action( 'wp_ajax_aio_test_telegram_connection', [ $this, 'aio_test_telegram_connection_ajax' ] );
add_action( 'wp_ajax_aio_test_larksuite_connection', [ $this, 'aio_test_larksuite_connection_ajax' ] );
add_action( 'wp_ajax_aio_purge_all_caches', [ $this, 'aio_purge_all_caches_ajax' ] );
add_action( 'wp_ajax_aio_admin_bar_action', [ $this, 'aio_admin_bar_action_ajax' ] );
add_action( 'admin_post_aio_purge_all_caches', [ $this, 'aio_purge_all_caches_admin_post' ] );
add_action( 'admin_notices', [ $this, 'aio_render_cache_purged_notice' ] );
// Load sub-modules
require_once AIO_ADMIN_PATH . 'modules/class-aio-security-admin.php';
require_once AIO_ADMIN_PATH . 'modules/class-aio-utility-admin.php';
require_once AIO_ADMIN_PATH . 'modules/class-aio-smtp-admin.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-dropin-manager.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-htaccess-cache.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-object-cache.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-asset-optimizer.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-font-optimizer.php';
require_once AIO_MODULES_PATH . 'performance/class-aio-speed-analyzer.php';
if ( ! class_exists( 'AIO_Caching' ) ) {
require_once AIO_MODULES_PATH . 'optimizer/class-aio-caching.php';
}
new AIO_Security_Admin();
new AIO_Utility_Admin();
new AIO_Smtp_Admin();
new AIO_Object_Cache_Manager();
new AIO_Speed_Analyzer();
}
/**
* Register the stylesheets for the admin area.
*
* @since 1.0.0
*/
public function enqueue_styles( $hook_suffix = '' ) {
if ( strpos( (string) $hook_suffix, 'aio-settings' ) === false && strpos( (string) $hook_suffix, 'aio-audit-logs' ) === false ) {
return;
}
// Enqueue locally bundled Phosphor Icons (zero external CDN requests)
wp_enqueue_style( 'phosphor-icons', AIO_URL . 'assets/vendor/phosphor/regular/style.css', array(), '2.1.1', 'all' );
wp_enqueue_style( 'phosphor-icons-fill', AIO_URL . 'assets/vendor/phosphor/fill/style.css', array(), '2.1.1', 'all' );
$admin_css_ver = file_exists( AIO_PATH . 'assets/css/aio-tools-admin.css' ) ? $this->version . '.' . (string) filemtime( AIO_PATH . 'assets/css/aio-tools-admin.css' ) : $this->version;
$resp_css_ver = file_exists( AIO_PATH . 'assets/css/responsive.css' ) ? $this->version . '.' . (string) filemtime( AIO_PATH . 'assets/css/responsive.css' ) : $this->version;
wp_enqueue_style( $this->plugin_name, AIO_URL . 'assets/css/aio-tools-admin.css', array(), $admin_css_ver, 'all' );
wp_enqueue_style( 'aio-tools-responsive', AIO_URL . 'assets/css/responsive.css', array(), $resp_css_ver, 'all' );
}
/**
* Register the JavaScript for the admin area.
*
* @since 1.0.0
*/
public function enqueue_scripts( $hook_suffix = '' ) {
if ( strpos( (string) $hook_suffix, 'aio-settings' ) === false && strpos( (string) $hook_suffix, 'aio-audit-logs' ) === false ) {
return;
}
if ( strpos( (string) $hook_suffix, 'aio-settings' ) !== false ) {
wp_enqueue_media();
wp_enqueue_script( 'jquery-ui-sortable' );
wp_enqueue_script( 'aio-qrcode', AIO_URL . 'assets/js/aio-qrcode.js', array(), $this->version, true );
}
wp_register_script( $this->plugin_name, false, array( 'jquery' ), $this->version, false );
wp_enqueue_script( $this->plugin_name );
wp_localize_script(
$this->plugin_name,
'aio_smtp_param',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'aio-smtp-check-nonce' ),
'settings_nonce' => wp_create_nonce( 'aio-settings-nonce' ),
'message' => array(
'sending' => __( 'Sending...', 'aio-tools' ),
'success' => __( 'Success! Please check your email inbox.', 'aio-tools' ),
'error' => __( 'The following error occurred: ', 'aio-tools' ),
'alertdata' => __( 'You have entered an invalid email address!', 'aio-tools' ),
),
)
);
}
public function load_dependencies_frameworks() {
// Legacy unused framework dependencies removed for faster boot.
}
public function create_settings_page() {
add_action( 'admin_menu', [ $this, 'aio_add_admin_menu' ] );
}
public function aio_add_admin_menu() {
$plugin_name = __('AIO Tools', 'aio-tools');
$menu_title = 'AIO Tools';
add_menu_page(
$plugin_name,
$menu_title,
'manage_options',
'aio-settings',
[ $this, 'aio_display_settings_page' ],
AIO_URL . 'assets/images/favicon.png',
4
);
add_submenu_page(
'aio-settings',
__('Audit Logs', 'aio-tools'),
__('Audit Logs', 'aio-tools'),
'manage_options',
'aio-audit-logs',
[ $this, 'aio_display_audit_logs_page' ]
);
}
public function aio_display_audit_logs_page() {
require_once AIO_ADMIN_PATH . 'partials/aio-audit-logs-display.php';
}
public function aio_display_settings_page() {
require_once AIO_ADMIN_PATH . 'partials/aio-tools-admin-display.php';
}
public function aio_add_admin_bar_links( WP_Admin_Bar $admin_bar ) {
self::render_smart_admin_bar( $admin_bar );
}
public static function get_admin_icon_alignment_css() {
$icon_url = esc_url( AIO_URL . 'assets/images/favicon.png' );
return '#adminmenu #toplevel_page_aio-settings div.wp-menu-image{display:flex !important;align-items:center !important;justify-content:center !important;height:34px !important;float:left !important;width:36px !important;margin:0 !important;padding:0 !important;}'
. '#adminmenu #toplevel_page_aio-settings div.wp-menu-image img{padding:0 !important;margin:0 !important;width:18px !important;height:18px !important;display:block !important;transform:translateY(-1px) !important;opacity:.88 !important;transition:opacity .15s ease !important;}'
. '#adminmenu #toplevel_page_aio-settings:hover div.wp-menu-image img,#adminmenu #toplevel_page_aio-settings.current div.wp-menu-image img,#adminmenu #toplevel_page_aio-settings.wp-has-current-submenu div.wp-menu-image img{opacity:1 !important;}'
. '#wpadminbar #wp-admin-bar-aio-tools > .ab-item{background:url("' . $icon_url . '") no-repeat 7px 47%/18px 18px !important;padding-left:30px !important;}'
. '#wpadminbar #wp-admin-bar-aio-tools > .ab-item:hover{color:#fde047 !important;}'
. '#wpadminbar #wp-admin-bar-aio-tools-maint-badge > .ab-item{background:#d97706 !important;color:#fff !important;font-weight:600;border-radius:4px;margin:0 4px;}'
. '#wpadminbar #wp-admin-bar-aio-tools .aio-ab-ico,#wpadminbar #wp-admin-bar-aio-tools-maint-badge .aio-ab-ico{display:inline-block !important;width:14px !important;height:14px !important;vertical-align:-2px !important;margin-right:6px !important;fill:none;}'
. '#wpadminbar #wp-admin-bar-aio-tools-purge-cache .aio-ab-ico{fill:currentColor !important;}'
. '#wpadminbar #wp-admin-bar-aio-tools img.emoji{display:none !important;}';
}
public static function output_admin_menu_icon_css() {
echo '' . "\n";
}
public static function render_smart_admin_bar( WP_Admin_Bar $admin_bar ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$maint_active = aio_is_module_active( 'opt-module-utility' ) && ! empty( aio_get_option( 'optEnableMaintenance' ) );
$ico_maint = '';
$ico_dash = '';
$ico_speed = '';
$ico_purge_url = '';
$ico_purge_all = '';
$ico_object = '';
$ico_assets = '';
$admin_bar->add_menu(
[
'id' => 'aio-tools',
'title' => 'AIO Tools',
'href' => admin_url( 'admin.php?page=aio-settings' ),
'meta' => [
'target' => '_self',
'html' => '',
],
]
);
if ( $maint_active ) {
$admin_bar->add_menu(
[
'id' => 'aio-tools-maint-badge',
'title' => $ico_maint . esc_html__( 'Maintenance: ON', 'aio-tools' ),
'href' => admin_url( 'admin.php?page=aio-settings&tab=utility' ),
'meta' => [
'title' => __( 'Maintenance Mode is active for visitors. Click to manage.', 'aio-tools' ),
],
]
);
}
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-dashboard',
'title' => $ico_dash . esc_html__( 'Dashboard', 'aio-tools' ),
'href' => admin_url( 'admin.php?page=aio-settings' ),
]
);
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-speed',
'title' => $ico_speed . esc_html__( 'Speed & Optimize', 'aio-tools' ),
'href' => admin_url( 'admin.php?page=aio-settings&tab=performance' ),
]
);
if ( ! is_admin() ) {
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-purge-url',
'title' => $ico_purge_url . esc_html__( 'Purge This Page Cache', 'aio-tools' ),
'href' => '#aio-bar-purge-url',
]
);
}
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-purge-cache',
'title' => $ico_purge_all . esc_html__( 'Purge All Caches', 'aio-tools' ),
'href' => wp_nonce_url( admin_url( 'admin-post.php?action=aio_purge_all_caches' ), 'aio_purge_all_caches_bar' ),
]
);
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-flush-object',
'title' => $ico_object . esc_html__( 'Flush Object Cache (RAM)', 'aio-tools' ),
'href' => '#aio-bar-flush-object',
]
);
$admin_bar->add_menu(
[
'parent' => 'aio-tools',
'id' => 'aio-tools-clear-assets',
'title' => $ico_assets . esc_html__( 'Clear Minified CSS/JS & Fonts', 'aio-tools' ),
'href' => '#aio-bar-clear-assets',
]
);
}
public static function output_admin_bar_ajax_script() {
if ( ! is_admin_bar_showing() || ! current_user_can( 'manage_options' ) ) {
return;
}
$ajax_url = admin_url( 'admin-ajax.php' );
$nonce = wp_create_nonce( 'aio-settings-nonce' );
?>
__( 'Current page cache purged successfully!', 'aio-tools' ) ] );
break;
case 'flush_object':
if ( function_exists( 'wp_cache_flush' ) ) {
wp_cache_flush();
}
wp_send_json_success( [ 'message' => __( 'Persistent Object Cache flushed successfully!', 'aio-tools' ) ] );
break;
case 'clear_assets':
if ( class_exists( 'AIO_Asset_Optimizer' ) ) {
AIO_Asset_Optimizer::clear_minified_assets();
}
if ( class_exists( 'AIO_Font_Optimizer' ) ) {
AIO_Font_Optimizer::clear_local_fonts();
}
delete_transient( 'aio_img_dims_cache' );
if ( class_exists( 'AIO_Caching' ) ) {
AIO_Caching::purge_all_static();
}
wp_send_json_success( [ 'message' => __( 'Minified CSS/JS, local fonts, and Page Cache cleared!', 'aio-tools' ) ] );
break;
case 'purge_all':
default:
$this->purge_all_caches_internal();
wp_send_json_success( [ 'message' => __( 'All caches (Page Cache, Minified CSS/JS & Object Cache) purged successfully!', 'aio-tools' ) ] );
break;
}
}
private function purge_all_caches_internal() {
if ( class_exists( 'AIO_Caching' ) ) {
AIO_Caching::purge_all_static();
}
if ( class_exists( 'AIO_Asset_Optimizer' ) ) {
AIO_Asset_Optimizer::clear_minified_assets();
}
if ( class_exists( 'AIO_Font_Optimizer' ) ) {
AIO_Font_Optimizer::clear_local_fonts();
}
delete_transient( 'aio_img_dims_cache' );
if ( function_exists( 'wp_cache_flush' ) ) {
wp_cache_flush();
}
}
public function aio_purge_all_caches_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
$this->purge_all_caches_internal();
wp_send_json_success( [
'message' => __( 'All caches (Page Cache, Minified CSS/JS & Object Cache) purged successfully!', 'aio-tools' ),
] );
}
public function aio_purge_all_caches_admin_post() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Unauthorized', 'aio-tools' ) );
}
check_admin_referer( 'aio_purge_all_caches_bar' );
$this->purge_all_caches_internal();
$ref = wp_get_referer();
$url = $ref ? add_query_arg( 'aio_cache_purged', '1', $ref ) : admin_url( 'admin.php?page=aio-settings&tab=performance&aio_cache_purged=1' );
wp_safe_redirect( $url );
exit;
}
public function aio_render_cache_purged_notice() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET['aio_cache_purged'] ) && $_GET['aio_cache_purged'] === '1' && current_user_can( 'manage_options' ) ) {
echo '
AIO Tools: ' . esc_html__( 'All caches (Page Cache, Minified CSS/JS & Object Cache) purged successfully!', 'aio-tools' ) . '
';
}
}
public function aio_add_dashboard_widgets() {
if ( !current_user_can('manage_options') ) return;
$plugin_name = __('AIO Tools', 'aio-tools');
wp_add_dashboard_widget(
'aio_tools_dashboard_widget',
$plugin_name . ' - ' . __('Overview', 'aio-tools'),
[ $this, 'aio_dashboard_widget_render' ]
);
}
public function aio_dashboard_widget_render() {
$plugin_name = __( 'AIO Tools', 'aio-tools' );
$settings = get_option( 'aio_options', [] );
$sec_on = aio_is_module_active( 'opt-module-security' );
$perf_on = aio_is_module_active( 'opt-module-performance' );
$cache_on = $perf_on && ! empty( $settings['optEnablePageCache'] );
$smtp_on = aio_is_module_active( 'opt-module-smtp' );
$mailer = $settings['opt-mailer'] ?? 'smtp';
$smtp_ready = $smtp_on && (
( $mailer === 'smtp' && ! empty( $settings['txtSmtpHost'] ) ) ||
( $mailer === 'google' && ! empty( $settings['optOAuthRefreshToken_google'] ) ) ||
( $mailer === 'microsoft' && ! empty( $settings['optOAuthRefreshToken_microsoft'] ) )
);
?>
' . sprintf( __( 'It looks like WP Mail SMTP is active on your site. WP Mail SMTP feature may cause conflict with %1$s.', 'aio-tools' ), AIO_PLUGIN_NAME ) . '', 'warning' );
}
}
public function aio_add_plugin_page_settings_link( $links ) {
$aio_links[] = '' . esc_html__('Settings', 'aio-tools') . '';
return $aio_links + $links;
}
// SMTP functions moved to class-aio-smtp-admin.php
public function aio_get_system_status_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
global $wpdb;
$theme = wp_get_theme();
$settings = get_option( 'aio_options', [] );
// Calculate Security Posture Score (0-100)
$sec_points = 0;
if ( aio_is_module_active( 'opt-module-security' ) ) {
if ( ! empty( $settings['optHideLoginUrl'] ) ) {
$sec_points += 20;
}
if ( ! empty( $settings['optEnableWAF'] ) ) {
$sec_points += 20;
}
if ( ! empty( $settings['optEnableLimitLogin'] ) ) {
$sec_points += 15;
}
if ( ! empty( $settings['opt-perf-disable-xmlrpc'] ) ) {
$sec_points += 15;
}
if ( ! empty( $settings['optEnableDisableFileEdit'] ) ) {
$sec_points += 10;
}
if ( ! empty( $settings['optEnableUploadProtection'] ) ) {
$sec_points += 10;
}
if ( get_user_meta( get_current_user_id(), '_aio_2fa_enabled', true ) || ! empty( $settings['optCaptchaSiteKey'] ) ) {
$sec_points += 10;
}
}
$lockouts_table = $wpdb->prefix . 'aio_lockouts';
$active_lockouts = 0;
$total_lockouts = 0;
if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $lockouts_table ) ) === $lockouts_table ) {
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$active_lockouts = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$lockouts_table} WHERE expires_at > %s", current_time( 'mysql' ) ) );
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$total_lockouts = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$lockouts_table}" );
}
$webp_stats = get_option( 'aio_webp_bulk_stats', [] );
$webp_saved_bytes = 0;
if ( is_array( $webp_stats ) && isset( $webp_stats['original_bytes'], $webp_stats['webp_bytes'] ) ) {
$webp_saved_bytes = max( 0, (int) $webp_stats['original_bytes'] - (int) $webp_stats['webp_bytes'] );
}
$email_logs_table = $wpdb->prefix . 'aio_email_logs';
$emails_sent = 0;
$emails_failed = 0;
if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $email_logs_table ) ) === $email_logs_table ) {
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$emails_sent = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$email_logs_table} WHERE status = 'sent'" );
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$emails_failed = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$email_logs_table} WHERE status = 'failed'" );
}
$status = [
'wp_version' => get_bloginfo( 'version' ),
'php_version' => phpversion(),
'mysql_version' => method_exists( $wpdb, 'db_version' ) ? $wpdb->db_version() : 'Unknown',
'memory_limit' => defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : ini_get( 'memory_limit' ),
'theme_name' => $theme->get( 'Name' ),
'plugin_version' => $this->version,
'server' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : 'Unknown',
'is_ssl' => is_ssl(),
'security_score' => min( 100, $sec_points ),
'active_lockouts' => $active_lockouts,
'total_lockouts' => $total_lockouts,
'webp_saved' => size_format( $webp_saved_bytes ),
'page_cache_on' => aio_is_module_active( 'opt-module-performance' ) && ! empty( $settings['optEnablePageCache'] ),
'object_cache_on' => function_exists( 'wp_using_ext_object_cache' ) && wp_using_ext_object_cache(),
'emails_sent' => $emails_sent,
'emails_failed' => $emails_failed,
];
wp_send_json_success( $status );
}
public function aio_get_settings_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
$options = get_option( 'aio_options', [] );
// Mask all sensitive keys before sending to browser
foreach ( AIO_Crypto::get_sensitive_keys() as $secret_key ) {
if ( ! empty( $options[ $secret_key ] ) ) {
$options[ $secret_key ] = '********';
}
}
wp_send_json_success( $options );
}
public function aio_update_settings_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
$raw_settings = isset( $_POST['settings'] ) ? $_POST['settings'] : '';
$params = json_decode( wp_unslash( $raw_settings ), true );
if ( ! is_array( $params ) && ! empty( $raw_settings ) ) {
$params = json_decode( $raw_settings, true );
}
if ( ! is_array( $params ) || ( ! empty( $params ) && array_keys( $params ) === range( 0, count( $params ) - 1 ) ) ) {
wp_send_json_error( __( 'Invalid data', 'aio-tools' ) );
}
$old_options = get_option( 'aio_options', [] );
$sensitive_keys = AIO_Crypto::get_sensitive_keys();
$sanitized_params = [];
// Optional 301 redirect rules bundle from JSON Import
if ( isset( $params['_aio_redirect_rules'] ) ) {
if ( is_array( $params['_aio_redirect_rules'] ) ) {
$clean_rules = [];
foreach ( $params['_aio_redirect_rules'] as $r_src => $r_dst ) {
$r_src = '/' . ltrim( sanitize_text_field( (string) $r_src ), '/' );
$r_dst = esc_url_raw( (string) $r_dst );
if ( '/' !== $r_src && '' !== $r_dst ) {
$clean_rules[ $r_src ] = $r_dst;
}
}
update_option( 'aio_redirect_rules', $clean_rules );
}
unset( $params['_aio_redirect_rules'] );
}
foreach ( $params as $key => $value ) {
$key = sanitize_text_field( (string) $key );
if ( $key === '' ) {
continue;
}
if ( in_array( $key, [ 'optHeader', 'optBodyOpen', 'optFooter', 'txtTawktoScript', 'txtChativeScript' ], true ) ) {
if ( current_user_can( 'unfiltered_html' ) ) {
$sanitized_params[ $key ] = (string) $value;
} else {
$sanitized_params[ $key ] = wp_kses_post( (string) $value );
}
} elseif ( $key === 'optCriticalCss' ) {
$clean_css = preg_replace( '#?[a-zA-Z][^>]*>#', '', (string) $value );
$clean_css = str_ireplace( [ 'aio_sanitize_array_recursive( $value );
} elseif ( in_array( $key, $sensitive_keys, true ) ) {
// Preserve exact password/secret characters (<, &, %xx) without HTML stripping before AES-256 encryption
$clean_secret = trim( (string) preg_replace( '/[\r\n\0]/', '', (string) $value ) );
if ( $clean_secret === '********' ) {
// Keep previously saved encrypted value when unchanged
$sanitized_params[ $key ] = isset( $old_options[ $key ] ) ? $old_options[ $key ] : '';
} elseif ( $clean_secret === '' ) {
// Explicitly allow clearing a saved password/secret
$sanitized_params[ $key ] = '';
} else {
$sanitized_params[ $key ] = AIO_Crypto::encrypt( $clean_secret );
}
} elseif ( $key === 'optSocialLoginRole' ) {
$role_candidate = sanitize_key( (string) $value );
$allowed_roles = [ 'subscriber' ];
if ( wp_roles()->is_role( 'customer' ) ) {
$allowed_roles[] = 'customer';
}
$sanitized_params[ $key ] = in_array( $role_candidate, $allowed_roles, true ) ? $role_candidate : 'subscriber';
} elseif ( $key === 'optRecaptchaV3Threshold' ) {
$score = (float) $value;
$sanitized_params[ $key ] = (string) round( min( 0.9, max( 0.1, $score > 0 ? $score : 0.5 ) ), 1 );
} elseif ( $key === 'optContactStyle' ) {
$style_candidate = sanitize_key( (string) $value );
$sanitized_params[ $key ] = in_array( $style_candidate, [ 'bento', 'pills', 'dock' ], true ) ? $style_candidate : 'bento';
} elseif ( $key === 'optHideLoginUrl' ) {
$raw_slug = trim( (string) $value );
if ( false !== strpos( $raw_slug, '://' ) ) {
$raw_slug = (string) wp_parse_url( $raw_slug, PHP_URL_PATH );
}
$clean_slug = trim( sanitize_text_field( $raw_slug ), "/ \t\n\r\0\x0B" );
if ( in_array( strtolower( $clean_slug ), [ 'wp-admin', 'wp-login.php' ], true ) ) {
$clean_slug = '';
}
$sanitized_params[ $key ] = $clean_slug;
} elseif ( in_array( $key, [ 'txtSmtpPort', 'optLimitLoginMax', 'optLimitLoginDuration', 'optHeartbeatInterval', 'optRevisionsLimit', 'optAutosaveInterval', 'optCacheTtlHours', 'txtObjectCachePort', 'txtObjectCacheDb', 'numBubbleTimeout', 'numButtonOffset', 'numWcFreeShippingGoal', 'numSmtpLogRetention' ], true ) ) {
$sanitized_params[ $key ] = absint( $value );
} elseif ( in_array( $key, [ 'optPrefetchDomains', 'optPreloadAssets', 'optDelayJsExcludes', 'optAsyncCssExcludes', 'optMinifyExcludes', 'optCacheExcludeUrls', 'optCacheExcludeCookies', 'txtLoginWhitelist', 'txtMaintWhitelist', 'txtMaintenanceMessage', 'txtMaintMessage', 'txtBubbleMessage', 'optFakeSalesNames', 'optFakeSalesCities', 'optFakeSalesProducts' ], true ) ) {
$sanitized_params[ $key ] = sanitize_textarea_field( (string) $value );
} elseif ( is_bool( $value ) ) {
$sanitized_params[ $key ] = $value;
} else {
$sanitized_params[ $key ] = sanitize_text_field( (string) $value );
}
}
// Preserve all encrypted secrets & OAuth refresh tokens when omitted from payload (e.g. JSON Import)
// Note: explicitly clearing a field in Admin UI sends "" which IS present via array_key_exists() and clears cleanly.
foreach ( $sensitive_keys as $secret_key ) {
if ( ! array_key_exists( $secret_key, $sanitized_params ) && ! empty( $old_options[ $secret_key ] ) ) {
$sanitized_params[ $secret_key ] = $old_options[ $secret_key ];
}
}
// Clean up OAuth account metadata & access-token transients when an OAuth connection is removed
foreach ( [ 'google', 'microsoft' ] as $oauth_prov ) {
$tok_key = 'optOAuthRefreshToken_' . $oauth_prov;
if ( array_key_exists( $tok_key, $sanitized_params ) && '' === $sanitized_params[ $tok_key ] ) {
$sanitized_params[ 'optOAuthEmail_' . $oauth_prov ] = '';
$sanitized_params[ 'optOAuthScopes_' . $oauth_prov ] = '';
if ( class_exists( 'AIO_Mailer' ) ) {
AIO_Mailer::clear_cached_access_token( $oauth_prov, $old_options );
}
}
}
update_option( 'aio_options', $sanitized_params );
// Sync standalone 3-Tier Page Cache Drop-in, .htaccess rules, and Object Cache runtime config
$perf_enabled = ! isset( $sanitized_params['opt-module-performance'] ) || ! empty( $sanitized_params['opt-module-performance'] );
$page_cache_on = $perf_enabled && ! empty( $sanitized_params['optEnablePageCache'] ) && empty( $sanitized_params['optEnableMaintenance'] );
if ( class_exists( 'AIO_Dropin_Manager' ) ) {
$adv_dropin_on = $page_cache_on && ( ! isset( $sanitized_params['optEnableAdvCacheDropin'] ) || ! empty( $sanitized_params['optEnableAdvCacheDropin'] ) );
AIO_Dropin_Manager::sync_advanced_cache( $adv_dropin_on, false, $sanitized_params );
}
if ( class_exists( 'AIO_Htaccess_Cache' ) ) {
$ht_page_on = $page_cache_on && empty( $sanitized_params['optCacheSeparateMobile'] ) && ( ! isset( $sanitized_params['optEnableHtaccessPageCache'] ) || ! empty( $sanitized_params['optEnableHtaccessPageCache'] ) );
$webp_ht_on = $perf_enabled && ! empty( $sanitized_params['optEnableWebpRewrite'] );
$browser_cache = $perf_enabled && ! empty( $sanitized_params['optEnableBrowserCache'] );
AIO_Htaccess_Cache::sync_page_cache( $ht_page_on, $sanitized_params );
AIO_Htaccess_Cache::sync_webp_rewrite( $webp_ht_on );
AIO_Htaccess_Cache::sync( $browser_cache );
}
if ( class_exists( 'AIO_Object_Cache_Manager' ) ) {
if ( ! $perf_enabled ) {
AIO_Object_Cache_Manager::remove_dropin();
} elseif ( ! empty( $sanitized_params['optEnableObjectCache'] ) ) {
AIO_Object_Cache_Manager::write_runtime_config( AIO_Object_Cache_Manager::build_connection_params() );
}
}
if ( class_exists( 'AIO_Asset_Optimizer' ) ) {
AIO_Asset_Optimizer::clear_minified_assets();
}
if ( empty( $sanitized_params['optSelfHostGoogleFonts'] ) && class_exists( 'AIO_Font_Optimizer' ) ) {
AIO_Font_Optimizer::clear_local_fonts();
}
// Flush rewrite rules automatically when XML Sitemap toggle changes
$old_sitemap = ! empty( $old_options['optEnableSitemap'] );
$new_sitemap = ! empty( $sanitized_params['optEnableSitemap'] );
if ( $old_sitemap !== $new_sitemap ) {
if ( $new_sitemap ) {
add_rewrite_rule( '^sitemap\.xml$', 'index.php?aio_sitemap=1', 'top' );
}
flush_rewrite_rules();
}
do_action( 'aio_tools_settings_updated', $sanitized_params, $old_options );
wp_send_json_success( [ 'message' => __( 'Settings saved successfully', 'aio-tools' ) ] );
}
private function aio_sanitize_array_recursive($array) {
$sanitized = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$sanitized[$key] = $this->aio_sanitize_array_recursive($value);
} else {
$sanitized[$key] = sanitize_text_field($value);
}
}
return $sanitized;
}
public static function is_valid_larksuite_webhook( $url ) {
if ( empty( $url ) || ! is_string( $url ) ) {
return false;
}
$parsed = wp_parse_url( $url );
if ( ! is_array( $parsed ) || empty( $parsed['scheme'] ) || empty( $parsed['host'] ) || empty( $parsed['path'] ) ) {
return false;
}
if ( strtolower( $parsed['scheme'] ) !== 'https' ) {
return false;
}
$host = strtolower( $parsed['host'] );
if ( ! preg_match( '/(^|\.)(larksuite\.com|feishu\.cn)$/', $host ) ) {
return false;
}
return strpos( $parsed['path'], '/open-apis/bot/' ) === 0;
}
public function aio_test_telegram_connection_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
$token = isset( $_POST['token'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['token'] ) ) ) : '';
$chat_id = isset( $_POST['chat_id'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['chat_id'] ) ) ) : '';
if ( $token === '********' ) {
$token = AIO_Crypto::decrypt( (string) aio_get_option( 'txtTelegramToken', '' ) );
}
if ( empty( $token ) || empty( $chat_id ) ) {
wp_send_json_error( __( 'Please provide both Bot Token and Chat ID.', 'aio-tools' ) );
}
if ( ! preg_match( '/^\d+:[A-Za-z0-9_-]{20,}$/', $token ) ) {
wp_send_json_error( __( 'Invalid Telegram Bot Token format.', 'aio-tools' ) );
}
$url = "https://api.telegram.org/bot{$token}/sendMessage";
$domain = wp_parse_url( home_url(), PHP_URL_HOST );
$message = '🎉 ' . esc_html__( 'AIO Tools: Connection Successful!', 'aio-tools' ) . "\n";
$message .= esc_html__( 'Your Telegram notification settings are configured correctly.', 'aio-tools' ) . "\n";
$message .= esc_html__( 'Domain:', 'aio-tools' ) . ' ' . esc_html( (string) $domain ) . "\n";
$message .= esc_html__( 'Time:', 'aio-tools' ) . ' ' . esc_html( current_time( 'Y-m-d H:i:s' ) );
$response = wp_safe_remote_post( $url, [
'body' => [
'chat_id' => $chat_id,
'text' => $message,
'parse_mode' => 'HTML',
],
'timeout' => 15,
] );
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response->get_error_message() );
}
$status_code = wp_remote_retrieve_response_code( $response );
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( $status_code == 200 && isset( $body['ok'] ) && $body['ok'] === true ) {
wp_send_json_success( __( 'Test message sent successfully!', 'aio-tools' ) );
} else {
$error_msg = isset( $body['description'] ) ? sanitize_text_field( $body['description'] ) : __( 'Unknown error', 'aio-tools' );
wp_send_json_error( sprintf( __( 'Telegram API Error: %s', 'aio-tools' ), $error_msg ) );
}
}
public function aio_test_larksuite_connection_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) );
}
$raw_webhook = isset( $_POST['webhook'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['webhook'] ) ) ) : '';
if ( $raw_webhook === '********' ) {
$raw_webhook = AIO_Crypto::decrypt( (string) aio_get_option( 'txtLarksuiteWebhook', '' ) );
}
$webhook = esc_url_raw( $raw_webhook );
if ( empty( $webhook ) ) {
wp_send_json_error( __( 'Please provide the Webhook URL.', 'aio-tools' ) );
}
if ( ! self::is_valid_larksuite_webhook( $webhook ) ) {
wp_send_json_error( __( 'Invalid Larksuite/Feishu Webhook URL. Must use https://open.larksuite.com/open-apis/bot/... or https://open.feishu.cn/open-apis/bot/...', 'aio-tools' ) );
}
$domain = wp_parse_url( home_url(), PHP_URL_HOST );
$message = "🎉 AIO Tools: Connection Successful!\n";
$message .= "Your Larksuite notification settings are configured correctly.\n";
$message .= 'Domain: ' . (string) $domain . "\n";
$message .= 'Time: ' . current_time( 'Y-m-d H:i:s' );
$body = [
'msg_type' => 'post',
'content' => [
'post' => [
'vi_vn' => [
'title' => __( 'AIO Tools Connection Test', 'aio-tools' ),
'content' => [
[
[
'tag' => 'text',
'text' => $message,
],
],
],
],
],
],
];
$response = wp_safe_remote_post( $webhook, [
'headers' => [ 'Content-Type' => 'application/json' ],
'body' => wp_json_encode( $body ),
'timeout' => 15,
] );
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response->get_error_message() );
}
$status_code = wp_remote_retrieve_response_code( $response );
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( $status_code == 200 && isset( $response_body['code'] ) && $response_body['code'] === 0 ) {
wp_send_json_success( __( 'Test message sent successfully!', 'aio-tools' ) );
} else {
$error_msg = isset( $response_body['msg'] ) ? sanitize_text_field( $response_body['msg'] ) : __( 'Unknown error', 'aio-tools' );
wp_send_json_error( sprintf( __( 'Larksuite API Error: %s', 'aio-tools' ), $error_msg ) );
}
}
private function aio_get_email_message_html() {
ob_start();
?>
SMTP Test Email
Thank you for trying out . We're on a mission to make sure that your emails actually get delivered.
Thanks,
.
|
|