url = $url; } /** * Normalize a possibly relative URL. * * @param string $url Relative or absolute URL. * @param string|null $base_url Base URL. * * @return string */ public static function normalize( string $url, ?string $base_url = null ): string { if ( '' === $url || ! isset( $base_url ) ) { return $url; } $parts = wp_parse_url( $url ); if ( isset( $parts['host'] ) ) { return $url; } $is_root_relative = isset( $parts['path'] ) && str_starts_with( $parts['path'], '/' ); $base_parts = wp_parse_url( $base_url ); if ( $is_root_relative ) { $base_parts['path'] = $parts['path']; } elseif ( isset( $parts['path'] ) ) { if ( isset( $base_parts['path'] ) && str_ends_with( $base_parts['path'], '/' ) ) { $base_parts['path'] .= $parts['path']; } elseif ( isset( $base_parts['path'] ) ) { $last_segment_at = strrpos( $base_parts['path'], '/' ); $base_parts['path'] = substr( $base_parts['path'], 0, $last_segment_at + 1 ) . $parts['path']; } } foreach ( [ 'query', 'fragment' ] as $part ) { if ( isset( $parts[ $part ] ) ) { $base_parts[ $part ] = $parts[ $part ]; } } $normalized = ''; if ( isset( $base_parts['scheme'] ) ) { $normalized .= $base_parts['scheme'] . '://'; } if ( isset( $base_parts['user'] ) || isset( $base_parts['pass'] ) ) { if ( isset( $base_parts['user'], $base_parts['pass'] ) ) { $normalized .= $base_parts['user'] . ':' . $base_parts['pass'] . '@'; } elseif ( isset( $base_parts['user'] ) ) { $normalized .= $base_parts['user'] . '@'; } else { $normalized .= ':' . $base_parts['pass'] . '@'; } } if ( isset( $base_parts['host'] ) ) { $normalized .= $base_parts['host']; } if ( isset( $base_parts['port'] ) ) { $normalized .= ':' . $base_parts['port']; } if ( isset( $base_parts['path'] ) ) { $normalized .= $base_parts['path']; } if ( isset( $base_parts['query'] ) ) { $normalized .= '?' . $base_parts['query']; } if ( isset( $base_parts['fragment'] ) ) { $normalized .= '#' . $base_parts['fragment']; } return $normalized; } }