| 1 |
<?php |
| 2 |
/** |
| 3 |
* The Jetpack Connection package Urls class file. |
| 4 |
* |
| 5 |
* @package automattic/jetpack-connection |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace Automattic\Jetpack\Connection; |
| 9 |
|
| 10 |
use Automattic\Jetpack\Constants; |
| 11 |
|
| 12 |
/** |
| 13 |
* Provides Url methods for the Connection package. |
| 14 |
*/ |
| 15 |
class Urls { |
| 16 |
|
| 17 |
const HTTPS_CHECK_OPTION_PREFIX = 'jetpack_sync_https_history_'; |
| 18 |
const HTTPS_CHECK_HISTORY = 5; |
| 19 |
|
| 20 |
/** |
| 21 |
* Return URL from option or PHP constant. |
| 22 |
* |
| 23 |
* @param string $option_name (e.g. 'home'). |
| 24 |
* |
| 25 |
* @return mixed|null URL. |
| 26 |
*/ |
| 27 |
public static function get_raw_url( $option_name ) { |
| 28 |
$value = null; |
| 29 |
$constant = ( 'home' === $option_name ) |
| 30 |
? 'WP_HOME' |
| 31 |
: 'WP_SITEURL'; |
| 32 |
|
| 33 |
// Since we disregard the constant for multisites in ms-default-filters.php, |
| 34 |
// let's also use the db value if this is a multisite. |
| 35 |
if ( ! is_multisite() && Constants::is_defined( $constant ) ) { |
| 36 |
$value = Constants::get_constant( $constant ); |
| 37 |
} else { |
| 38 |
// Let's get the option from the database so that we can bypass filters. This will help |
| 39 |
// ensure that we get more uniform values. |
| 40 |
$value = \Jetpack_Options::get_raw_option( $option_name ); |
| 41 |
} |
| 42 |
|
| 43 |
return $value; |
| 44 |
} |
| 45 |
|
| 46 |
/** |
| 47 |
* Normalize domains by removing www unless declared in the site's option. |
| 48 |
* |
| 49 |
* @param string $option Option value from the site. |
| 50 |
* @param callable $url_function Function retrieving the URL to normalize. |
| 51 |
* @return mixed|string URL. |
| 52 |
*/ |
| 53 |
public static function normalize_www_in_url( $option, $url_function ) { |
| 54 |
$url = wp_parse_url( call_user_func( $url_function ) ); |
| 55 |
$option_url = wp_parse_url( get_option( $option ) ); |
| 56 |
|
| 57 |
if ( ! $option_url || ! $url ) { |
| 58 |
return $url; |
| 59 |
} |
| 60 |
|
| 61 |
if ( "www.{$option_url[ 'host' ]}" === $url['host'] ) { |
| 62 |
// remove www if not present in option URL. |
| 63 |
$url['host'] = $option_url['host']; |
| 64 |
} |
| 65 |
if ( "www.{$url[ 'host' ]}" === $option_url['host'] ) { |
| 66 |
// add www if present in option URL. |
| 67 |
$url['host'] = $option_url['host']; |
| 68 |
} |
| 69 |
|
| 70 |
$normalized_url = "{$url['scheme']}://{$url['host']}"; |
| 71 |
if ( isset( $url['path'] ) ) { |
| 72 |
$normalized_url .= "{$url['path']}"; |
| 73 |
} |
| 74 |
|
| 75 |
if ( isset( $url['query'] ) ) { |
| 76 |
$normalized_url .= "?{$url['query']}"; |
| 77 |
} |
| 78 |
|
| 79 |
return $normalized_url; |
| 80 |
} |
| 81 |
|
| 82 |
/** |
| 83 |
* Return URL with a normalized protocol. |
| 84 |
* |
| 85 |
* @param string $callable Function name that was used to retrieve URL option. |
| 86 |
* @param string $new_value URL Protocol to set URLs to. |
| 87 |
* @return string Normalized URL. |
| 88 |
*/ |
| 89 |
public static function get_protocol_normalized_url( $callable, $new_value ) { |
| 90 |
$option_key = self::HTTPS_CHECK_OPTION_PREFIX . $callable; |
| 91 |
|
| 92 |
$parsed_url = wp_parse_url( $new_value ); |
| 93 |
|
| 94 |
if ( ! $parsed_url ) { |
| 95 |
return $new_value; |
| 96 |
} |
| 97 |
if ( array_key_exists( 'scheme', $parsed_url ) ) { |
| 98 |
$scheme = $parsed_url['scheme']; |
| 99 |
} else { |
| 100 |
$scheme = ''; |
| 101 |
} |
| 102 |
$scheme_history = get_option( $option_key, array() ); |
| 103 |
|
| 104 |
if ( ! is_array( $scheme_history ) ) { |
| 105 |
$scheme_history = array(); |
| 106 |
} |
| 107 |
|
| 108 |
$scheme_history[] = $scheme; |
| 109 |
|
| 110 |
// Limit length to self::HTTPS_CHECK_HISTORY. |
| 111 |
$scheme_history = array_slice( $scheme_history, ( self::HTTPS_CHECK_HISTORY * -1 ) ); |
| 112 |
|
| 113 |
update_option( $option_key, $scheme_history ); |
| 114 |
|
| 115 |
$forced_scheme = in_array( 'https', $scheme_history, true ) ? 'https' : 'http'; |
| 116 |
|
| 117 |
return set_url_scheme( $new_value, $forced_scheme ); |
| 118 |
} |
| 119 |
|
| 120 |
/** |
| 121 |
* Helper function that is used when getting home or siteurl values. Decides |
| 122 |
* whether to get the raw or filtered value. |
| 123 |
* |
| 124 |
* @param string $url_type URL to get, home or siteurl. |
| 125 |
* @return string |
| 126 |
*/ |
| 127 |
public static function get_raw_or_filtered_url( $url_type ) { |
| 128 |
$url_function = ( 'home' === $url_type ) |
| 129 |
? 'home_url' |
| 130 |
: 'site_url'; |
| 131 |
|
| 132 |
if ( |
| 133 |
! Constants::is_defined( 'JETPACK_SYNC_USE_RAW_URL' ) || |
| 134 |
Constants::get_constant( 'JETPACK_SYNC_USE_RAW_URL' ) |
| 135 |
) { |
| 136 |
$scheme = is_ssl() ? 'https' : 'http'; |
| 137 |
$url = (string) self::get_raw_url( $url_type ); |
| 138 |
$url = set_url_scheme( $url, $scheme ); |
| 139 |
} else { |
| 140 |
$url = self::normalize_www_in_url( $url_type, $url_function ); |
| 141 |
} |
| 142 |
|
| 143 |
return self::get_protocol_normalized_url( $url_function, $url ); |
| 144 |
} |
| 145 |
|
| 146 |
/** |
| 147 |
* Return the escaped home_url. |
| 148 |
* |
| 149 |
* @return string |
| 150 |
*/ |
| 151 |
public static function home_url() { |
| 152 |
$url = self::get_raw_or_filtered_url( 'home' ); |
| 153 |
|
| 154 |
/** |
| 155 |
* Allows overriding of the home_url value that is synced back to WordPress.com. |
| 156 |
* |
| 157 |
* @since 1.7.0 |
| 158 |
* @since-jetpack 5.2.0 |
| 159 |
* |
| 160 |
* @param string $home_url |
| 161 |
*/ |
| 162 |
return esc_url_raw( apply_filters( 'jetpack_sync_home_url', $url ) ); |
| 163 |
} |
| 164 |
|
| 165 |
/** |
| 166 |
* Return the escaped siteurl. |
| 167 |
* |
| 168 |
* @return string |
| 169 |
*/ |
| 170 |
public static function site_url() { |
| 171 |
$url = self::get_raw_or_filtered_url( 'siteurl' ); |
| 172 |
|
| 173 |
/** |
| 174 |
* Allows overriding of the site_url value that is synced back to WordPress.com. |
| 175 |
* |
| 176 |
* @since 1.7.0 |
| 177 |
* @since-jetpack 5.2.0 |
| 178 |
* |
| 179 |
* @param string $site_url |
| 180 |
*/ |
| 181 |
return esc_url_raw( apply_filters( 'jetpack_sync_site_url', $url ) ); |
| 182 |
} |
| 183 |
|
| 184 |
/** |
| 185 |
* Return main site URL with a normalized protocol. |
| 186 |
* |
| 187 |
* @return string |
| 188 |
*/ |
| 189 |
public static function main_network_site_url() { |
| 190 |
return self::get_protocol_normalized_url( 'main_network_site_url', network_site_url() ); |
| 191 |
} |
| 192 |
|
| 193 |
/** |
| 194 |
* Maybe add the origin_site_id query parameter to a URL. |
| 195 |
* |
| 196 |
* The parameter is only added for users who are members of the current blog. |
| 197 |
* |
| 198 |
* @since 7.1.0 |
| 199 |
* |
| 200 |
* @param string $url The URL to add the query param to. |
| 201 |
* @return string The URL with the origin_site_id query parameter maybe added. |
| 202 |
*/ |
| 203 |
public static function maybe_add_origin_site_id( $url ) { |
| 204 |
$site_id = Manager::get_site_id(); |
| 205 |
if ( is_wp_error( $site_id ) ) { |
| 206 |
return $url; |
| 207 |
} |
| 208 |
|
| 209 |
// Add query param to URL only for users who can access wp-admin. |
| 210 |
if ( ! is_user_member_of_blog() ) { |
| 211 |
return $url; |
| 212 |
} |
| 213 |
|
| 214 |
return add_query_arg( 'origin_site_id', $site_id, $url ); |
| 215 |
} |
| 216 |
} |
| 217 |
|