PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.2
4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Utils / Urls.php
wp-staging / Framework / Utils Last commit date
Cache 7 months ago DBPermissions.php 9 months ago DataEncoder.php 10 months ago DatabaseOptions.php 2 weeks ago Escape.php 9 months ago Glob.php 2 years ago Hooks.php 2 months ago Math.php 9 months ago PluginInfo.php 5 months ago Sanitize.php 2 months ago ServerVars.php 2 years ago SlashMode.php 5 years ago Strings.php 7 months ago Times.php 5 months ago Urls.php 2 weeks ago Version.php 1 year ago WpDefaultDirectories.php 2 years ago
Urls.php
198 lines
1 <?php
2
3 namespace WPStaging\Framework\Utils;
4
5 use WPStaging\Backup\Service\BackupsDirectoryResolver;
6 use WPStaging\Core\WPStaging;
7
8 /**
9 * Resolves public URLs for WordPress and WP STAGING resources
10 */
11 class Urls
12 {
13 /**
14 * Retrieves the URL for a given site where the front end is accessible.
15 *
16 * Returns the 'home' option with the appropriate protocol. The protocol will be 'https'
17 * if is_ssl() evaluates to true; otherwise, it will be the same as the 'home' option.
18 * If `$scheme` is 'http' or 'https', is_ssl() is overridden.
19 * @param int|null $blogId
20 * @param string|null $scheme
21 * @return string
22 */
23 public function getHomeUrl($blogId = null, $scheme = null): string
24 {
25 if (empty($blogId) || !is_multisite()) {
26 $url = get_option('home');
27 } else {
28 switch_to_blog($blogId);
29 $url = get_option('home');
30 restore_current_blog();
31 }
32
33 if (!in_array($scheme, ['http', 'https', 'relative'])) {
34 if (is_ssl()) {
35 $scheme = 'https';
36 } else {
37 $scheme = parse_url($url, PHP_URL_SCHEME);
38 }
39 }
40
41 return set_url_scheme($url, $scheme);
42 }
43
44 /**
45 * Return WordPress home url without scheme e.h. host.com or www.host.com
46 * @return string
47 */
48 public function getHomeUrlWithoutScheme(): string
49 {
50 return preg_replace('#^https?://#', '', rtrim($this->getHomeUrl(), '/'));
51 }
52
53 /**
54 * Retrieves the URL for a given site where the front end is accessible.
55 *
56 * Returns the 'home' option with the appropriate protocol. The protocol will be 'https'
57 * if is_ssl() evaluates to true; otherwise, it will be the same as the 'home' option.
58 * If `$scheme` is 'http' or 'https', is_ssl() is overridden.
59 * @param int|null $blogId
60 * @param string|null $scheme
61 * @return string
62 */
63 public function getSiteUrl($blogId = null, $scheme = null): string
64 {
65 if (empty($blogId) || !is_multisite()) {
66 $url = get_option('siteurl');
67 } else {
68 switch_to_blog($blogId);
69 $url = get_option('siteurl');
70 restore_current_blog();
71 }
72
73 if (!in_array($scheme, ['http', 'https', 'relative'])) {
74 if ($this->sslAvailable()) {
75 $scheme = 'https';
76 } else {
77 $scheme = parse_url($url, PHP_URL_SCHEME);
78 }
79 }
80
81 return set_url_scheme($url, $scheme);
82 }
83
84 /**
85 * Get raw base URL e.g. https://blog.domain.com or https://domain.com without any subfolder
86 * @return string
87 */
88 public function getBaseUrl(): string
89 {
90 $result = parse_url($this->getHomeUrl());
91 return $result['scheme'] . "://" . $result['host'];
92 }
93
94 /**
95 * Return base URL (domain) without scheme e.g. blog.domain.com or domain.com
96 * @return string
97 */
98 public function getBaseUrlWithoutScheme(): string
99 {
100 return preg_replace('#^https?://#', '', rtrim($this->getBaseUrl(), '/'));
101 }
102
103 /**
104 * Get hostname of production site including scheme
105 * @return string
106 */
107 public function getProductionHostname(): string
108 {
109 $connection = get_option('wpstg_connection');
110 // Get the stored hostname
111 if (!empty($connection['prodHostname'])) {
112 return $connection['prodHostname'];
113 }
114
115 // Default. Try to get the hostname from the main domain (Workaround for WP Staging Pro older < 2.9.1)
116 $siteurl = get_site_url();
117 $result = parse_url($siteurl);
118 return $result['scheme'] . "://" . $result['host'];
119 }
120
121 /**
122 * Get url of the uploads directory, e.g. http://example.com/wp-content/uploads
123 * @return string
124 */
125 public function getUploadsUrl(): string
126 {
127 $upload_dir = wp_upload_dir(null, false, false);
128 return trailingslashit($upload_dir['baseurl']);
129 }
130
131 /**
132 * Get url of the backup directory, e.g. http://example.com/wp-content/uploads/wp-staging/backups/
133 *
134 * @return string
135 */
136 public function getBackupUrl(): string
137 {
138 $uploads = wp_upload_dir(null, false);
139 $backupsDirResolver = WPStaging::make(BackupsDirectoryResolver::class);
140 $normalizedBackupPath = $backupsDirResolver->resolveFromUploadsDirectory($uploads['basedir']);
141 $normalizedUploadsDir = trailingslashit(wp_normalize_path($uploads['basedir']));
142
143 if (strpos($normalizedBackupPath, $normalizedUploadsDir) === 0) {
144 $relativePath = substr($normalizedBackupPath, strlen($normalizedUploadsDir));
145 return trailingslashit($this->maybeUseProtocolRelative($uploads['baseurl'])) . ltrim($relativePath, '/');
146 }
147
148 $normalizedWpContentDir = trailingslashit(wp_normalize_path(WP_CONTENT_DIR));
149 if (strpos($normalizedBackupPath, $normalizedWpContentDir) === 0) {
150 $relativePath = substr($normalizedBackupPath, strlen($normalizedWpContentDir));
151 return trailingslashit($this->maybeUseProtocolRelative(content_url())) . ltrim($relativePath, '/');
152 }
153
154 $normalizedAbspath = trailingslashit(wp_normalize_path(ABSPATH));
155 $relativePath = $normalizedBackupPath;
156 if (strpos($normalizedBackupPath, $normalizedAbspath) === 0) {
157 $relativePath = substr($normalizedBackupPath, strlen($normalizedAbspath));
158 }
159
160 $siteurl = $this->maybeUseProtocolRelative(get_option('siteurl'));
161
162 return trailingslashit($siteurl) . ltrim($relativePath, '/');
163 }
164
165 /** @return bool */
166 public function sslAvailable(): bool
167 {
168 // Cloudflare
169 if (!empty($_SERVER['HTTP_CF_VISITOR'])) {
170 // phpcs:ignore WPStagingCS.Security.SanitizeInput.InputNotSanitized
171 $cfo = json_decode($_SERVER['HTTP_CF_VISITOR']);
172 if (isset($cfo->scheme) && $cfo->scheme === 'https') {
173 return true;
174 }
175 }
176
177 // Other proxy
178 if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
179 return true;
180 }
181
182 return is_ssl();
183 }
184
185 /**
186 * @param string $url
187 * @return string
188 */
189 public function maybeUseProtocolRelative(string $url): string
190 {
191 if ($this->sslAvailable() && substr($url, 0, 7) === 'http://') {
192 $url = preg_replace('@^http://@', '//', $url);
193 }
194
195 return $url;
196 }
197 }
198