PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.0.4
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.0.4
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 / Backend / Modules / SystemInfo.php
wp-staging / Backend / Modules Last commit date
Jobs 2 years ago Views 5 years ago SystemInfo.php 2 years ago
SystemInfo.php
794 lines
1 <?php
2
3 namespace WPStaging\Backend\Modules;
4
5 use WPStaging\Backend\Upgrade\Upgrade;
6 use WPStaging\Backup\Ajax\FileList\ListableBackupsCollection;
7 use WPStaging\Core\Utils\Browser;
8 use WPStaging\Core\WPStaging;
9 use WPStaging\Core\Utils\Multisite;
10 use WPStaging\Framework\Utils\Urls;
11 use WPStaging\Framework\Adapter\Database;
12 use WPStaging\Framework\BackgroundProcessing\Queue;
13 use WPStaging\Framework\Facades\Sanitize;
14 use WPStaging\Framework\Staging\Sites;
15 use WPStaging\Framework\SiteInfo;
16
17 // No Direct Access
18 if (!defined("WPINC")) {
19 die;
20 }
21
22 /**
23 * Class SystemInfo
24 * @package WPStaging\Backend\Modules
25 */
26 class SystemInfo
27 {
28 /**
29 * @var bool
30 */
31 private $isMultiSite;
32
33 /** @var mixed|Database */
34 private $database;
35
36 /**
37 * @var Urls
38 */
39 private $urlsHelper;
40
41 public function __construct()
42 {
43 $this->isMultiSite = is_multisite();
44 $this->urlsHelper = WPStaging::make(Urls::class);
45 $this->database = WPStaging::make(Database::class);
46 }
47
48 /**
49 * Magic method
50 * @return string
51 */
52 public function __toString()
53 {
54 return $this->get();
55 }
56
57 /**
58 * Get System Information as text
59 * @return string
60 */
61 public function get()
62 {
63 $output = $this->server();
64
65 $output .= $this->php();
66
67 $output .= $this->wp();
68
69 $output .= $this->wpstaging();
70
71 $output .= $this->getMultisiteInfo();
72
73 $output .= $this->plugins();
74
75 $output .= $this->multiSitePlugins();
76
77 $output .= $this->phpExtensions();
78
79 $output .= $this->browser();
80
81 $output .= PHP_EOL . "### End System Info ###";
82
83 return $output;
84 }
85
86 /**
87 * @param string $string
88 * @return string
89 */
90 public function header($string)
91 {
92 return PHP_EOL . "### {$string} ###" . PHP_EOL . PHP_EOL;
93 }
94
95 /**
96 * Formating title and the value
97 * @param string $title
98 * @param string $value
99 * @return string
100 */
101 public function info($title, $value)
102 {
103 return str_pad($title, 56, ' ', STR_PAD_RIGHT) . print_r($value, true) . PHP_EOL;
104 }
105
106 /**
107 * WordPress Configuration
108 * @return string
109 */
110 public function wp()
111 {
112 global $wpdb;
113
114 $output = $this->header("WordPress");
115
116 $output .= $this->info("WP Version:", get_bloginfo("version"));
117 $output .= $this->info("Installed in subdir:", ($this->isSubDir() ? 'Yes' : 'No'));
118 $output .= $this->info("Table Prefix:", $this->getTablePrefix());
119 $output .= $this->info("site_url():", site_url());
120 $output .= $this->info("home_url():", $this->urlsHelper->getHomeUrl());
121 $output .= $this->info("get_home_path():", get_home_path());
122 $output .= $this->info("ABSPATH:", ABSPATH);
123 $output .= $this->info("WP_PLUGIN_DIR:", WP_PLUGIN_DIR);
124 $output .= $this->info("WP_CONTENT_DIR:", WP_CONTENT_DIR);
125
126 if (defined('UPLOADS')) {
127 $output .= $this->info("WP UPLOADS CONST:", UPLOADS);
128 }
129
130 $uploads = wp_upload_dir();
131 $output .= $this->info("uploads['path']:", $uploads['path']);
132 $output .= $this->info("uploads['subdir']:", $uploads['subdir']);
133 $output .= $this->info("uploads['basedir']:", $uploads['basedir']);
134 $output .= $this->info("uploads['baseurl']:", $uploads['baseurl']);
135 $output .= $this->info("uploads['url']:", $uploads['url']);
136
137 $output .= $this->info("UPLOAD_PATH in wp-config.php:", (defined("UPLOAD_PATH")) ? UPLOAD_PATH : '[not set]');
138 $output .= $this->info("upload_path in " . $wpdb->prefix . 'options:', get_option("upload_path") ?: "[not set]");
139
140 if (defined('WP_TEMP_DIR')) {
141 $output .= $this->info("WP_TEMP_DIR:", WP_TEMP_DIR);
142 }
143
144 $output .= $this->info("WP_DEBUG:", (defined("WP_DEBUG")) ? (WP_DEBUG ? "Enabled" : "Disabled") : "Not set");
145 $output .= $this->info("WP_MEMORY_LIMIT:", WP_MEMORY_LIMIT);
146 $output .= $this->info("WP_MAX_MEMORY_LIMIT:", WP_MAX_MEMORY_LIMIT);
147 $output .= $this->info("Active Theme:", $this->theme());
148 $output .= $this->info("Permalink Structure:", get_option("permalink_structure") ?: "Default");
149 $output .= $this->wpRemotePost();
150 $output .= $this->info("WPLANG:", (defined("WPLANG") && WPLANG) ? WPLANG : "en_US");
151 $output .= $this->info("Wordpress cron:", wp_json_encode(get_option('cron', [])));
152
153 return $output;
154 }
155
156 /**
157 * Theme Information
158 * @return string
159 */
160 public function theme()
161 {
162 // Versions earlier than 3.4
163 if (get_bloginfo("version") < "3.4") {
164 $themeData = get_theme_data(get_stylesheet_directory() . "/style.css");
165 return "{$themeData["Name"]} {$themeData["Version"]}";
166 }
167
168 $themeData = wp_get_theme();
169 return "{$themeData->Name} {$themeData->Version}";
170 }
171
172 /**
173 * Multisite information
174 * @return string
175 */
176 private function getMultisiteInfo()
177 {
178 if (!$this->isMultiSite) {
179 return '';
180 }
181
182 $multisite = new Multisite();
183
184 $output = $this->info("Multisite:", "Yes");
185 $output .= $this->info("Multisite Blog ID:", get_current_blog_id());
186 $output .= $this->info("MultiSite URL:", $multisite->getHomeURL());
187 $output .= $this->info("MultiSite URL without scheme:", $multisite->getHomeUrlWithoutScheme());
188 $output .= $this->info("MultiSite is Main Site:", is_main_site() ? 'Yes' : 'No');
189
190 return $output;
191 }
192
193 /**
194 * Wp Staging plugin Information
195 * @return string
196 */
197 public function wpstaging()
198 {
199 $settings = (object)get_option('wpstg_settings', []);
200
201 $output = PHP_EOL . "## WP Staging ##" . PHP_EOL . PHP_EOL;
202
203 $output .= $this->info("Pro Version:", get_option('wpstgpro_version', '[not set]'));
204 $output .= $this->info("Pro License Key:", get_option('wpstg_license_key') ?: '[not set]');
205 // @see \WPStaging\Backend\Pro\Upgrade\Upgrade::OPTION_INSTALL_DATE
206 $output .= $this->info("Pro Install Date:", get_option('wpstgpro_install_date', '[not set]'));
207 // @see \WPStaging\Backend\Pro\Upgrade\Upgrade::OPTION_UPGRADE_DATE
208 $output .= $this->info("Pro Update Date:", get_option('wpstgpro_upgrade_date', '[not set]'));
209 $output .= $this->info("Free or Pro Install Date (legacy):", get_option('wpstg_installDate', '[not set]'));
210 $output .= $this->info("Free Version:", get_option('wpstg_version', '[not set]'));
211 $output .= $this->info("Free Install Date:", get_option(Upgrade::OPTION_INSTALL_DATE, '[not set]'));
212 $output .= $this->info("Free Update Date:", get_option(Upgrade::OPTION_UPGRADE_DATE, '[not set]'));
213 $output .= $this->info("Updated from Pro Version:", get_option('wpstgpro_version_upgraded_from') ?: "[not set]");
214 $output .= $this->info("Updated from Free Version:", get_option('wpstg_version_upgraded_from') ?: "[not set]");
215 $output .= $this->info("Is Staging Site:", (new SiteInfo())->isStagingSite() ? 'true' : 'false');
216 $output .= $this->getBackupDetails();
217 $output .= $this->getScheduleInfo();
218 $output .= $this->info("DB Query Limit:", isset($settings->queryLimit) ? $settings->queryLimit : '[not set]');
219 $output .= $this->info("DB Search & Replace Limit:", isset($settings->querySRLimit) ? $settings->querySRLimit : '[not set]');
220 $output .= $this->info("File Copy Limit:", isset($settings->fileLimit) ? $settings->fileLimit : '[not set]');
221 $output .= $this->info("Maximum File Size:", isset($settings->maxFileSize) ? $settings->maxFileSize : '[not set]');
222 $output .= $this->info("File Copy Batch Size:", isset($settings->batchSize) ? $settings->batchSize : '[not set]');
223 $output .= $this->info("CPU Load Priority:", isset($settings->cpuLoad) ? $settings->cpuLoad : '[not set]');
224 $output .= $this->info("Keep Permalinks:", isset($settings->keepPermalinks) ? $settings->keepPermalinks : '[not set]');
225 $output .= $this->info("Debug Mode:", isset($settings->debugMode) ? $settings->debugMode : '[NOT SET]');
226 $output .= $this->info("Optimize Active:", isset($settings->optimizer) ? $settings->optimizer : '[not set]');
227 $output .= $this->info("Delete on Uninstall:", isset($settings->unInstallOnDelete) ? $settings->unInstallOnDelete : '[not set]');
228 $output .= $this->info("Check Directory Size:", isset($settings->checkDirectorySize) ? $settings->checkDirectorySize : '[not set]');
229 $output .= $this->info("Access Permissions:", isset($settings->userRoles) ? $settings->userRoles : '[not set]');
230 $output .= $this->info("Users With Staging Access:", isset($settings->usersWithStagingAccess) ? $settings->usersWithStagingAccess : '[not set]');
231 $output .= $this->info("Admin Bar Color:", isset($settings->adminBarColor) ? $settings->adminBarColor : '[not set]');
232 $analyticsHasConsent = get_option('wpstg_analytics_has_consent');
233 $output .= $this->info("Send Usage Information:", !empty($analyticsHasConsent) ? 'true' : 'false');
234 $output .= $this->info("Send Backup Errors via E-Mail:", isset($settings->schedulesErrorReport) ? $settings->schedulesErrorReport : '[not set]');
235 $output .= $this->info("E-Mail Address:", isset($settings->schedulesReportEmail) ? $settings->schedulesReportEmail : '[not set]');
236
237 $output .= PHP_EOL . "-- Google Drive Settings" . PHP_EOL;
238
239 $googleDriveSettings = (array)get_option('wpstg_googledrive', []);
240 if (!empty($googleDriveSettings)) {
241 foreach ($googleDriveSettings as $key => $value) {
242 $output .= $this->info($key, empty($value) ? '[not set]' : $this->removeCredentials($key, $value));
243 }
244 }
245
246 $output .= PHP_EOL . "-- Amazon S3 Settings" . PHP_EOL;
247
248 $amazonS3Settings = (array)get_option('wpstg_amazons3', []);
249 if (!empty($amazonS3Settings)) {
250 foreach ($amazonS3Settings as $key => $value) {
251 $output .= $this->info($key, empty($value) ? '[not set]' : $this->removeCredentials($key, $value));
252 }
253 }
254
255 $output .= PHP_EOL . "-- DigitalOcean Spaces Settings" . PHP_EOL;
256
257 $digitalOceanSpacesSettings = (array)get_option('wpstg_digitalocean-spaces', []);
258 if (!empty($digitalOceanSpacesSettings)) {
259 foreach ($digitalOceanSpacesSettings as $key => $value) {
260 $output .= $this->info($key, empty($value) ? 'not set' : $this->removeCredentials($key, $value));
261 }
262 }
263
264 $output .= PHP_EOL . "-- Wasabi Settings" . PHP_EOL;
265
266 $wasabiSettings = (array)get_option('wpstg_wasabi-s3', []);
267 if (!empty($wasabiSettings)) {
268 foreach ($wasabiSettings as $key => $value) {
269 $output .= $this->info($key, empty($value) ? 'not set' : $this->removeCredentials($key, $value));
270 }
271 }
272 $output .= PHP_EOL . "-- Generic S3 Settings" . PHP_EOL;
273
274 $genericS3Settings = (array)get_option('wpstg_generic-s3', []);
275 if (!empty($genericS3Settings)) {
276 foreach ($genericS3Settings as $key => $value) {
277 $output .= $this->info($key, empty($value) ? 'not set' : $this->removeCredentials($key, $value));
278 }
279 }
280 $output .= PHP_EOL . "-- SFTP Settings" . PHP_EOL;
281
282 $sftpSettings = (array)get_option('wpstg_sftp', []);
283 if (!empty($sftpSettings)) {
284 foreach ($sftpSettings as $key => $value) {
285 $output .= $this->info($key, empty($value) ? '[not set]' : $this->removeCredentials($key, $value));
286 }
287 }
288 $output .= PHP_EOL . "-- Existing Staging Sites" . PHP_EOL . PHP_EOL;
289
290 // Clones data version > 2.x
291 // old name wpstg_existing_clones_beta
292 // New name since version 4.0.3 wpstg_staging_sites
293 $stagingSites = get_option(Sites::STAGING_SITES_OPTION, []);
294 if (is_array($stagingSites)) {
295 foreach ($stagingSites as $key => $clone) {
296 $path = !empty($clone['path']) ? $clone['path'] : '[not set]';
297
298 $output .= $this->info("Number:", isset($clone['number']) ? $clone['number'] : '[not set]');
299 $output .= $this->info("directoryName:", isset($clone['directoryName']) ? $clone['directoryName'] : '[not set]');
300 $output .= $this->info("Path:", $path);
301 $output .= $this->info("URL:", isset($clone['url']) ? $clone['url'] : '[not set]');
302 $output .= $this->info("DB Prefix:", isset($clone['prefix']) ? $clone['prefix'] : '[not set]');
303 $output .= $this->info("DB Prefix wp-config.php:", $this->getStagingPrefix($clone));
304 $output .= $this->info("WP STAGING Version:", isset($clone['version']) ? $clone['version'] : '[not set]');
305 $output .= $this->info("WP Version:", $this->getStagingWpVersion($path)) . PHP_EOL . PHP_EOL;
306 }
307 }
308
309 $output .= $this->info(Sites::STAGING_SITES_OPTION . ": ", serialize(get_option(Sites::STAGING_SITES_OPTION, [])));
310 $output .= $this->info(Sites::BACKUP_STAGING_SITES_OPTION . ": ", serialize(get_option(Sites::BACKUP_STAGING_SITES_OPTION, [])));
311 $output .= PHP_EOL;
312
313 $output .= "-- Legacy Options" . PHP_EOL . PHP_EOL;
314
315 $output .= $this->info("wpstg_existing_clones: ", serialize(get_option('wpstg_existing_clones')));
316 $output .= $this->info(Sites::OLD_STAGING_SITES_OPTION . ": ", serialize(get_option(Sites::OLD_STAGING_SITES_OPTION, [])));
317
318 return $output;
319 }
320
321 /**
322 * @return string
323 */
324 public function getWpStagingVersion()
325 {
326 if (defined('WPSTG_VERSION')) {
327 return WPSTG_VERSION;
328 }
329
330 if (defined('WPSTGPRO_VERSION')) {
331 return 'Pro ' . WPSTGPRO_VERSION;
332 }
333
334 return 'unknown';
335 }
336
337 /**
338 * Browser Information
339 * @return string
340 */
341 public function browser()
342 {
343 $output = $this->header("User Browser");
344 $output .= (new Browser());
345
346 return $output;
347 }
348
349 /**
350 * Check wp_remote_post() functionality
351 * @return string
352 */
353 public function wpRemotePost()
354 {
355 // Make sure wp_remote_post() is working
356 $wpRemotePost = "does not work";
357
358 // Send request
359 $response = wp_remote_post(
360 "https://www.paypal.com/cgi-bin/webscr",
361 [
362 "sslverify" => false,
363 "timeout" => 60,
364 "user-agent" => "WPSTG/" . WPStaging::getVersion(),
365 "body" => ["cmd" => "_notify-validate"]
366 ]
367 );
368
369 // Validate it worked
370 if (!is_wp_error($response) && $response["response"]["code"] >= 200 && $response["response"]["code"] < 300) {
371 $wpRemotePost = "works";
372 }
373
374 return $this->info("wp_remote_post():", $wpRemotePost);
375 }
376
377 /**
378 * List of Active Plugins
379 * @param array $plugins
380 * @param array $activePlugins
381 * @return string
382 */
383 public function activePlugins($plugins, $activePlugins)
384 {
385 $output = $this->header("WordPress Active Plugins");
386
387 foreach ($plugins as $path => $plugin) {
388 if (!in_array($path, $activePlugins)) {
389 continue;
390 }
391
392 $output .= $this->info($plugin["Name"] . ":", $plugin["Version"]);
393 }
394
395 return $output;
396 }
397
398 /**
399 * List of Inactive Plugins
400 * @param array $plugins
401 * @param array $activePlugins
402 * @return string
403 */
404 public function inactivePlugins($plugins, $activePlugins)
405 {
406 $output = $this->header("WordPress Inactive Plugins");
407
408 foreach ($plugins as $path => $plugin) {
409 if (in_array($path, $activePlugins)) {
410 continue;
411 }
412
413 $output .= $this->info($plugin["Name"] . ":", $plugin["Version"]);
414 }
415
416 return $output;
417 }
418
419 /**
420 * Get list of active and inactive plugins
421 * @return string
422 */
423 public function plugins()
424 {
425 // Get plugins and active plugins
426 $plugins = get_plugins();
427 $activePlugins = get_option("active_plugins", []);
428
429 // Active plugins
430 $output = $this->activePlugins($plugins, $activePlugins);
431 $output .= $this->inactivePlugins($plugins, $activePlugins);
432
433 return $output;
434 }
435
436 /**
437 * Multisite Plugins
438 * @return string
439 */
440 public function multiSitePlugins()
441 {
442 if (!$this->isMultiSite) {
443 return '';
444 }
445
446 $output = $this->header("Network Active Plugins");
447
448 $plugins = wp_get_active_network_plugins();
449 $activePlugins = get_site_option("active_sitewide_plugins", []);
450
451 foreach ($plugins as $pluginPath) {
452 $pluginBase = plugin_basename($pluginPath);
453
454 if (!array_key_exists($pluginBase, $activePlugins)) {
455 continue;
456 }
457
458 $plugin = get_plugin_data($pluginPath);
459
460 $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
461 }
462 unset($plugins, $activePlugins);
463
464 return $output;
465 }
466
467 /**
468 * Server Information
469 * @return string
470 */
471 public function server()
472 {
473 $output = $this->header("Start System Info");
474
475 /** @var Database */
476 $database = WPStaging::make(Database::class);
477
478 $output .= $this->info("Webserver:", isset($_SERVER["SERVER_SOFTWARE"]) ? Sanitize::sanitizeString($_SERVER["SERVER_SOFTWARE"]) : '');
479 $output .= $this->info("MySQL Server Type:", $database->getServerType());
480 $output .= $this->info("MySQL Version:", $database->getSqlVersion($compact = true));
481 $output .= $this->info("MySQL Version Full Info:", $database->getSqlVersion());
482 $output .= $this->info("PHP Version:", PHP_VERSION);
483
484 return $output;
485 }
486
487 /**
488 * @return string
489 */
490 public function getMySqlServerType()
491 {
492 return $this->database->getServerType();
493 }
494
495 /**
496 * @return string
497 */
498 public function getMySqlFullVersion()
499 {
500 return $this->database->getSqlVersion();
501 }
502
503 /**
504 * @return string
505 */
506 public function getMySqlVersionCompact()
507 {
508 return $this->database->getSqlVersion($compact = true);
509 }
510
511 /**
512 * @return string
513 */
514 public function getPhpVersion()
515 {
516 return PHP_VERSION;
517 }
518
519 /**
520 * @return array|string
521 */
522 public function getWebServerInfo()
523 {
524 return isset($_SERVER["SERVER_SOFTWARE"]) ? Sanitize::sanitizeString($_SERVER["SERVER_SOFTWARE"]) : '';
525 }
526
527 /**
528 * PHP Configuration
529 * @return string
530 */
531 public function php()
532 {
533 $output = $this->info("PHP memory_limit:", ini_get("memory_limit"));
534 $output .= $this->info("PHP memory_limit in Bytes:", wp_convert_hr_to_bytes(ini_get("memory_limit")));
535 $output .= $this->info("PHP max_execution_time:", ini_get("max_execution_time"));
536 $output .= $this->info("PHP Safe Mode:", ($this->isSafeModeEnabled() ? "Enabled" : "Disabled"));
537 $output .= $this->info("PHP Upload Max File Size:", ini_get("upload_max_filesize"));
538 $output .= $this->info("PHP Post Max Size:", ini_get("post_max_size"));
539 $output .= $this->info("PHP Upload Max Filesize:", ini_get("upload_max_filesize"));
540 $output .= $this->info("PHP Max Input Vars:", ini_get("max_input_vars"));
541 $displayErrors = ini_get("display_errors");
542 $output .= $this->info("PHP display_errors:", ($displayErrors) ? "On ({$displayErrors})" : "N/A");
543 $output .= $this->info("PHP User:", $this->getPHPUser());
544
545 return $output;
546 }
547
548 /**
549 *
550 * @return string
551 */
552 public function getPHPUser()
553 {
554
555 $user = '';
556
557 if (extension_loaded('posix') && function_exists('posix_getpwuid')) {
558 $file = WPSTG_PLUGIN_DIR . 'Core/WPStaging.php';
559 $user = posix_getpwuid(fileowner($file));
560 return isset($user['name']) ? $user['name'] : 'can not detect PHP user name';
561 }
562
563 if (function_exists('exec') && @exec('echo EXEC') == 'EXEC') {
564 return exec('whoami');
565 }
566
567 return $user;
568 }
569
570 /**
571 * Check if PHP is on Safe Mode
572 * @return bool
573 */
574 public function isSafeModeEnabled()
575 {
576 return (
577 version_compare(PHP_VERSION, "5.4.0", '<') &&
578 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
579 @ini_get("safe_mode")
580 );
581 }
582
583 /**
584 * Checks if function exists or not
585 * @param string $functionName
586 * @return string
587 */
588 public function isSupported($functionName)
589 {
590 return (function_exists($functionName)) ? "Supported" : "Not Supported";
591 }
592
593 /**
594 * Checks if class or extension is loaded / exists to determine if it is installed or not
595 * @param string $name
596 * @param bool $isClass
597 * @return string
598 */
599 public function isInstalled($name, $isClass = true)
600 {
601 if ($isClass === true) {
602 return (class_exists($name)) ? "Installed" : "Not Installed";
603 } else {
604 return (extension_loaded($name)) ? "Installed" : "Not Installed";
605 }
606 }
607
608 /**
609 * Gets Installed Important PHP Extensions
610 * @return string
611 */
612 public function phpExtensions()
613 {
614 // Important PHP Extensions
615 $version = function_exists('curl_version') ? curl_version() : ['version' => 'Error: not available', 'ssl_version' => 'Error: not available', 'host' => 'Error: not available', 'protocols' => [], 'features' => []];
616
617 $bitfields = [
618 'CURL_VERSION_IPV6',
619 'CURL_VERSION_KERBEROS4',
620 'CURL_VERSION_SSL',
621 'CURL_VERSION_LIBZ'
622 ];
623
624 $output = $this->header("PHP Extensions");
625
626 $output .= $this->info("cURL:", $this->isSupported("curl_init"));
627 $output .= $this->info("cURL version:", $version['version']);
628 $output .= $this->info("cURL ssl version number:", $version['ssl_version']);
629 $output .= $this->info("cURL host:", $version['host']);
630
631 foreach ($version['protocols'] as $protocols) {
632 $output .= $this->info("cURL protocols:", $protocols);
633 }
634
635 foreach ($bitfields as $feature) {
636 $output .= $this->info($feature . ":", ($version['features'] & constant($feature) ? 'yes' : 'no'));
637 }
638
639
640 $output .= $this->info("fsockopen:", $this->isSupported("fsockopen"));
641 $output .= $this->info("SOAP Client:", $this->isInstalled("SoapClient"));
642 $output .= $this->info("Suhosin:", $this->isInstalled("suhosin", false));
643
644 return $output;
645 }
646
647 /**
648 * Check if WP is installed in subdir
649 * @return bool
650 */
651 private function isSubDir()
652 {
653 // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
654 // This is happening much more often than you would expect
655 $siteurl = preg_replace('#^https?://#', '', rtrim(get_option('siteurl'), '/'));
656 $home = preg_replace('#^https?://#', '', rtrim(get_option('home'), '/'));
657
658 if ($home !== $siteurl) {
659 return true;
660 }
661 return false;
662 }
663
664 /**
665 * Check and return prefix of the staging site
666 */
667
668 /**
669 * Try to get the staging prefix from wp-config.php of staging site
670 * @param array $clone
671 * @return string
672 */
673 private function getStagingPrefix($clone = [])
674 {
675 // Throw error
676 $path = ABSPATH . $clone['directoryName'] . DIRECTORY_SEPARATOR . "wp-config.php";
677
678 if (!file_exists($path)) {
679 return 'File does not exist in: ' . $path;
680 }
681
682 if (($content = @file_get_contents($path)) === false) {
683 return 'Can\'t find staging wp-config.php';
684 } else {
685 // Get prefix from wp-config.php
686 //preg_match_all("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
687 preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
688 //wp_die(var_dump($matches));
689
690 if (!empty($matches[1])) {
691 return $matches[1];
692 } else {
693 return 'No table_prefix in wp-config.php';
694 }
695 }
696 }
697
698 /**
699 * Get staging site wordpress version number
700 * @return string
701 */
702 private function getStagingWpVersion($path)
703 {
704
705 if ($path === '[not set]') {
706 return "Error: Cannot detect WP version";
707 }
708
709 // Get version number of wp staging
710 $file = trailingslashit($path) . 'wp-includes/version.php';
711
712 if (!file_exists($file)) {
713 return "Error: Cannot detect WP version. File does not exist: $file";
714 }
715
716 $version = @file_get_contents($file);
717
718 $versionStaging = empty($version) ? 'unknown' : $version;
719
720 preg_match("/\\\$wp_version.*=.*'(.*)';/", $versionStaging, $matches);
721
722 if (empty($matches[1])) {
723 return "Error: Cannot detect WP version";
724 }
725 return $matches[1];
726 }
727
728 /**
729 * @param $key
730 * @param $value
731 * @return mixed|string
732 */
733 private function removeCredentials($key, $value)
734 {
735 $protectedFields = ['accessToken', 'refreshToken', 'accessKey', 'secretKey', 'password', 'passphrase'];
736 if (!empty($value) && in_array($key, $protectedFields)) {
737 return '[REMOVED]';
738 }
739 return empty($value) ? '[not set]' : $value;
740 }
741
742 private function getScheduleInfo()
743 {
744 $output = '';
745 $backupSchedules = get_option('wpstg_backup_schedules', []);
746 if (!empty($backupSchedules)) {
747 foreach ($backupSchedules as $key => $value) {
748 $output .= $this->info('Schedule ' . !empty($key) ? $key : '', empty($value) ? '[not set]' : print_r($value, true));
749 }
750 } else {
751 $output .= $this->info('wpstg_backup_schedules ', '[not set]');
752 }
753
754 /** @var Queue */
755 $queue = WPStaging::make(Queue::class);
756
757 $output .= $this->info("Backup All Actions in DB:", $queue->count());
758 $output .= $this->info("Backup Pending Actions (ready):", $queue->count(Queue::STATUS_READY));
759 $output .= $this->info("Backup Processing Actions (processing):", $queue->count(Queue::STATUS_PROCESSING));
760 $output .= $this->info("Backup Completed Actions (completed):", $queue->count(Queue::STATUS_COMPLETED));
761 $output .= $this->info("Backup Failed Actions (failed):", $queue->count(Queue::STATUS_FAILED));
762
763 return $output;
764 }
765
766 private function getTablePrefix()
767 {
768 global $wpdb;
769 $tablePrefix = "DB Prefix: " . $wpdb->prefix . ' ';
770 $tablePrefix .= "Length: " . strlen($wpdb->prefix) . " Status: ";
771 $tablePrefix .= (strlen($wpdb->prefix) > 16) ? " ERROR: Too long" : " Acceptable";
772
773 return $tablePrefix;
774 }
775
776 /**
777 * @return string
778 */
779 private function getBackupDetails()
780 {
781 $backups = WPStaging::make(ListableBackupsCollection::class)->getListableBackups();
782
783 $output = $this->info("Number of Backups:", count($backups));
784
785 $totalBackupSize = 0;
786 foreach ($backups as $backup) {
787 $totalBackupSize += (float)$backup->size;
788 }
789 $output .= $this->info("Backup Total File Size:", esc_html($totalBackupSize) . 'M');
790
791 return $output;
792 }
793 }
794