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

Version Description

  • Fix: Security, prevent downloading wp staging log files by third party users from uploads folder
  • New: Compatible up to WordPress 5.0 Gutenberg
Download this release

Release Info

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

Code changes from version 2.4.3 to 2.4.4

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.4";
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,14 @@ 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 +201,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.4
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
+
152
+
153
+ = 2.4.4 =
154
+ * Fix: Security, prevent downloading wp staging log files by third party users from uploads folder
155
+ * New: Compatible up to WordPress 5.0 Gutenberg
156
+
157
  = 2.4.3 =
158
  * Fix: Updating staging site does not exclude Windows IIS configuration file web.config and can lead to server error
159
  * Fix: Redirect to the correct url after log in to staging site
201
 
202
  == Upgrade Notice ==
203
 
204
+ = 2.4.4 =
205
+ * Fix: Security, prevent downloading wp staging log files by third party users from uploads folder
206
+ * New: Compatible up to WordPress 5.0 Gutenberg
207
 
208
 
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,7 @@ 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.4
11
  * Text Domain: wp-staging
12
  * Domain Path: /languages/
13
 
51
 
52
  // Version
53
  if( !defined( 'WPSTG_VERSION' ) ) {
54
+ define( 'WPSTG_VERSION', '2.4.4' );
55
  }
56
 
57
  /**