*/
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( 'init', [ $this, 'aio_set_notices' ] );
$this->create_settings_page();
add_action( 'wp_dashboard_setup', [ $this, 'aio_add_dashboard_widgets' ] );
add_action( 'admin_enqueue_scripts', 'add_thickbox' );
add_action('wp_ajax_w2wSmtpCheckHandler', [ $this,'w2wSmtpCheckHandler' ]);
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_generate_2fa', [ $this, 'aio_generate_2fa_ajax' ] );
add_action( 'wp_ajax_aio_verify_2fa', [ $this, 'aio_verify_2fa_ajax' ] );
add_action( 'wp_ajax_aio_disable_2fa', [ $this, 'aio_disable_2fa_ajax' ] );
add_action( 'wp_ajax_aio_unblock_ip', [ $this, 'aio_unblock_ip_ajax' ] );
add_action( 'wp_ajax_aio_get_convertible_images', [ $this, 'aio_get_convertible_images_ajax' ] );
add_action( 'wp_ajax_aio_process_webp_batch', [ $this, 'aio_process_webp_batch_ajax' ] );
add_action( 'wp_ajax_aio_update_redirect_rules', [ $this, 'aio_update_redirect_rules_ajax' ] );
add_action( 'wp_ajax_aio_scan_file_integrity', [ $this, 'aio_scan_file_integrity_ajax' ] );
add_action( 'admin_init', [ $this, 'aio_handle_oauth_callback' ] );
}
/**
* Register the stylesheets for the admin area.
*
* @since 1.0.0
*/
public function enqueue_styles() {
// Enqueue Phosphor Icons
wp_enqueue_style( 'phosphor-icons', 'https://unpkg.com/@phosphor-icons/web@2.1.1/src/regular/style.css', array(), '2.1.1', 'all' );
wp_enqueue_style( 'phosphor-icons-fill', 'https://unpkg.com/@phosphor-icons/web@2.1.1/src/fill/style.css', array(), '2.1.1', 'all' );
wp_enqueue_style( $this->plugin_name, AIO_URL . 'assets/css/aio-tools-admin.css', array(), $this->version, 'all' );
wp_enqueue_style( 'mobile', AIO_URL . 'assets/css/responsive.css', array(), $this->version, 'all' );
}
/**
* Register the JavaScript for the admin area.
*
* @since 1.0.0
*/
public function enqueue_scripts( $hook_suffix ) {
if ( strpos( $hook_suffix, 'aio-settings' ) !== false ) {
wp_enqueue_media();
}
wp_enqueue_script( $this->plugin_name, AIO_URL . 'assets/js/aio-tools-admin.js', array( 'jquery' ), $this->version, true );
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'),
'success' => __('Success! Please check your email inbox.','aio'),
'error' => __('The following error occured: ','aio'),
'alertdata' => __('You have entered an invalid email address!','aio'),
),
) );
}
public function load_dependencies_frameworks() {
require_once AIO_VENDOR_PATH . 'announce4wp/announce4wp-client.php';
}
public function create_settings_page() {
add_action( 'admin_menu', [ $this, 'aio_add_admin_menu' ] );
}
public function aio_add_admin_menu() {
$plugin_name = aio_get_option('txtWhiteLabelName', __('AIO Tools', 'aio'));
$menu_title = aio_get_option('txtWhiteLabelMenu', 'AIO Tools');
if (empty($plugin_name)) $plugin_name = __('AIO Tools', 'aio');
if (empty($menu_title)) $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'),
__('Audit Logs', 'aio'),
'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 ) {
if ( current_user_can( 'manage_options' ) ) {
$menu_title = aio_get_option('txtWhiteLabelMenu', 'AIO Tools');
if (empty($menu_title)) $menu_title = 'AIO Tools';
$admin_bar->add_menu( [
'id' => 'aio-tools',
'title' => $menu_title,
'href' => admin_url( 'admin.php?page=aio-settings' ),
'meta' => [
'target' => '_self',
'html' => '',
],
] );
}
}
public function aio_add_dashboard_widgets() {
if ( !current_user_can('manage_options') ) return;
$plugin_name = aio_get_option('txtWhiteLabelName', __('AIO Tools', 'aio'));
if (empty($plugin_name)) $plugin_name = __('AIO Tools', 'aio');
wp_add_dashboard_widget(
'aio_tools_dashboard_widget',
$plugin_name . ' - ' . __('Overview', 'aio'),
[ $this, 'aio_dashboard_widget_render' ]
);
}
public function aio_dashboard_widget_render() {
$plugin_name = aio_get_option('txtWhiteLabelName', __('AIO Tools', 'aio'));
if (empty($plugin_name)) $plugin_name = __('AIO Tools', 'aio');
?>
' . sprintf( __( 'It looks like WP Mail SMTP is active on your site. WP Mail SMTP feature may cause conflict with %1$s.', 'aio' ), AIO_PLUGIN_NAME ) . '', 'warning' );
}
}
public function aio_handle_oauth_callback() {
if ( !isset($_GET['page']) || $_GET['page'] !== 'aio-settings' || !isset($_GET['code']) || !isset($_GET['state']) ) {
return;
}
if ( !current_user_can('manage_options') ) return;
$code = sanitize_text_field($_GET['code']);
$state = sanitize_text_field($_GET['state']);
$settings = get_option('aio_options', []);
$client_id = $settings['txtOAuthClientId'] ?? '';
$client_secret = $settings['txtOAuthClientSecret'] ?? '';
if (!empty($client_secret)) {
$client_secret = AIO_Crypto::decrypt($client_secret);
}
$redirect_uri = str_replace('admin-ajax.php', '', admin_url('admin-ajax.php')) . 'options-general.php?page=aio-settings&tab=smtp';
if ( empty($client_id) || empty($client_secret) ) return;
$token_url = '';
$args = [
'method' => 'POST',
'body' => [
'client_id' => $client_id,
'client_secret' => $client_secret,
'code' => $code,
'redirect_uri' => $redirect_uri,
'grant_type' => 'authorization_code'
]
];
if ($state === 'google') {
$token_url = 'https://oauth2.googleapis.com/token';
} elseif ($state === 'microsoft') {
$token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
}
if (empty($token_url)) return;
$response = wp_remote_post($token_url, $args);
if ( !is_wp_error($response) ) {
$body = json_decode(wp_remote_retrieve_body($response), true);
if ( isset($body['refresh_token']) ) {
$settings['optOAuthRefreshToken_' . $state] = AIO_Crypto::encrypt($body['refresh_token']);
update_option('aio_options', $settings);
// Redirect to clean URL
wp_redirect($redirect_uri);
exit;
}
}
}
function aio_add_plugin_page_settings_link( $links ) {
$aio_links[] = '' . esc_html__('Settings', 'aio') . '';
return $aio_links + $links;
}
function w2wSmtpCheckHandler(){
check_ajax_referer( 'aio-smtp-check-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'You do not have sufficient permissions to access this page.', 'aio' ) );
}
$recipient = sanitize_email($_POST['your_email']);
if ( ! is_email( $recipient ) ) {
wp_send_json_error( __( 'Invalid email address.', 'aio' ) );
}
$subject = __('AIO Tool: SMTP Test Connection', 'aio' );
$headers = array('Content-Type: text/html; charset=UTF-8');
$message = '
SMTP Test Successful!
Hello,
This is a test email sent from your website using AIO Tools.
If you are reading this, it means your SMTP configuration is working perfectly.
Sent via: ' . site_url() . '
Time: ' . current_time('Y-m-d H:i:s') . '
© ' . date('Y') . ' AIO Tools. All rights reserved.
';
// Inject PHPMailer debug interceptor
add_action( 'phpmailer_init', function( $phpmailer ) {
$phpmailer->SMTPDebug = 2; // Enable verbose debug output
$phpmailer->Debugoutput = 'html';
});
ob_start();
try {
$result = wp_mail($recipient, $subject, $message, $headers);
$debug_log = ob_get_clean();
$debug_log = strip_tags(str_replace("
\n", "\n", $debug_log)); // Clean up HTML formatting from Debugoutput='html'
if ( ! $result ) {
wp_send_json_error([
'debug_log' => $debug_log ?: 'Mailer Error: Failed to send via wp_mail. (Check PHP error log)'
]);
} else {
wp_send_json_success([
'debug_log' => $debug_log ?: 'Sent successfully via wp_mail. (Native mail() may not produce debug logs)'
]);
}
} catch (Exception $e) {
$debug_log = ob_get_clean();
wp_send_json_error([
'debug_log' => $debug_log . "\nException: " . $e->getMessage()
]);
}
}
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' ) );
}
$options = get_option( 'aio_options', [] );
// Hide sensitive data before sending to frontend
if (isset($options['txtSmtpPassword']) && !empty($options['txtSmtpPassword'])) {
$options['txtSmtpPassword'] = '********';
}
if (isset($options['txtOAuthClientSecret']) && !empty($options['txtOAuthClientSecret'])) {
$options['txtOAuthClientSecret'] = '********';
}
wp_send_json_success( $options );
}
public function aio_generate_2fa_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$user = wp_get_current_user();
$site_name = preg_replace('/[^a-zA-Z0-9]+/', '', get_bloginfo('name'));
$secret = AIO_TOTP::generate_secret();
$qr_url = AIO_TOTP::get_qr_url($site_name, $user->user_login, $secret);
wp_send_json_success([
'secret' => $secret,
'qr_url' => $qr_url
]);
}
public function aio_verify_2fa_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$code = isset($_POST['code']) ? sanitize_text_field($_POST['code']) : '';
$secret = isset($_POST['secret']) ? sanitize_text_field($_POST['secret']) : '';
if ( empty($code) || empty($secret) ) {
wp_send_json_error( __( 'Missing information!', 'aio' ) );
}
$is_valid = AIO_TOTP::verify_code($secret, $code);
if ( $is_valid ) {
$user_id = get_current_user_id();
update_user_meta( $user_id, '_aio_2fa_secret', $secret );
update_user_meta( $user_id, '_aio_2fa_enabled', true );
wp_send_json_success( __( 'Successfully activated!', 'aio' ) );
} else {
wp_send_json_error( __( 'Invalid 6-digit code! Please try again.', 'aio' ) );
}
}
public function aio_disable_2fa_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$user_id = get_current_user_id();
delete_user_meta( $user_id, '_aio_2fa_enabled' );
delete_user_meta( $user_id, '_aio_2fa_secret' );
wp_send_json_success( __( 'Successfully disabled!', 'aio' ) );
}
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' ) );
}
$theme = wp_get_theme();
$status = [
'wp_version' => get_bloginfo('version'),
'php_version' => phpversion(),
'theme_name' => $theme->get('Name'),
'plugin_version' => $this->version,
'server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown',
];
wp_send_json_success( $status );
}
public function aio_unblock_ip_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$ip = isset($_POST['ip']) ? sanitize_text_field($_POST['ip']) : '';
if (empty($ip)) {
wp_send_json_error( __( 'Invalid IP', 'aio' ) );
}
$blocked_ips = get_option('aio_blocked_ips', []);
if (isset($blocked_ips[$ip])) {
unset($blocked_ips[$ip]);
update_option('aio_blocked_ips', $blocked_ips, false);
}
// Also delete the transient
delete_transient('aio_lockout_' . md5($ip));
delete_transient('aio_login_attempts_' . md5($ip));
wp_send_json_success( __( 'IP has been unblocked successfully!', 'aio' ) );
}
public function aio_get_convertible_images_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
global $wpdb;
// Lấy tất cả ảnh (jpeg, jpg, png) không phải webp
$query = "
SELECT ID
FROM {$wpdb->posts}
WHERE post_type = 'attachment'
AND post_mime_type IN ('image/jpeg', 'image/png')
";
$results = $wpdb->get_col($query);
// Lọc những ID chưa có meta _aio_webp_converted
$convertible_ids = [];
foreach ($results as $id) {
if (!get_post_meta($id, '_aio_webp_converted', true)) {
$convertible_ids[] = $id;
}
}
wp_send_json_success([ 'ids' => $convertible_ids ]);
}
public function aio_process_webp_batch_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$ids = isset($_POST['ids']) ? array_map('intval', (array) $_POST['ids']) : [];
if (empty($ids)) {
wp_send_json_error( __( 'No IDs provided', 'aio' ) );
}
if (!function_exists('aio_generate_webp_for_attachment')) {
require_once AIO_MODULES_PATH . 'optimizer/public-optimizer.php';
}
$log = [];
foreach ($ids as $id) {
$file = get_attached_file($id);
if ($file && file_exists($file)) {
$result = aio_generate_webp_for_attachment($id);
if ($result) {
$log[] = "Optimized ID {$id}: " . basename($file);
} else {
$log[] = "Failed or skipped ID {$id}";
}
// Đánh dấu là đã xử lý
update_post_meta($id, '_aio_webp_converted', true);
} else {
update_post_meta($id, '_aio_webp_converted', 'not_found');
}
}
wp_send_json_success([ 'log' => implode("\n", $log) ]);
}
public function aio_update_redirect_rules_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
$raw_rules = isset($_POST['rules']) ? $_POST['rules'] : '';
$rules = json_decode(wp_unslash($raw_rules), true);
if ( !is_array($rules) && !empty($raw_rules) ) {
$rules = json_decode($raw_rules, true);
}
if ( !is_array($rules) ) {
$rules = [];
}
if (!is_array($rules)) {
wp_send_json_error( __( 'Invalid rules format', 'aio' ) );
}
$sanitized_rules = [];
foreach ($rules as $old => $new) {
$sanitized_rules[sanitize_text_field($old)] = sanitize_text_field($new);
}
update_option('aio_redirect_rules', $sanitized_rules);
wp_send_json_success();
}
public function aio_scan_file_integrity_ajax() {
check_ajax_referer( 'aio-settings-nonce', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'Unauthorized', 'aio' ) );
}
if (!function_exists('aio_scan_core_files')) {
require_once AIO_MODULES_PATH . 'security/public-security.php';
}
$result = aio_scan_core_files();
if ($result['success']) {
wp_send_json_success($result['modified']);
} else {
wp_send_json_error($result['message']);
}
}
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' ) );
}
$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) ) {
$params = [];
}
if ( is_array($params) ) {
$sanitized_params = [];
foreach ($params as $key => $value) {
if (in_array($key, ['optHeader', 'optFooter', 'txtTawktoScript', 'txtChativeScript'])) {
if ( current_user_can( 'unfiltered_html' ) ) {
$sanitized_params[$key] = $value;
} else {
$sanitized_params[$key] = wp_kses_post($value);
}
} else if (is_array($value)) {
$sanitized_params[$key] = $this->aio_sanitize_array_recursive($value);
} else {
$sanitized_params[$key] = sanitize_text_field($value);
if (in_array($key, ['txtSmtpPassword', 'txtOAuthClientSecret'])) {
if (empty($sanitized_params[$key]) || $sanitized_params[$key] === '********') {
// Keep old password
$old_options = get_option('aio_options', []);
$sanitized_params[$key] = isset($old_options[$key]) ? $old_options[$key] : '';
} else {
$sanitized_params[$key] = AIO_Crypto::encrypt($sanitized_params[$key]);
}
}
}
}
update_option( 'aio_options', $sanitized_params );
wp_send_json_success( [ 'message' => __( 'Settings saved successfully', 'aio' ) ] );
} else {
wp_send_json_error( __( 'Invalid data', 'aio' ) );
}
}
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;
}
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,
.
|
|