WP Staging – DB & File Duplicator & Migration - Version 2.4.5

Version Description

  • New: Compatible up to WordPress 5.0.1 Gutenberg
  • New: Show WP version of staging site in the sysinfo log
  • Fix: Make sure optimizer must-use plugin is updated as well after updating the main plugin
  • Fix: Plugin can not be uninstalled if WP Staging Pro is activated
  • Fix: Prevent error $this not in object context in install.php
Download this release

Release Info

Developer ReneHermi
Plugin Icon 128x128 WP Staging – DB & File Duplicator & Migration
Version 2.4.5
Comparing to
See all releases

Code changes from version 2.4.3 to 2.4.5

apps/Backend/Modules/SystemInfo.php CHANGED
@@ -10,7 +10,7 @@ use WPStaging\Utils\Multisite;
10
 
11
  // No Direct Access
12
  if( !defined( "WPINC" ) ) {
13
- die;
14
  }
15
 
16
  /**
@@ -19,533 +19,558 @@ if( !defined( "WPINC" ) ) {
19
  */
20
  class SystemInfo extends InjectionAware {
21
 
22
- /**
23
- * @var bool
24
- */
25
- private $isMultiSite;
26
-
27
- /**
28
- *
29
- * @var obj
30
- */
31
- private $helper;
32
-
33
- /**
34
- * Initialize class
35
- */
36
- public function initialize() {
37
- $this->isMultiSite = is_multisite();
38
- $this->helper = new Utils\Helper();
39
- }
40
-
41
- /**
42
- * Magic method
43
- * @return string
44
- */
45
- public function __toString() {
46
- return $this->get();
47
- }
48
-
49
- /**
50
- * Get System Information as text
51
- * @return string
52
- */
53
- public function get() {
54
- $output = "### Begin System Info ###" . PHP_EOL . PHP_EOL;
55
-
56
- $output .= $this->wpstaging();
57
-
58
- $output .= $this->site();
59
-
60
- $output .= $this->getMultisiteInfo();
61
-
62
- $output .= $this->browser();
63
-
64
- $output .= $this->wp();
65
-
66
- $output .= $this->plugins();
67
-
68
- $output .= $this->multiSitePlugins();
69
-
70
- $output .= $this->server();
71
-
72
- $output .= $this->php();
73
-
74
- $output .= $this->phpExtensions();
75
-
76
- $output .= PHP_EOL . "### End System Info ###";
77
-
78
- return $output;
79
- }
80
-
81
- /**
82
- * @param string $string
83
- * @return string
84
- */
85
- public function header( $string ) {
86
- return PHP_EOL . "-- {$string}" . PHP_EOL . PHP_EOL;
87
- }
88
-
89
- /**
90
- * Formating title and the value
91
- * @param string $title
92
- * @param string $value
93
- * @return string
94
- */
95
- public function info( $title, $value ) {
96
- return str_pad( $title, 56, ' ', STR_PAD_RIGHT ) . $value . PHP_EOL;
97
- }
98
-
99
- /**
100
- * Theme Information
101
- * @return string
102
- */
103
- public function theme() {
104
- // Versions earlier than 3.4
105
- if( get_bloginfo( "version" ) < "3.4" ) {
106
- $themeData = get_theme_data( get_stylesheet_directory() . "/style.css" );
107
- return "{$themeData["Name"]} {$themeData["Version"]}";
108
- }
109
-
110
- $themeData = wp_get_theme();
111
- return "{$themeData->Name} {$themeData->Version}";
112
- }
113
-
114
- /**
115
- * Site Information
116
- * @return string
117
- */
118
- public function site() {
119
- $output = "-- Site Info" . PHP_EOL . PHP_EOL;
120
- $output .= $this->info( "Site URL:", site_url() );
121
- $output .= $this->info( "Home URL:", $this->helper->get_home_url() );
122
- $output .= $this->info( "Home Path:", get_home_path() );
123
- $output .= $this->info( "ABSPATH:", ABSPATH );
124
- $output .= $this->info( "Installed in subdir:", ( $this->isSubDir() ? 'Yes' : 'No' ) );
125
-
126
- return apply_filters( "wpstg_sysinfo_after_site_info", $output );
127
- }
128
-
129
- /**
130
- * Multisite information
131
- * @return string
132
- */
133
- private function getMultisiteInfo(){
134
- if (!$this->isMultiSite){
135
- return '';
136
- }
137
-
138
- $multisite = new Multisite();
139
-
140
- $output = $this->info( "Multisite:", ($this->isMultiSite ? "Yes" : "No" ) );
141
- $output .= $this->info( "Multisite Blog ID:", get_current_blog_id() );
142
- $output .= $this->info( "MultiSite URL:", $multisite->getHomeURL() );
143
- $output .= $this->info( "MultiSite URL without scheme:", $multisite->getHomeUrlWithoutScheme() );
144
- $output .= $this->info( "MultiSite is Main Site:", is_main_site() ? 'Yes' : 'No' );
145
-
146
- return apply_filters( "wpstg_sysinfo_after_multisite_info", $output );
147
-
148
-
149
- }
150
-
151
-
152
- /**
153
- * Wp Staging plugin Information
154
- * @return string
155
- */
156
- public function wpstaging() {
157
- // Get wpstg settings
158
- $settings = ( object ) get_option( 'wpstg_settings', array() );
159
-
160
- // Clones data < 1.1.6.x
161
- $clones = ( object ) get_option( 'wpstg_existing_clones', array() );
162
- // Clones data version > 2.x
163
- $clonesBeta = get_option( 'wpstg_existing_clones_beta', array() );
164
-
165
-
166
- $output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
167
- $output .= $this->info( "Query Limit:", isset( $settings->queryLimit ) ? $settings->queryLimit : 'undefined' );
168
- $output .= $this->info( "DB Search & Replace Limit:", isset( $settings->querySRLimit ) ? $settings->querySRLimit : 'undefined' );
169
- $output .= $this->info( "File Copy Limit:", isset( $settings->fileLimit ) ? $settings->fileLimit : 'undefined' );
170
- $output .= $this->info( "Batch Size:", isset( $settings->batchSize ) ? $settings->batchSize : 'undefined' );
171
- $output .= $this->info( "CPU Load:", isset( $settings->cpuLoad ) ? $settings->cpuLoad : 'undefined' );
172
- $output .= $this->info( "WP in Subdir:", $this->isSubDir() ? 'true' : 'false' );
173
-
174
- $output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.1.6.x" . PHP_EOL . PHP_EOL;
175
-
176
- foreach ( $clones as $key => $value ) {
177
- $output .= $this->info( "Site name & subfolder :", $value );
178
- }
179
- $output .= PHP_EOL . PHP_EOL . "-- Available Sites Version > 2.0.x" . PHP_EOL . PHP_EOL;
180
-
181
- foreach ( $clonesBeta as $key => $clone ) {
182
- $output .= $this->info( "Number:", isset( $clone['number'] ) ? $clone['number'] : 'undefined' );
183
- $output .= $this->info( "directoryName:", isset( $clone['directoryName'] ) ? $clone['directoryName'] : 'undefined' );
184
- $output .= $this->info( "Path:", isset( $clone['path'] ) ? $clone['path'] : 'undefined' );
185
- $output .= $this->info( "URL:", isset( $clone['url'] ) ? $clone['url'] : 'undefined' );
186
- $output .= $this->info( "DB Prefix:", isset( $clone['prefix'] ) ? $clone['prefix'] : 'undefined' );
187
- $output .= $this->info( "DB Prefix wp-config.php:", $this->getStagingPrefix( $clone ) );
188
- $output .= $this->info( "Version:", isset( $clone['version'] ) ? $clone['version'] : 'undefined' ) . PHP_EOL . PHP_EOL;
189
- }
190
-
191
-
192
- $output .= $this->info( "Raw Clones Data:", json_encode( get_option( 'wpstg_existing_clones_beta', 'undefined' ) ) );
193
-
194
- $output .= '' . PHP_EOL;
195
-
196
-
197
- //$output .= PHP_EOL . PHP_EOL;
198
-
199
- $output .= $this->info( "Plugin Version:", get_option( 'wpstg_version', 'undefined' ) );
200
- $output .= $this->info( "Install Date:", get_option( 'wpstg_installDate', 'undefined' ) );
201
- $output .= $this->info( "Upgraded from:", get_option( 'wpstg_version_upgraded_from', 'undefined' ) );
202
- $output .= $this->info( "Is Staging Site:", get_option( 'wpstg_is_staging_site', 'undefined' ) ) . PHP_EOL . PHP_EOL;
203
-
204
-
205
- return apply_filters( "wpstg_sysinfo_after_wpstaging_info", $output );
206
- }
207
-
208
- /**
209
- * Browser Information
210
- * @return string
211
- */
212
- public function browser() {
213
- $output = $this->header( "User Browser" );
214
- $output .= (new Browser);
215
-
216
- return apply_filters( "wpstg_sysinfo_after_user_browser", $output );
217
- }
218
-
219
- /**
220
- * Frontpage Information when frontpage is set to "page"
221
- * @return string
222
- */
223
- public function frontPage() {
224
- if( get_option( "show_on_front" ) !== "page" ) {
225
- return '';
226
- }
227
-
228
- $frontPageID = get_option( "page_on_front" );
229
- $blogPageID = get_option( "page_for_posts" );
230
-
231
- // Front Page
232
- $pageFront = ($frontPageID != 0) ? get_the_title( $frontPageID ) . " (#{$frontPageID})" : "Unset";
233
- // Blog Page ID
234
- $pageBlog = ($blogPageID != 0) ? get_the_title( $blogPageID ) . " (#{$blogPageID})" : "Unset";
235
-
236
- $output = $this->info( "Page On Front:", $pageFront );
237
- $output .= $this->info( "Page For Posts:", $pageBlog );
238
-
239
- return $output;
240
- }
241
-
242
- /**
243
- * Check wp_remote_post() functionality
244
- * @return string
245
- */
246
- public function wpRemotePost() {
247
- // Make sure wp_remote_post() is working
248
- $wpRemotePost = "wp_remote_post() does not work";
249
-
250
- // Send request
251
- $response = wp_remote_post(
252
- "https://www.paypal.com/cgi-bin/webscr", array(
253
- "sslverify" => false,
254
- "timeout" => 60,
255
- "user-agent" => "WPSTG/" . WPStaging::VERSION,
256
- "body" => array("cmd" => "_notify-validate")
257
- )
258
- );
259
-
260
- // Validate it worked
261
- if( !is_wp_error( $response ) && 200 <= $response["response"]["code"] && 300 > $response["response"]["code"] ) {
262
- $wpRemotePost = "wp_remote_post() works";
263
- }
264
-
265
- return $this->info( "Remote Post:", $wpRemotePost );
266
- }
267
-
268
- /**
269
- * WordPress Configuration
270
- * @return string
271
- */
272
- public function wp() {
273
- $output = $this->header( "WordPress Configuration" );
274
- $output .= $this->info( "Version:", get_bloginfo( "version" ) );
275
- $output .= $this->info( "Language:", (defined( "WPLANG" ) && WPLANG) ? WPLANG : "en_US" );
276
-
277
- $permalinkStructure = get_option( "permalink_structure" );
278
- ;
279
- $output .= $this->info( "Permalink Structure:", ($permalinkStructure) ? $permalinkStructure : "Default" );
280
-
281
- $output .= $this->info( "Active Theme:", $this->theme() );
282
- $output .= $this->info( "Show On Front:", get_option( "show_on_front" ) );
283
-
284
- // Frontpage information
285
- $output .= $this->frontPage();
286
-
287
- // WP Remote Post
288
- $output .= $this->wpRemotePost();
289
-
290
- // Table Prefix
291
- $wpDB = $this->di->get( "wpdb" );
292
- $tablePrefix = "DB Prefix: " . $wpDB->prefix . ' ';
293
- $tablePrefix .= "Length: " . strlen( $wpDB->prefix ) . " Status: ";
294
- $tablePrefix .= (strlen( $wpDB->prefix ) > 16) ? " ERROR: Too long" : " Acceptable";
295
-
296
- $output .= $this->info( "Table Prefix:", $tablePrefix );
297
-
298
- // Constants
299
- $output .= $this->info( "WP Content Path:", WP_CONTENT_DIR );
300
- $output .= $this->info( "WP Plugin Dir:", WP_PLUGIN_DIR );
301
- if( defined( 'UPLOADS' ) )
302
- $output .= $this->info( "WP UPLOADS CONST:", UPLOADS );
303
- $uploads = wp_upload_dir();
304
- $output .= $this->info( "WP Uploads Dir:", $uploads['basedir'] );
305
- if( defined( 'WP_TEMP_DIR' ) )
306
- $output .= $this->info( "WP Temp Dir:", WP_TEMP_DIR );
307
-
308
- // WP Debug
309
- $output .= $this->info( "WP_DEBUG:", (defined( "WP_DEBUG" )) ? WP_DEBUG ? "Enabled" : "Disabled" : "Not set" );
310
- $output .= $this->info( "Memory Limit:", WP_MEMORY_LIMIT );
311
- $output .= $this->info( "Registered Post Stati:", implode( ", ", \get_post_stati() ) );
312
-
313
- return apply_filters( "wpstg_sysinfo_after_wpstg_config", $output );
314
- }
315
-
316
- /**
317
- * List of Active Plugins
318
- * @param array $plugins
319
- * @param array $activePlugins
320
- * @return string
321
- */
322
- public function activePlugins( $plugins, $activePlugins ) {
323
- $output = $this->header( "WordPress Active Plugins" );
324
-
325
- foreach ( $plugins as $path => $plugin ) {
326
- if( !in_array( $path, $activePlugins ) ) {
327
- continue;
328
- }
329
-
330
- $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
331
- }
332
-
333
- return apply_filters( "wpstg_sysinfo_after_wordpress_plugins", $output );
334
- }
335
-
336
- /**
337
- * List of Inactive Plugins
338
- * @param array $plugins
339
- * @param array $activePlugins
340
- * @return string
341
- */
342
- public function inactivePlugins( $plugins, $activePlugins ) {
343
- $output = $this->header( "WordPress Inactive Plugins" );
344
-
345
- foreach ( $plugins as $path => $plugin ) {
346
- if( in_array( $path, $activePlugins ) ) {
347
- continue;
348
- }
349
-
350
- $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
351
- }
352
-
353
- return apply_filters( "wpstg_sysinfo_after_wordpress_plugins_inactive", $output );
354
- }
355
-
356
- /**
357
- * Get list of active and inactive plugins
358
- * @return string
359
- */
360
- public function plugins() {
361
- // Get plugins and active plugins
362
- $plugins = get_plugins();
363
- $activePlugins = get_option( "active_plugins", array() );
364
-
365
- // Active plugins
366
- $output = $this->activePlugins( $plugins, $activePlugins );
367
- $output .= $this->inactivePlugins( $plugins, $activePlugins );
368
-
369
- return $output;
370
- }
371
-
372
- /**
373
- * Multisite Plugins
374
- * @return string
375
- */
376
- public function multiSitePlugins() {
377
- if( !$this->isMultiSite ) {
378
- return '';
379
- }
380
-
381
- $output = $this->header( "Network Active Plugins" );
382
-
383
- $plugins = wp_get_active_network_plugins();
384
- $activePlugins = get_site_option( "active_sitewide_plugins", array() );
385
-
386
- foreach ( $plugins as $pluginPath ) {
387
- $pluginBase = plugin_basename( $pluginPath );
388
-
389
- if( !array_key_exists( $pluginBase, $activePlugins ) ) {
390
- continue;
391
- }
392
-
393
- $plugin = get_plugin_data( $pluginPath );
394
-
395
- $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
396
- }
397
- unset( $plugins, $activePlugins );
398
-
399
- return $output;
400
- }
401
-
402
- /**
403
- * Server Information
404
- * @return string
405
- */
406
- public function server() {
407
- // Server Configuration
408
- $output = $this->header( "Webserver Configuration" );
409
-
410
- $output .= $this->info( "PHP Version:", PHP_VERSION );
411
- $output .= $this->info( "MySQL Version:", $this->di->get( "wpdb" )->db_version() );
412
- $output .= $this->info( "Webserver Info:", $_SERVER["SERVER_SOFTWARE"] );
413
-
414
- return apply_filters( "wpstg_sysinfo_after_webserver_config", $output );
415
- }
416
-
417
- /**
418
- * PHP Configuration
419
- * @return string
420
- */
421
- public function php() {
422
- $output = $this->header( "PHP Configuration" );
423
- $output .= $this->info( "Safe Mode:", ($this->isSafeModeEnabled() ? "Enabled" : "Disabled" ) );
424
- $output .= $this->info( "Memory Limit:", ini_get( "memory_limit" ) );
425
- $output .= $this->info( "Upload Max Size:", ini_get( "upload_max_filesize" ) );
426
- $output .= $this->info( "Post Max Size:", ini_get( "post_max_size" ) );
427
- $output .= $this->info( "Upload Max Filesize:", ini_get( "upload_max_filesize" ) );
428
- $output .= $this->info( "Time Limit:", ini_get( "max_execution_time" ) );
429
- $output .= $this->info( "Max Input Vars:", ini_get( "max_input_vars" ) );
430
-
431
- $displayErrors = ini_get( "display_errors" );
432
- $output .= $this->info( "Display Errors:", ($displayErrors) ? "On ({$displayErrors})" : "N/A" );
433
-
434
- return apply_filters( "wpstg_sysinfo_after_php_config", $output );
435
- }
436
-
437
- /**
438
- * Check if PHP is on Safe Mode
439
- * @return bool
440
- */
441
- public function isSafeModeEnabled() {
442
- return (
443
- version_compare( PHP_VERSION, "5.4.0", '<' ) &&
444
- @ini_get( "safe_mode" )
445
- );
446
- }
447
-
448
- /**
449
- * Checks if function exists or not
450
- * @param string $functionName
451
- * @return string
452
- */
453
- public function isSupported( $functionName ) {
454
- return (function_exists( $functionName )) ? "Supported" : "Not Supported";
455
- }
456
-
457
- /**
458
- * Checks if class or extension is loaded / exists to determine if it is installed or not
459
- * @param string $name
460
- * @param bool $isClass
461
- * @return string
462
- */
463
- public function isInstalled( $name, $isClass = true ) {
464
- if( true === $isClass ) {
465
- return (class_exists( $name )) ? "Installed" : "Not Installed";
466
- } else {
467
- return (extension_loaded( $name )) ? "Installed" : "Not Installed";
468
- }
469
- }
470
-
471
- /**
472
- * Gets Installed Important PHP Extensions
473
- * @return string
474
- */
475
- public function phpExtensions() {
476
- // Important PHP Extensions
477
- $version = curl_version();
478
-
479
- $bitfields = Array(
480
- 'CURL_VERSION_IPV6',
481
- 'CURL_VERSION_KERBEROS4',
482
- 'CURL_VERSION_SSL',
483
- 'CURL_VERSION_LIBZ'
484
- );
485
-
486
- $output = $this->header( "PHP Extensions" );
487
- $output .= $this->info( "cURL:", $this->isSupported( "curl_init" ) );
488
- $output .= $this->info( "cURL version:", $version['version'] );
489
- $output .= $this->info( "cURL ssl version number:", $version['ssl_version'] );
490
- $output .= $this->info( "cURL host:", $version['host'] );
491
- foreach ( $version['protocols'] as $protocols ) {
492
- $output .= $this->info( "cURL protocols:", $protocols );
493
- }
494
- foreach ( $bitfields as $feature ) {
495
- $output .= $feature . ($version['features'] & constant( $feature ) ? ' yes' : ' no') . PHP_EOL;
496
- }
497
-
498
-
499
- $output .= $this->info( "fsockopen:", $this->isSupported( "fsockopen" ) );
500
- $output .= $this->info( "SOAP Client:", $this->isInstalled( "SoapClient" ) );
501
- $output .= $this->info( "Suhosin:", $this->isInstalled( "suhosin", false ) );
502
-
503
- return apply_filters( "wpstg_sysinfo_after_php_ext", $output );
504
- }
505
-
506
- /**
507
- * Check if WP is installed in subdir
508
- * @return boolean
509
- */
510
- private function isSubDir() {
511
- // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
512
- // This is happening much more often than you would expect
513
- $siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
514
- $home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
515
-
516
- if( $home !== $siteurl ) {
517
- return true;
518
- }
519
- return false;
520
- }
521
-
522
- /**
523
- * Check and return prefix of the staging site
524
- */
525
-
526
- /**
527
- * Try to get the staging prefix from wp-config.php of staging site
528
- * @param array $clone
529
- * @return sting
530
- */
531
- private function getStagingPrefix( $clone = array() ) {
532
- // Throw error
533
- $path = ABSPATH . $clone['directoryName'] . DIRECTORY_SEPARATOR . "wp-config.php";
534
- if( false === ($content = @file_get_contents( $path )) ) {
535
- return 'Can\'t find staging wp-config.php';
536
- } else {
537
-
538
- // Get prefix from wp-config.php
539
- //preg_match_all("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
540
- preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
541
- //wp_die(var_dump($matches));
542
-
543
- if( !empty( $matches[1] ) ) {
544
- return $matches[1];
545
- } else {
546
- return 'No table_prefix in wp-config.php';
547
- }
548
- }
549
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
 
551
  }
10
 
11
  // No Direct Access
12
  if( !defined( "WPINC" ) ) {
13
+ die;
14
  }
15
 
16
  /**
19
  */
20
  class SystemInfo extends InjectionAware {
21
 
22
+ /**
23
+ * @var bool
24
+ */
25
+ private $isMultiSite;
26
+
27
+ /**
28
+ *
29
+ * @var obj
30
+ */
31
+ private $helper;
32
+
33
+ /**
34
+ * Initialize class
35
+ */
36
+ public function initialize() {
37
+ $this->isMultiSite = is_multisite();
38
+ $this->helper = new Utils\Helper();
39
+ }
40
+
41
+ /**
42
+ * Magic method
43
+ * @return string
44
+ */
45
+ public function __toString() {
46
+ return $this->get();
47
+ }
48
+
49
+ /**
50
+ * Get System Information as text
51
+ * @return string
52
+ */
53
+ public function get() {
54
+ $output = "### Begin System Info ###" . PHP_EOL . PHP_EOL;
55
+
56
+ $output .= $this->wpstaging();
57
+
58
+ $output .= $this->wp();
59
+
60
+ $output .= $this->site();
61
+
62
+ $output .= $this->getMultisiteInfo();
63
+
64
+ $output .= $this->plugins();
65
+
66
+ $output .= $this->multiSitePlugins();
67
+
68
+ $output .= $this->server();
69
+
70
+ $output .= $this->php();
71
+
72
+ $output .= $this->phpExtensions();
73
+
74
+ $output .= $this->browser();
75
+
76
+ $output .= PHP_EOL . "### End System Info ###";
77
+
78
+ return $output;
79
+ }
80
+
81
+ /**
82
+ * @param string $string
83
+ * @return string
84
+ */
85
+ public function header( $string ) {
86
+ return PHP_EOL . "-- {$string}" . PHP_EOL . PHP_EOL;
87
+ }
88
+
89
+ /**
90
+ * Formating title and the value
91
+ * @param string $title
92
+ * @param string $value
93
+ * @return string
94
+ */
95
+ public function info( $title, $value ) {
96
+ return str_pad( $title, 56, ' ', STR_PAD_RIGHT ) . $value . PHP_EOL;
97
+ }
98
+
99
+ /**
100
+ * Theme Information
101
+ * @return string
102
+ */
103
+ public function theme() {
104
+ // Versions earlier than 3.4
105
+ if( get_bloginfo( "version" ) < "3.4" ) {
106
+ $themeData = get_theme_data( get_stylesheet_directory() . "/style.css" );
107
+ return "{$themeData["Name"]} {$themeData["Version"]}";
108
+ }
109
+
110
+ $themeData = wp_get_theme();
111
+ return "{$themeData->Name} {$themeData->Version}";
112
+ }
113
+
114
+ /**
115
+ * Site Information
116
+ * @return string
117
+ */
118
+ public function site() {
119
+ $output = $this->header( "-- Site Info" );
120
+ $output .= $this->info( "Site URL:", site_url() );
121
+ $output .= $this->info( "Home URL:", $this->helper->get_home_url() );
122
+ $output .= $this->info( "Home Path:", get_home_path() );
123
+ $output .= $this->info( "ABSPATH:", ABSPATH );
124
+ $output .= $this->info( "Installed in subdir:", ( $this->isSubDir() ? 'Yes' : 'No' ) );
125
+
126
+ return apply_filters( "wpstg_sysinfo_after_site_info", $output );
127
+ }
128
+
129
+ /**
130
+ * Multisite information
131
+ * @return string
132
+ */
133
+ private function getMultisiteInfo() {
134
+ if( !$this->isMultiSite ) {
135
+ return '';
136
+ }
137
+
138
+ $multisite = new Multisite();
139
+
140
+ $output = $this->info( "Multisite:", ($this->isMultiSite ? "Yes" : "No" ) );
141
+ $output .= $this->info( "Multisite Blog ID:", get_current_blog_id() );
142
+ $output .= $this->info( "MultiSite URL:", $multisite->getHomeURL() );
143
+ $output .= $this->info( "MultiSite URL without scheme:", $multisite->getHomeUrlWithoutScheme() );
144
+ $output .= $this->info( "MultiSite is Main Site:", is_main_site() ? 'Yes' : 'No' );
145
+
146
+ return apply_filters( "wpstg_sysinfo_after_multisite_info", $output );
147
+ }
148
+
149
+ /**
150
+ * Wp Staging plugin Information
151
+ * @return string
152
+ */
153
+ public function wpstaging() {
154
+ // Get wpstg settings
155
+ $settings = ( object ) get_option( 'wpstg_settings', array() );
156
+
157
+ // Clones data < 1.1.6.x
158
+ $clones = ( object ) get_option( 'wpstg_existing_clones', array() );
159
+ // Clones data version > 2.x
160
+ $clonesBeta = get_option( 'wpstg_existing_clones_beta', array() );
161
+
162
+
163
+ $output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
164
+ $output .= $this->info( "Query Limit:", isset( $settings->queryLimit ) ? $settings->queryLimit : 'undefined' );
165
+ $output .= $this->info( "DB Search & Replace Limit:", isset( $settings->querySRLimit ) ? $settings->querySRLimit : 'undefined' );
166
+ $output .= $this->info( "File Copy Limit:", isset( $settings->fileLimit ) ? $settings->fileLimit : 'undefined' );
167
+ $output .= $this->info( "Batch Size:", isset( $settings->batchSize ) ? $settings->batchSize : 'undefined' );
168
+ $output .= $this->info( "CPU Load:", isset( $settings->cpuLoad ) ? $settings->cpuLoad : 'undefined' );
169
+ $output .= $this->info( "WP in Subdir:", $this->isSubDir() ? 'true' : 'false' );
170
+
171
+ $output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.1.6.x" . PHP_EOL . PHP_EOL;
172
+
173
+ foreach ( $clones as $key => $value ) {
174
+ $output .= $this->info( "Site name & subfolder :", $value );
175
+ }
176
+ $output .= PHP_EOL . PHP_EOL . "-- Available Sites Version > 2.0.x" . PHP_EOL . PHP_EOL;
177
+
178
+ foreach ( $clonesBeta as $key => $clone ) {
179
+
180
+ $path = !empty( $clone['path'] ) ? $clone['path'] : 'undefined';
181
+
182
+ $output .= $this->info( "Number:", isset( $clone['number'] ) ? $clone['number'] : 'undefined' );
183
+ $output .= $this->info( "directoryName:", isset( $clone['directoryName'] ) ? $clone['directoryName'] : 'undefined' );
184
+ $output .= $this->info( "Path:", $path );
185
+ $output .= $this->info( "URL:", isset( $clone['url'] ) ? $clone['url'] : 'undefined' );
186
+ $output .= $this->info( "DB Prefix:", isset( $clone['prefix'] ) ? $clone['prefix'] : 'undefined' );
187
+ $output .= $this->info( "DB Prefix wp-config.php:", $this->getStagingPrefix( $clone ) );
188
+ $output .= $this->info( "WP Staging Version:", isset( $clone['version'] ) ? $clone['version'] : 'undefined' );
189
+ $output .= $this->info( "WP Version:", $this->getStagingWpVersion($path)) . PHP_EOL . PHP_EOL;
190
+ }
191
+
192
+
193
+ $output .= $this->info( "Raw Clones Data:", json_encode( get_option( 'wpstg_existing_clones_beta', 'undefined' ) ) );
194
+
195
+ $output .= '' . PHP_EOL;
196
+
197
+
198
+ //$output .= PHP_EOL . PHP_EOL;
199
+
200
+ $output .= $this->info( "Plugin Version:", get_option( 'wpstg_version', 'undefined' ) );
201
+ $output .= $this->info( "Install Date:", get_option( 'wpstg_installDate', 'undefined' ) );
202
+ $output .= $this->info( "Upgraded from:", get_option( 'wpstg_version_upgraded_from', 'undefined' ) );
203
+ $output .= $this->info( "Is Staging Site:", get_option( 'wpstg_is_staging_site', 'undefined' ) ) . PHP_EOL . PHP_EOL;
204
+
205
+
206
+ return apply_filters( "wpstg_sysinfo_after_wpstaging_info", $output );
207
+ }
208
+
209
+ /**
210
+ * Browser Information
211
+ * @return string
212
+ */
213
+ public function browser() {
214
+ $output = $this->header( "User Browser" );
215
+ $output .= (new Browser);
216
+
217
+ return apply_filters( "wpstg_sysinfo_after_user_browser", $output );
218
+ }
219
+
220
+ /**
221
+ * Frontpage Information when frontpage is set to "page"
222
+ * @return string
223
+ */
224
+ public function frontPage() {
225
+ if( get_option( "show_on_front" ) !== "page" ) {
226
+ return '';
227
+ }
228
+
229
+ $frontPageID = get_option( "page_on_front" );
230
+ $blogPageID = get_option( "page_for_posts" );
231
+
232
+ // Front Page
233
+ $pageFront = ($frontPageID != 0) ? get_the_title( $frontPageID ) . " (#{$frontPageID})" : "Unset";
234
+ // Blog Page ID
235
+ $pageBlog = ($blogPageID != 0) ? get_the_title( $blogPageID ) . " (#{$blogPageID})" : "Unset";
236
+
237
+ $output = $this->info( "Page On Front:", $pageFront );
238
+ $output .= $this->info( "Page For Posts:", $pageBlog );
239
+
240
+ return $output;
241
+ }
242
+
243
+ /**
244
+ * Check wp_remote_post() functionality
245
+ * @return string
246
+ */
247
+ public function wpRemotePost() {
248
+ // Make sure wp_remote_post() is working
249
+ $wpRemotePost = "wp_remote_post() does not work";
250
+
251
+ // Send request
252
+ $response = wp_remote_post(
253
+ "https://www.paypal.com/cgi-bin/webscr", array(
254
+ "sslverify" => false,
255
+ "timeout" => 60,
256
+ "user-agent" => "WPSTG/" . WPStaging::VERSION,
257
+ "body" => array("cmd" => "_notify-validate")
258
+ )
259
+ );
260
+
261
+ // Validate it worked
262
+ if( !is_wp_error( $response ) && 200 <= $response["response"]["code"] && 300 > $response["response"]["code"] ) {
263
+ $wpRemotePost = "wp_remote_post() works";
264
+ }
265
+
266
+ return $this->info( "Remote Post:", $wpRemotePost );
267
+ }
268
+
269
+ /**
270
+ * WordPress Configuration
271
+ * @return string
272
+ */
273
+ public function wp() {
274
+ $output = $this->header( "WordPress Configuration" );
275
+ $output .= $this->info( "Version:", get_bloginfo( "version" ) );
276
+ $output .= $this->info( "Language:", (defined( "WPLANG" ) && WPLANG) ? WPLANG : "en_US" );
277
+
278
+ $permalinkStructure = get_option( "permalink_structure" );
279
+ ;
280
+ $output .= $this->info( "Permalink Structure:", ($permalinkStructure) ? $permalinkStructure : "Default" );
281
+
282
+ $output .= $this->info( "Active Theme:", $this->theme() );
283
+ $output .= $this->info( "Show On Front:", get_option( "show_on_front" ) );
284
+
285
+ // Frontpage information
286
+ $output .= $this->frontPage();
287
+
288
+ // WP Remote Post
289
+ $output .= $this->wpRemotePost();
290
+
291
+ // Table Prefix
292
+ $wpDB = $this->di->get( "wpdb" );
293
+ $tablePrefix = "DB Prefix: " . $wpDB->prefix . ' ';
294
+ $tablePrefix .= "Length: " . strlen( $wpDB->prefix ) . " Status: ";
295
+ $tablePrefix .= (strlen( $wpDB->prefix ) > 16) ? " ERROR: Too long" : " Acceptable";
296
+
297
+ $output .= $this->info( "Table Prefix:", $tablePrefix );
298
+
299
+ // Constants
300
+ $output .= $this->info( "WP Content Path:", WP_CONTENT_DIR );
301
+ $output .= $this->info( "WP Plugin Dir:", WP_PLUGIN_DIR );
302
+ if( defined( 'UPLOADS' ) )
303
+ $output .= $this->info( "WP UPLOADS CONST:", UPLOADS );
304
+ $uploads = wp_upload_dir();
305
+ $output .= $this->info( "WP Uploads Dir:", $uploads['basedir'] );
306
+ if( defined( 'WP_TEMP_DIR' ) )
307
+ $output .= $this->info( "WP Temp Dir:", WP_TEMP_DIR );
308
+
309
+ // WP Debug
310
+ $output .= $this->info( "WP_DEBUG:", (defined( "WP_DEBUG" )) ? WP_DEBUG ? "Enabled" : "Disabled" : "Not set" );
311
+ $output .= $this->info( "Memory Limit:", WP_MEMORY_LIMIT );
312
+ $output .= $this->info( "Registered Post Stati:", implode( ", ", \get_post_stati() ) );
313
+
314
+ return apply_filters( "wpstg_sysinfo_after_wpstg_config", $output );
315
+ }
316
+
317
+ /**
318
+ * List of Active Plugins
319
+ * @param array $plugins
320
+ * @param array $activePlugins
321
+ * @return string
322
+ */
323
+ public function activePlugins( $plugins, $activePlugins ) {
324
+ $output = $this->header( "WordPress Active Plugins" );
325
+
326
+ foreach ( $plugins as $path => $plugin ) {
327
+ if( !in_array( $path, $activePlugins ) ) {
328
+ continue;
329
+ }
330
+
331
+ $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
332
+ }
333
+
334
+ return apply_filters( "wpstg_sysinfo_after_wordpress_plugins", $output );
335
+ }
336
+
337
+ /**
338
+ * List of Inactive Plugins
339
+ * @param array $plugins
340
+ * @param array $activePlugins
341
+ * @return string
342
+ */
343
+ public function inactivePlugins( $plugins, $activePlugins ) {
344
+ $output = $this->header( "WordPress Inactive Plugins" );
345
+
346
+ foreach ( $plugins as $path => $plugin ) {
347
+ if( in_array( $path, $activePlugins ) ) {
348
+ continue;
349
+ }
350
+
351
+ $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
352
+ }
353
+
354
+ return apply_filters( "wpstg_sysinfo_after_wordpress_plugins_inactive", $output );
355
+ }
356
+
357
+ /**
358
+ * Get list of active and inactive plugins
359
+ * @return string
360
+ */
361
+ public function plugins() {
362
+ // Get plugins and active plugins
363
+ $plugins = get_plugins();
364
+ $activePlugins = get_option( "active_plugins", array() );
365
+
366
+ // Active plugins
367
+ $output = $this->activePlugins( $plugins, $activePlugins );
368
+ $output .= $this->inactivePlugins( $plugins, $activePlugins );
369
+
370
+ return $output;
371
+ }
372
+
373
+ /**
374
+ * Multisite Plugins
375
+ * @return string
376
+ */
377
+ public function multiSitePlugins() {
378
+ if( !$this->isMultiSite ) {
379
+ return '';
380
+ }
381
+
382
+ $output = $this->header( "Network Active Plugins" );
383
+
384
+ $plugins = wp_get_active_network_plugins();
385
+ $activePlugins = get_site_option( "active_sitewide_plugins", array() );
386
+
387
+ foreach ( $plugins as $pluginPath ) {
388
+ $pluginBase = plugin_basename( $pluginPath );
389
+
390
+ if( !array_key_exists( $pluginBase, $activePlugins ) ) {
391
+ continue;
392
+ }
393
+
394
+ $plugin = get_plugin_data( $pluginPath );
395
+
396
+ $output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
397
+ }
398
+ unset( $plugins, $activePlugins );
399
+
400
+ return $output;
401
+ }
402
+
403
+ /**
404
+ * Server Information
405
+ * @return string
406
+ */
407
+ public function server() {
408
+ // Server Configuration
409
+ $output = $this->header( "Webserver Configuration" );
410
+
411
+ $output .= $this->info( "PHP Version:", PHP_VERSION );
412
+ $output .= $this->info( "MySQL Version:", $this->di->get( "wpdb" )->db_version() );
413
+ $output .= $this->info( "Webserver Info:", $_SERVER["SERVER_SOFTWARE"] );
414
+
415
+ return apply_filters( "wpstg_sysinfo_after_webserver_config", $output );
416
+ }
417
+
418
+ /**
419
+ * PHP Configuration
420
+ * @return string
421
+ */
422
+ public function php() {
423
+ $output = $this->header( "PHP Configuration" );
424
+ $output .= $this->info( "Safe Mode:", ($this->isSafeModeEnabled() ? "Enabled" : "Disabled" ) );
425
+ $output .= $this->info( "Memory Limit:", ini_get( "memory_limit" ) );
426
+ $output .= $this->info( "Upload Max Size:", ini_get( "upload_max_filesize" ) );
427
+ $output .= $this->info( "Post Max Size:", ini_get( "post_max_size" ) );
428
+ $output .= $this->info( "Upload Max Filesize:", ini_get( "upload_max_filesize" ) );
429
+ $output .= $this->info( "Time Limit:", ini_get( "max_execution_time" ) );
430
+ $output .= $this->info( "Max Input Vars:", ini_get( "max_input_vars" ) );
431
+
432
+ $displayErrors = ini_get( "display_errors" );
433
+ $output .= $this->info( "Display Errors:", ($displayErrors) ? "On ({$displayErrors})" : "N/A" );
434
+
435
+ return apply_filters( "wpstg_sysinfo_after_php_config", $output );
436
+ }
437
+
438
+ /**
439
+ * Check if PHP is on Safe Mode
440
+ * @return bool
441
+ */
442
+ public function isSafeModeEnabled() {
443
+ return (
444
+ version_compare( PHP_VERSION, "5.4.0", '<' ) &&
445
+ @ini_get( "safe_mode" )
446
+ );
447
+ }
448
+
449
+ /**
450
+ * Checks if function exists or not
451
+ * @param string $functionName
452
+ * @return string
453
+ */
454
+ public function isSupported( $functionName ) {
455
+ return (function_exists( $functionName )) ? "Supported" : "Not Supported";
456
+ }
457
+
458
+ /**
459
+ * Checks if class or extension is loaded / exists to determine if it is installed or not
460
+ * @param string $name
461
+ * @param bool $isClass
462
+ * @return string
463
+ */
464
+ public function isInstalled( $name, $isClass = true ) {
465
+ if( true === $isClass ) {
466
+ return (class_exists( $name )) ? "Installed" : "Not Installed";
467
+ } else {
468
+ return (extension_loaded( $name )) ? "Installed" : "Not Installed";
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Gets Installed Important PHP Extensions
474
+ * @return string
475
+ */
476
+ public function phpExtensions() {
477
+ // Important PHP Extensions
478
+ $version = curl_version();
479
+
480
+ $bitfields = Array(
481
+ 'CURL_VERSION_IPV6',
482
+ 'CURL_VERSION_KERBEROS4',
483
+ 'CURL_VERSION_SSL',
484
+ 'CURL_VERSION_LIBZ'
485
+ );
486
+
487
+ $output = $this->header( "PHP Extensions" );
488
+ $output .= $this->info( "cURL:", $this->isSupported( "curl_init" ) );
489
+ $output .= $this->info( "cURL version:", $version['version'] );
490
+ $output .= $this->info( "cURL ssl version number:", $version['ssl_version'] );
491
+ $output .= $this->info( "cURL host:", $version['host'] );
492
+ foreach ( $version['protocols'] as $protocols ) {
493
+ $output .= $this->info( "cURL protocols:", $protocols );
494
+ }
495
+ foreach ( $bitfields as $feature ) {
496
+ $output .= $feature . ($version['features'] & constant( $feature ) ? ' yes' : ' no') . PHP_EOL;
497
+ }
498
+
499
+
500
+ $output .= $this->info( "fsockopen:", $this->isSupported( "fsockopen" ) );
501
+ $output .= $this->info( "SOAP Client:", $this->isInstalled( "SoapClient" ) );
502
+ $output .= $this->info( "Suhosin:", $this->isInstalled( "suhosin", false ) );
503
+
504
+ return apply_filters( "wpstg_sysinfo_after_php_ext", $output );
505
+ }
506
+
507
+ /**
508
+ * Check if WP is installed in subdir
509
+ * @return boolean
510
+ */
511
+ private function isSubDir() {
512
+ // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
513
+ // This is happening much more often than you would expect
514
+ $siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
515
+ $home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
516
+
517
+ if( $home !== $siteurl ) {
518
+ return true;
519
+ }
520
+ return false;
521
+ }
522
+
523
+ /**
524
+ * Check and return prefix of the staging site
525
+ */
526
+
527
+ /**
528
+ * Try to get the staging prefix from wp-config.php of staging site
529
+ * @param array $clone
530
+ * @return sting
531
+ */
532
+ private function getStagingPrefix( $clone = array() ) {
533
+ // Throw error
534
+ $path = ABSPATH . $clone['directoryName'] . DIRECTORY_SEPARATOR . "wp-config.php";
535
+ if( false === ($content = @file_get_contents( $path )) ) {
536
+ return 'Can\'t find staging wp-config.php';
537
+ } else {
538
+
539
+ // Get prefix from wp-config.php
540
+ //preg_match_all("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
541
+ preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
542
+ //wp_die(var_dump($matches));
543
+
544
+ if( !empty( $matches[1] ) ) {
545
+ return $matches[1];
546
+ } else {
547
+ return 'No table_prefix in wp-config.php';
548
+ }
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Get staging site wordpress version number
554
+ * @return string
555
+ */
556
+ private function getStagingWpVersion( $path ) {
557
+
558
+ if( $path === 'undefined' ) {
559
+ return "Error: Cannot detect WP version";
560
+ }
561
+
562
+ // Get version number of wp staging
563
+ $file = $path . 'wp-includes/version.php';
564
+ $versionStaging = file_get_contents( $file );
565
+
566
+ preg_match( "/\\\$wp_version.*=.*'(.*)';/", $versionStaging, $matches );
567
+
568
+ $error = '';
569
+ if( empty( $matches[1] ) ) {
570
+ $error .= "Error: Cannot detect WP version";
571
+ }
572
+ return $matches[1];
573
+
574
+ }
575
 
576
  }
apps/Backend/Optimizer/Optimizer.php CHANGED
@@ -24,13 +24,17 @@ class Optimizer {
24
  }
25
 
26
  public function installOptimizer() {
 
 
 
 
27
  if( wp_mkdir_p( $this->mudir ) ) {
28
  $this->copy();
29
  }
30
  return false;
31
  }
32
 
33
- public function unstallOptimizer() {
34
  if( file_exists( $this->dest ) && !unlink( $this->dest ) ) {
35
  return false;
36
  }
@@ -42,4 +46,26 @@ class Optimizer {
42
  }
43
  }
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
24
  }
25
 
26
  public function installOptimizer() {
27
+ if (file_exists( $this->dest ) && false === $this->mustUpdateOptimizer()){
28
+ return false;
29
+ }
30
+
31
  if( wp_mkdir_p( $this->mudir ) ) {
32
  $this->copy();
33
  }
34
  return false;
35
  }
36
 
37
+ public function uninstallOptimizer() {
38
  if( file_exists( $this->dest ) && !unlink( $this->dest ) ) {
39
  return false;
40
  }
46
  }
47
  }
48
 
49
+ /**
50
+ * Check if the Optimizer must use plugin must be updated
51
+ * @return boolean
52
+ */
53
+ private function mustUpdateOptimizer(){
54
+ $isVersionNumber = defined('WPSTG_OPTIMIZER_VERSION') ? WPSTG_OPTIMIZER_VERSION : false;
55
+
56
+ $update = false;
57
+
58
+ if (false === $isVersionNumber){
59
+ return true;
60
+ }
61
+
62
+ $mustVersionNumber = defined('WPSTG_OPTIMIZER_MUVERSION') ? WPSTG_OPTIMIZER_MUVERSION : false;
63
+
64
+ if ($mustVersionNumber){
65
+ $update = version_compare($isVersionNumber, $mustVersionNumber, '!=');
66
+ }
67
+
68
+ return $update;
69
+ }
70
+
71
  }
apps/Backend/Optimizer/wp-staging-optimizer.php CHANGED
@@ -10,6 +10,11 @@
10
  Credit: Original version is made by Delicious Brains (WP Migrate DB). Thank you guys!
11
  */
12
 
 
 
 
 
 
13
  /**
14
  * Get plugins dir
15
  * @return string
10
  Credit: Original version is made by Delicious Brains (WP Migrate DB). Thank you guys!
11
  */
12
 
13
+
14
+ if ( ! defined( 'WPSTG_OPTIMIZER_VERSION' ) ){
15
+ define( 'WPSTG_OPTIMIZER_VERSION', 1.1 );
16
+ }
17
+
18
  /**
19
  * Get plugins dir
20
  * @return string
apps/Backend/Upgrade/Upgrade.php CHANGED
@@ -5,6 +5,9 @@ namespace WPStaging\Backend\Upgrade;
5
  use WPStaging\WPStaging;
6
  use WPStaging\Utils\Logger;
7
  use WPStaging\Utils\Helper;
 
 
 
8
 
9
  /**
10
  * Upgrade Class
@@ -13,265 +16,292 @@ use WPStaging\Utils\Helper;
13
  */
14
  // No Direct Access
15
  if( !defined( "WPINC" ) ) {
16
- die;
17
  }
18
 
19
  class Upgrade {
20
 
21
- /**
22
- * Previous Version number
23
- * @var string
24
- */
25
- private $previousVersion;
26
-
27
- /**
28
- * Clone data
29
- * @var obj
30
- */
31
- private $clones;
32
-
33
- /**
34
- * Global settings
35
- * @var type obj
36
- */
37
- private $settings;
38
-
39
- /**
40
- * Cron data
41
- * @var obj
42
- */
43
- private $cron;
44
-
45
- /**
46
- * Logger
47
- * @var obj
48
- */
49
- private $logger;
50
-
51
- /**
52
- * db object
53
- * @var obj
54
- */
55
- private $db;
56
-
57
- public function __construct() {
58
-
59
- // add wpstg_weekly_event to cron events
60
- $this->cron = new \WPStaging\Cron\Cron;
61
-
62
- // Previous version
63
- $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
64
-
65
- $this->settings = (object)get_option( "wpstg_settings", array() );
66
-
67
- // Logger
68
- $this->logger = new Logger;
69
-
70
- // db
71
- $this->db = WPStaging::getInstance()->get( "wpdb" );
72
- }
73
-
74
- public function doUpgrade() {
75
- $this->upgrade2_0_3();
76
- $this->upgrade2_1_2();
77
- $this->upgrade2_2_0();
78
- $this->setVersion();
79
- }
80
-
81
- /**
82
- * Upgrade method 2.2.0
83
- */
84
- public function upgrade2_2_0() {
85
- // Previous version lower than 2.2.0
86
- if( version_compare( $this->previousVersion, '2.2.0', '<' ) ) {
87
- $this->upgradeElements();
88
- }
89
- }
90
-
91
- /**
92
- * Add missing elements
93
- */
94
- private function upgradeElements() {
95
- // Current options
96
- $sites = get_option( "wpstg_existing_clones_beta", array() );
97
-
98
- if( false === $sites || count( $sites ) === 0 ) {
99
- return;
100
- }
101
-
102
- // Check if key prefix is missing and add it
103
- foreach ( $sites as $key => $value ) {
104
- if( empty( $sites[$key]['directoryName'] ) ) {
105
- continue;
106
- }
107
- //!empty( $sites[$key]['prefix'] ) ? $sites[$key]['prefix'] = $value['prefix'] : $sites[$key]['prefix'] = $key . '_';
108
- !empty( $sites[$key]['prefix'] ) ?
109
- $sites[$key]['prefix'] = $value['prefix'] :
110
- $sites[$key]['prefix'] = $this->getStagingPrefix( $sites[$key]['directoryName'] );
111
- }
112
-
113
- if( !empty( $sites ) ) {
114
- update_option( 'wpstg_existing_clones_beta', $sites );
115
- }
116
- }
117
-
118
- /**
119
- * Check and return prefix of the staging site
120
- * @param string $directory
121
- * @return string
122
- */
123
- private function getStagingPrefix( $directory ) {
124
- // Try to get staging prefix from wp-config.php of staging site
125
-
126
- $path = ABSPATH . $directory . "/wp-config.php";
127
- if( false === ($content = @file_get_contents( $path )) ) {
128
- $prefix = "";
129
- } else {
130
- // Get prefix from wp-config.php
131
- preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
132
-
133
- if( !empty( $matches[1] ) ) {
134
- $prefix = $matches[1];
135
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  $prefix = "";
137
- }
138
- }
139
- // return result: Check if staging prefix is the same as the live prefix
140
- if( $this->db->prefix != $prefix ) {
141
- return $prefix;
142
- } else {
143
- return "";
144
- }
145
- }
146
-
147
- /**
148
- * NEW INSTALLATION
149
- * Upgrade method 2.0.3
150
- */
151
- public function upgrade2_0_3() {
152
- // Previous version lower than 2.0.2 or new install
153
- if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
154
- $this->upgradeOptions();
155
- $this->upgradeClonesBeta();
156
- $this->upgradeNotices();
157
- }
158
- }
159
-
160
- /**
161
- * Upgrade method 2.1.2
162
- * Sanitize the clone key value.
163
- */
164
- private function upgrade2_1_2() {
165
-
166
- // Current options
167
- $this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
168
-
169
- if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.1.7', '<' ) ) {
170
- foreach ( $this->clonesBeta as $key => $value ) {
171
- unset( $this->clonesBeta[$key] );
172
- $this->clonesBeta[preg_replace( "#\W+#", '-', strtolower( $key ) )] = $value;
173
- }
174
- if( empty( $this->clonesBeta ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  return false;
176
-
177
- update_option( 'wpstg_existing_clones_beta', $this->clonesBeta );
178
- }
179
- }
180
-
181
- /**
182
- * Upgrade routine for new install
183
- */
184
- private function upgradeOptions() {
185
- // Write some default vars
186
- add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
187
- $this->settings->optimizer = 1;
188
- update_option( 'wpstg_settings', $this->settings );
189
- }
190
-
191
- /**
192
- * Write new version number into db
193
- * return bool
194
- */
195
- private function setVersion() {
196
- // Check if version number in DB is lower than version number in current plugin
197
- if( version_compare( $this->previousVersion, \WPStaging\WPStaging::VERSION, '<' ) ) {
198
- // Update Version number
199
- update_option( 'wpstg_version', preg_replace( '/[^0-9.].*/', '', \WPStaging\WPStaging::VERSION ) );
200
- // Update "upgraded from" version number
201
- update_option( 'wpstg_version_upgraded_from', preg_replace( '/[^0-9.].*/', '', $this->previousVersion ) );
202
-
203
- return true;
204
- }
205
- return false;
206
- }
207
-
208
- /**
209
- * Create a new db option for beta version 2.0.2
210
- * @return bool
211
- */
212
- private function upgradeClonesBeta() {
213
-
214
-
215
- $new = array();
216
-
217
- if( empty( $this->clones ) || count( $this->clones ) === 0 ) {
218
- return false;
219
- }
220
-
221
-
222
- foreach ( $this->clones as $key => &$value ) {
223
-
224
- // Skip the rest of the loop if data is already compatible to wpstg 2.0.2
225
- if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
226
- continue;
227
- }
228
-
229
- $new[$value]['directoryName'] = $value;
230
- $new[$value]['path'] = get_home_path() . $value;
231
- $helper = new Helper();
232
- $new[$value]['url'] = $helper->get_home_url() . "/" . $value;
233
- $new[$value]['number'] = $key + 1;
234
- $new[$value]['version'] = $this->previousVersion;
235
- //$new[$value]['prefix'] = $value;
236
- }
237
- unset( $value );
238
-
239
- if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
240
- $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
241
- }
242
- }
243
-
244
- /**
245
- * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
246
- * Fix some logical db options
247
- */
248
- private function upgradeNotices() {
249
- $poll = get_option( "wpstg_start_poll", false );
250
- $beta = get_option( "wpstg_hide_beta", false );
251
- $rating = get_option( "wpstg_RatingDiv", false );
252
-
253
- if( $poll && $poll === "no" ) {
254
- update_option( 'wpstg_poll', 'no' );
255
- }
256
- if( $beta && $beta === "yes" ) {
257
- update_option( 'wpstg_beta', 'no' );
258
- }
259
- if( $rating && $rating === 'yes' ) {
260
- update_option( 'wpstg_rating', 'no' );
261
- }
262
- }
263
-
264
- /**
265
- * Throw a errror message via json and stop further execution
266
- * @param string $message
267
- */
268
- private function returnException( $message = '' ) {
269
- wp_die( json_encode( array(
270
- 'job' => isset( $this->options->currentJob ) ? $this->options->currentJob : '',
271
- 'status' => false,
272
- 'message' => $message,
273
- 'error' => true
274
- ) ) );
275
- }
276
 
277
  }
5
  use WPStaging\WPStaging;
6
  use WPStaging\Utils\Logger;
7
  use WPStaging\Utils\Helper;
8
+ use WPStaging\Utils\IISWebConfig;
9
+ use WPStaging\Utils\Htaccess;
10
+ use WPStaging\Utils\Filesystem;
11
 
12
  /**
13
  * Upgrade Class
16
  */
17
  // No Direct Access
18
  if( !defined( "WPINC" ) ) {
19
+ die;
20
  }
21
 
22
  class Upgrade {
23
 
24
+ /**
25
+ * Previous Version number
26
+ * @var string
27
+ */
28
+ private $previousVersion;
29
+
30
+ /**
31
+ * Clone data
32
+ * @var obj
33
+ */
34
+ private $clones;
35
+
36
+ /**
37
+ * Global settings
38
+ * @var type obj
39
+ */
40
+ private $settings;
41
+
42
+ /**
43
+ * Cron data
44
+ * @var obj
45
+ */
46
+ private $cron;
47
+
48
+ /**
49
+ * Logger
50
+ * @var obj
51
+ */
52
+ private $logger;
53
+
54
+ /**
55
+ * db object
56
+ * @var obj
57
+ */
58
+ private $db;
59
+
60
+ public function __construct() {
61
+
62
+ // add wpstg_weekly_event to cron events
63
+ $this->cron = new \WPStaging\Cron\Cron;
64
+
65
+ // Previous version
66
+ $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
67
+
68
+ $this->settings = ( object ) get_option( "wpstg_settings", array() );
69
+
70
+ // Logger
71
+ $this->logger = new Logger;
72
+
73
+ // db
74
+ $this->db = WPStaging::getInstance()->get( "wpdb" );
75
+ }
76
+
77
+ public function doUpgrade() {
78
+ $this->upgrade2_0_3();
79
+ $this->upgrade2_1_2();
80
+ $this->upgrade2_2_0();
81
+ $this->upgrade2_4_4();
82
+
83
+ $this->setVersion();
84
+ }
85
+
86
+ private function upgrade2_4_4() {
87
+ // Previous version lower than 2.4.4
88
+ if( version_compare( $this->previousVersion, '2.4.4', '<' ) ) {
89
+ // Add htaccess to wp staging uploads folder
90
+ $htaccess = new Htaccess();
91
+ $htaccess->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . '.htaccess' );
92
+ $htaccess->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/.htaccess' );
93
+
94
+ // Add litespeed htaccess to wp root folder
95
+ if( extension_loaded( 'litespeed' ) ) {
96
+ $htaccess->createLitespeed( ABSPATH . '.htaccess' );
97
+ }
98
+
99
+ // Create empty index.php in wp staging uploads folder
100
+ $filesystem = new Filesystem();
101
+ $filesystem->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'index.php', "<?php // silence" );
102
+ $filesystem->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/index.php', "<?php // silence" );
103
+
104
+ // create web.config file for IIS in wp staging uploads folder
105
+ $webconfig = new IISWebConfig();
106
+ $webconfig->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'web.config' );
107
+ $webconfig->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/web.config' );
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Upgrade method 2.2.0
113
+ */
114
+ public function upgrade2_2_0() {
115
+ // Previous version lower than 2.2.0
116
+ if( version_compare( $this->previousVersion, '2.2.0', '<' ) ) {
117
+ $this->upgradeElements();
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Add missing elements
123
+ */
124
+ private function upgradeElements() {
125
+ // Current options
126
+ $sites = get_option( "wpstg_existing_clones_beta", array() );
127
+
128
+ if( false === $sites || count( $sites ) === 0 ) {
129
+ return;
130
+ }
131
+
132
+ // Check if key prefix is missing and add it
133
+ foreach ( $sites as $key => $value ) {
134
+ if( empty( $sites[$key]['directoryName'] ) ) {
135
+ continue;
136
+ }
137
+ //!empty( $sites[$key]['prefix'] ) ? $sites[$key]['prefix'] = $value['prefix'] : $sites[$key]['prefix'] = $key . '_';
138
+ !empty( $sites[$key]['prefix'] ) ?
139
+ $sites[$key]['prefix'] = $value['prefix'] :
140
+ $sites[$key]['prefix'] = $this->getStagingPrefix( $sites[$key]['directoryName'] );
141
+ }
142
+
143
+ if( !empty( $sites ) ) {
144
+ update_option( 'wpstg_existing_clones_beta', $sites );
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Check and return prefix of the staging site
150
+ * @param string $directory
151
+ * @return string
152
+ */
153
+ private function getStagingPrefix( $directory ) {
154
+ // Try to get staging prefix from wp-config.php of staging site
155
+
156
+ $path = ABSPATH . $directory . "/wp-config.php";
157
+ if( false === ($content = @file_get_contents( $path )) ) {
158
  $prefix = "";
159
+ } else {
160
+ // Get prefix from wp-config.php
161
+ preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
162
+
163
+ if( !empty( $matches[1] ) ) {
164
+ $prefix = $matches[1];
165
+ } else {
166
+ $prefix = "";
167
+ }
168
+ }
169
+ // return result: Check if staging prefix is the same as the live prefix
170
+ if( $this->db->prefix != $prefix ) {
171
+ return $prefix;
172
+ } else {
173
+ return "";
174
+ }
175
+ }
176
+
177
+ /**
178
+ * NEW INSTALLATION
179
+ * Upgrade method 2.0.3
180
+ */
181
+ public function upgrade2_0_3() {
182
+ // Previous version lower than 2.0.2 or new install
183
+ if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
184
+ $this->upgradeOptions();
185
+ $this->upgradeClonesBeta();
186
+ $this->upgradeNotices();
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Upgrade method 2.1.2
192
+ * Sanitize the clone key value.
193
+ */
194
+ private function upgrade2_1_2() {
195
+
196
+ // Current options
197
+ $this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
198
+
199
+ if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.1.7', '<' ) ) {
200
+ foreach ( $this->clonesBeta as $key => $value ) {
201
+ unset( $this->clonesBeta[$key] );
202
+ $this->clonesBeta[preg_replace( "#\W+#", '-', strtolower( $key ) )] = $value;
203
+ }
204
+ if( empty( $this->clonesBeta ) )
205
+ return false;
206
+
207
+ update_option( 'wpstg_existing_clones_beta', $this->clonesBeta );
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Upgrade routine for new install
213
+ */
214
+ private function upgradeOptions() {
215
+ // Write some default vars
216
+ add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
217
+ $this->settings->optimizer = 1;
218
+ update_option( 'wpstg_settings', $this->settings );
219
+ }
220
+
221
+ /**
222
+ * Write new version number into db
223
+ * return bool
224
+ */
225
+ private function setVersion() {
226
+ // Check if version number in DB is lower than version number in current plugin
227
+ if( version_compare( $this->previousVersion, \WPStaging\WPStaging::VERSION, '<' ) ) {
228
+ // Update Version number
229
+ update_option( 'wpstg_version', preg_replace( '/[^0-9.].*/', '', \WPStaging\WPStaging::VERSION ) );
230
+ // Update "upgraded from" version number
231
+ update_option( 'wpstg_version_upgraded_from', preg_replace( '/[^0-9.].*/', '', $this->previousVersion ) );
232
+
233
+ return true;
234
+ }
235
+ return false;
236
+ }
237
+
238
+ /**
239
+ * Create a new db option for beta version 2.0.2
240
+ * @return bool
241
+ */
242
+ private function upgradeClonesBeta() {
243
+
244
+
245
+ $new = array();
246
+
247
+ if( empty( $this->clones ) || count( $this->clones ) === 0 ) {
248
  return false;
249
+ }
250
+
251
+
252
+ foreach ( $this->clones as $key => &$value ) {
253
+
254
+ // Skip the rest of the loop if data is already compatible to wpstg 2.0.2
255
+ if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
256
+ continue;
257
+ }
258
+
259
+ $new[$value]['directoryName'] = $value;
260
+ $new[$value]['path'] = get_home_path() . $value;
261
+ $helper = new Helper();
262
+ $new[$value]['url'] = $helper->get_home_url() . "/" . $value;
263
+ $new[$value]['number'] = $key + 1;
264
+ $new[$value]['version'] = $this->previousVersion;
265
+ //$new[$value]['prefix'] = $value;
266
+ }
267
+ unset( $value );
268
+
269
+ if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
270
+ $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
276
+ * Fix some logical db options
277
+ */
278
+ private function upgradeNotices() {
279
+ $poll = get_option( "wpstg_start_poll", false );
280
+ $beta = get_option( "wpstg_hide_beta", false );
281
+ $rating = get_option( "wpstg_RatingDiv", false );
282
+
283
+ if( $poll && $poll === "no" ) {
284
+ update_option( 'wpstg_poll', 'no' );
285
+ }
286
+ if( $beta && $beta === "yes" ) {
287
+ update_option( 'wpstg_beta', 'no' );
288
+ }
289
+ if( $rating && $rating === 'yes' ) {
290
+ update_option( 'wpstg_rating', 'no' );
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Throw a errror message via json and stop further execution
296
+ * @param string $message
297
+ */
298
+ private function returnException( $message = '' ) {
299
+ wp_die( json_encode( array(
300
+ 'job' => isset( $this->options->currentJob ) ? $this->options->currentJob : '',
301
+ 'status' => false,
302
+ 'message' => $message,
303
+ 'error' => true
304
+ ) ) );
305
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
 
307
  }
apps/Core/Utils/Filesystem.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Utils;
4
+
5
+ // No Direct Access
6
+ if( !defined( "WPINC" ) ) {
7
+ die;
8
+ }
9
+
10
+ class Filesystem {
11
+
12
+ /**
13
+ * Create a file with content
14
+ *
15
+ * @param string $path Path to the file
16
+ * @param string $content Content of the file
17
+ * @return boolean
18
+ */
19
+ public function create( $path, $content ) {
20
+ if( !@file_exists( $path ) ) {
21
+ if( !@is_writable( dirname( $path ) ) ) {
22
+ return false;
23
+ }
24
+
25
+ if( !@touch( $path ) ) {
26
+ return false;
27
+ }
28
+ } elseif( !@is_writable( $path ) ) {
29
+ return false;
30
+ }
31
+
32
+ $written = false;
33
+ if( ( $handle = @fopen( $path, 'w' ) ) !== false ) {
34
+ if( @fwrite( $handle, $content ) !== false ) {
35
+ $written = true;
36
+ }
37
+
38
+ @fclose( $handle );
39
+ }
40
+
41
+ return $written;
42
+ }
43
+
44
+ /**
45
+ * Create a file with marker and content
46
+ *
47
+ * @param string $path Path to the file
48
+ * @param string $marker Name of the marker
49
+ * @param string $content Content of the file
50
+ * @return boolean
51
+ */
52
+ public function createWithMarkers( $path, $marker, $content ) {
53
+ return @insert_with_markers( $path, $marker, $content );
54
+ }
55
+
56
+ }
apps/Core/Utils/Htaccess.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Utils;
4
+
5
+ use WPStaging\Utils\Filesystem;
6
+
7
+ // No Direct Access
8
+ if (!defined("WPINC"))
9
+ {
10
+ die;
11
+ }
12
+
13
+ /**
14
+ * Description of Htaccess
15
+ *
16
+ * @author IronMan
17
+ */
18
+ class Htaccess {
19
+
20
+ /**
21
+ *
22
+ * @var obj
23
+ */
24
+ public $filesystem;
25
+
26
+ public function __construct() {
27
+ $this->filesystem = new Filesystem();
28
+ }
29
+
30
+ /**
31
+ * Create .htaccess file
32
+ *
33
+ * @param string $path Path to file
34
+ * @return boolean
35
+ */
36
+ public function create( $path ) {
37
+ return $this->filesystem->create( $path, implode( PHP_EOL, array(
38
+ '<IfModule mod_mime.c>',
39
+ 'AddType application/octet-stream .log',
40
+ '</IfModule>',
41
+ '<IfModule mod_dir.c>',
42
+ 'DirectoryIndex index.php',
43
+ '</IfModule>',
44
+ '<IfModule mod_autoindex.c>',
45
+ 'Options -Indexes',
46
+ '</IfModule>',
47
+ ) ) );
48
+ }
49
+
50
+ /**
51
+ * Create .htaccess file (LiteSpeed)
52
+ *
53
+ * @param string $path Path to file
54
+ * @return boolean
55
+ */
56
+ public function createLitespeed( $path ) {
57
+ return $this->filesystem->createWithMarkers( $path, 'LiteSpeed', array(
58
+ '<IfModule Litespeed>',
59
+ 'SetEnv noabort 1',
60
+ '</IfModule>',
61
+ ) );
62
+ }
63
+
64
+ }
apps/Core/Utils/IISWebConfig.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Utils;
4
+
5
+ use WPStaging\Utils\Filesystem;
6
+
7
+ // No Direct Access
8
+ if( !defined( "WPINC" ) ) {
9
+ die;
10
+ }
11
+
12
+ /**
13
+ * Description of IISWEbConfig
14
+ *
15
+ * @author IronMan
16
+ */
17
+ class IISWebConfig {
18
+
19
+ /**
20
+ *
21
+ * @var obj
22
+ */
23
+ private $filesystem;
24
+
25
+ public function __construct() {
26
+ $this->filesystem = new Filesystem();
27
+ }
28
+
29
+ /**
30
+ * Create web.config file
31
+ *
32
+ * @param string $path Path to file
33
+ * @return boolean
34
+ */
35
+ public function create( $path ) {
36
+ return $this->filesystem->create( $path, implode( PHP_EOL, array(
37
+ '<configuration>',
38
+ '<system.webServer>',
39
+ '<staticContent>',
40
+ '<mimeMap fileExtension=".log" mimeType="application/octet-stream" />',
41
+ '</staticContent>',
42
+ '<defaultDocument>',
43
+ '<files>',
44
+ '<add value="index.php" />',
45
+ '</files>',
46
+ '</defaultDocument>',
47
+ '<directoryBrowse enabled="false" />',
48
+ '</system.webServer>',
49
+ '</configuration>',
50
+ ) ) );
51
+ }
52
+
53
+ }
apps/Core/WPStaging.php CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
29
  /**
30
  * Plugin version
31
  */
32
- const VERSION = "2.4.3";
33
 
34
  /**
35
  * Plugin name
@@ -44,7 +44,7 @@ final class WPStaging {
44
  /**
45
  * Compatible WP Version
46
  */
47
- const WP_COMPATIBLE = "5.0.0";
48
 
49
  public $wpPath;
50
 
29
  /**
30
  * Plugin version
31
  */
32
+ const VERSION = "2.4.5";
33
 
34
  /**
35
  * Plugin name
44
  /**
45
  * Compatible WP Version
46
  */
47
+ const WP_COMPATIBLE = "5.0.1";
48
 
49
  public $wpPath;
50
 
install.php CHANGED
@@ -5,41 +5,69 @@ namespace WPStaging;
5
  use WPStaging\WPStaging;
6
  use WPStaging\Backend\Optimizer\Optimizer;
7
  use WPStaging\Cron\Cron;
 
 
 
 
8
 
9
- /**
10
- * Install Function
11
- *
12
- */
13
  // Exit if accessed directly
14
  if( !defined( 'ABSPATH' ) )
15
- exit;
16
 
17
- /*
18
- * Install Multisite
19
- * check first if multisite is enabled
20
- * @since 2.1.1
21
- *
22
  */
23
 
24
-
25
  class Install {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- public function __construct() {
28
- register_activation_hook( __DIR__ . DIRECTORY_SEPARATOR . WPSTG_PLUGIN_SLUG . '.php', array($this, 'activation') );
29
- }
30
-
31
- public static function activation() {
32
- // Register cron job.
33
- $cron = new \WPStaging\Cron\Cron;
34
- $cron->schedule_event();
35
-
36
- // Install Optimizer
37
- $optimizer = new Optimizer();
38
- $optimizer->installOptimizer();
39
-
40
- // Add the transient to redirect for class Welcome (not for multisites)
41
- set_transient( 'wpstg_activation_redirect', true, 3600 );
42
- }
43
 
44
  }
45
 
5
  use WPStaging\WPStaging;
6
  use WPStaging\Backend\Optimizer\Optimizer;
7
  use WPStaging\Cron\Cron;
8
+ use WPStaging\Utils\IISWebConfig;
9
+ use WPStaging\Utils\Htaccess;
10
+ use WPStaging\Utils\Filesystem;
11
+
12
 
 
 
 
 
13
  // Exit if accessed directly
14
  if( !defined( 'ABSPATH' ) )
15
+ exit;
16
 
17
+ /**
18
+ * Install Class
19
+ *
 
 
20
  */
21
 
 
22
  class Install {
23
+
24
+ public function __construct() {
25
+ register_activation_hook( __DIR__ . DIRECTORY_SEPARATOR . WPSTG_PLUGIN_SLUG . '.php', array($this, 'activation') );
26
+ }
27
+
28
+ public static function activation() {
29
+ $install = new Install();
30
+
31
+ $install->installOptimizer();
32
+ $install->createHtaccess();
33
+ $install->createIndex();
34
+ $install->createWebConfig();
35
+ }
36
+
37
+ private function installOptimizer() {
38
+ // Register cron job.
39
+ $cron = new \WPStaging\Cron\Cron;
40
+ $cron->schedule_event();
41
+
42
+ // Install Optimizer
43
+ $optimizer = new Optimizer();
44
+ $optimizer->installOptimizer();
45
+
46
+ // Add the transient to redirect for class Welcome (not for multisites)
47
+ set_transient( 'wpstg_activation_redirect', true, 3600 );
48
+ }
49
+
50
+ private function createHtaccess() {
51
+ $htaccess = new Htaccess();
52
+ $htaccess->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . '.htaccess' );
53
+ $htaccess->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/.htaccess' );
54
+
55
+ if( extension_loaded( 'litespeed' ) ) {
56
+ $htaccess->createLitespeed( ABSPATH . '.htaccess' );
57
+ }
58
+ }
59
+
60
+ private function createIndex() {
61
+ $filesystem = new Filesystem();
62
+ $filesystem->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'index.php', "<?php // silence" );
63
+ $filesystem->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/index.php', "<?php // silence" );
64
+ }
65
 
66
+ private function createWebConfig() {
67
+ $webconfig = new IISWebConfig();
68
+ $webconfig->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'web.config' );
69
+ $webconfig->create( trailingslashit( \WPStaging\WPStaging::getContentDir() ) . 'logs/web.config' );
70
+ }
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  }
73
 
readme.txt CHANGED
@@ -1,4 +1,4 @@
1
- === WP Staging - DB & File Duplicator & Migration ===
2
 
3
  Author URL: https://wordpress.org/plugins/wp-staging
4
  Plugin URL: https://wordpress.org/plugins/wp-staging
@@ -9,7 +9,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
10
  Requires at least: 3.6+
11
  Tested up to: 5.0
12
- Stable tag: 2.4.3
13
  Requires PHP: 5.3
14
 
15
  A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
@@ -146,6 +146,18 @@ https://wp-staging.com
146
 
147
  == Changelog ==
148
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  = 2.4.3 =
150
  * Fix: Updating staging site does not exclude Windows IIS configuration file web.config and can lead to server error
151
  * Fix: Redirect to the correct url after log in to staging site
@@ -193,7 +205,8 @@ Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-sta
193
 
194
  == Upgrade Notice ==
195
 
196
- = 2.4.3 =
197
- * New: Support for custom directories of wp-content and uploads folder
 
198
 
199
 
1
+ === WP Staging - DB & File Duplicator & Migration ===
2
 
3
  Author URL: https://wordpress.org/plugins/wp-staging
4
  Plugin URL: https://wordpress.org/plugins/wp-staging
9
  Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
10
  Requires at least: 3.6+
11
  Tested up to: 5.0
12
+ Stable tag: 2.4.5
13
  Requires PHP: 5.3
14
 
15
  A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
146
 
147
  == Changelog ==
148
 
149
+ = 2.4.5 =
150
+ * New: Compatible up to WordPress 5.0.1 Gutenberg
151
+ * New: Show WP version of staging site in the sysinfo log
152
+ * Fix: Make sure optimizer must-use plugin is updated as well after updating the main plugin
153
+ * Fix: Plugin can not be uninstalled if WP Staging Pro is activated
154
+ * Fix: Prevent error $this not in object context in install.php
155
+
156
+
157
+ = 2.4.4 =
158
+ * Fix: Security, prevent downloading wp staging log files by third party users from uploads folder
159
+ * New: Compatible up to WordPress 5.0 Gutenberg
160
+
161
  = 2.4.3 =
162
  * Fix: Updating staging site does not exclude Windows IIS configuration file web.config and can lead to server error
163
  * Fix: Redirect to the correct url after log in to staging site
205
 
206
  == Upgrade Notice ==
207
 
208
+ = 2.4.5 =
209
+ * Fix: Security, prevent downloading wp staging log files by third party users from uploads folder
210
+ * New: Compatible up to WordPress 5.0.1 Gutenberg
211
 
212
 
uninstall.php CHANGED
@@ -14,7 +14,7 @@ use WPStaging\Backend\Optimizer\Optimizer;
14
  * @since 0.9.0
15
  */
16
  // No direct access
17
- if (!defined('WP_UNINSTALL_PLUGIN')) {
18
  exit;
19
  }
20
 
@@ -23,16 +23,16 @@ class uninstall {
23
  public function __construct() {
24
 
25
  // Plugin Folder Path
26
- if (!defined('WPSTG_PLUGIN_DIR')) {
27
- define('WPSTG_PLUGIN_DIR', plugin_dir_path(__FILE__));
28
  }
29
 
30
  /**
31
  * Path to main WP Staging class
32
  * Make sure to not redeclare class in case free version has been installed previosly
33
  */
34
- if (!class_exists('WPStaging\WPStaging')) {
35
- require_once plugin_dir_path(__FILE__) . "apps/Core/WPStaging.php";
36
  }
37
  $wpStaging = \WPStaging\WPStaging::getInstance();
38
 
@@ -44,18 +44,18 @@ class uninstall {
44
 
45
  private function init() {
46
 
47
- $options = json_decode(json_encode(get_option("wpstg_settings", array())));
48
 
49
- if (isset($options->unInstallOnDelete) && '1' === $options->unInstallOnDelete) {
50
  // Delete options
51
- delete_option("wpstg_version_upgraded_from");
52
- delete_option("wpstg_version");
53
- delete_option("wpstg_installDate");
54
- delete_option("wpstg_firsttime");
55
- delete_option("wpstg_is_staging_site");
56
- delete_option("wpstg_settings");
57
- delete_option("wpstg_rmpermalinks_executed");
58
- delete_option("wpstg_activation_redirect");
59
 
60
  /* Do not delete these fields without actually deleting the staging site
61
  * @create a delete routine which deletes the staging sites first
@@ -63,17 +63,17 @@ class uninstall {
63
  //delete_option( "wpstg_existing_clones" );
64
  //delete_option( "wpstg_existing_clones_beta" );
65
  // Old wpstg 1.3 options for admin notices
66
- delete_option("wpstg_start_poll");
67
- delete_option("wpstg_hide_beta");
68
- delete_option("wpstg_RatingDiv");
69
 
70
  // New 2.x options for admin notices
71
- delete_option("wpstg_poll");
72
- delete_option("wpstg_rating");
73
- delete_option("wpstg_beta");
74
 
75
  // Delete events
76
- wp_clear_scheduled_hook('wpstg_weekly_event');
77
  }
78
  }
79
 
@@ -81,8 +81,14 @@ class uninstall {
81
  * delete MuPlugin
82
  */
83
  private function deleteMuPlugin() {
84
- $optimizer = new Optimizer;
85
- $optimizer->unstallOptimizer();
 
 
 
 
 
 
86
  }
87
 
88
  }
14
  * @since 0.9.0
15
  */
16
  // No direct access
17
+ if( !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
18
  exit;
19
  }
20
 
23
  public function __construct() {
24
 
25
  // Plugin Folder Path
26
+ if( !defined( 'WPSTG_PLUGIN_DIR' ) ) {
27
+ define( 'WPSTG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
28
  }
29
 
30
  /**
31
  * Path to main WP Staging class
32
  * Make sure to not redeclare class in case free version has been installed previosly
33
  */
34
+ if( !class_exists( 'WPStaging\WPStaging' ) ) {
35
+ require_once plugin_dir_path( __FILE__ ) . "apps/Core/WPStaging.php";
36
  }
37
  $wpStaging = \WPStaging\WPStaging::getInstance();
38
 
44
 
45
  private function init() {
46
 
47
+ $options = json_decode( json_encode( get_option( "wpstg_settings", array() ) ) );
48
 
49
+ if( isset( $options->unInstallOnDelete ) && '1' === $options->unInstallOnDelete ) {
50
  // Delete options
51
+ delete_option( "wpstg_version_upgraded_from" );
52
+ delete_option( "wpstg_version" );
53
+ delete_option( "wpstg_installDate" );
54
+ delete_option( "wpstg_firsttime" );
55
+ delete_option( "wpstg_is_staging_site" );
56
+ delete_option( "wpstg_settings" );
57
+ delete_option( "wpstg_rmpermalinks_executed" );
58
+ delete_option( "wpstg_activation_redirect" );
59
 
60
  /* Do not delete these fields without actually deleting the staging site
61
  * @create a delete routine which deletes the staging sites first
63
  //delete_option( "wpstg_existing_clones" );
64
  //delete_option( "wpstg_existing_clones_beta" );
65
  // Old wpstg 1.3 options for admin notices
66
+ delete_option( "wpstg_start_poll" );
67
+ delete_option( "wpstg_hide_beta" );
68
+ delete_option( "wpstg_RatingDiv" );
69
 
70
  // New 2.x options for admin notices
71
+ delete_option( "wpstg_poll" );
72
+ delete_option( "wpstg_rating" );
73
+ delete_option( "wpstg_beta" );
74
 
75
  // Delete events
76
+ wp_clear_scheduled_hook( 'wpstg_weekly_event' );
77
  }
78
  }
79
 
81
  * delete MuPlugin
82
  */
83
  private function deleteMuPlugin() {
84
+ $muDir = ( defined( 'WPMU_PLUGIN_DIR' ) && defined( 'WPMU_PLUGIN_URL' ) ) ? WPMU_PLUGIN_DIR : trailingslashit( WP_CONTENT_DIR ) . 'mu-plugins';
85
+ $destination = trailingslashit( $muDir ) . 'wp-staging-optimizer.php';
86
+ if( file_exists( $destination ) && !unlink( $destination ) ) {
87
+ return false;
88
+ }
89
+
90
+ //$optimizer = new Optimizer;
91
+ //$optimizer->unstallOptimizer();
92
  }
93
 
94
  }
wp-staging.php CHANGED
@@ -7,7 +7,7 @@
7
  * Author: WP-Staging
8
  * Author URI: https://wp-staging.com
9
  * Contributors: ReneHermi, ilgityildirim
10
- * Version: 2.4.3
11
  * Text Domain: wp-staging
12
  * Domain Path: /languages/
13
 
@@ -51,7 +51,12 @@ if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
51
 
52
  // Version
53
  if( !defined( 'WPSTG_VERSION' ) ) {
54
- define( 'WPSTG_VERSION', '2.4.3' );
 
 
 
 
 
55
  }
56
 
57
  /**
7
  * Author: WP-Staging
8
  * Author URI: https://wp-staging.com
9
  * Contributors: ReneHermi, ilgityildirim
10
+ * Version: 2.4.5
11
  * Text Domain: wp-staging
12
  * Domain Path: /languages/
13
 
51
 
52
  // Version
53
  if( !defined( 'WPSTG_VERSION' ) ) {
54
+ define( 'WPSTG_VERSION', '2.4.5' );
55
+ }
56
+
57
+ // Must use version of the optimizer
58
+ if( !defined( 'WPSTG_OPTIMIZER_MUVERSION' ) ) {
59
+ define( 'WPSTG_OPTIMIZER_MUVERSION', 1.1 );
60
  }
61
 
62
  /**