PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 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 / SiteInfo.php
wp-staging / Framework Last commit date
Adapter 1 day ago Analytics 1 day ago Assets 1 day ago BackgroundProcessing 1 day ago CloningProcess 1 day ago Collection 1 day ago Command 1 day ago Component 1 day ago DI 1 day ago Database 1 day ago DependencyResolver 1 day ago Exceptions 2 years ago Experiments 1 day ago Facades 1 day ago Filesystem 1 day ago Interfaces 1 day ago Job 1 day ago Language 1 day ago Logger 1 day ago Mails 1 day ago Network 1 day ago Newsfeed 1 day ago Notices 1 day ago Onboarding 1 day ago Performance 1 day ago Permalinks 1 day ago Queue 1 day ago Rest 1 day ago Security 1 day ago Settings 1 day ago TemplateEngine 1 day ago ThirdParty 1 day ago Traits 1 day ago Upgrade 1 day ago Utils 1 day ago AnalyticsServiceProvider.php 1 day ago AssetServiceProvider.php 1 year ago CommonServiceProvider.php 1 day ago ErrorHandler.php 1 day ago NoticeServiceProvider.php 1 year ago SettingsServiceProvider.php 4 months ago SiteInfo.php 1 day ago Url.php 1 day ago
SiteInfo.php
420 lines
1 <?php
2
3 namespace WPStaging\Framework;
4
5 use WPStaging\Framework\Facades\Hooks;
6 use WPStaging\Framework\Facades\Sanitize;
7 use WPStaging\Staging\CloneOptions;
8
9
10
11
12
13
14
15
16 class SiteInfo
17 {
18
19
20
21
22 const IS_CLONEABLE_KEY = 'isCloneable';
23
24
25
26
27
28
29 const CLONEABLE_FILE = '.wp-staging-cloneable';
30
31
32
33
34
35 const IS_STAGING_KEY = 'wpstg_is_staging_site';
36
37
38
39
40
41 const STAGING_FILE = '.wp-staging';
42
43
44 const HOSTED_ON_WP = 'wp.com';
45
46
47 const HOSTED_ON_FLYWHEEL = 'flywheel';
48
49
50 const HOSTED_ON_BITNAMI = 'bitnami';
51
52
53 const OTHER_HOST = 'other';
54
55
56
57
58
59
60
61 const LOCAL_HOSTNAME_SUFFIXES = [
62 '.local',
63 '.test',
64 '.localhost',
65 '.dev',
66 ];
67
68
69 const LOCAL_HOSTNAMES = [
70 'localhost',
71 ];
72
73
74 const LOCAL_IP_PREFIXES = [
75 '10.0.0.',
76 '172.16.0.',
77 '192.168.0.',
78 ];
79
80
81
82
83 private $cloneOptions;
84
85
86
87
88 private $errors = [];
89
90 public function __construct()
91 {
92
93 $this->cloneOptions = new CloneOptions();
94 }
95
96
97
98
99 public function isStagingSite(): bool
100 {
101
102 return wpstgIsStagingSite(self::STAGING_FILE, self::IS_STAGING_KEY);
103 }
104
105
106
107
108 public function isCloneable(): bool
109 {
110
111 if (!$this->isStagingSite()) {
112 return true;
113 }
114
115
116 if (file_exists(ABSPATH . self::CLONEABLE_FILE)) {
117 return true;
118 }
119
120
121 return $this->cloneOptions->get(self::IS_CLONEABLE_KEY, false);
122 }
123
124
125
126
127
128
129
130
131 public function isInstalledInSubDir(): bool
132 {
133 $siteUrl = get_option('siteurl');
134 $homeUrl = get_option('home');
135
136
137 $siteUrlPath = wp_parse_url($siteUrl, PHP_URL_PATH);
138 $homeUrlPath = wp_parse_url($homeUrl, PHP_URL_PATH);
139
140 if ($siteUrlPath === null && $homeUrlPath === null || $siteUrlPath === $homeUrlPath) {
141 return false;
142 }
143
144 if ($siteUrlPath === null && $homeUrlPath !== null) {
145 return true;
146 }
147
148 return false;
149 }
150
151
152
153
154
155
156 public function enableStagingSiteCloning(): bool
157 {
158
159 if (!$this->isStagingSite()) {
160 return false;
161 }
162
163
164 if ($this->isCloneable()) {
165 return true;
166 }
167
168 return $this->cloneOptions->set(self::IS_CLONEABLE_KEY, true);
169 }
170
171
172
173
174
175
176 public function disableStagingSiteCloning(): bool
177 {
178
179 if (!$this->isStagingSite()) {
180 return false;
181 }
182
183
184 if (!$this->isCloneable()) {
185 return true;
186 }
187
188
189 $cloneableFile = trailingslashit(ABSPATH) . self::CLONEABLE_FILE;
190 if (file_exists($cloneableFile) && !unlink($cloneableFile)) {
191
192 return false;
193 }
194
195
196
197 return (!file_exists($cloneableFile) && $this->cloneOptions->delete(self::IS_CLONEABLE_KEY));
198 }
199
200
201
202
203 public function isPhpShortTagsEnabled(): bool
204 {
205 return in_array(strtolower(ini_get('short_open_tags')), ['1', 'on', 'true']);
206 }
207
208
209
210
211
212
213 public function isWpBakeryActive(): bool
214 {
215 return defined('WPB_VC_VERSION');
216 }
217
218
219
220
221
222
223 public function isJetpackActive(): bool
224 {
225 return class_exists('Jetpack');
226 }
227
228
229
230
231 public function getErrors(): array
232 {
233 return $this->errors;
234 }
235
236
237
238
239 public function isBitnami(): bool
240 {
241 return ABSPATH === '/opt/bitnami/wordpress/';
242 }
243
244
245
246
247 public function isWpContentOutsideAbspath(): bool
248 {
249 $wpContentDir = wp_normalize_path(WP_CONTENT_DIR);
250 $abspath = wp_normalize_path(ABSPATH);
251
252 return !(strpos($wpContentDir, $abspath) === 0);
253 }
254
255
256
257
258 public function isUploadsOutsideAbspath(): bool
259 {
260 $uploadDir = wp_normalize_path(wp_upload_dir()['basedir']);
261 $abspath = wp_normalize_path(ABSPATH);
262
263 return strpos($uploadDir, $abspath) !== 0;
264 }
265
266
267
268
269 public function isFlywheel(): bool
270 {
271 if (!$this->isWpContentOutsideAbspath()) {
272 return false;
273 }
274
275 return file_exists(trailingslashit(wp_normalize_path(ABSPATH)) . '.fw-config.php');
276 }
277
278
279
280
281 public function isHostedOnWordPressCom(): bool
282 {
283 if (!$this->isWpContentOutsideAbspath()) {
284 return false;
285 }
286
287 $parentDirectory = dirname(trailingslashit(wp_normalize_path(WP_CONTENT_DIR)));
288 $wpcomDetection = trailingslashit($parentDirectory) . '__wp__';
289 if (!is_link($wpcomDetection)) {
290 return false;
291 }
292
293 return true;
294 }
295
296
297
298
299 public function getHostingType(): string
300 {
301 if ($this->isFlywheel()) {
302 return self::HOSTED_ON_FLYWHEEL;
303 }
304
305 if ($this->isHostedOnWordPressCom()) {
306 return self::HOSTED_ON_WP;
307 }
308
309 if ($this->isBitnami()) {
310 return self::HOSTED_ON_BITNAMI;
311 }
312
313 return self::OTHER_HOST;
314 }
315
316 public function getPhpArchitecture(): string
317 {
318 return PHP_INT_SIZE === 8 ? '64-bit' : '32-bit';
319 }
320
321 public function getOsArchitecture(): string
322 {
323 try {
324 if (!function_exists('php_uname')) {
325 return 'N/A';
326 }
327
328 if (in_array('php_uname', explode(',', ini_get('disable_functions')))) {
329 return 'N/A';
330 }
331
332 return strpos(php_uname('m'), '64') !== false ? '64-bit' : '32-bit';
333 } catch (\Throwable $ex) {
334 return 'N/A';
335 }
336 }
337
338
339
340
341 public function isHostedOnElementorCloud(): bool
342 {
343 $httpHost = !empty($_SERVER['HTTP_HOST']) ? Sanitize::sanitizeString($_SERVER['HTTP_HOST']) : '';
344 if (strpos($httpHost, 'elementor.cloud') !== false) {
345 return true;
346 }
347
348 $headers = headers_list();
349 foreach ($headers as $header) {
350 if (stripos($header, 'ec-source') !== false || stripos($header, 'ec-coldstart') !== false || stripos($header, 'EC-LB-OP-STATUS') !== false) {
351 return true;
352 }
353 }
354
355 return false;
356 }
357
358
359
360
361
362
363
364
365
366 public function isLocal(): bool
367 {
368 $host = strtolower((string)wp_parse_url(get_site_url(), PHP_URL_HOST));
369
370 return apply_filters('wpstg.tests.is_local_site', $this->isLocalHost($host));
371 }
372
373 private function isLocalHost(string $host): bool
374 {
375 if ($host === '') {
376 return false;
377 }
378
379 if (in_array($host, self::LOCAL_HOSTNAMES, true)) {
380 return true;
381 }
382
383 foreach (self::LOCAL_HOSTNAME_SUFFIXES as $suffix) {
384 if (substr($host, -strlen($suffix)) === $suffix) {
385 return true;
386 }
387 }
388
389 return $this->isPrivateIp($host);
390 }
391
392
393
394
395
396 private function isPrivateIp(string $host): bool
397 {
398 if (filter_var($host, FILTER_VALIDATE_IP) === false) {
399 return false;
400 }
401
402 foreach (self::LOCAL_IP_PREFIXES as $prefix) {
403 if (strpos($host, $prefix) === 0) {
404 return true;
405 }
406 }
407
408 return false;
409 }
410
411
412
413
414
415 public function isMultisite(): bool
416 {
417 return is_multisite();
418 }
419 }
420