diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 6de20675c0246..168863cdb6421 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -84,7 +84,7 @@ jobs: run: echo "::set-output name=date::$(/bin/date -u --date='last Mon' "+%F")" - name: Cache PHPCS scan cache - uses: actions/cache@136d96b4aee02b1f0de3ba493b1d47135042d9c0 # v3.0.1 + uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 with: path: .cache/phpcs.json key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', 'phpcs.xml.dist') }} diff --git a/.github/workflows/php-compatibility.yml b/.github/workflows/php-compatibility.yml index 79f5d97de58f6..1db95deb63696 100644 --- a/.github/workflows/php-compatibility.yml +++ b/.github/workflows/php-compatibility.yml @@ -78,7 +78,7 @@ jobs: run: echo "::set-output name=date::$(/bin/date -u --date='last Mon' "+%F")" - name: Cache PHP compatibility scan cache - uses: actions/cache@136d96b4aee02b1f0de3ba493b1d47135042d9c0 # v3.0.1 + uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 with: path: .cache/phpcompat.json key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcompat-cache-${{ hashFiles('**/composer.json', 'phpcompat.xml.dist') }} diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 578ebc6adf2b4..cc8bd5f190344 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -132,7 +132,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache Composer dependencies - uses: actions/cache@136d96b4aee02b1f0de3ba493b1d47135042d9c0 # v3.0.1 + uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 env: cache-name: cache-composer-dependencies with: diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml index f1b08567cd257..d1b9aae94ac54 100644 --- a/.github/workflows/test-coverage.yml +++ b/.github/workflows/test-coverage.yml @@ -96,7 +96,7 @@ jobs: run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache Composer dependencies - uses: actions/cache@136d96b4aee02b1f0de3ba493b1d47135042d9c0 # v3.0.1 + uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 env: cache-name: cache-composer-dependencies with: diff --git a/src/wp-admin/includes/network.php b/src/wp-admin/includes/network.php index ae3e906fccd23..9fbd857e965e3 100644 --- a/src/wp-admin/includes/network.php +++ b/src/wp-admin/includes/network.php @@ -138,7 +138,10 @@ function network_step1( $errors = false ) { $hostname = get_clean_basedomain(); $has_ports = strstr( $hostname, ':' ); - if ( ( false !== $has_ports && ! in_array( $has_ports, array( ':80', ':443' ), true ) ) ) { + /** This filter is documented in wp-includes/ms-settings.php */ + $allowed_ports = apply_filters( 'allowed_multisite_ports', array( ':80', ':443' ) ); + + if ( ( false !== $has_ports && is_array( $allowed_ports ) && ! in_array( $has_ports, $allowed_ports, true ) ) ) { echo '

' . __( 'Error:' ) . ' ' . __( 'You cannot install a network of sites with your server address.' ) . '

'; echo '

' . sprintf( /* translators: %s: Port number. */ @@ -179,7 +182,7 @@ function network_step1( $errors = false ) { } ?>

-

+

' . substr( $hostname, 4 ) . '', '' . $hostname . '', 'www' @@ -444,7 +447,7 @@ function network_step2( $errors = false ) { echo '' . __( 'Caution:' ) . ' '; printf( /* translators: 1: wp-config.php, 2: .htaccess */ - __( 'You should back up your existing %1$s and %2$s files.' ), + __( 'We recommend you back up your existing %1$s and %2$s files.' ), 'wp-config.php', '.htaccess' ); @@ -452,7 +455,7 @@ function network_step2( $errors = false ) { echo '' . __( 'Caution:' ) . ' '; printf( /* translators: 1: wp-config.php, 2: web.config */ - __( 'You should back up your existing %1$s and %2$s files.' ), + __( 'We recommend you back up your existing %1$s and %2$s files.' ), 'wp-config.php', 'web.config' ); @@ -460,7 +463,7 @@ function network_step2( $errors = false ) { echo '' . __( 'Caution:' ) . ' '; printf( /* translators: %s: wp-config.php */ - __( 'You should back up your existing %s file.' ), + __( 'We recommend you back up your existing %s file.' ), 'wp-config.php' ); } diff --git a/src/wp-includes/ms-settings.php b/src/wp-includes/ms-settings.php index 6824895880f8b..1df500afa8968 100644 --- a/src/wp-includes/ms-settings.php +++ b/src/wp-includes/ms-settings.php @@ -54,15 +54,23 @@ // have not been populated in the global scope through something like `sunrise.php`. if ( ! isset( $current_site ) || ! isset( $current_blog ) ) { - $domain = strtolower( stripslashes( $_SERVER['HTTP_HOST'] ) ); - if ( ':80' === substr( $domain, -3 ) ) { - $domain = substr( $domain, 0, -3 ); - $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 ); - } elseif ( ':443' === substr( $domain, -4 ) ) { - $domain = substr( $domain, 0, -4 ); - $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 ); + /** + * Filters allowed HTTP ports in Multisite. + * + * @since 6.0.0 + * @param array $allowed_ports The allowed ports. Default is [ ':80', ':443' ]. + */ + $allowed_ports = apply_filters( 'allowed_multisite_ports', array( ':80', ':443' ) ); + + if ( is_array( $allowed_ports ) ) { + foreach ( $allowed_ports as $allowed_port ) { + $str_length = strlen( $allowed_port ); + if ( str_ends_with( $domain, $allowed_port ) ) { + $domain = substr( $domain, 0, - $str_length ); + $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, - $str_length ); + } + } } - $path = stripslashes( $_SERVER['REQUEST_URI'] ); if ( is_admin() ) { $path = preg_replace( '#(.*)/wp-admin/.*#', '$1/', $path ); diff --git a/src/wp-includes/ms-site.php b/src/wp-includes/ms-site.php index cdce8ff03381a..ed94bc95d83c5 100644 --- a/src/wp-includes/ms-site.php +++ b/src/wp-includes/ms-site.php @@ -503,7 +503,17 @@ function wp_normalize_site_data( $data ) { // Sanitize domain if passed. if ( array_key_exists( 'domain', $data ) ) { $data['domain'] = trim( $data['domain'] ); + $has_ports = strstr( $data['domain'], ':' ); + + // Remove ports. + $data['domain'] = preg_replace( '|:\d+$|', '', $data['domain'] ); $data['domain'] = preg_replace( '/\s+/', '', sanitize_user( $data['domain'], true ) ); + /** This filter is documented in wp-includes/ms-settings.php */ + $allowed_ports = apply_filters( 'allowed_multisite_ports', array( ':80', ':443' ) ); + if ( ( false !== $has_ports && is_array( $allowed_ports ) && in_array( $has_ports, $allowed_ports, true ) ) ) { + $data['domain'] .= $has_ports; + } + if ( is_subdomain_install() ) { $data['domain'] = str_replace( '@', '', $data['domain'] ); } diff --git a/tests/phpunit/tests/multisite/site.php b/tests/phpunit/tests/multisite/site.php index e2d4d78ddb98b..b25f54dbaee41 100644 --- a/tests/phpunit/tests/multisite/site.php +++ b/tests/phpunit/tests/multisite/site.php @@ -1603,6 +1603,12 @@ public function action_wp_validate_site_deletion_prevent_deletion( $errors ) { * @dataProvider data_wp_normalize_site_data */ public function test_wp_normalize_site_data( $data, $expected ) { + add_filter( + 'allowed_multisite_ports', + function( $ports ) { + return array( ':80', ':443', ':8080' ); + } + ); $result = wp_normalize_site_data( $data ); $this->assertSameSetsWithIndex( $expected, $result ); @@ -1674,6 +1680,30 @@ public function data_wp_normalize_site_data() { ), array(), ), + array( + array( + 'domain' => 'domainwithport.com:443', + ), + array( + 'domain' => 'domainwithport.com:443', + ), + ), + array( + array( + 'domain' => 'anotherdomainwithport.com:80', + ), + array( + 'domain' => 'anotherdomainwithport.com:80', + ), + ), + array( + array( + 'domain' => 'anotherwithport.com:8080', + ), + array( + 'domain' => 'anotherwithport.com:8080', + ), + ), ); }