' . esc_html__( 'Do not use any of the following slugs as custom login URLs:', 'accessdoor-smart-admin-login-url-control' ) . '
wp-admin, wp-login, wp-login.php, login, admin, logout, lostpassword, resetpassword, register, wp-json, xmlrpc, xmlrpc.php, my-account, cart, checkout, shop, account, profile, signin, signup, etc.
';
echo '
';
}
/**
* Sanitize settings before saving.
*
* @param array $input Settings input.
* @return array Sanitized settings.
*/
public function sanitize_settings( $input ) {
// Get existing settings to merge with new input
$existing = get_option( $this->option_name, array() );
$sanitized = $existing; // Start with existing data
if ( isset( $input['enable_custom_login'] ) ) {
$sanitized['enable_custom_login'] = 1;
} elseif ( isset( $input['redirect_wp_login'] ) || isset( $input['role_slugs'] ) ) {
// Only set to 0 if we're saving the general tab (has these fields)
$sanitized['enable_custom_login'] = 0;
}
// Sanitize role-based slugs and block restricted/existing slugs.
if ( isset( $input['role_slugs'] ) && is_array( $input['role_slugs'] ) ) {
$sanitized['role_slugs'] = array();
$restricted_slugs = array(
'wp-admin', 'wp-login', 'wp-login.php', 'login', 'admin',
'logout', 'lostpassword', 'resetpassword', 'register',
'wp-json', 'xmlrpc', 'xmlrpc.php',
'my-account', 'cart', 'checkout', 'shop',
'account', 'profile', 'signin', 'signup',
);
foreach ( $input['role_slugs'] as $role => $slug ) {
if ( empty( $slug ) ) {
continue;
}
$slug = sanitize_title( $slug );
// Block restricted slugs
if ( in_array( $slug, $restricted_slugs, true ) ) {
add_settings_error(
$this->option_name,
'restricted_slug_' . $role,
/* translators: %s: The slug entered by the user */
sprintf( __( 'The slug "%s" is not allowed for security reasons.', 'accessdoor-smart-admin-login-url-control' ), esc_html( $slug ) ),
'error'
);
continue;
}
// Block if slug matches an existing page
if ( get_page_by_path( $slug ) ) {
add_settings_error(
$this->option_name,
'existing_page_slug_' . $role,
/* translators: %s: The slug entered by the user */
sprintf( __( 'The slug "%s" is already used by a page. Please choose another.', 'accessdoor-smart-admin-login-url-control' ), esc_html( $slug ) ),
'error'
);
continue;
}
$sanitized['role_slugs'][ $role ] = $slug;
}
}
if ( isset( $input['redirect_wp_login'] ) ) {
$sanitized['redirect_wp_login'] = 1;
} elseif ( isset( $input['role_slugs'] ) ) {
// Only set to 0 if we're saving the general tab
$sanitized['redirect_wp_login'] = 0;
}
if ( isset( $input['redirect_url'] ) ) {
$sanitized['redirect_url'] = esc_url_raw( $input['redirect_url'] );
}
// Sanitize role logo IDs.
if ( isset( $input['role_logo'] ) && is_array( $input['role_logo'] ) ) {
if ( ! isset( $sanitized['role_logo'] ) ) {
$sanitized['role_logo'] = array();
}
foreach ( $input['role_logo'] as $role => $attachment_id ) {
if ( ! empty( $attachment_id ) ) {
$sanitized['role_logo'][ $role ] = absint( $attachment_id );
} else {
// Remove if empty
unset( $sanitized['role_logo'][ $role ] );
}
}
}
// Save Security tab options, but validate .htaccess changes for relevant features
$security_fields = array(
'disable_comments',
'disable_xmlrpc_pingback',
'disable_rest_api',
'disable_xmlrpc',
'block_directory_browsing',
'forbid_php_uploads',
'turn_off_pingbacks',
'disable_file_editing',
);
foreach ( $security_fields as $field ) {
// Default: set from input
$sanitized[$field] = isset($input[$field]) ? 1 : 0;
}
// Sanitize role background image IDs.
if ( isset( $input['role_bg_image'] ) && is_array( $input['role_bg_image'] ) ) {
if ( ! isset( $sanitized['role_bg_image'] ) ) {
$sanitized['role_bg_image'] = array();
}
foreach ( $input['role_bg_image'] as $role => $attachment_id ) {
if ( ! empty( $attachment_id ) ) {
$sanitized['role_bg_image'][ $role ] = absint( $attachment_id );
} else {
// Remove if empty
unset( $sanitized['role_bg_image'][ $role ] );
}
}
}
// Sanitize role background colors.
if ( isset( $input['role_bg_color'] ) && is_array( $input['role_bg_color'] ) ) {
if ( ! isset( $sanitized['role_bg_color'] ) ) {
$sanitized['role_bg_color'] = array();
}
foreach ( $input['role_bg_color'] as $role => $color ) {
if ( ! empty( $color ) ) {
$sanitized['role_bg_color'][ $role ] = sanitize_hex_color( $color );
} else {
// Remove if empty
unset( $sanitized['role_bg_color'][ $role ] );
}
}
}
if (
isset( $input['change_admin_email'] ) ||
isset( $input['change_user_email'] ) ||
isset( $input['change_admin_username'] )
) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
$is_admin = user_can( $current_user, 'manage_options' );
if ( empty( $user_id ) || ! $is_admin ) {
return $sanitized;
}
// Track which fields were actually changed
$changed_fields = array();
/**
* ---------------------------------------
* 1. Update ADMIN EMAIL (Settings → General)
* No confirmation email
* ---------------------------------------
*/
if ( isset( $input['change_admin_email'] ) ) {
$new_admin_email = sanitize_email( $input['change_admin_email'] );
$current_admin_email = get_option( 'admin_email' );
if($new_admin_email != $current_admin_email){
if ( ! is_email( $new_admin_email ) ) {
add_settings_error(
$this->option_name,
'invalid_admin_email',
__( 'Please enter a valid admin email address.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
}else {
// Force update without confirmation, allow any email (even if used by another user)
update_option( 'admin_email', $new_admin_email );
delete_option( 'new_admin_email' );
remove_action( 'update_option_admin_email', 'wp_send_new_admin_email', 10 );
add_settings_error(
$this->option_name,
'admin_email_updated',
__( 'Admin email updated successfully.', 'accessdoor-smart-admin-login-url-control' ),
'updated'
);
}
$sanitized['change_admin_email'] = $new_admin_email;
}
}
/**
* ---------------------------------------
* 2. Update ADMIN USER EMAIL
* ---------------------------------------
*/
if ( isset( $input['change_user_email'] ) ) {
$new_user_email = sanitize_email( $input['change_user_email'] );
// Only process if username is changed
if ( $new_user_email !== $current_user->user_email ) {
if ( ! is_email( $new_user_email ) ) {
add_settings_error(
$this->option_name,
'invalid_user_email',
__( 'Please enter a valid user email address.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_user_email'] = $current_user->user_email;
} elseif ( email_exists( $new_user_email ) && $new_user_email !== $current_user->user_email ) {
add_settings_error(
$this->option_name,
'user_email_exists',
__( 'This email is already in use by another user.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_user_email'] = $current_user->user_email;
}else {
$result = wp_update_user( array(
'ID' => $user_id,
'user_email' => $new_user_email,
) );
if ( is_wp_error( $result ) ) {
add_settings_error(
$this->option_name,
'user_email_update_failed',
__( 'Failed to update user email: ', 'accessdoor-smart-admin-login-url-control' ) . $result->get_error_message(),
'error'
);
$sanitized['change_user_email'] = $current_user->user_email;
} else {
add_settings_error(
$this->option_name,
'user_email_updated',
__( 'User email updated successfully.', 'accessdoor-smart-admin-login-url-control' ),
'updated'
);
$sanitized['change_user_email'] = $new_user_email;
}
}
}
}
/**
* ---------------------------------------
* 3. Update ADMIN USERNAME (Advanced)
* ---------------------------------------
*/
if ( isset( $input['change_admin_username'] ) ) {
$new_username = sanitize_user( $input['change_admin_username'], true );
// Only process if username is changed
if ( $new_username !== $current_user->user_login ) {
// Block for super admins in multisite
if ( is_multisite() && is_super_admin( $user_id ) ) {
add_settings_error(
$this->option_name,
'superadmin_username_change_blocked',
__( 'Changing the username for a network (super) admin is not allowed for security reasons.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_admin_username'] = $current_user->user_login;
} elseif ( empty( $new_username ) ) {
add_settings_error(
$this->option_name,
'invalid_username',
__( 'Username cannot be empty.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_admin_username'] = $current_user->user_login;
} elseif ( username_exists( $new_username ) ) {
add_settings_error(
$this->option_name,
'username_exists',
__( 'This username already exists.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_admin_username'] = $current_user->user_login;
} else {
global $wpdb;
$updated = $wpdb->update(
$wpdb->users,
array( 'user_login' => $new_username ),
array( 'ID' => $user_id ),
array( '%s' ),
array( '%d' )
);
if ( false === $updated ) {
add_settings_error(
$this->option_name,
'username_update_failed',
__( 'Failed to update username.', 'accessdoor-smart-admin-login-url-control' ),
'error'
);
$sanitized['change_admin_username'] = $current_user->user_login;
} else {
// Refresh login session
wp_clear_auth_cookie();
wp_set_current_user( $user_id );
wp_set_auth_cookie( $user_id );
add_settings_error(
$this->option_name,
'username_updated',
__( 'Username updated successfully.', 'accessdoor-smart-admin-login-url-control' ),
'updated'
);
$sanitized['change_admin_username'] = $new_username;
}
}
}
}
}
// Improved: Only set transient if values actually changed (robust for unset/empty cases)
$settings_changed = false;
// Compare role_slugs
$old_slugs = isset( $existing['role_slugs'] ) ? $existing['role_slugs'] : array();
$new_slugs = isset( $sanitized['role_slugs'] ) ? $sanitized['role_slugs'] : array();
if ( $old_slugs !== $new_slugs ) {
$settings_changed = true;
}
// Compare enable_custom_login
$old_enable = isset( $existing['enable_custom_login'] ) ? (int)$existing['enable_custom_login'] : 0;
$new_enable = isset( $sanitized['enable_custom_login'] ) ? (int)$sanitized['enable_custom_login'] : 0;
if ( $old_enable !== $new_enable ) {
$settings_changed = true;
}
if ( $settings_changed ) {
set_transient( 'ADALC_permalinks_flush_needed', true, 60 );
set_transient( 'ADALC_permalinks_flushed', true, 30 );
}
return $sanitized;
}
/**
* Display admin notices.
*/
public function display_admin_notices() {
static $notice_shown = false;
if ( $notice_shown ) {
return;
}
// Check if we just flushed permalinks.
if ( get_transient( 'ADALC_permalinks_flushed' ) ) {
delete_transient( 'ADALC_permalinks_flushed' );
$notice_shown = true;
?>
' . esc_html__( 'Configure your custom login URL settings below.', 'accessdoor-smart-admin-login-url-control' ) . '';
}
/**
* Redirect settings section callback.
*/
public function redirect_section_callback() {
// echo '
' . esc_html__( 'Configure what happens when someone tries to access the default wp-login.php directly.', 'accessdoor-smart-admin-login-url-control' ) . '
';
}
/**
* Branding settings section callback.
*/
public function branding_section_callback() {
// echo '
' . esc_html__( 'Customize the login page design for each user role. Set a custom logo and background.', 'accessdoor-smart-admin-login-url-control' ) . '
';
}
/**
* Admin Information settings section callback.
*/
public function admin_info_section_callback() {
// echo '