HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.31
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/wp-cloud-client/previous/src/Multisite/DomainProtector.php
<?php

declare(strict_types=1);

namespace VPlugins\WPCloudClient\Multisite;

/**
 * Prevents users from changing the base domain of a multisite sub-site.
 *
 * Injects JavaScript on the network-admin site-edit screen that intercepts
 * the form submission and blocks any attempt to change the site's base domain.
 * DNS and SSL are bound to the base domain, so any change there would break
 * all sub-sites.
 *
 * Based on the wsp-bootstrapper RestrictDomainEditAddon implementation.
 */
final class DomainProtector {

	/**
	 * Register WordPress hooks.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action( 'admin_enqueue_scripts', [ $this, 'maybeInjectScript' ] );
	}

	/**
	 * Conditionally inject the domain-protection script on the site-edit screen.
	 *
	 * Reads the site ID from the query string, fetches the current domain from
	 * the database, and registers an admin_print_footer_scripts closure that
	 * outputs the validation JS.
	 *
	 * @return void
	 */
	public function maybeInjectScript(): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only: determines which site to protect.
		$siteId = isset( $_GET['id'] ) ? (int) sanitize_text_field( wp_unslash( (string) $_GET['id'] ) ) : 0;

		if ( ! $siteId || ! is_multisite() || ! function_exists( 'get_site' ) ) {
			return;
		}

		$site = get_site( $siteId );

		if ( ! $site || empty( $site->domain ) ) {
			return;
		}

		$scheme = is_ssl() ? 'https' : 'http';
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- used only for port comparison, not output.
		$port = isset( $_SERVER['SERVER_PORT'] ) ? (int) $_SERVER['SERVER_PORT'] : 0;
		$host = $site->domain;
		$base = $scheme . '://' . $host;

		if ( $port && 80 !== $port && 443 !== $port && false === strpos( $host, ':' ) ) {
			$base .= ':' . $port;
		}

		$baseJs = esc_js( $base );

		add_action(
			'admin_print_footer_scripts',
			static function () use ( $baseJs ): void {
				?>
				<script>
				(function($){
					$(function(){
						const $urlField  = $('#url');
						const baseDomain = "<?php echo $baseJs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- already escaped via esc_js() above. ?>";

						const $errorMsg = $('<div id="wpcc-url-error-msg" style="color:red;margin-top:4px;display:none;"></div>');
						if ( ! $('#wpcc-url-error-msg').length ) {
							$urlField.after( $errorMsg );
						}

						$('form').on('submit', function(e) {
							const submitted = $urlField.val().trim();
							let submittedBase = '';

							$urlField.css({ border: '', backgroundColor: '' });
							$errorMsg.hide().text('');

							try {
								const parsed = new URL(submitted);
								submittedBase = parsed.origin;
							} catch (err) {
								e.preventDefault();
								$urlField.css({ border: '2px solid red', backgroundColor: '#ffe6e6' });
								$errorMsg.text('<?php echo esc_js( __( 'Invalid URL format.', 'wp-cloud-client' ) ); ?>').show();
								return;
							}

							if ( submittedBase !== baseDomain ) {
								e.preventDefault();
								$urlField.css({ border: '2px solid red' });
								$errorMsg.text('<?php echo esc_js( __( 'Changing the base domain is not allowed.', 'wp-cloud-client' ) ); ?>').show();
								$urlField.focus();
							}
						});
					});
				})(jQuery);
				</script>
				<?php
			}
		);
	}
}