'integer', 'sanitize_callback' => 'absint', 'default' => 1 )); register_setting('admilogu_settings_group', 'admilogu_login_slug', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'admin-login-guard-branding' )); register_setting('admilogu_settings_group', 'admilogu_block_shortcuts', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 1 )); // --- Logo --- register_setting('admilogu_settings_group', 'admilogu_hide_logo', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_logo_url', array( 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', 'default' => admilogu_DEFAULT_LOGO )); register_setting('admilogu_settings_group', 'admilogu_logo_width', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '100%' )); register_setting('admilogu_settings_group', 'admilogu_logo_height', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '80px' )); register_setting('admilogu_settings_group', 'admilogu_logo_title', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_logo_link', array( 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', 'default' => 'https://wordpress.org/' )); register_setting('admilogu_settings_group', 'admilogu_logo_target_blank', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 1 )); register_setting('admilogu_settings_group', 'admilogu_logo_bg_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' )); // --- Background --- register_setting('admilogu_settings_group', 'admilogu_bg_type', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'color' )); register_setting('admilogu_settings_group', 'admilogu_bg_image', array( 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', 'default' => admilogu_DEFAULT_BG )); register_setting('admilogu_settings_group', 'admilogu_bg_video', array( 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', 'default' => admilogu_DEFAULT_VIDEO )); register_setting('admilogu_settings_group', 'admilogu_bg_video_mute', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 1 )); register_setting('admilogu_settings_group', 'admilogu_bg_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#f0f0f1' )); // --- Colors --- register_setting('admilogu_settings_group', 'admilogu_lostpwd_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#2271b1' )); register_setting('admilogu_settings_group', 'admilogu_backtoblog_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#2271b1' )); register_setting('admilogu_settings_group', 'admilogu_lostpwd_hover_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#135e96' )); register_setting('admilogu_settings_group', 'admilogu_backtoblog_hover_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#135e96' )); register_setting('admilogu_settings_group', 'admilogu_hide_backtoblog', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_center_form', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_loginform_bg_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#ffffff' )); register_setting('admilogu_settings_group', 'admilogu_loginform_border_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#c3c4c7' )); register_setting('admilogu_settings_group', 'admilogu_loginform_label_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#3c434a' )); register_setting('admilogu_settings_group', 'admilogu_btn_bg_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#2271b1' )); register_setting('admilogu_settings_group', 'admilogu_btn_text_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#ffffff' )); register_setting('admilogu_settings_group', 'admilogu_btn_bg_hover_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#135e96' )); register_setting('admilogu_settings_group', 'admilogu_btn_text_hover_color', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '#ffffff' )); register_setting('admilogu_settings_group', 'admilogu_custom_css', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_custom_js', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_custom_font', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_custom_footer', array( 'type' => 'string', // allow some HTML for the footer 'sanitize_callback' => 'wp_kses_post', 'default' => '' )); // --- Security --- register_setting('admilogu_settings_group', 'admilogu_enable_2fa', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_max_attempts', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 3 )); register_setting('admilogu_settings_group', 'admilogu_lockout_duration', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 20 )); register_setting('admilogu_settings_group', 'admilogu_fail_redirect_page', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_ip_whitelist', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_ip_blacklist', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' )); register_setting('admilogu_settings_group', 'admilogu_notify_admin_lockout', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); register_setting('admilogu_settings_group', 'admilogu_notify_user_new_ip', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 )); // --- Telemetry --- register_setting('admilogu_settings_group', 'admilogu_tracking_optin', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'no' )); } add_action('admin_init', 'admilogu_register_settings'); /** * Redirect to the settings page after first activation. * * Checks for the `admilogu_activation_redirect` transient (set during * activation) and sends the user to the plugin settings page. The * transient is deleted immediately to prevent repeated redirects. * * @since 1.0.0 * * @return void */ function admilogu_handle_activation_redirect() { if (get_transient('admilogu_activation_redirect')) { delete_transient('admilogu_activation_redirect'); // Do not redirect if it's a bulk activation or on network admin if ( isset( $_GET['activate-multi'] ) || is_network_admin() ) { return; } // Only redirect if not already on the plugin's settings page to avoid loops // phpcs:ignore WordPress.Security.NonceVerification.Recommended $current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; if ($current_page === 'admilogu-settings') { return; } wp_safe_redirect(admin_url('admin.php?page=admilogu-settings')); exit; } } add_action('admin_init', 'admilogu_handle_activation_redirect'); /** * Register the admin menu page. * * Adds a top-level "Login Guard & Branding" menu item that renders the * settings interface via `admilogu_settings_page()`. * * @since 1.0.0 * * @return void */ function admilogu_add_menu() { add_menu_page( __('Admin Login Guard & Branding', 'admin-login-guard-branding'), __('Login Guard & Branding', 'admin-login-guard-branding'), 'manage_options', 'admilogu-settings', 'admilogu_settings_page', 'dashicons-lock' ); } add_action('admin_menu', 'admilogu_add_menu'); /** * Check whether another plugin is altering the login URL. * * Temporarily unhooks this plugin's own `login_url` and `site_url` * filters, calls `wp_login_url()`, and inspects the result. If * `wp-login.php` is absent from the URL, another plugin is * interfering. * * @since 1.0.0 * * @return string|false The conflicting URL if detected, false otherwise. */ function admilogu_check_login_url_conflict() { // Remove our filters temporarily remove_filter('login_url', 'admilogu_filter_login_url', 10); remove_filter('site_url', 'admilogu_filter_site_url', 10); $login_url = wp_login_url(); // Add them back add_filter('login_url', 'admilogu_filter_login_url', 10, 3); add_filter('site_url', 'admilogu_filter_site_url', 10, 4); // If wp-login.php is NOT in the URL, someone else changed it if (strpos($login_url, 'wp-login.php') === false) { return $login_url; } return false; } /** * Display a dismissible admin notice when a login-URL conflict is found. * * Only shown to users with the `manage_options` capability. * * @since 1.0.0 * * @return void */ function admilogu_admin_notice_conflict() { if (!current_user_can('manage_options')) { return; } if (admilogu_check_login_url_conflict()) { ?>