From bbb5d42b9f1c3d8be64135e4d896f1809a503193 Mon Sep 17 00:00:00 2001 From: Chirag Mathur Date: Tue, 30 Sep 2025 14:01:43 +0530 Subject: [PATCH 01/11] Refactored the code to have centralised network settings --- src/Container.php | 4 +- src/Modules/Settings.php | 636 ++++++++++++++++++++++++++++++++------- 2 files changed, 524 insertions(+), 116 deletions(-) diff --git a/src/Container.php b/src/Container.php index 8ce01d65..762bbcc9 100644 --- a/src/Container.php +++ b/src/Container.php @@ -116,8 +116,8 @@ public function define_services(): void { return new GoogleClient( [ - 'client_id' => $settings->client_id, - 'client_secret' => $settings->client_secret, + 'client_id' => $settings->get_client_id(), + 'client_secret' => $settings->get_client_secret(), 'redirect_uri' => wp_login_url(), ] ); diff --git a/src/Modules/Settings.php b/src/Modules/Settings.php index 71215273..704da6ca 100644 --- a/src/Modules/Settings.php +++ b/src/Modules/Settings.php @@ -15,30 +15,23 @@ use RtCamp\GoogleLogin\Interfaces\Module as ModuleInterface; /** - * Class Settings. - * - * @property string|null whitelisted_domains - * @property string|null client_id - * @property string|null client_secret - * @property bool|null registration_enabled - * @property bool|null one_tap_login - * @property string one_tap_login_screen + * Class Settings * * @package RtCamp\GoogleLogin\Modules */ class Settings implements ModuleInterface { /** - * Settings values. + * Options array. * * @var array */ public $options; /** - * Getters for settings values. + * List of getters for settings. * - * @var string[] + * @var array */ private $getters = [ 'WP_GOOGLE_LOGIN_CLIENT_ID' => 'client_id', @@ -50,14 +43,15 @@ class Settings implements ModuleInterface { ]; /** - * Getter method. + * Magic getter to access settings as properties. + * + * @param string $name Name of the property. * - * @param string $name Name of option to fetch. + * @return mixed */ public function __get( string $name ) { if ( in_array( $name, $this->getters, true ) ) { $constant_name = array_search( $name, $this->getters, true ); - return defined( $constant_name ) ? constant( $constant_name ) : ( $this->options[ $name ] ?? '' ); } @@ -65,75 +59,317 @@ public function __get( string $name ) { } /** - * Return module name. + * Name of the module. * * @return string */ public function name(): string { - return 'settings'; - } + return 'settings'; } /** - * Initialization of module. - * - * @return void + * Initializes the settings module. */ public function init(): void { $this->options = get_option( 'wp_google_login_settings', [] ); - /** - * Actions. - */ add_action( 'admin_init', [ $this, 'register_settings' ] ); add_action( 'admin_menu', [ $this, 'settings_page' ] ); - /** - * Filters. - */ - // Add filters here. + if ( is_multisite() ) { + add_action( 'network_admin_menu', [ $this, 'register_network_settings_page' ] ); + add_action( 'network_admin_menu', [ $this, 'register_network_settings' ] ); + add_action( 'network_admin_edit_wp_google_login_network_settings', [ $this, 'save_network_settings' ] ); + } + } + + /** + * Retrieves the Google OAuth Client ID, respecting multisite/global settings. + * + * @return string + */ + public function get_client_id() { + if ( is_multisite() ) { + $network_settings = get_site_option( 'wp_google_login_network_settings', [] ); + + if ( ! empty( $network_settings['apply_globally'] ) && ! empty( $network_settings['client_id'] ) ) { + return $network_settings['client_id']; + } + } + + return $this->client_id; } /** - * Register the settings, section and fields. + * Retrieves the Google OAuth Client Secret, respecting multisite/global settings. + * + * @return string + */ + public function get_client_secret() { + if ( is_multisite() ) { + $network_settings = get_site_option( 'wp_google_login_network_settings', [] ); + + if ( ! empty( $network_settings['apply_globally'] ) && ! empty( $network_settings['client_secret'] ) ) { + return $network_settings['client_secret']; + } + } + + return $this->client_secret; + } + + /** + * Registers the network settings page for multisite installations. * * @return void */ - public function register_settings(): void { - register_setting( 'wp_google_login', 'wp_google_login_settings' ); + public function register_network_settings_page(): void { + add_submenu_page( + 'settings.php', + __( 'Login with Google Network Settings', 'login-with-google' ), + __( 'Login with Google', 'login-with-google' ), + 'manage_network_options', + 'login-with-google-network', + [ $this, 'output_network_settings' ] + ); + } + + /** + * Outputs the network settings page HTML. + */ + public function output_network_settings(): void { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( isset( $_GET['updated'] ) ) { + echo '

' . esc_html__( 'Settings saved.', 'login-with-google' ) . '

'; + } + ?> +
+

+
+ +
+
+ 'client-id' ] + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'client-id', + ] ); add_settings_field( 'wp_google_login_client_secret', __( 'Client Secret', 'login-with-google' ), [ $this, 'client_secret_field' ], - 'login-with-google', + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'client-secret', + ] + ); + + add_settings_field( + 'wp_google_login_apply_globally', + __( 'Apply settings to all sites in the network', 'login-with-google' ), + [ $this, 'apply_globally_field' ], + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'apply-globally', + ] + ); + + add_settings_field( + 'wp_google_allow_registration', + __( 'Create New User', 'login-with-google' ), + [ $this, 'user_registration' ], + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'user-registration', + ] + ); + + add_settings_field( + 'wp_google_one_tap_login', + __( 'Enable One Tap Login', 'login-with-google' ), + [ $this, 'one_tap_login' ], + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'one-tap-login', + ] + ); + + add_settings_field( + 'wp_google_one_tap_login_screen', + __( 'One Tap Login Locations', 'login-with-google' ), + [ $this, 'one_tap_login_screens' ], + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'one-tap-login-screen', + ] + ); + + add_settings_field( + 'wp_google_whitelisted_domain', + __( 'Whitelisted Domains', 'login-with-google' ), + [ $this, 'whitelisted_domains' ], + 'login-with-google-network', + 'wp_google_login_network_section', + [ + 'context' => 'network', + 'label_for' => 'whitelisted-domains', + ] + ); + } + + /** + * Saves the network settings for multisite installations. + * + * @return void + */ + public function save_network_settings() { + if ( ! current_user_can( 'manage_network_options' ) ) { + wp_die( esc_html__( 'Sorry, you are not allowed to manage network options.', 'login-with-google' ) ); + } + + check_admin_referer( 'wp_google_login_network-options' ); + + $defaults = [ + 'apply_globally' => 0, + 'one_tap_login' => 0, + 'registration_enabled' => 0, + 'one_tap_login_screen' => 'login', + 'whitelisted_domains' => '', + 'client_id' => '', + 'client_secret' => '', + ]; + + $settings = $_POST['wp_google_login_network_settings'] ?? []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + // Sanitize each field. + $sanitized_settings = [ + 'apply_globally' => isset( $settings['apply_globally'] ) ? 1 : 0, + 'one_tap_login' => isset( $settings['one_tap_login'] ) ? 1 : 0, + 'registration_enabled' => isset( $settings['registration_enabled'] ) ? 1 : 0, + 'one_tap_login_screen' => isset( $settings['one_tap_login_screen'] ) ? sanitize_text_field( $settings['one_tap_login_screen'] ) : 'login', + 'whitelisted_domains' => isset( $settings['whitelisted_domains'] ) ? sanitize_text_field( $settings['whitelisted_domains'] ) : '', + 'client_id' => isset( $settings['client_id'] ) ? sanitize_text_field( $settings['client_id'] ) : '', + 'client_secret' => isset( $settings['client_secret'] ) ? sanitize_text_field( $settings['client_secret'] ) : '', + ]; + + $settings = array_merge( $defaults, $sanitized_settings ); + + update_site_option( 'wp_google_login_network_settings', $settings ); + + wp_cache_delete( 'wp_google_login_network_settings', 'site-options' ); + + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'login-with-google-network', + 'updated' => 'true', + ], + network_admin_url( 'settings.php' ) + ) + ); + exit; + } + + /** + * Registers the settings for the single site installations. + * + * @return void + */ + public function register_settings(): void { + if ( is_multisite() && is_network_admin() ) { + return; + } + + register_setting( 'wp_google_login', 'wp_google_login_settings' ); + + add_settings_section( 'wp_google_login_section', - [ 'label_for' => 'client-secret' ] + __( 'Log in with Google Settings', 'login-with-google' ), + function () {}, + 'login-with-google' ); + if ( ! is_multisite() ) { + add_settings_field( + 'wp_google_login_client_id', + __( 'Client ID', 'login-with-google' ), + [ $this, 'client_id_field' ], + 'login-with-google', + 'wp_google_login_section', + [ 'label_for' => 'client-id' ] + ); + + add_settings_field( + 'wp_google_login_client_secret', + __( 'Client Secret', 'login-with-google' ), + [ $this, 'client_secret_field' ], + 'login-with-google', + 'wp_google_login_section', + [ 'label_for' => 'client-secret' ] + ); + } + + $apply_globally = false; + $network_settings = []; + + if ( is_multisite() ) { + $network_settings = get_site_option( 'wp_google_login_network_settings', [] ); + $apply_globally = ! empty( $network_settings['apply_globally'] ); + } + add_settings_field( 'wp_google_allow_registration', __( 'Create New User', 'login-with-google' ), [ $this, 'user_registration' ], 'login-with-google', 'wp_google_login_section', - [ 'label_for' => 'user-registration' ] + [ + 'readonly' => $apply_globally, + 'network_settings' => $network_settings, + 'label_for' => 'user-registration', + ] ); add_settings_field( @@ -142,7 +378,11 @@ function () { [ $this, 'one_tap_login' ], 'login-with-google', 'wp_google_login_section', - [ 'label_for' => 'one-tap-login' ] + [ + 'readonly' => $apply_globally, + 'network_settings' => $network_settings, + 'label_for' => 'one-tap-login', + ] ); add_settings_field( @@ -151,7 +391,11 @@ function () { [ $this, 'one_tap_login_screens' ], 'login-with-google', 'wp_google_login_section', - [ 'label_for' => 'one-tap-login-screen' ] + [ + 'readonly' => $apply_globally, + 'network_settings' => $network_settings, + 'label_for' => 'one-tap-login-screen', + ] ); add_settings_field( @@ -160,18 +404,30 @@ function () { [ $this, 'whitelisted_domains' ], 'login-with-google', 'wp_google_login_section', - [ 'label_for' => 'whitelisted-domains' ] + [ + 'readonly' => $apply_globally, + 'network_settings' => $network_settings, + 'label_for' => 'whitelisted-domains', + ] ); } /** - * Render client ID field. + * Renders the input field for the Client ID setting. + * + * @param array $args Additional arguments for the field. * * @return void */ - public function client_id_field(): void { + public function client_id_field( $args = [] ): void { + $is_network = isset( $args['context'] ) && 'network' === $args['context']; + $value = $is_network + ? ( get_site_option( 'wp_google_login_network_settings' )['client_id'] ?? '' ) + : $this->get_client_id(); // Use the robust getter! + $name = $is_network ? 'wp_google_login_network_settings[client_id]' : 'wp_google_login_settings[client_id]'; ?> - disabled( 'client_id' ); ?> /> + +

get_client_secret(); + $name = $is_network ? 'wp_google_login_network_settings[client_secret]' : 'wp_google_login_settings[client_secret]'; ?> - disabled( 'client_secret' ); ?> /> + + /> + General + * @param array $args Additional arguments for the field. * * @return void */ - public function user_registration(): void { + public function user_registration( $args = [] ): void { + $is_network = isset( $args['context'] ) && 'network' === $args['context']; + $readonly = ! empty( $args['readonly'] ); + $network_settings = $args['network_settings'] ?? []; + + if ( $is_network ) { + $checked = ! empty( get_site_option( 'wp_google_login_network_settings', [] )['registration_enabled'] ); + ?> + +

+ membership setting is off.', 'login-with-google' ), + 'network/settings.php' + ) + ); + ?> +

+ + /> + +