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

Version Description

  • New: Complete rewrite of the code base
  • New: Batch processing allows to clone even huge sites without any timeouts
  • New: Preparation for WP QUADS PRO with ability to copy file changes back to live site
Download this release

Release Info

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

Code changes from version 2.0.4 to 2.0.3

CHANGELOG.md ADDED
File without changes
CONTRIBUTING.md ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Contribute To WP Staging
2
+
3
+ Community made patches, localisations, bug reports and contributions are always welcome.
4
+
5
+ When contributing please ensure you follow the guidelines below so that we can keep on top of things.
6
+
7
+ __Please Note:__ GitHub is for bug reports and contributions only.
8
+
9
+ ## Getting Started
10
+
11
+ * Submit a ticket for your issue, assuming one does not already exist.
12
+ * Raise it on our [Issue Tracker](https://github.com/rene-hermenau/wp-staging/issues)
13
+ * Clearly describe the issue including steps to reproduce the bug.
14
+ * Make sure you fill in the earliest version that you know has the issue as well as the version of WordPress you're using.
15
+
16
+ ## Making Changes
17
+
18
+ * Fork the repository on GitHub
19
+ * Make the changes to your forked repository
20
+ * Ensure you stick to the [WordPress Coding Standards](https://codex.wordpress.org/WordPress_Coding_Standards)
21
+ * When committing, reference your issue (if present) and include a note about the fix
22
+ * (coming soon) If possible, and if applicable, please also add/update unit tests for your changes
23
+ * Push the changes to your fork and submit a pull request to the 'master' branch of the WP Staging repository
24
+
25
+ ## Code Documentation
26
+
27
+ * We ensure that every WP Staging function is documented well and follows the standards set by phpDoc
28
+ * An example function can be found [here](https://gist.github.com/rene-hermenau/8d3d7ee0633ee2f64b4b)
29
+ * Please make sure that every function is documented so that when we update our API Documentation it will complete
30
+ * If you're adding/editing a function in a class, make sure to add `@access {private|public|protected}`
31
+ * Finally, please use tabs and not spaces. The tab indent size should be 4 for all WP Staging code.
32
+
33
+ At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
34
+
35
+ # Additional Resources
36
+ * [General GitHub Documentation](http://help.github.com/)
37
+ * [GitHub Pull Request documentation](http://help.github.com/send-pull-requests/)
38
+ * [PHPUnit Tests Guide](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html)
README.md ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Welcome to the WP-Staging repository
2
+
3
+ ## Note ##
4
+
5
+ This is the latest developer version of WP-Staging for WordPress.
6
+
7
+ ## Installation ##
8
+
9
+ 1. You can clone the GitHub repository: `https://github.com/rene-hermenau/wp-staging.git`
10
+ 2. Or download it directly as a ZIP file: `https://github.com/rene-hermenau/wp-staging/archive/master.zip`
11
+ 3. Upload it via WordPress->Plugin->AddNew
12
+
13
+ This will download the latest developer copy of WP-Staging.
14
+
15
+ ## Bugs ##
16
+ If you find an issue, let us know [here](https://github.com/rene-hermenau/wp-staging/issues?state=open)!
17
+
18
+ ## Support ##
19
+ This is a developer's portal for WP-Staging
20
+
21
+ ## Contributions ##
22
+ Anyone is welcome to contribute to WP-Staging. Please read the [guidelines for contributing](https://github.com/rene-hermenau/wp-staging/blob/master/CONTRIBUTING.md) to this repository.
23
+
24
+ There are various ways you can contribute:
25
+
26
+ 1. Raise an [Issue](https://github.com/rene-hermenau/wp-staging/issues) on GitHub
27
+ 2. Send us a Pull Request with your bug fixes and/or new features
28
+ 3. Translate WP-Staging into different languages
29
+ 4. Provide feedback and suggestions on [enhancements](https://github.com/rene-hermenau/wp-staging/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open)
30
+
31
+ ## Contributors ##
32
+ [@rene-hermenau](https://github.com/rene-hermenau), [@ilgityildirim](https://github.com/ilgityildirim)
apps/Backend/Activation/Activation.php CHANGED
@@ -1,58 +1,47 @@
1
  <?php
2
-
3
  namespace WPStaging\Backend\Activation;
4
 
5
  // No Direct Access
6
- if( !defined( "WPINC" ) ) {
7
- die;
 
8
  }
9
 
10
  use WPStaging\WPStaging;
11
- use WPStaging\Backend\Optimizer\Optimizer;
12
- use WPStaging\Cron\Cron;
13
 
14
  class Activation {
15
-
16
- /**
17
- * Checks if another version of WPSTG (Pro) is active and deactivates it.
18
- * To be hooked on `activated_plugin` so other plugin is deactivated when current plugin is activated.
19
- *
20
- * @param string $plugin
21
- *
22
- */
23
- public static function deactivate_other_instances( $plugin ) {
24
- if( !in_array( basename( $plugin ), array('wp-staging-pro.php', 'wp-staging.php') ) ) {
25
- return;
26
- }
27
- $plugin_to_deactivate = 'wp-staging.php';
28
- $deactivated_notice_id = '1';
29
- if( basename( $plugin ) == $plugin_to_deactivate ) {
30
- $plugin_to_deactivate = 'wp-staging-pro.php';
31
- $deactivated_notice_id = '2';
32
- }
33
- if( is_multisite() ) {
34
- $active_plugins = ( array ) get_site_option( 'active_sitewide_plugins', array() );
35
- $active_plugins = array_keys( $active_plugins );
36
- } else {
37
- $active_plugins = ( array ) get_option( 'active_plugins', array() );
38
- }
39
- foreach ( $active_plugins as $basename ) {
40
- if( false !== strpos( $basename, $plugin_to_deactivate ) ) {
41
- set_transient( 'wp_staging_deactivated_notice_id', $deactivated_notice_id, 1 * HOUR_IN_SECONDS );
42
- deactivate_plugins( $basename );
43
- return;
44
- }
45
- }
46
- }
47
-
48
- public static function install_dependancies() {
49
- // Register cron job.
50
- $cron = new \WPStaging\Cron\Cron;
51
- $cron->schedule_event();
52
-
53
- // Install Optimizer
54
- $optimizer = new Optimizer();
55
- $optimizer->installOptimizer();
56
- }
57
-
58
- }
1
  <?php
 
2
  namespace WPStaging\Backend\Activation;
3
 
4
  // No Direct Access
5
+ if (!defined("WPINC"))
6
+ {
7
+ die;
8
  }
9
 
10
  use WPStaging\WPStaging;
 
 
11
 
12
  class Activation {
13
+
14
+
15
+ /**
16
+ * Checks if another version of WPSTG (Pro) is active and deactivates it.
17
+ * To be hooked on `activated_plugin` so other plugin is deactivated when current plugin is activated.
18
+ *
19
+ * @param string $plugin
20
+ *
21
+ */
22
+ public static function deactivate_other_instances( $plugin ) {
23
+ if ( ! in_array( basename( $plugin ), array( 'wp-staging-pro.php', 'wp-staging.php' ) ) ) {
24
+ return;
25
+ }
26
+
27
+ $plugin_to_deactivate = 'wp-staging.php';
28
+ $deactivated_notice_id = '1';
29
+ if ( basename( $plugin ) == $plugin_to_deactivate ) {
30
+ $plugin_to_deactivate = 'wp-staging-pro.php';
31
+ $deactivated_notice_id = '2';
32
+ }
33
+ if ( is_multisite() ) {
34
+ $active_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
35
+ $active_plugins = array_keys( $active_plugins );
36
+ } else {
37
+ $active_plugins = (array) get_option( 'active_plugins', array() );
38
+ }
39
+ foreach ( $active_plugins as $basename ) {
40
+ if ( false !== strpos( $basename, $plugin_to_deactivate ) ) {
41
+ set_transient( 'wp_staging_deactivated_notice_id', $deactivated_notice_id, 1 * HOUR_IN_SECONDS );
42
+ deactivate_plugins( $basename );
43
+ return;
44
+ }
45
+ }
46
+ }
47
+ }
 
 
 
 
 
 
 
 
 
apps/Backend/Administrator.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
-
3
  namespace WPStaging\Backend;
4
 
5
  // No Direct Access
6
- if( !defined( "WPINC" ) ) {
7
- die;
 
8
  }
9
 
10
  use WPStaging\Backend\Modules\Jobs\Cancel;
@@ -23,616 +23,632 @@ use WPStaging\DI\InjectionAware;
23
  use WPStaging\Backend\Modules\Views\Forms\Settings as FormSettings;
24
  use WPStaging\Backend\Activation;
25
  use WPStaging\WPStaging;
26
- use WPStaging\Backend\Pro\Modules\Jobs\Processing;
27
- use WPStaging\Backend\Pro\Licensing;
28
 
29
  /**
30
  * Class Administrator
31
  * @package WPStaging\Backend
32
  */
33
- class Administrator extends InjectionAware {
34
-
35
- /**
36
- * @var string
37
- */
38
- private $path;
39
-
40
- /**
41
- * @var string
42
- */
43
- private $url;
44
-
45
- /**
46
- * Initialize class
47
- */
48
- public function initialize() {
49
- $this->defineHooks();
50
-
51
- // Path to backend
52
- $this->path = plugin_dir_path( __FILE__ );
53
-
54
- // URL to public backend folder
55
- $this->url = plugin_dir_url( __FILE__ ) . "public/";
56
-
57
- // Load plugins meta data
58
- $this->loadMeta();
59
- }
60
-
61
- /**
62
- * Load plugn meta data
63
- */
64
- public function loadMeta() {
65
- $run = new \WPStaging\Backend\Pluginmeta\Pluginmeta();
66
- }
67
-
68
- /**
69
- * Define Hooks
70
- */
71
- private function defineHooks() {
72
- // Get loader
73
- $loader = $this->di->get( "loader" );
74
-
75
- $Activation = new \WPStaging\Backend\Activation\Activation();
76
-
77
- $loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
78
- $loader->addAction( "admin_menu", $this, "addMenu", 10 );
79
- $loader->addAction( "admin_init", $this, "setOptionFormElements" );
80
- $loader->addAction( "admin_init", $this, "upgrade" );
81
- $loader->addAction( "admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload" );
82
- $loader->addAction( "admin_post_wpstg_export", $this, "export" );
83
- $loader->addAction( "admin_post_wpstg_import_settings", $this, "import" );
84
- $loader->addAction( "admin_notices", $this, "messages" );
85
-
86
- // Settings
87
- $settings = $this->di->get( "settings" );
88
-
89
- // Optimizer is ON
90
- if( $settings->isOptimizer() ) {
91
- $optimizer = new Optimizer( $this->di );
92
-
93
- $loader->addAction( "admin_init", $optimizer, "compatibility", 1 );
94
- $loader->addFilter( "option_active_plugins", $optimizer, "excludedPlugins" );
95
- $loader->addFilter( "site_option_active_sitewide_plugins", $optimizer, "excludedPlugins" );
96
- }
97
-
98
- // Ajax Requests
99
- $loader->addAction( "wp_ajax_wpstg_overview", $this, "ajaxOverview" );
100
- $loader->addAction( "wp_ajax_wpstg_scanning", $this, "ajaxScan" );
101
- $loader->addAction( "wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName" );
102
- $loader->addAction( "wp_ajax_wpstg_cloning", $this, "ajaxStartClone" );
103
- $loader->addAction( "wp_ajax_wpstg_clone_database", $this, "ajaxCloneDatabase" );
104
- $loader->addAction( "wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories" );
105
- $loader->addAction( "wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles" );
106
- $loader->addAction( "wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData" );
107
- $loader->addAction( "wp_ajax_wpstg_clone_finish", $this, "ajaxFinish" );
108
- $loader->addAction( "wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation" );
109
- $loader->addAction( "wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone" );
110
- $loader->addAction( "wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone" );
111
- $loader->addAction( "wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll" );
112
- $loader->addAction( "wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating" );
113
- $loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
114
- $loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
115
- $loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
116
-
117
- // Ajax hooks pro Version
118
- $loader->addAction( "wp_ajax_wpstg_start_processing", $this, "ajaxProcessing" );
119
- $loader->addAction( "wp_ajax_wpstg_push_changes", $this, "ajaxPushChanges" );
120
- }
121
-
122
- /**
123
- * Register options form elements
124
- */
125
- public function setOptionFormElements() {
126
- register_setting( "wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions") );
127
- }
128
-
129
- /**
130
- * Upgrade routine
131
- */
132
- public function upgrade() {
133
- $upgrade = new Upgrade\Upgrade();
134
- $upgrade->doUpgrade();
135
- }
136
-
137
- /**
138
- * Sanitize options data and delete the cache
139
- * @param array $data
140
- * @return array
141
- */
142
- public function sanitizeOptions( $data = array() ) {
143
- $sanitized = $this->sanitizeData( $data );
144
-
145
- add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wpstg" ), "updated" );
146
-
147
- // Return sanitized data
148
- //return $sanitized;
149
- return apply_filters( "wpstg-settings", $sanitized, $data );
150
- }
151
-
152
- /**
153
- * @param array $data
154
- * @return array
155
- */
156
- private function sanitizeData( $data = array() ) {
157
- $sanitized = array();
158
-
159
- foreach ( $data as $key => $value ) {
160
- $sanitized[$key] = (is_array( $value )) ? $this->sanitizeData( $value ) : htmlspecialchars( $value );
161
- }
162
-
163
- return $sanitized;
164
- }
165
-
166
- /**
167
- * Add Admin Menu(s)
168
- */
169
- public function addMenu() {
170
-
171
- $logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
172
-
173
- // Main WP Staging Menu
174
- add_menu_page(
175
- "WP-Staging", __( "WP Staging", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
176
- );
177
-
178
- // Page: Clone
179
- add_submenu_page(
180
- "wpstg_clone", __( "WP Staging Jobs", "wpstg" ), __( "Start", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
181
- );
182
-
183
- // Page: Settings
184
- add_submenu_page(
185
- "wpstg_clone", __( "WP Staging Settings", "wpstg" ), __( "Settings", "wpstg" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
186
- );
187
-
188
- // Page: Tools
189
- add_submenu_page(
190
- "wpstg_clone", __( "WP Staging Tools", "wpstg" ), __( "Tools", "wpstg" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
191
- );
192
-
193
- if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
194
- // Page: License
195
- add_submenu_page(
196
- "wpstg_clone", __( "WP Staging License", "wpstg" ), __( "License", "wpstg" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
197
- );
198
- }
199
- }
200
-
201
- /**
202
- * Settings Page
203
- */
204
- public function getSettingsPage() {
205
- // Tabs
206
- $tabs = new Tabs( array(
207
- "general" => __( "General", "wpstg" )
208
- ) );
209
-
210
-
211
- $this->di
212
- // Set tabs
213
- ->set( "tabs", $tabs )
214
- // Forms
215
- ->set( "forms", new FormSettings( $tabs ) );
216
-
217
- require_once "{$this->path}views/settings/index.php";
218
- }
219
-
220
- /**
221
- * Clone Page
222
- */
223
- public function getClonePage() {
224
- // Existing clones
225
- $availableClones = get_option( "wpstg_existing_clones_beta", array() );
226
-
227
- require_once "{$this->path}views/clone/index.php";
228
- }
229
-
230
- /**
231
- * Tools Page
232
- */
233
- public function getToolsPage() {
234
- // Tabs
235
- $tabs = new Tabs( array(
236
- "import_export" => __( "Import/Export", "wpstg" ),
237
- "system_info" => __( "System Info", "wpstg" )
238
- ) );
239
-
240
- $this->di->set( "tabs", $tabs );
241
-
242
- $this->di->set( "systemInfo", new SystemInfo( $this->di ) );
243
-
244
- require_once "{$this->path}views/tools/index.php";
245
- }
246
-
247
- /**
248
- * System Information Download
249
- */
250
- public function systemInfoDownload() {
251
- if( !current_user_can( "update_plugins" ) ) {
252
- return;
253
- }
254
-
255
- nocache_headers();
256
- header( "Content-Type: text/plain" );
257
- header( "Content-Disposition: attachment; filename='wpstg-system-info.txt'" );
258
- echo wp_strip_all_tags( new SystemInfo( $this->di ) );
259
- }
260
-
261
- /**
262
- * Import JSON settings file
263
- */
264
- public function import() {
265
- if( empty( $_POST["wpstg_import_nonce"] ) ) {
266
- return;
267
- }
268
-
269
- if( !wp_verify_nonce( $_POST["wpstg_import_nonce"], "wpstg_import_nonce" ) ) {
270
- return;
271
- }
272
-
273
- if( !current_user_can( "update_plugins" ) ) {
274
- return;
275
- }
276
-
277
- $fileExtension = explode( '.', $_FILES["import_file"]["name"] );
278
- $fileExtension = end( $fileExtension );
279
- if( "json" !== $fileExtension ) {
280
- wp_die( "Please upload a valid .json file", "wpstg" );
281
- }
282
-
283
-
284
- $importFile = $_FILES["import_file"]["tmp_name"];
285
-
286
- if( empty( $importFile ) ) {
287
- wp_die( __( "Please upload a file to import", "wpstg" ) );
288
- }
289
-
290
- update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
291
-
292
- wp_safe_redirect( admin_url( "admin.php?page=wpstg-tools&amp;wpstg-message=settings-imported" ) );
293
-
294
- return;
295
- }
296
-
297
- /**
298
- * Export settings to JSON file
299
- */
300
- public function export() {
301
- if( empty( $_POST["wpstg_export_nonce"] ) ) {
302
- return;
303
- }
304
-
305
- if( !wp_verify_nonce( $_POST["wpstg_export_nonce"], "wpstg_export_nonce" ) ) {
306
- return;
307
- }
308
-
309
- if( !current_user_can( "manage_options" ) ) {
310
- return;
311
- }
312
-
313
- $settings = get_option( "wpstg_settings", array() );
314
-
315
- ignore_user_abort( true );
316
-
317
- if( !in_array( "set_time_limit", explode( ',', ini_get( "disable_functions" ) ) ) && !@ini_get( "safe_mode" ) ) {
318
- set_time_limit( 0 );
319
- }
320
-
321
- $fileName = apply_filters( "wpstg_settings_export_filename", "wpstg-settings-export-" . date( "m-d-Y" ) ) . ".json";
322
-
323
- nocache_headers();
324
- header( "Content-Type: application/json; charset=utf-8" );
325
- header( "Content-Disposition: attachment; filename={$fileName}" );
326
- header( "Expires: 0" );
327
-
328
- echo json_encode( $settings );
329
- }
330
-
331
- /**
332
- * Render a view file
333
- * @param string $file
334
- * @param array $vars
335
- * @return string
336
- */
337
- public function render( $file, $vars = array() ) {
338
- $fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
339
- $fullPath = str_replace( array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php" );
340
-
341
- if( !file_exists( $fullPath ) || !is_readable( $fullPath ) ) {
342
- return "Can't render : {$fullPath} either file doesn't exist or can't read it";
343
- }
344
-
345
- $contents = @file_get_contents( $fullPath );
346
-
347
- // Variables are set
348
- if( count( $vars ) > 0 ) {
349
- $vars = array_combine(
350
- array_map( function ($key) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  return "{{" . $key . "}}";
352
- }, array_keys( $vars )
353
- ), $vars
354
- );
355
-
356
- $contents = str_replace( array_keys( $vars ), array_values( $vars ), $contents );
357
- }
358
-
359
- return $contents;
360
- }
361
-
362
- /**
363
- * Ajax Overview
364
- */
365
- public function ajaxOverview() {
366
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
367
-
368
- // Existing clones
369
- $availableClones = get_option( "wpstg_existing_clones_beta", array() );
370
-
371
- // Get license data
372
- $license = get_option( 'wpstg_license_status' );
373
-
374
- if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
375
- require_once "{$this->path}Pro/views/single-overview-pro.php";
376
- } else {
377
- require_once "{$this->path}views/clone/ajax/single-overview.php";
378
- }
379
-
380
- wp_die();
381
- }
382
-
383
- /**
384
- * Ajax Scan
385
- */
386
- public function ajaxScan() {
387
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
388
-
389
- // Scan
390
- $scan = new Scan();
391
- $scan->start();
392
-
393
- // Get Options
394
- $options = $scan->getOptions();
395
-
396
- require_once "{$this->path}views/clone/ajax/scan.php";
397
-
398
- wp_die();
399
- }
400
-
401
- /**
402
- * Ajax Check Clone Name
403
- */
404
- public function ajaxCheckCloneName() {
405
- $cloneName = sanitize_key( $_POST["cloneID"] );
406
- $cloneNameLength = strlen( $cloneName );
407
- $clones = get_option( "wpstg_existing_clones_beta", array() );
408
-
409
- // Check clone name length
410
- if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
411
- echo wp_send_json( array(
412
- "status" => "failed",
413
- "message" => "Clone name must be between 1 - 16 characters"
414
- ) );
415
- } elseif( array_key_exists( $cloneName, $clones ) ) {
416
- echo wp_send_json( array(
417
- "status" => "failed",
418
- "message" => "Clone name is already in use, please choose an another clone name"
419
- ) );
420
- }
421
-
422
- echo wp_send_json( array("status" => "success") );
423
- }
424
-
425
- /**
426
- * Ajax Start Clone (Basically just layout and saving data)
427
- */
428
- public function ajaxStartClone() {
429
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
430
-
431
- $cloning = new Cloning();
432
-
433
- if( !$cloning->save() ) {
434
- wp_die();
435
- }
436
-
437
- require_once "{$this->path}views/clone/ajax/start.php";
438
-
439
- wp_die();
440
- }
441
-
442
- /**
443
- * Ajax Clone Database
444
- */
445
- public function ajaxCloneDatabase() {
446
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
447
-
448
- $cloning = new Cloning();
449
-
450
- wp_send_json( $cloning->start() );
451
- }
452
-
453
- /**
454
- * Ajax Prepare Directories (get listing of files)
455
- */
456
- public function ajaxPrepareDirectories() {
457
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
458
-
459
- $cloning = new Cloning();
460
-
461
- wp_send_json( $cloning->start() );
462
- }
463
-
464
- /**
465
- * Ajax Clone Files
466
- */
467
- public function ajaxCopyFiles() {
468
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
469
-
470
- $cloning = new Cloning();
471
-
472
- wp_send_json( $cloning->start() );
473
- }
474
-
475
- /**
476
- * Ajax Replace Data
477
- */
478
- public function ajaxReplaceData() {
479
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
480
-
481
- $cloning = new Cloning();
482
-
483
- wp_send_json( $cloning->start() );
484
- }
485
-
486
- /**
487
- * Ajax Finish
488
- */
489
- public function ajaxFinish() {
490
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
491
-
492
- $cloning = new Cloning();
493
-
494
- wp_send_json( $cloning->start() );
495
- }
496
-
497
- /**
498
- * Ajax Delete Confirmation
499
- */
500
- public function ajaxDeleteConfirmation() {
501
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
502
-
503
- $delete = new Delete();
504
- $delete->setData();
505
-
506
- $clone = $delete->getClone();
507
-
508
- require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
509
-
510
- wp_die();
511
- }
512
-
513
- /**
514
- * Delete clone
515
- */
516
- public function ajaxDeleteClone() {
517
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
518
-
519
- $delete = new Delete();
520
- wp_send_json( $delete->start() );
521
- }
522
-
523
- /**
524
- * Delete clone
525
- */
526
- public function ajaxCancelClone() {
527
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
528
-
529
- $cancel = new Cancel();
530
- wp_send_json( $cancel->start() );
531
- }
532
-
533
- /**
534
- * Admin Messages
535
- */
536
- public function messages() {
537
- $notice = new Notices( $this->path, $this->url );
538
-
539
- $run = $notice->messages();
540
- }
541
-
542
- /**
543
- * Ajax Hide Poll
544
- * @return mixed boolean | json
545
- */
546
- public function ajaxHidePoll() {
547
- if( false !== update_option( "wpstg_poll", "no" ) ) {
548
- wp_send_json( true );
549
- }
550
- return wp_send_json();
551
- }
552
-
553
- /**
554
- * Ajax Hide Rating
555
- * @return mixed bool | json
556
- */
557
- public function ajaxHideRating() {
558
- if( false !== update_option( "wpstg_rating", "no" ) ) {
559
- wp_send_json( true );
560
- }
561
- return wp_send_json();
562
- }
563
-
564
- /**
565
- * Ajax Hide Beta
566
- */
567
- public function ajaxHideBeta() {
568
- wp_send_json( update_option( "wpstg_beta", "no" ) );
569
- }
570
-
571
- /**
572
- * Clone logs
573
- */
574
- public function ajaxLogs() {
575
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
576
-
577
- $logs = new Logs();
578
- wp_send_json( $logs->start() );
579
- }
580
-
581
- /**
582
- * Ajax Checks Free Disk Space
583
- */
584
- public function ajaxCheckFreeSpace() {
585
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
586
-
587
- $scan = new Scan();
588
- return $scan->hasFreeDiskSpace();
589
- }
590
-
591
- /**
592
- * Ajax Start Push Changes Process
593
- */
594
- public function ajaxProcessing() {
595
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
596
-
597
- if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
598
- return false;
599
- }
600
-
601
- // Scan
602
- $scan = new Pro\Modules\Jobs\Scan();
603
- $scan->start();
604
-
605
- // Get Options
606
- $options = $scan->getOptions();
607
-
608
- require_once "{$this->path}Pro/views/scan.php";
609
-
610
- wp_die();
611
- }
612
-
613
- /**
614
- * Ajax Start Pushing. Needs wp quads pro)
615
- */
616
- public function ajaxPushChanges() {
617
- check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
618
-
619
- if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Processing' ) ) {
620
- return false;
621
- }
622
- // Start the process
623
- $processing = new Processing();
624
- wp_send_json( $processing->start() );
625
- }
626
-
627
- /**
628
- * License Page
629
- */
630
- public function getLicensePage() {
631
-
632
- // Get license data
633
- $license = get_option( 'wpstg_license_status' );
634
-
635
- require_once "{$this->path}Pro/views/licensing.php";
636
- }
637
-
638
- }
1
  <?php
 
2
  namespace WPStaging\Backend;
3
 
4
  // No Direct Access
5
+ if (!defined("WPINC"))
6
+ {
7
+ die;
8
  }
9
 
10
  use WPStaging\Backend\Modules\Jobs\Cancel;
23
  use WPStaging\Backend\Modules\Views\Forms\Settings as FormSettings;
24
  use WPStaging\Backend\Activation;
25
  use WPStaging\WPStaging;
 
 
26
 
27
  /**
28
  * Class Administrator
29
  * @package WPStaging\Backend
30
  */
31
+ class Administrator extends InjectionAware
32
+ {
33
+
34
+ /**
35
+ * @var string
36
+ */
37
+ private $path;
38
+
39
+ /**
40
+ * @var string
41
+ */
42
+ private $url;
43
+
44
+ /**
45
+ * Initialize class
46
+ */
47
+ public function initialize()
48
+ {
49
+ $this->defineHooks();
50
+
51
+ // Path to backend
52
+ $this->path = plugin_dir_path(__FILE__);
53
+
54
+ // URL to public backend folder
55
+ $this->url = plugin_dir_url(__FILE__) . "public/";
56
+
57
+ // Load plugins meta data
58
+ $this->loadMeta();
59
+
60
+ }
61
+
62
+ public function loadMeta(){
63
+ $run = new \WPStaging\Backend\Pluginmeta\Pluginmeta();
64
+ }
65
+
66
+ /**
67
+ * Define Hooks
68
+ */
69
+ private function defineHooks()
70
+ {
71
+ // Get loader
72
+ $loader = $this->di->get("loader");
73
+
74
+ $Activation = new \WPStaging\Backend\Activation\Activation();
75
+
76
+ $loader->addAction("activated_plugin", $Activation, 'deactivate_other_instances');
77
+ $loader->addAction("admin_menu", $this, "addMenu", 10);
78
+ $loader->addAction("admin_init", $this, "setOptionFormElements");
79
+ $loader->addAction("admin_init", $this, "upgrade");
80
+ $loader->addAction("admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload");
81
+ $loader->addAction("admin_post_wpstg_export", $this, "export");
82
+ $loader->addAction("admin_post_wpstg_import_settings", $this, "import");
83
+ $loader->addAction("admin_notices", $this, "messages");
84
+
85
+ // Settings
86
+ $settings = $this->di->get("settings");
87
+
88
+ // Optimizer is ON
89
+ if ($settings->isOptimizer())
90
+ {
91
+ $optimizer = new Optimizer($this->di);
92
+
93
+ $loader->addAction("admin_init", $optimizer, "compatibility", 1);
94
+ $loader->addFilter("option_active_plugins", $optimizer, "excludedPlugins");
95
+ $loader->addFilter("site_option_active_sitewide_plugins", $optimizer, "excludedPlugins");
96
+ }
97
+
98
+ // Ajax Requests
99
+ $loader->addAction("wp_ajax_wpstg_overview", $this, "ajaxOverview");
100
+ $loader->addAction("wp_ajax_wpstg_scanning", $this, "ajaxScan");
101
+ $loader->addAction("wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName");
102
+ $loader->addAction("wp_ajax_wpstg_cloning", $this, "ajaxStartClone");
103
+ $loader->addAction("wp_ajax_wpstg_clone_database", $this, "ajaxCloneDatabase");
104
+ $loader->addAction("wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories");
105
+ $loader->addAction("wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles");
106
+ $loader->addAction("wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData");
107
+ $loader->addAction("wp_ajax_wpstg_clone_finish", $this, "ajaxFinish");
108
+ $loader->addAction("wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation");
109
+ $loader->addAction("wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone");
110
+ $loader->addAction("wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone");
111
+ $loader->addAction("wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll");
112
+ $loader->addAction("wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating");
113
+ $loader->addAction("wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta");
114
+ $loader->addAction("wp_ajax_wpstg_logs", $this, "ajaxLogs");
115
+ $loader->addAction("wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace");
116
+ }
117
+
118
+ public function Activation(){
119
+ $run = new \WPStaging\Backend\Activation();
120
+ $run->deactivate_other_instances();
121
+ //echo 'activated';
122
+ }
123
+
124
+
125
+ /**
126
+ * Register options form elements
127
+ */
128
+ public function setOptionFormElements()
129
+ {
130
+ register_setting("wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions"));
131
+ }
132
+
133
+ /**
134
+ * Upgrade routine
135
+ */
136
+ public function upgrade(){
137
+ $upgrade = new Upgrade\Upgrade();
138
+ $upgrade->doUpgrade();
139
+ }
140
+
141
+ /**
142
+ * Sanitize options data and delete the cache
143
+ * @param array $data
144
+ * @return array
145
+ */
146
+ public function sanitizeOptions($data = array())
147
+ {
148
+ $sanitized = $this->sanitizeData($data);
149
+
150
+ add_settings_error("wpstg-notices", '', __("Settings updated.", "wpstg"), "updated");
151
+
152
+ // Return sanitized data
153
+ //return $sanitized;
154
+ return apply_filters("wpstg-settings", $sanitized, $data);
155
+ }
156
+
157
+ /**
158
+ * @param array $data
159
+ * @return array
160
+ */
161
+ private function sanitizeData($data = array())
162
+ {
163
+ $sanitized = array();
164
+
165
+ foreach ($data as $key => $value)
166
+ {
167
+ $sanitized[$key] = (is_array($value)) ? $this->sanitizeData($value) : htmlspecialchars($value);
168
+ }
169
+
170
+ return $sanitized;
171
+ }
172
+
173
+ /**
174
+ * Add Admin Menu(s)
175
+ */
176
+ public function addMenu()
177
+ {
178
+
179
+ $logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
180
+
181
+ // Main WP Staging Menu
182
+ add_menu_page(
183
+ "WP-Staging",
184
+ __("WP Staging", "wpstg"),
185
+ "manage_options",
186
+ "wpstg_clone",
187
+ array($this, "getClonePage"),
188
+ $logo
189
+ );
190
+
191
+ // Page: Clone
192
+ add_submenu_page(
193
+ "wpstg_clone",
194
+ __("WP Staging Jobs", "wpstg"),
195
+ __("Start", "wpstg"),
196
+ "manage_options",
197
+ "wpstg_clone",
198
+ array($this, "getClonePage")
199
+ );
200
+
201
+ // Page: Settings
202
+ add_submenu_page(
203
+ "wpstg_clone",
204
+ __("WP Staging Settings", "wpstg"),
205
+ __("Settings", "wpstg"),
206
+ "manage_options",
207
+ "wpstg-settings",
208
+ array($this, "getSettingsPage")
209
+ );
210
+
211
+ // Page: Tools
212
+ add_submenu_page(
213
+ "wpstg_clone",
214
+ __("WP Staging Tools", "wpstg"),
215
+ __("Tools", "wpstg"),
216
+ "manage_options",
217
+ "wpstg-tools",
218
+ array($this, "getToolsPage")
219
+ );
220
+ }
221
+
222
+
223
+
224
+ /**
225
+ * Settings Page
226
+ */
227
+ public function getSettingsPage()
228
+ {
229
+ // Tabs
230
+ $tabs = new Tabs(array(
231
+ "general" => __("General", "wpstg")
232
+ ));
233
+
234
+
235
+ $this->di
236
+ // Set tabs
237
+ ->set("tabs", $tabs)
238
+ // Forms
239
+ ->set("forms", new FormSettings($tabs));
240
+
241
+ require_once "{$this->path}views/settings/index.php";
242
+ }
243
+
244
+ /**
245
+ * Clone Page
246
+ */
247
+ public function getClonePage()
248
+ {
249
+ // Existing clones
250
+ $availableClones = get_option("wpstg_existing_clones_beta", array());
251
+
252
+ require_once "{$this->path}views/clone/index.php";
253
+ }
254
+
255
+ /**
256
+ * Tools Page
257
+ */
258
+ public function getToolsPage()
259
+ {
260
+ // Tabs
261
+ $tabs = new Tabs(array(
262
+ "import_export" => __("Import/Export", "wpstg"),
263
+ "system_info" => __("System Info", "wpstg")
264
+ ));
265
+
266
+ $this->di->set("tabs", $tabs);
267
+
268
+ $this->di->set("systemInfo", new SystemInfo($this->di));
269
+
270
+ require_once "{$this->path}views/tools/index.php";
271
+ }
272
+
273
+ /**
274
+ * System Information Download
275
+ */
276
+ public function systemInfoDownload()
277
+ {
278
+ if (!current_user_can("update_plugins"))
279
+ {
280
+ return;
281
+ }
282
+
283
+ nocache_headers();
284
+ header("Content-Type: text/plain");
285
+ header("Content-Disposition: attachment; filename='wpstg-system-info.txt'");
286
+ echo wp_strip_all_tags(new SystemInfo($this->di));
287
+ }
288
+
289
+ /**
290
+ * Import JSON settings file
291
+ */
292
+ public function import()
293
+ {
294
+ if (empty($_POST["wpstg_import_nonce"]))
295
+ {
296
+ return;
297
+ }
298
+
299
+ if (!wp_verify_nonce($_POST["wpstg_import_nonce"], "wpstg_import_nonce"))
300
+ {
301
+ return;
302
+ }
303
+
304
+ if (!current_user_can("update_plugins"))
305
+ {
306
+ return;
307
+ }
308
+
309
+ $fileExtension = explode('.', $_FILES["import_file"]["name"]);
310
+ $fileExtension = end($fileExtension);
311
+ if ("json" !== $fileExtension)
312
+ {
313
+ wp_die("Please upload a valid .json file", "wpstg");
314
+ }
315
+
316
+
317
+ $importFile = $_FILES["import_file"]["tmp_name"];
318
+
319
+ if (empty($importFile))
320
+ {
321
+ wp_die(__("Please upload a file to import", "wpstg"));
322
+ }
323
+
324
+ update_option("wpstg_settings", json_decode(file_get_contents($importFile, true)));
325
+
326
+ wp_safe_redirect(admin_url("admin.php?page=wpstg-tools&amp;wpstg-message=settings-imported"));
327
+
328
+ return;
329
+ }
330
+
331
+ /**
332
+ * Export settings to JSON file
333
+ */
334
+ public function export()
335
+ {
336
+ if (empty($_POST["wpstg_export_nonce"]))
337
+ {
338
+ return;
339
+ }
340
+
341
+ if (!wp_verify_nonce($_POST["wpstg_export_nonce"], "wpstg_export_nonce"))
342
+ {
343
+ return;
344
+ }
345
+
346
+ if (!current_user_can("manage_options"))
347
+ {
348
+ return;
349
+ }
350
+
351
+ $settings = get_option("wpstg_settings", array());
352
+
353
+ ignore_user_abort(true);
354
+
355
+ if (!in_array("set_time_limit", explode(',', ini_get("disable_functions"))) && !@ini_get("safe_mode"))
356
+ {
357
+ set_time_limit(0);
358
+ }
359
+
360
+ $fileName = apply_filters("wpstg_settings_export_filename", "wpstg-settings-export-" . date("m-d-Y")) . ".json";
361
+
362
+ nocache_headers();
363
+ header("Content-Type: application/json; charset=utf-8");
364
+ header("Content-Disposition: attachment; filename={$fileName}");
365
+ header("Expires: 0");
366
+
367
+ echo json_encode($settings);
368
+ }
369
+
370
+
371
+ /**
372
+ * Render a view file
373
+ * @param string $file
374
+ * @param array $vars
375
+ * @return string
376
+ */
377
+ public function render($file, $vars = array())
378
+ {
379
+ $fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
380
+ $fullPath = str_replace(array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php");
381
+
382
+ if (!file_exists($fullPath) || !is_readable($fullPath))
383
+ {
384
+ return "Can't render : {$fullPath} either file doesn't exist or can't read it";
385
+ }
386
+
387
+ $contents = @file_get_contents($fullPath);
388
+
389
+ // Variables are set
390
+ if (count($vars) > 0)
391
+ {
392
+ $vars = array_combine(
393
+ array_map(function ($key)
394
+ {
395
  return "{{" . $key . "}}";
396
+ },
397
+ array_keys($vars)
398
+ ),
399
+ $vars
400
+ );
401
+
402
+ $contents = str_replace(array_keys($vars), array_values($vars), $contents);
403
+ }
404
+
405
+ return $contents;
406
+ }
407
+
408
+ /**
409
+ * Ajax Overview
410
+ */
411
+ public function ajaxOverview()
412
+ {
413
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
414
+
415
+ // Existing clones
416
+ $availableClones = get_option("wpstg_existing_clones_beta", array());
417
+
418
+ require_once "{$this->path}views/clone/ajax/single-overview.php";
419
+
420
+ wp_die();
421
+ }
422
+
423
+ /**
424
+ * Ajax Scan
425
+ */
426
+ public function ajaxScan()
427
+ {
428
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
429
+
430
+ // Scan
431
+ $scan = new Scan();
432
+ $scan->start();
433
+
434
+ // Get Options
435
+ $options = $scan->getOptions();
436
+
437
+ require_once "{$this->path}views/clone/ajax/scan.php";
438
+
439
+ wp_die();
440
+ }
441
+
442
+ /**
443
+ * Ajax Check Clone Name
444
+ */
445
+ public function ajaxCheckCloneName()
446
+ {
447
+ $cloneName = sanitize_key($_POST["cloneID"]);
448
+ $cloneNameLength = strlen($cloneName);
449
+ $clones = get_option("wpstg_existing_clones_beta", array());
450
+
451
+ // Check clone name length
452
+ if ($cloneNameLength < 1 || $cloneNameLength > 16)
453
+ {
454
+ echo wp_send_json(array(
455
+ "status" => "failed",
456
+ "message" => "Clone name must be between 1 - 16 characters"
457
+ ));
458
+ }
459
+ elseif (array_key_exists($cloneName, $clones))
460
+ {
461
+ echo wp_send_json(array(
462
+ "status" => "failed",
463
+ "message" => "Clone name is already in use, please choose an another clone name"
464
+ ));
465
+ }
466
+
467
+ echo wp_send_json(array("status" => "success"));
468
+ }
469
+
470
+ /**
471
+ * Ajax Start Clone (Basically just layout and saving data)
472
+ */
473
+ public function ajaxStartClone()
474
+ {
475
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
476
+
477
+ $cloning = new Cloning();
478
+
479
+ if (!$cloning->save())
480
+ {
481
+ wp_die();
482
+ }
483
+
484
+ require_once "{$this->path}views/clone/ajax/start.php";
485
+
486
+ wp_die();
487
+ }
488
+
489
+ /**
490
+ * Ajax Clone Database
491
+ */
492
+ public function ajaxCloneDatabase()
493
+ {
494
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
495
+
496
+ $cloning = new Cloning();
497
+
498
+ wp_send_json($cloning->start());
499
+ }
500
+
501
+ /**
502
+ * Ajax Prepare Directories (get listing of files)
503
+ */
504
+ public function ajaxPrepareDirectories()
505
+ {
506
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
507
+
508
+ $cloning = new Cloning();
509
+
510
+ wp_send_json($cloning->start());
511
+ }
512
+
513
+ /**
514
+ * Ajax Clone Files
515
+ */
516
+ public function ajaxCopyFiles()
517
+ {
518
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
519
+
520
+ $cloning = new Cloning();
521
+
522
+ wp_send_json($cloning->start());
523
+ }
524
+
525
+ /**
526
+ * Ajax Replace Data
527
+ */
528
+ public function ajaxReplaceData()
529
+ {
530
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
531
+
532
+ $cloning = new Cloning();
533
+
534
+ wp_send_json($cloning->start());
535
+ }
536
+
537
+ /**
538
+ * Ajax Finish
539
+ */
540
+ public function ajaxFinish()
541
+ {
542
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
543
+
544
+ $cloning = new Cloning();
545
+
546
+ wp_send_json($cloning->start());
547
+ }
548
+
549
+ /**
550
+ * Ajax Delete Confirmation
551
+ */
552
+ public function ajaxDeleteConfirmation()
553
+ {
554
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
555
+
556
+ $delete = new Delete();
557
+ $delete->setData();
558
+
559
+ $clone = $delete->getClone();
560
+
561
+ require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
562
+
563
+ wp_die();
564
+ }
565
+
566
+ /**
567
+ * Delete clone
568
+ */
569
+ public function ajaxDeleteClone()
570
+ {
571
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
572
+
573
+ $delete = new Delete();
574
+ wp_send_json($delete->start());
575
+ }
576
+
577
+ /**
578
+ * Delete clone
579
+ */
580
+ public function ajaxCancelClone()
581
+ {
582
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
583
+
584
+ $cancel = new Cancel();
585
+ wp_send_json($cancel->start());
586
+ }
587
+
588
+ /**
589
+ * Admin Messages
590
+ */
591
+ public function messages()
592
+ {
593
+ $notice = new Notices($this->path, $this->url);
594
+
595
+ $run = $notice->messages();
596
+ }
597
+
598
+ /**
599
+ * Ajax Hide Poll
600
+ * @return mixed boolean | json
601
+ */
602
+ public function ajaxHidePoll()
603
+ {
604
+ if( false !== update_option( "wpstg_poll", "no" ) ) {
605
+ wp_send_json( true );
606
+ }
607
+ return wp_send_json();
608
+ }
609
+
610
+ /**
611
+ * Ajax Hide Rating
612
+ * @return mixed bool | json
613
+ */
614
+ public function ajaxHideRating()
615
+ {
616
+ if( false !== update_option( "wpstg_rating", "no" ) ) {
617
+ wp_send_json( true );
618
+ }
619
+ return wp_send_json();
620
+ }
621
+
622
+ /**
623
+ * Ajax Hide Beta
624
+ */
625
+ public function ajaxHideBeta()
626
+ {
627
+ wp_send_json(update_option("wpstg_beta", "no"));
628
+ }
629
+
630
+ /**
631
+ * Clone logs
632
+ */
633
+ public function ajaxLogs()
634
+ {
635
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
636
+
637
+ $logs = new Logs();
638
+ wp_send_json($logs->start());
639
+ }
640
+
641
+ /**
642
+ * Ajax Checks Free Disk Space
643
+ */
644
+ public function ajaxCheckFreeSpace()
645
+ {
646
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
647
+
648
+ $scan = new Scan();
649
+ return $scan->hasFreeDiskSpace();
650
+ }
651
+
652
+
653
+
654
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Modules/Jobs/Delete.php CHANGED
@@ -2,7 +2,7 @@
2
  namespace WPStaging\Backend\Modules\Jobs;
3
 
4
  use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
5
- //use WPStaging\Utils\Directories;
6
  use WPStaging\Utils\Logger;
7
  use WPStaging\WPStaging;
8
 
@@ -75,11 +75,19 @@ class Delete extends Job
75
  if (empty($clones) || !isset($clones[$name]))
76
  {
77
  $this->log("Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL);
78
- //throw new CloneNotFoundException();
79
  }
80
 
81
  $this->clone = $clones[$name];
82
  $this->clone["name"] = $name;
 
 
 
 
 
 
 
 
83
 
84
  $this->clone = (object) $this->clone;
85
 
@@ -93,6 +101,10 @@ class Delete extends Job
93
  {
94
  $wpdb = WPStaging::getInstance()->get("wpdb");
95
 
 
 
 
 
96
  $tables = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wpstg{$this->clone->number}_%'");
97
 
98
  $this->tables = array();
@@ -107,8 +119,8 @@ class Delete extends Job
107
 
108
  $this->tables = json_decode(json_encode($this->tables));
109
  }
110
-
111
- /**
112
  * Format bytes into human readable form
113
  * @param int $bytes
114
  * @param int $precision
@@ -130,7 +142,6 @@ class Delete extends Job
130
  return round($pow, $precision) . ' ' . $units[(int) floor($base)];
131
  }
132
 
133
-
134
  /**
135
  * @return false
136
  */
@@ -167,27 +178,25 @@ class Delete extends Job
167
  /**
168
  * Get job data
169
  */
170
- private function getJob() {
171
- $this->job = $this->cache->get( "delete_job_{$this->clone->name}" );
172
-
173
-
174
- if( null !== $this->job ) {
175
- return;
176
- }
177
 
178
- // Generate JOB
179
- $this->job = ( object ) array(
180
- "current" => "tables",
181
- "nextDirectoryToDelete" => $this->clone->path,
182
- "name" => $this->clone->name
183
- );
184
 
185
- $this->cache->save( "delete_job_{$this->clone->name}", $this->job );
186
- }
187
-
 
 
188
 
 
 
189
 
190
- /**
191
  * @return bool
192
  */
193
  private function updateJob()
@@ -260,43 +269,8 @@ class Delete extends Job
260
  $length = strlen($needle);
261
  return (substr($haystack, 0, $length) === $needle);
262
  }
263
-
264
- /**
265
- * Delete a specific directory and all of its subfolders in a native way without using any external caching data
266
- *
267
- * @param array $dir
268
- * @param array $excluded_dirs
269
- * @return boolean false when its finished
270
- */
271
- // function deleteDirectoryNative( $dir = '' ) {
272
- //
273
- // if( !file_exists( $dir ) ) {
274
- // return $this->isFinished();
275
- // }
276
- //
277
- // if( !is_dir( $dir ) || is_link( $dir ) ) {
278
- // unlink( $dir );
279
- // return $this->isFinished();
280
- // }
281
- // foreach ( scandir( $dir ) as $item ) {
282
- // if( $item == '.' || $item == '..' ) {
283
- // continue;
284
- // }
285
- // if( !$this->deleteDirectoryNative( $dir . "/" . $item, false ) ) {
286
- // //chmod( $dir . "/" . $item, 0777 );
287
- // //if( !$this->deleteDirectoryNative( $dir . "/" . $item, false ) ){
288
- // //return false;
289
- // //}
290
- // }
291
- // };
292
- //
293
- // rmdir( $dir );
294
- // return $this->isFinished();
295
- // }
296
-
297
 
298
-
299
- /**
300
  * Delete Directories
301
  */
302
  public function deleteDirectory()
@@ -418,8 +392,6 @@ class Delete extends Job
418
  $this->cache->delete("delete_job_{$this->clone->name}");
419
  $this->cache->delete("delete_directories_{$this->clone->name}");
420
 
421
- //return true;
422
- $response = array('delete' => 'finished');
423
- wp_die(json_encode($response));
424
  }
425
  }
2
  namespace WPStaging\Backend\Modules\Jobs;
3
 
4
  use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
5
+ use WPStaging\Utils\Directories;
6
  use WPStaging\Utils\Logger;
7
  use WPStaging\WPStaging;
8
 
75
  if (empty($clones) || !isset($clones[$name]))
76
  {
77
  $this->log("Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL);
78
+ throw new CloneNotFoundException();
79
  }
80
 
81
  $this->clone = $clones[$name];
82
  $this->clone["name"] = $name;
83
+ // $this->clone["size"] = null;
84
+ //
85
+ // if (isset($this->settings->checkDirectorySize) || '1' === $this->settings->checkDirectorySize)
86
+ // {
87
+ // $directories = new Directories();
88
+ // $this->clone["size"] = $this->formatSize($directories->size($this->clone));
89
+ // unset($directories);
90
+ // }
91
 
92
  $this->clone = (object) $this->clone;
93
 
101
  {
102
  $wpdb = WPStaging::getInstance()->get("wpdb");
103
 
104
+ // if ($this->clone['version']){
105
+ //
106
+ // }
107
+
108
  $tables = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wpstg{$this->clone->number}_%'");
109
 
110
  $this->tables = array();
119
 
120
  $this->tables = json_decode(json_encode($this->tables));
121
  }
122
+
123
+ /**
124
  * Format bytes into human readable form
125
  * @param int $bytes
126
  * @param int $precision
142
  return round($pow, $precision) . ' ' . $units[(int) floor($base)];
143
  }
144
 
 
145
  /**
146
  * @return false
147
  */
178
  /**
179
  * Get job data
180
  */
181
+ private function getJob()
182
+ {
183
+ $this->job = $this->cache->get("delete_job_{$this->clone->name}");
 
 
 
 
184
 
185
+ if (null !== $this->job)
186
+ {
187
+ return;
188
+ }
 
 
189
 
190
+ // Generate JOB
191
+ $this->job = (object) array(
192
+ "current" => "tables",
193
+ "nextDirectoryToDelete" => $this->clone->path
194
+ );
195
 
196
+ $this->cache->save("delete_job_{$this->clone->name}", $this->job);
197
+ }
198
 
199
+ /**
200
  * @return bool
201
  */
202
  private function updateJob()
269
  $length = strlen($needle);
270
  return (substr($haystack, 0, $length) === $needle);
271
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
+ /**
 
274
  * Delete Directories
275
  */
276
  public function deleteDirectory()
392
  $this->cache->delete("delete_job_{$this->clone->name}");
393
  $this->cache->delete("delete_directories_{$this->clone->name}");
394
 
395
+ return true;
 
 
396
  }
397
  }
apps/Backend/Modules/Jobs/Delete_deprecated.php DELETED
@@ -1,397 +0,0 @@
1
- <?php
2
- namespace WPStaging\Backend\Modules\Jobs;
3
-
4
- use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
5
- //use WPStaging\Utils\Directories;
6
- use WPStaging\Utils\Logger;
7
- use WPStaging\WPStaging;
8
-
9
- /**
10
- * Class Delete
11
- * @package WPStaging\Backend\Modules\Jobs
12
- */
13
- class Delete_deprecated extends Job
14
- {
15
-
16
- /**
17
- * @var false
18
- */
19
- private $clone = false;
20
-
21
- /**
22
- * @var null|object
23
- */
24
- private $tables = null;
25
-
26
- /**
27
- * @var object|null
28
- */
29
- private $job = null;
30
-
31
- /**
32
- * @var bool
33
- */
34
- private $forceDeleteDirectories = false;
35
-
36
- /**
37
- * Sets Clone and Table Records
38
- * @param null|array $clone
39
- */
40
- public function setData($clone = null)
41
- {
42
- if (!is_array($clone))
43
- {
44
- $this->getCloneRecords();
45
- }
46
- else
47
- {
48
- $this->clone = (object) $clone;
49
- $this->forceDeleteDirectories = true;
50
- }
51
-
52
- $this->getTableRecords();
53
- }
54
-
55
- /**
56
- * Get clone
57
- * @param null|string $name
58
- * @throws CloneNotFoundException
59
- */
60
- private function getCloneRecords($name = null)
61
- {
62
- if (null === $name && !isset($_POST["clone"]))
63
- {
64
- $this->log("Clone name is not set", Logger::TYPE_FATAL);
65
- throw new CloneNotFoundException();
66
- }
67
-
68
- if (null === $name)
69
- {
70
- $name = $_POST["clone"];
71
- }
72
-
73
- $clones = get_option("wpstg_existing_clones_beta", array());
74
-
75
- if (empty($clones) || !isset($clones[$name]))
76
- {
77
- $this->log("Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL);
78
- throw new CloneNotFoundException();
79
- }
80
-
81
- $this->clone = $clones[$name];
82
- $this->clone["name"] = $name;
83
- // $this->clone["size"] = null;
84
- //
85
- // if (isset($this->settings->checkDirectorySize) || '1' === $this->settings->checkDirectorySize)
86
- // {
87
- // $directories = new Directories();
88
- // $this->clone["size"] = $this->formatSize($directories->size($this->clone));
89
- // unset($directories);
90
- // }
91
-
92
- $this->clone = (object) $this->clone;
93
-
94
- unset($clones);
95
- }
96
-
97
- /**
98
- * Get Tables
99
- */
100
- private function getTableRecords()
101
- {
102
- $wpdb = WPStaging::getInstance()->get("wpdb");
103
-
104
- // if ($this->clone['version']){
105
- //
106
- // }
107
-
108
- $tables = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wpstg{$this->clone->number}_%'");
109
-
110
- $this->tables = array();
111
-
112
- foreach ($tables as $table)
113
- {
114
- $this->tables[] = array(
115
- "name" => $table->Name,
116
- "size" => $this->formatSize(($table->Data_length + $table->Index_length))
117
- );
118
- }
119
-
120
- $this->tables = json_decode(json_encode($this->tables));
121
- }
122
-
123
- /**
124
- * Format bytes into human readable form
125
- * @param int $bytes
126
- * @param int $precision
127
- * @return string
128
- */
129
- public function formatSize($bytes, $precision = 2)
130
- {
131
- if ((int) $bytes < 1)
132
- {
133
- return '';
134
- }
135
-
136
- $units = array('B', "KB", "MB", "GB", "TB");
137
-
138
- $bytes = (int) $bytes;
139
- $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
140
- $pow = pow(1000, $base - floor($base)); // Same rule for 1000
141
-
142
- return round($pow, $precision) . ' ' . $units[(int) floor($base)];
143
- }
144
-
145
- /**
146
- * @return false
147
- */
148
- public function getClone()
149
- {
150
- return $this->clone;
151
- }
152
-
153
- /**
154
- * @return null|object
155
- */
156
- public function getTables()
157
- {
158
- return $this->tables;
159
- }
160
-
161
- /**
162
- * Start Module
163
- * @param null|array $clone
164
- * @return bool
165
- */
166
- public function start($clone = null)
167
- {
168
- // Set data
169
- $this->setData($clone);
170
-
171
- // Get the job first
172
- $this->getJob();
173
-
174
- $method = "delete" . ucwords($this->job->current);
175
- return $this->{$method}();
176
- }
177
-
178
- /**
179
- * Get job data
180
- */
181
- private function getJob()
182
- {
183
- $this->job = $this->cache->get("delete_job_{$this->clone->name}");
184
-
185
- if (null !== $this->job)
186
- {
187
- return;
188
- }
189
-
190
- // Generate JOB
191
- $this->job = (object) array(
192
- "current" => "tables",
193
- "nextDirectoryToDelete" => $this->clone->path
194
- );
195
-
196
- $this->cache->save("delete_job_{$this->clone->name}", $this->job);
197
- }
198
-
199
- /**
200
- * @return bool
201
- */
202
- private function updateJob()
203
- {
204
- $this->job->nextDirectoryToDelete = trim($this->job->nextDirectoryToDelete);
205
- return $this->cache->save("delete_job_{$this->clone->name}", $this->job);
206
- }
207
-
208
- /**
209
- * @return array
210
- */
211
- private function getTablesToRemove()
212
- {
213
- $tables = $this->getTableNames();
214
-
215
- if (!isset($_POST["excludedTables"]) || !is_array($_POST["excludedTables"]) || empty($_POST["excludedTables"]))
216
- {
217
- return $tables;
218
- }
219
-
220
- return array_diff($tables, $_POST["excludedTables"]);
221
- }
222
-
223
- /**
224
- * @return array
225
- */
226
- private function getTableNames()
227
- {
228
- return (!is_array($this->tables)) ? array() : array_map(function($value) {
229
- return ($value->name);
230
- }, $this->tables);
231
- }
232
-
233
- /**
234
- * Delete Tables
235
- */
236
- public function deleteTables()
237
- {
238
- if ($this->isOverThreshold())
239
- {
240
- return;
241
- }
242
-
243
- $wpdb = WPStaging::getInstance()->get("wpdb");
244
-
245
- foreach ($this->getTablesToRemove() as $table)
246
- {
247
- // PROTECTION: Never delete any table that beginns with wp prefix of live site
248
- if($this->startsWith($table, $wpdb->prefix)){
249
- $this->log("Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL);
250
- return false;
251
- } else{
252
- $wpdb->query("DROP TABLE {$table}");
253
- }
254
- }
255
-
256
- // Move on to the next
257
- $this->job->current = "directory";
258
- $this->updateJob();
259
- }
260
-
261
- /**
262
- * Check if a strings start with a specific string
263
- * @param string $haystack
264
- * @param string $needle
265
- * @return bool
266
- */
267
- protected function startsWith($haystack, $needle)
268
- {
269
- $length = strlen($needle);
270
- return (substr($haystack, 0, $length) === $needle);
271
- }
272
-
273
- /**
274
- * Delete Directories
275
- */
276
- public function deleteDirectory()
277
- {
278
- // No deleting directories or root of this clone is deleted
279
- if ($this->isDirectoryDeletingFinished())
280
- {
281
- $this->job->current = "finish";
282
- $this->updateJob();
283
- return;
284
- }
285
-
286
- $this->processDirectory($this->job->nextDirectoryToDelete);
287
-
288
- return;
289
- }
290
-
291
- /**
292
- * @return bool
293
- */
294
- public function isDirectoryDeletingFinished()
295
- {
296
- return (
297
- (false === $this->forceDeleteDirectories && (!isset($_POST["deleteDir"]) || '1' !== $_POST["deleteDir"])) ||
298
- !is_dir($this->clone->path) || ABSPATH === $this->job->nextDirectoryToDelete
299
- );
300
- }
301
-
302
- /**
303
- * Delete contents of the directory if there are no directories in it and then delete itself
304
- * @param string $path
305
- * @return mixed
306
- */
307
- private function processDirectory($path)
308
- {
309
- // We hit the limit, stop
310
- if ($this->shouldStop($path))
311
- {
312
- $this->updateJob();
313
- return false;
314
- }
315
-
316
- $this->totalRecursion++;
317
-
318
- $contents = new \DirectoryIterator($path);
319
-
320
- foreach ($contents as $content)
321
- {
322
- // Skip dots
323
- if ($content->isDot())
324
- {
325
- continue;
326
- }
327
-
328
- // Get into the directory
329
- if (!$content->isLink() && $content->isDir())
330
- {
331
- return $this->processDirectory($content->getRealPath());
332
- }
333
-
334
- // Delete file
335
- if ($content->isFile())
336
- {
337
- @unlink($content->getRealPath());
338
- }
339
- }
340
-
341
- // Delete directory
342
- $this->job->lastDeletedDirectory = realpath($path . "/..");
343
- @rmdir($path);
344
- $this->updateJob();
345
- $this->processDirectory($this->job->nextDirectoryToDelete);
346
- }
347
-
348
- /**
349
- * @param string $path
350
- * @return bool
351
- */
352
- private function shouldStop($path)
353
- {
354
- // Just to make sure the root dir is never deleted!
355
- if ($path === get_home_path()){
356
- $this->log("Fatal Error: Trying to delete root of WP installation!", Logger::TYPE_CRITICAL);
357
- return true;
358
- }
359
-
360
- // Check if threshold is reached and is valid dir
361
- return (
362
- $this->isOverThreshold() ||
363
- !is_dir($path) ||
364
- $this->isDirectoryDeletingFinished()
365
- );
366
- }
367
-
368
- /**
369
- * Finish / Update Existing Clones
370
- */
371
- public function deleteFinish()
372
- {
373
- $existingClones = get_option("wpstg_existing_clones_beta", array());
374
-
375
- // Check if clones still exist
376
- $this->log("Verifying existing clones...");
377
- foreach ($existingClones as $name => $clone)
378
- {
379
- if (!is_dir($clone["path"]))
380
- {
381
- unset($existingClones[$name]);
382
- }
383
- }
384
- $this->log("Existing clones verified!");
385
-
386
- if (false === update_option("wpstg_existing_clones_beta", $existingClones))
387
- {
388
- $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
389
- }
390
-
391
- // Delete cached file
392
- $this->cache->delete("delete_job_{$this->clone->name}");
393
- $this->cache->delete("delete_directories_{$this->clone->name}");
394
-
395
- return true;
396
- }
397
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Modules/Jobs/Delete_new.php DELETED
@@ -1,382 +0,0 @@
1
- <?php
2
- namespace WPStaging\Backend\Modules\Jobs;
3
-
4
- use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
5
- //use WPStaging\Utils\Directories;
6
- use WPStaging\Utils\Logger;
7
- use WPStaging\WPStaging;
8
-
9
- /**
10
- * Class Delete
11
- * @package WPStaging\Backend\Modules\Jobs
12
- */
13
- class Delete_new extends Job
14
- {
15
-
16
- /**
17
- * @var false
18
- */
19
- private $clone = false;
20
-
21
- /**
22
- * @var null|object
23
- */
24
- private $tables = null;
25
-
26
- /**
27
- * @var object|null
28
- */
29
- private $job = null;
30
-
31
- /**
32
- * @var bool
33
- */
34
- private $forceDeleteDirectories = false;
35
-
36
- /**
37
- * Sets Clone and Table Records
38
- * @param null|array $clone
39
- */
40
- public function setData($clone = null)
41
- {
42
- if (!is_array($clone))
43
- {
44
- $this->getCloneRecords();
45
- }
46
- else
47
- {
48
- $this->clone = (object) $clone;
49
- $this->forceDeleteDirectories = true;
50
- }
51
-
52
- $this->getTableRecords();
53
- }
54
-
55
- /**
56
- * Get clone
57
- * @param null|string $name
58
- * @throws CloneNotFoundException
59
- */
60
- private function getCloneRecords($name = null)
61
- {
62
- if (null === $name && !isset($_POST["clone"]))
63
- {
64
- $this->log("Clone name is not set", Logger::TYPE_FATAL);
65
- throw new CloneNotFoundException();
66
- }
67
-
68
- if (null === $name)
69
- {
70
- $name = $_POST["clone"];
71
- }
72
-
73
- $clones = get_option("wpstg_existing_clones_beta", array());
74
-
75
- if (empty($clones) || !isset($clones[$name]))
76
- {
77
- $this->log("Couldn't find clone name {$name} or no existing clone", Logger::TYPE_FATAL);
78
- throw new CloneNotFoundException();
79
- }
80
-
81
- $this->clone = $clones[$name];
82
- $this->clone["name"] = $name;
83
- $this->clone = (object) $this->clone;
84
-
85
- unset($clones);
86
- }
87
-
88
- /**
89
- * Get Tables
90
- */
91
- private function getTableRecords()
92
- {
93
- $wpdb = WPStaging::getInstance()->get("wpdb");
94
-
95
- $tables = $wpdb->get_results("SHOW TABLE STATUS LIKE 'wpstg{$this->clone->number}_%'");
96
-
97
- $this->tables = array();
98
-
99
- foreach ($tables as $table)
100
- {
101
- $this->tables[] = array(
102
- "name" => $table->Name,
103
- "size" => $this->formatSize(($table->Data_length + $table->Index_length))
104
- );
105
- }
106
-
107
- $this->tables = json_decode(json_encode($this->tables));
108
- }
109
-
110
- /**
111
- * @return false
112
- */
113
- public function getClone()
114
- {
115
- return $this->clone;
116
- }
117
-
118
- /**
119
- * @return null|object
120
- */
121
- public function getTables()
122
- {
123
- return $this->tables;
124
- }
125
-
126
- /**
127
- * Start Module
128
- * @param null|array $clone
129
- * @return bool
130
- */
131
- public function start($clone = null)
132
- {
133
- // Set data
134
- $this->setData($clone);
135
-
136
- // Get the job first
137
- $this->getJob();
138
-
139
- $method = "delete" . ucwords($this->job->current);
140
- return $this->{$method}();
141
- }
142
-
143
-
144
-
145
- /**
146
- * Get job data
147
- */
148
- private function getJob()
149
- {
150
- $this->job = $this->cache->get("delete_job_{$this->clone->name}");
151
-
152
- if (null !== $this->job)
153
- {
154
- return;
155
- }
156
-
157
- // Generate JOB
158
- $this->job = (object) array(
159
- "current" => "tables",
160
- "nextDirectoryToDelete" => $this->clone->path
161
- );
162
-
163
- $this->cache->save("delete_job_{$this->clone->name}", $this->job);
164
- }
165
-
166
- /**
167
- * Delete Directories
168
- */
169
- // public function deleteDirectory()
170
- // {
171
- // // No deleting directories or root of this clone is deleted
172
- // if ($this->isDirectoryDeletingFinished())
173
- // {
174
- // $this->job->current = "finish";
175
- // $this->updateJob();
176
- // return;
177
- // }
178
- //
179
- // $this->processDirectory($this->job->nextDirectoryToDelete);
180
- //
181
- // return;
182
- // }
183
-
184
- public function deleteDirectory(){
185
- // Just to make sure the root dir is never deleted!
186
- if ($this->clone->path === get_home_path()){
187
- $this->log("Fatal Error: Trying to delete root of WP installation!", Logger::TYPE_CRITICAL);
188
- return false;
189
- }
190
-
191
- $files = glob($this->clone->path . '/*');
192
- foreach ($files as $file) {
193
- is_dir($file) ? $this->deleteDirectory($file) : unlink($file);
194
- }
195
- rmdir($path);
196
- $this->processDirectory($this->job->nextDirectoryToDelete);
197
- return;
198
- }
199
-
200
- /**
201
- * @return bool
202
- */
203
- private function updateJob()
204
- {
205
- $this->job->nextDirectoryToDelete = trim($this->job->nextDirectoryToDelete);
206
- return $this->cache->save("delete_job_{$this->clone->name}", $this->job);
207
- }
208
-
209
- /**
210
- * @return array
211
- */
212
- private function getTablesToRemove()
213
- {
214
- $tables = $this->getTableNames();
215
-
216
- if (!isset($_POST["excludedTables"]) || !is_array($_POST["excludedTables"]) || empty($_POST["excludedTables"]))
217
- {
218
- return $tables;
219
- }
220
-
221
- return array_diff($tables, $_POST["excludedTables"]);
222
- }
223
-
224
- /**
225
- * @return array
226
- */
227
- private function getTableNames()
228
- {
229
- return (!is_array($this->tables)) ? array() : array_map(function($value) {
230
- return ($value->name);
231
- }, $this->tables);
232
- }
233
-
234
- /**
235
- * Delete Tables
236
- */
237
- public function deleteTables()
238
- {
239
- if ($this->isOverThreshold())
240
- {
241
- return;
242
- }
243
-
244
- $wpdb = WPStaging::getInstance()->get("wpdb");
245
-
246
- foreach ($this->getTablesToRemove() as $table)
247
- {
248
- // PROTECTION: Never delete any table that beginns with wp prefix of live site
249
- if($this->startsWith($table, $wpdb->prefix)){
250
- $this->log("Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL);
251
- return false;
252
- } else{
253
- $wpdb->query("DROP TABLE {$table}");
254
- }
255
- }
256
-
257
- // Move on to the next
258
- $this->job->current = "directory";
259
- $this->updateJob();
260
- }
261
-
262
- /**
263
- * Check if a strings start with a specific string
264
- * @param string $haystack
265
- * @param string $needle
266
- * @return bool
267
- */
268
- protected function startsWith($haystack, $needle)
269
- {
270
- $length = strlen($needle);
271
- return (substr($haystack, 0, $length) === $needle);
272
- }
273
-
274
-
275
-
276
- /**
277
- * @return bool
278
- */
279
- public function isDirectoryDeletingFinished()
280
- {
281
- return (
282
- (false === $this->forceDeleteDirectories && (!isset($_POST["deleteDir"]) || '1' !== $_POST["deleteDir"])) ||
283
- !is_dir($this->clone->path) || ABSPATH === $this->job->nextDirectoryToDelete
284
- );
285
- }
286
-
287
- /**
288
- * Delete contents of the directory if there are no directories in it and then delete itself
289
- * @param string $path
290
- * @return mixed
291
- */
292
- private function processDirectory($path)
293
- {
294
- // We hit the limit, stop
295
- if ($this->shouldStop($path))
296
- {
297
- $this->updateJob();
298
- return false;
299
- }
300
-
301
- $this->totalRecursion++;
302
-
303
- $contents = new \DirectoryIterator($path);
304
-
305
- foreach ($contents as $content)
306
- {
307
- // Skip dots
308
- if ($content->isDot())
309
- {
310
- continue;
311
- }
312
-
313
- // Get into the directory
314
- if (!$content->isLink() && $content->isDir())
315
- {
316
- return $this->processDirectory($content->getRealPath());
317
- }
318
-
319
- // Delete file
320
- if ($content->isFile())
321
- {
322
- @unlink($content->getRealPath());
323
- }
324
- }
325
-
326
- // Delete directory
327
- $this->job->lastDeletedDirectory = realpath($path . "/..");
328
- @rmdir($path);
329
- $this->updateJob();
330
- $this->processDirectory($this->job->nextDirectoryToDelete);
331
- }
332
-
333
- /**
334
- * @param string $path
335
- * @return bool
336
- */
337
- private function shouldStop($path)
338
- {
339
- // Just to make sure the root dir is never deleted!
340
- if ($path === get_home_path()){
341
- $this->log("Fatal Error: Trying to delete root of WP installation!", Logger::TYPE_CRITICAL);
342
- return true;
343
- }
344
-
345
- // Check if threshold is reached and is valid dir
346
- return (
347
- $this->isOverThreshold() ||
348
- !is_dir($path) ||
349
- $this->isDirectoryDeletingFinished()
350
- );
351
- }
352
-
353
- /**
354
- * Finish / Update Existing Clones
355
- */
356
- public function deleteFinish()
357
- {
358
- $existingClones = get_option("wpstg_existing_clones_beta", array());
359
-
360
- // Check if clones still exist
361
- $this->log("Verifying existing clones...");
362
- foreach ($existingClones as $name => $clone)
363
- {
364
- if (!is_dir($clone["path"]))
365
- {
366
- unset($existingClones[$name]);
367
- }
368
- }
369
- $this->log("Existing clones verified!");
370
-
371
- if (false === update_option("wpstg_existing_clones_beta", $existingClones))
372
- {
373
- $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
374
- }
375
-
376
- // Delete cached file
377
- $this->cache->delete("delete_job_{$this->clone->name}");
378
- $this->cache->delete("delete_directories_{$this->clone->name}");
379
-
380
- return true;
381
- }
382
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Modules/Jobs/Delete_old.php CHANGED
@@ -10,7 +10,7 @@ use WPStaging\WPStaging;
10
  * Class Delete
11
  * @package WPStaging\Backend\Modules\Jobs
12
  */
13
- class Delete_old extends Job
14
  {
15
 
16
  /**
10
  * Class Delete
11
  * @package WPStaging\Backend\Modules\Jobs
12
  */
13
+ class Delete extends Job
14
  {
15
 
16
  /**
apps/Backend/Modules/Jobs/Directories.php CHANGED
@@ -203,20 +203,10 @@ class Directories extends JobExecutable {
203
  * @return string|false
204
  */
205
  protected function getPath( $directory ) {
206
-
207
- /*
208
- * Do not follow root path like src/web/..
209
- * This must be done before \SplFileInfo->isDir() is used!
210
- * Prevents open base dir restriction fatal errors
211
- */
212
- if (strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
213
- return false;
214
- }
215
-
216
  $path = str_replace( ABSPATH, null, $directory->getRealPath() );
217
 
218
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
219
- if( !$directory->isDir() || strlen( $path ) < 1 ) {
220
  return false;
221
  }
222
 
@@ -277,7 +267,7 @@ class Directories extends JobExecutable {
277
  protected function getFiles() {
278
  $fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
279
 
280
- if( false === ($this->files = @file_get_contents( $fileName )) ) {
281
  $this->files = array();
282
  return;
283
  }
203
  * @return string|false
204
  */
205
  protected function getPath( $directory ) {
 
 
 
 
 
 
 
 
 
 
206
  $path = str_replace( ABSPATH, null, $directory->getRealPath() );
207
 
208
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
209
+ if( !$directory->isDir() || strlen( $path ) < 1 || strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
210
  return false;
211
  }
212
 
267
  protected function getFiles() {
268
  $fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
269
 
270
+ if( false === ($this->files = file_get_contents( $fileName )) ) {
271
  $this->files = array();
272
  return;
273
  }
apps/Backend/Modules/Jobs/Finish.php CHANGED
@@ -187,7 +187,14 @@ class Finish extends Job
187
  {
188
  // Check if clones still exist
189
  $this->log("Verifying existing clones...");
190
-
 
 
 
 
 
 
 
191
 
192
  // Clone data already exists
193
  if (isset($this->options->existingClones[$this->options->clone]))
@@ -207,7 +214,6 @@ class Finish extends Job
207
  "url" => get_site_url() . '/' . $this->options->cloneDirectoryName,
208
  "number" => $this->options->cloneNumber,
209
  "version" => \WPStaging\WPStaging::VERSION,
210
- "status" => false
211
  );
212
 
213
  if (false === update_option("wpstg_existing_clones_beta", $this->options->existingClones))
187
  {
188
  // Check if clones still exist
189
  $this->log("Verifying existing clones...");
190
+ // foreach ($this->options->existingClones as $name => $clone)
191
+ // {
192
+ // if (!is_dir($clone["path"]))
193
+ // {
194
+ // unset($this->options->existingClones[$name]);
195
+ // }
196
+ // }
197
+ // $this->log("Existing clones verified!");
198
 
199
  // Clone data already exists
200
  if (isset($this->options->existingClones[$this->options->clone]))
214
  "url" => get_site_url() . '/' . $this->options->cloneDirectoryName,
215
  "number" => $this->options->cloneNumber,
216
  "version" => \WPStaging\WPStaging::VERSION,
 
217
  );
218
 
219
  if (false === update_option("wpstg_existing_clones_beta", $this->options->existingClones))
apps/Backend/Modules/Jobs/Job.php CHANGED
@@ -95,7 +95,6 @@ abstract class Job implements JobInterface
95
  $this->start = $this->time();
96
  $this->maxMemoryLimit = $this->getMemoryInBytes(@ini_get("memory_limit"));
97
  $this->maxExecutionTime = (int) ini_get("max_execution_time");
98
- //$this->maxExecutionTime = (int) 9;
99
 
100
  if ($this->maxExecutionTime < 1)
101
  {
@@ -425,11 +424,6 @@ abstract class Job implements JobInterface
425
  */
426
  protected function log($msg, $type = Logger::TYPE_INFO)
427
  {
428
-
429
- if (!isset($this->options->clone)){
430
- $this->options->clone = date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
431
- }
432
-
433
  if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
434
  {
435
  $this->logger->setFileName($this->options->clone);
@@ -444,11 +438,6 @@ abstract class Job implements JobInterface
444
  */
445
  protected function debugLog($msg, $type = Logger::TYPE_INFO)
446
  {
447
-
448
- if (!isset($this->options->clone)){
449
- $this->options->clone = date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
450
- }
451
-
452
  if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
453
  {
454
  $this->logger->setFileName($this->options->clone);
95
  $this->start = $this->time();
96
  $this->maxMemoryLimit = $this->getMemoryInBytes(@ini_get("memory_limit"));
97
  $this->maxExecutionTime = (int) ini_get("max_execution_time");
 
98
 
99
  if ($this->maxExecutionTime < 1)
100
  {
424
  */
425
  protected function log($msg, $type = Logger::TYPE_INFO)
426
  {
 
 
 
 
 
427
  if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
428
  {
429
  $this->logger->setFileName($this->options->clone);
438
  */
439
  protected function debugLog($msg, $type = Logger::TYPE_INFO)
440
  {
 
 
 
 
 
441
  if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
442
  {
443
  $this->logger->setFileName($this->options->clone);
apps/Backend/Modules/Jobs/Scan.php CHANGED
@@ -285,18 +285,10 @@ class Scan extends Job
285
  */
286
  protected function getPath($directory)
287
  {
288
- /*
289
- * Do not follow root path like src/web/..
290
- * This must be done before \SplFileInfo->isDir() is used!
291
- * Prevents open base dir restriction fatal errors
292
- */
293
- if (strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
294
- return false;
295
- }
296
  $path = str_replace(ABSPATH, null, $directory->getRealPath());
297
 
298
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
299
- if (!$directory->isDir() || strlen($path) < 1)
300
  {
301
  return false;
302
  }
285
  */
286
  protected function getPath($directory)
287
  {
 
 
 
 
 
 
 
 
288
  $path = str_replace(ABSPATH, null, $directory->getRealPath());
289
 
290
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
291
+ if (!$directory->isDir() || strlen($path) < 1 || strpos($directory->getRealPath(), ABSPATH) !== 0)
292
  {
293
  return false;
294
  }
apps/Backend/Modules/Optimizer.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WPStaging\Backend\Modules;
3
+
4
+ use WPStaging\DI\InjectionAware;
5
+
6
+ // No Direct Access
7
+ if (!defined("WPINC"))
8
+ {
9
+ die;
10
+ }
11
+
12
+ /**
13
+ * Class Optimizer
14
+ * @package WPStaging\Backend\Modules;
15
+ */
16
+ class Optimizer extends InjectionAware
17
+ {
18
+
19
+ /**
20
+ * @var array
21
+ */
22
+ private $wpFilter;
23
+
24
+ /**
25
+ * Optimizer constructor.
26
+ */
27
+ public function initialize()
28
+ {
29
+ $this->wpFilter = $this->getDI()->get("wpFilter");
30
+ }
31
+
32
+ /**
33
+ * Remove TGM Plugin Activation "force_activation" from admin_init action hook if it exists
34
+ * @desc Stop excluded plugins being deactivated after a migration when a theme uses TGMPA
35
+ * to require a plugin to be always active
36
+ * @return bool
37
+ */
38
+ public function compatibility()
39
+ {
40
+ if (!$this->shouldRemove() || !$this->wpFilter)
41
+ {
42
+ return false;
43
+ }
44
+
45
+ foreach ($this->wpFilter["admin_init"] as $priority => $functions)
46
+ {
47
+ foreach ($functions as $key => $function)
48
+ {
49
+ if (false !== strpos($key, "force_activation"))
50
+ {
51
+ unset($this->wpFilter["admin_init"][$priority][$key]);
52
+ break;
53
+ }
54
+ }
55
+ }
56
+
57
+ return true;
58
+ }
59
+
60
+ /**
61
+ * @return bool
62
+ */
63
+ public function shouldRemove()
64
+ {
65
+ return (
66
+ (isset($_GET["page"]) && "wpstg_clone" === $_GET["page"]) ||
67
+ $this->isCompatibilityModeRequest()
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Checks if the current request should be processed by compatibility mode
73
+ * @return bool
74
+ */
75
+ public function isCompatibilityModeRequest()
76
+ {
77
+ return (
78
+ defined("DOING_AJAX") &&
79
+ DOING_AJAX &&
80
+ isset($_POST["action"]) &&
81
+ false !== strpos($_POST["action"], "wpstg")
82
+ );
83
+ }
84
+
85
+ /**
86
+ * Returns an array of plugin slugs to be blacklisted.
87
+ * @return array
88
+ */
89
+ public function blackListedPlugins()
90
+ {
91
+ $blackListedPlugins = $this->getDI()->get("settings")->getBlackListedPlugins();
92
+
93
+ return (empty($blackListedPlugins)) ? $blackListedPlugins : array_flip($blackListedPlugins);
94
+ }
95
+
96
+ /**
97
+ * @param array $plugins
98
+ * @return array|bool
99
+ */
100
+ public function getBlackListedPluginsForExcludes($plugins = array())
101
+ {
102
+ if (!is_array($plugins) || empty($plugins) || !$this->isCompatibilityModeRequest())
103
+ {
104
+ return false;
105
+ }
106
+
107
+ $blackListedPlugins = $this->blackListedPlugins();
108
+
109
+ if (empty($blackListedPlugins))
110
+ {
111
+ return false;
112
+ }
113
+
114
+ return $blackListedPlugins;
115
+ }
116
+
117
+ /**
118
+ * Remove blacklisted plugins
119
+ * @param array $plugins
120
+ * @return array
121
+ */
122
+ public function excludedPlugins($plugins = array())
123
+ {
124
+ $blackListedPlugins = $this->getBlackListedPluginsForExcludes($plugins);
125
+
126
+ if (false === $blackListedPlugins)
127
+ {
128
+ return $plugins;
129
+ }
130
+
131
+ foreach ($plugins as $key => $plugin)
132
+ {
133
+ if (false === strpos($plugin, "wp-staging") || isset($blackListedPlugins[$plugin]))
134
+ {
135
+ unset($plugins[$key]);
136
+ }
137
+ }
138
+
139
+ return $plugins;
140
+ }
141
+ }
apps/Backend/Notices/Notices.php CHANGED
@@ -88,10 +88,10 @@ class Notices {
88
  $varsDirectory = \WPStaging\WPStaging::getContentDir();
89
 
90
 
91
- // Poll do not show any longer
92
- /*if( $this->canShow( "wpstg_poll", 7 ) ) {
93
  require_once "{$viewsNoticesPath}poll.php";
94
- }*/
95
 
96
  // Cache directory in uploads is not writable
97
  if( !wp_is_writable( $varsDirectory ) ) {
88
  $varsDirectory = \WPStaging\WPStaging::getContentDir();
89
 
90
 
91
+ // Poll
92
+ if( $this->canShow( "wpstg_poll", 7 ) ) {
93
  require_once "{$viewsNoticesPath}poll.php";
94
+ }
95
 
96
  // Cache directory in uploads is not writable
97
  if( !wp_is_writable( $varsDirectory ) ) {
apps/Backend/Optimizer/Optimizer.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- namespace WPStaging\Backend\Optimizer;
3
-
4
- // No Direct Access
5
- if( !defined( "WPINC" ) ) {
6
- die;
7
- }
8
-
9
- /**
10
- * Optimizer
11
- */
12
-
13
- class Optimizer {
14
-
15
- private $mudir;
16
- private $source;
17
- private $dest;
18
-
19
- public function __construct() {
20
- $this->mudir = ( defined( 'WPMU_PLUGIN_DIR' ) && defined( 'WPMU_PLUGIN_URL' ) ) ? WPMU_PLUGIN_DIR : trailingslashit( WP_CONTENT_DIR ) . 'mu-plugins';
21
-
22
- $this->source = trailingslashit( WPSTG_PLUGIN_DIR ) . 'apps/Backend/Optimizer/wp-staging-optimizer.php';
23
- $this->dest = trailingslashit( $this->mudir ) . 'wp-staging-optimizer.php';
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
- }
37
- }
38
-
39
- private function copy() {
40
- if( !copy( $this->source, $this->dest ) ) {
41
- return false;
42
- }
43
- }
44
-
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Optimizer/wp-staging-optimizer.php DELETED
@@ -1,120 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Plugin Name: WP Staging Optimizer
5
- Plugin URI: https://wp-staging.com
6
- Description: Prevents 3rd party plugins from being loaded during WP Staging specific operations
7
- Author: René Hermenau
8
- Version: 1.0
9
- Author URI: https://wp-staging.com
10
- Credit: Original version is made by Delicious Brains (WP Migrate DB). Thank you guys!
11
- */
12
-
13
-
14
-
15
- /**
16
- * remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
17
- *
18
- * @param array $plugins numerically keyed array of plugin names
19
- *
20
- * @return array
21
- */
22
- function wpstg_exclude_plugins( $plugins ) {
23
- if( !is_array( $plugins ) || empty( $plugins ) ) {
24
- return $plugins;
25
- }
26
-
27
- if( !wpstg_is_compatibility_mode_request() ) {
28
- return $plugins;
29
- }
30
-
31
- foreach ( $plugins as $key => $plugin ) {
32
- if( false !== strpos( $plugin, 'wp-staging' ) ) {
33
- continue;
34
- }
35
- unset( $plugins[$key] );
36
- }
37
-
38
- return $plugins;
39
- }
40
- add_filter( 'option_active_plugins', 'wpstg_exclude_plugins' );
41
-
42
-
43
- /**
44
- * remove all plugins except wp-staging and wp-staging-pro from network-active plugins
45
- *
46
- * @param array $plugins array of plugins keyed by name (name=>timestamp pairs)
47
- *
48
- * @return array
49
- */
50
- function wpstg_exclude_site_plugins( $plugins ) {
51
- if( !is_array( $plugins ) || empty( $plugins ) ) {
52
- return $plugins;
53
- }
54
-
55
- if( !wpstg_is_compatibility_mode_request() ) {
56
- return $plugins;
57
- }
58
-
59
-
60
- foreach ( array_keys( $plugins ) as $plugin ) {
61
- if( false !== strpos( $plugin, 'wp-staging' ) || !isset( $blacklist_plugins[$plugin] ) ) {
62
- continue;
63
- }
64
- unset( $plugins[$plugin] );
65
- }
66
-
67
- return $plugins;
68
- }
69
- add_filter( 'site_option_active_sitewide_plugins', 'wpstg_exclude_site_plugins' );
70
-
71
- /**
72
- * Should the current request be processed by Compatibility Mode?
73
- *
74
- * @return bool
75
- */
76
- function wpstg_is_compatibility_mode_request() {
77
- if( !defined( 'DOING_AJAX' ) ||
78
- !DOING_AJAX ||
79
- !isset( $_POST['action'] ) ||
80
- false === strpos( $_POST['action'], 'wpstg' )
81
- ) {
82
-
83
- return false;
84
- }
85
- return true;
86
- }
87
-
88
- /**
89
- * Remove TGM Plugin Activation 'force_activation' admin_init action hook if present.
90
- *
91
- * This is to stop excluded plugins being deactivated after a migration, when a theme uses TGMPA to require a plugin to be always active.
92
- */
93
- function wpstg_tgmpa_compatibility() {
94
- $remove_function = false;
95
-
96
- // run on wpstg page
97
- if( isset( $_GET['page'] ) && 'wpstg_clone' == $_GET['page'] ) {
98
- $remove_function = true;
99
- }
100
- // run on wpstg ajax requests
101
- if( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['action'] ) && false !== strpos( $_POST['action'], 'wpstg' ) ) {
102
- $remove_function = true;
103
- }
104
-
105
- if( $remove_function ) {
106
- global $wp_filter;
107
- $admin_init_functions = $wp_filter['admin_init'];
108
- foreach ( $admin_init_functions as $priority => $functions ) {
109
- foreach ( $functions as $key => $function ) {
110
- // searching for function this way as can't rely on the calling class being named TGM_Plugin_Activation
111
- if( false !== strpos( $key, 'force_activation' ) ) {
112
- unset( $wp_filter['admin_init'][$priority][$key] );
113
-
114
- return;
115
- }
116
- }
117
- }
118
- }
119
- }
120
- add_action( 'admin_init', 'wpstg_tgmpa_compatibility', 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Upgrade/Upgrade.php CHANGED
@@ -3,16 +3,11 @@
3
  namespace WPStaging\Backend\Upgrade;
4
 
5
  use WPStaging\WPStaging;
6
- //use WPStaging\Backend\Optimizer\Optimizer;
7
- //use WPStaging\Cron\Cron;
8
  use WPStaging\Utils\Logger;
9
 
10
  /**
11
  * Upgrade Class
12
- * This must be loaded on every page init to ensure all settings are
13
- * adjusted correctly and to run any upgrade process if necessary.
14
  */
15
-
16
  // No Direct Access
17
  if( !defined( "WPINC" ) ) {
18
  die;
@@ -21,7 +16,7 @@ if( !defined( "WPINC" ) ) {
21
  class Upgrade {
22
 
23
  /**
24
- * Previous Version number
25
  * @var string
26
  */
27
  private $previousVersion;
@@ -39,69 +34,30 @@ class Upgrade {
39
  private $clonesBeta;
40
 
41
  /**
42
- * Cron data
43
- * @var obj
44
- */
45
- private $cron;
46
-
47
- /**
48
  * Logger
49
  * @var obj
50
  */
51
  private $logger;
52
 
53
  public function __construct() {
54
-
55
- // add wpstg_weekly_event to cron events
56
- $this->cron = new \WPStaging\Cron\Cron;
57
-
58
- // Previous version
59
  $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
60
-
61
- // Options earlier than version 2.0.0
62
  $this->clones = get_option( "wpstg_existing_clones", array() );
63
-
64
- // Current options
65
  $this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
66
-
67
- // Logger
68
  $this->logger = new Logger;
69
  }
70
 
71
  public function doUpgrade() {
72
- $this->upgrade2_0_3();
73
- //$this->upgrade2_0_4();
74
- $this->setVersion();
75
- }
76
-
77
- /**
78
- * Upgrade method 2.0.3
79
- */
80
- public function upgrade2_0_3() {
81
  // Previous version lower than 2.0.2 or new install
82
  if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
83
  $this->upgradeOptions();
84
  $this->upgradeClonesBeta();
85
  $this->upgradeNotices();
86
  }
 
87
  }
88
 
89
  /**
90
- * Upgrade method 2.0.4
91
- */
92
- // public function upgrade2_0_4() {
93
- // if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.4', '<' ) ) {
94
- //
95
- // // Register cron job.
96
- // $this->cron->schedule_event();
97
- //
98
- // // Install Optimizer
99
- // $optimizer = new Optimizer();
100
- // $optimizer->installOptimizer();
101
- // }
102
- // }
103
-
104
- /**
105
  * Upgrade routine for new install
106
  */
107
  private function upgradeOptions() {
@@ -194,7 +150,7 @@ class Upgrade {
194
  }
195
 
196
  /**
197
- * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
198
  * Fix some logical db options
199
  */
200
  private function upgradeNotices() {
3
  namespace WPStaging\Backend\Upgrade;
4
 
5
  use WPStaging\WPStaging;
 
 
6
  use WPStaging\Utils\Logger;
7
 
8
  /**
9
  * Upgrade Class
 
 
10
  */
 
11
  // No Direct Access
12
  if( !defined( "WPINC" ) ) {
13
  die;
16
  class Upgrade {
17
 
18
  /**
19
+ * Previous Version
20
  * @var string
21
  */
22
  private $previousVersion;
34
  private $clonesBeta;
35
 
36
  /**
 
 
 
 
 
 
37
  * Logger
38
  * @var obj
39
  */
40
  private $logger;
41
 
42
  public function __construct() {
 
 
 
 
 
43
  $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
44
+ // Original option
 
45
  $this->clones = get_option( "wpstg_existing_clones", array() );
 
 
46
  $this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
 
 
47
  $this->logger = new Logger;
48
  }
49
 
50
  public function doUpgrade() {
 
 
 
 
 
 
 
 
 
51
  // Previous version lower than 2.0.2 or new install
52
  if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
53
  $this->upgradeOptions();
54
  $this->upgradeClonesBeta();
55
  $this->upgradeNotices();
56
  }
57
+ $this->setVersion();
58
  }
59
 
60
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  * Upgrade routine for new install
62
  */
63
  private function upgradeOptions() {
150
  }
151
 
152
  /**
153
+ * Upgrade Notices Db options from wpstg 1.3 -> 2.0.1
154
  * Fix some logical db options
155
  */
156
  private function upgradeNotices() {
apps/Backend/public/css/wpstg-admin.css CHANGED
@@ -190,14 +190,14 @@ color:#777777;
190
  /* Cloning workflow */
191
  #wpstg-clonepage-wrapper {
192
  margin-bottom: 20px;
193
- /*width: 690px; */
194
  }
195
 
196
  @media screen and (min-width:1090px){
197
  #wpstg-clonepage-wrapper {
198
  float: left;
199
  margin-bottom: 20px;
200
- /*width: 690px;*/
201
  }
202
  .wpstg-sidebar{
203
  display: none;
@@ -371,36 +371,11 @@ color:#777777;
371
  margin-top:-5px;
372
  }
373
 
374
- #wpstg-loader.wpstg-finished {
375
- content:"Finished";
376
- background-color:#00c89a;
377
- color:white;
378
- padding:2px;
379
- margin-top:6px;
380
- }
381
-
382
  #wpstg-workflow {
383
  position: relative;
384
  clear:both;
385
  padding-top:20px;
386
  margin-right:20px;
387
- float:left;
388
- min-width: 500px;
389
- border-right: 1px solid #DFDFDF;
390
- min-height: 380px;
391
- padding-right: 20px;
392
- }
393
-
394
- #wpstg-sidebar {
395
- float: left;
396
- max-width: 400px;
397
- display: block;
398
- }
399
-
400
- @media screen and (max-width:1150px){
401
- #wpstg-sidebar img{
402
- margin-top: 30px;
403
- }
404
  }
405
 
406
  #wpstg-workflow.loading::after,
@@ -605,7 +580,6 @@ color:#777777;
605
 
606
  #wpstg-log-details{
607
  height: 300px;
608
- max-width: 700px;
609
  overflow: scroll;
610
  /*max-width: 650px;*/
611
  font-family: monospace;
190
  /* Cloning workflow */
191
  #wpstg-clonepage-wrapper {
192
  margin-bottom: 20px;
193
+ width: 690px;
194
  }
195
 
196
  @media screen and (min-width:1090px){
197
  #wpstg-clonepage-wrapper {
198
  float: left;
199
  margin-bottom: 20px;
200
+ width: 690px;
201
  }
202
  .wpstg-sidebar{
203
  display: none;
371
  margin-top:-5px;
372
  }
373
 
 
 
 
 
 
 
 
 
374
  #wpstg-workflow {
375
  position: relative;
376
  clear:both;
377
  padding-top:20px;
378
  margin-right:20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  }
380
 
381
  #wpstg-workflow.loading::after,
580
 
581
  #wpstg-log-details{
582
  height: 300px;
 
583
  overflow: scroll;
584
  /*max-width: 650px;*/
585
  font-family: monospace;
apps/Backend/public/img/wpstaging-banner200x400-tryout.gif DELETED
Binary file
apps/Backend/public/img/wpstaging-banner200x400.gif DELETED
Binary file
apps/Backend/public/js/wpstg-admin.js CHANGED
@@ -533,6 +533,10 @@ var WPStaging = (function ($)
533
  // Styling of elements
534
  $workFlow.removeClass("loading").html(response);
535
 
 
 
 
 
536
  },
537
  "HTML"
538
  );
@@ -581,28 +585,21 @@ var WPStaging = (function ($)
581
  },
582
  function (response)
583
  {
584
- if (response) {
585
- if ("undefined" !== typeof response.delete && response.delete === 'finished') {
586
-
587
- cache.get("#wpstg-removing-clone").removeClass("loading").html('');
588
- $(".wpstg-clone#" + clone).remove();
589
-
590
- if ($(".wpstg-clone").length < 1)
591
- {
592
- cache.get("#wpstg-existing-clones").find("h3").text('');
593
- }
594
-
595
- cache.get("#wpstg-loader").hide();
596
- return;
597
- }
598
- }
599
- // continue
600
  if (true !== response)
601
  {
602
  deleteClone(clone);
603
  return;
604
  }
605
 
 
 
 
 
 
 
 
 
 
606
  }
607
  );
608
  };
@@ -655,16 +652,14 @@ var WPStaging = (function ($)
655
  */
656
  var getLogs = function (log)
657
  {
 
 
 
658
  if (log != null && "undefined" !== typeof (log)) {
659
  if (log.constructor === Array) {
660
  $.each(log, function (index, value) {
661
-
662
  //console.log(index, value);
663
- if (value.type === 'ERROR'){
664
- cache.get("#wpstg-log-details").append('<span style="color:red;">[' + value.type + ']</span>-'+ '[' + value.date + '] ' + value.message + '</br>');
665
- } else {
666
  cache.get("#wpstg-log-details").append('[' + value.type + ']-'+ '[' + value.date + '] ' + value.message + '</br>');
667
- }
668
  })
669
  } else {
670
  cache.get("#wpstg-log-details").append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
@@ -1066,8 +1061,6 @@ var WPStaging = (function ($)
1066
  * @type {ajax}
1067
  */
1068
  that.ajax = ajax;
1069
- that.showError = showError;
1070
- that.getLogs = getLogs;
1071
 
1072
  return that;
1073
  })(jQuery);
533
  // Styling of elements
534
  $workFlow.removeClass("loading").html(response);
535
 
536
+ $currentStep
537
+ .removeClass("wpstg-current-step")
538
+ .next("li")
539
+ .addClass("wpstg-current-step");
540
  },
541
  "HTML"
542
  );
585
  },
586
  function (response)
587
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  if (true !== response)
589
  {
590
  deleteClone(clone);
591
  return;
592
  }
593
 
594
+ cache.get("#wpstg-removing-clone").removeClass("loading").html('');
595
+ $(".wpstg-clone#" + clone).remove();
596
+
597
+ if ($(".wpstg-clone").length < 1)
598
+ {
599
+ cache.get("#wpstg-existing-clones").find("h3").text('');
600
+ }
601
+
602
+ cache.get("#wpstg-loader").hide();
603
  }
604
  );
605
  };
652
  */
653
  var getLogs = function (log)
654
  {
655
+
656
+
657
+
658
  if (log != null && "undefined" !== typeof (log)) {
659
  if (log.constructor === Array) {
660
  $.each(log, function (index, value) {
 
661
  //console.log(index, value);
 
 
 
662
  cache.get("#wpstg-log-details").append('[' + value.type + ']-'+ '[' + value.date + '] ' + value.message + '</br>');
 
663
  })
664
  } else {
665
  cache.get("#wpstg-log-details").append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
1061
  * @type {ajax}
1062
  */
1063
  that.ajax = ajax;
 
 
1064
 
1065
  return that;
1066
  })(jQuery);
apps/Backend/views/_includes/messages/wp-version-compatible-message.php CHANGED
@@ -6,7 +6,7 @@
6
  '<br/> As WP Staging is using crucial DB and file functions it\'s important that you are using a ' .
7
  'WP Staging version <br> which has been verified to be working with your WordPress version. ' .
8
  'You risk unexpected results up to data lose if you do not so. ' .
9
- '<p>Please look at <a href="%1$s" target="_blank">%1$s</a> for the latest WP Staging version.', 'wpstg'), 'https://wp-staging.com', get_bloginfo( 'version' )
10
  );
11
  ?>
12
  </p>
6
  '<br/> As WP Staging is using crucial DB and file functions it\'s important that you are using a ' .
7
  'WP Staging version <br> which has been verified to be working with your WordPress version. ' .
8
  'You risk unexpected results up to data lose if you do not so. ' .
9
+ '<p>Please look at <a href="%1$s" target="_blank">%1$s</a> for the latest WP Staging version.', 'wpstg'), 'https://wordpress.org/plugins/wp-staging/', get_bloginfo( 'version' )
10
  );
11
  ?>
12
  </p>
apps/Backend/views/clone/ajax/delete-confirmation.php CHANGED
@@ -70,7 +70,7 @@
70
  <label>
71
  <input id="deleteDirectory" type="checkbox" class="wpstg-check-dir" name="deleteDirectory" value="1" checked>
72
  <?php echo $clone->path; ?>
73
- <span class="wpstg-size-info"></span>
74
  </label>
75
  </div>
76
  </div>
70
  <label>
71
  <input id="deleteDirectory" type="checkbox" class="wpstg-check-dir" name="deleteDirectory" value="1" checked>
72
  <?php echo $clone->path; ?>
73
+ <span class="wpstg-size-info"><?php echo $clone->size; ?></span>
74
  </label>
75
  </div>
76
  </div>
apps/Backend/views/clone/ajax/scan.php CHANGED
@@ -1,5 +1,5 @@
1
  <label id="wpstg-clone-label" for="wpstg-new-clone">
2
- <?php echo __('Staging Site Name:', 'wpstg')?>
3
  <input type="text" id="wpstg-new-clone-id" value="<?php echo $options->current; ?>"<?php if (null !== $options->current) echo " disabled='disabled'"?>>
4
  </label>
5
 
@@ -80,9 +80,7 @@
80
  <p>
81
  <span>
82
  <?php
83
- if (isset($options->clone)){
84
  echo __("All files are copied into: ", "wpstg") . $options->root . $options->clone;
85
- }
86
  ?>
87
  </span>
88
  </p>
1
  <label id="wpstg-clone-label" for="wpstg-new-clone">
2
+ <?php echo __('Name your new site, e.g. <i>staging</i> or <i>development</i>:', 'wpstg')?>
3
  <input type="text" id="wpstg-new-clone-id" value="<?php echo $options->current; ?>"<?php if (null !== $options->current) echo " disabled='disabled'"?>>
4
  </label>
5
 
80
  <p>
81
  <span>
82
  <?php
 
83
  echo __("All files are copied into: ", "wpstg") . $options->root . $options->clone;
 
84
  ?>
85
  </span>
86
  </p>
apps/Backend/views/clone/ajax/start.php CHANGED
@@ -30,7 +30,7 @@
30
  <?php echo __("Cancel", "wpstg")?>
31
  </button>
32
 
33
- <button type="button" id="wpstg-show-log-button" class="button" data-clone="<?php echo $cloning->getOptions()->clone?>" style="margin-top: 5px;display:none;">
34
  <?php _e('Display working log', 'wpstg')?>
35
  </button>
36
 
30
  <?php echo __("Cancel", "wpstg")?>
31
  </button>
32
 
33
+ <button type="button" id="wpstg-show-log-button" class="button" data-clone="<?php echo $cloning->getOptions()->clone?>" style="margin-top: 5px;">
34
  <?php _e('Display working log', 'wpstg')?>
35
  </button>
36
 
apps/Backend/views/clone/index.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  <?php require_once($this->path . "views/_includes/header.php")?>
4
 
5
- <h2 class="wpstg-nav-tab-wrapper"></h2>
6
 
7
  <?php
8
  do_action("wpstg_notifications");
2
 
3
  <?php require_once($this->path . "views/_includes/header.php")?>
4
 
5
+ <h2 class="nav-tab-wrapper"></h2>
6
 
7
  <?php
8
  do_action("wpstg_notifications");
apps/Backend/views/clone/single-site/index.php CHANGED
@@ -16,5 +16,4 @@
16
  </li>
17
  </ul>
18
 
19
- <div id="wpstg-workflow"></div>
20
- <div id="wpstg-sidebar"><a href="https://wp-staging.com/?utm_source=tryout&utm_medium=plugin&utm_campaign=tryout&utm_term=tryout" target="_new"><img src="<?php echo WPSTG_PLUGIN_URL . '/apps/Backend/public/img/wpstaging-banner200x400-tryout.gif'; ?>"></a></div>
16
  </li>
17
  </ul>
18
 
19
+ <div id="wpstg-workflow"></div>
 
apps/Backend/views/tools/index.php CHANGED
@@ -24,7 +24,7 @@
24
  ?>
25
  </ul>
26
 
27
- <h2 class="wpstg-nav-tab-wrapper"></h2>
28
 
29
  <div class="metabox-holder">
30
  <?php require_once $this->path . "views/tools/tabs/" . $activeTab . ".php"?>
24
  ?>
25
  </ul>
26
 
27
+ <h2 class="nav-tab-wrapper"></h2>
28
 
29
  <div class="metabox-holder">
30
  <?php require_once $this->path . "views/tools/tabs/" . $activeTab . ".php"?>
apps/Core/Cron/Cron.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Chron relevant stuff
5
- */
6
-
7
- namespace WPStaging\Cron;
8
-
9
- // No Direct Access
10
- if( !defined( "WPINC" ) ) {
11
- die;
12
- }
13
-
14
- class Cron {
15
-
16
-
17
- public function __construct() {
18
- add_filter( 'cron_schedules', array($this, 'add_new_intervals') );
19
- }
20
-
21
- /**
22
- * Add new intervals for wp cron jobs
23
- * @param type $schedules
24
- * @return type
25
- */
26
- public function add_new_intervals( $schedules ) {
27
- // add weekly and monthly intervals
28
- $schedules['weekly'] = array(
29
- 'interval' => 604800,
30
- 'display' => __( 'Once Weekly' )
31
- );
32
-
33
- $schedules['monthly'] = array(
34
- 'interval' => 2635200,
35
- 'display' => __( 'Once a month' )
36
- );
37
-
38
- return $schedules;
39
- }
40
-
41
- public function schedule_event() {
42
- if( !wp_next_scheduled( 'wpstg_weekly_event' ) ) {
43
- wp_schedule_event( time(), 'weekly', 'wpstg_weekly_event' );
44
- }
45
- }
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Core/WPStaging.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
-
3
  namespace WPStaging;
4
 
5
  // No Direct Access
6
- if( !defined( "WPINC" ) ) {
7
- die;
 
8
  }
9
 
10
  // Ensure to include autoloader class
@@ -18,407 +18,414 @@ use WPStaging\Utils\Cache;
18
  use WPStaging\Utils\Loader;
19
  use WPStaging\Utils\Logger;
20
  use WPStaging\DI\InjectionAware;
21
- use WPStaging\Cron\Cron;
22
 
23
  /**
24
  * Class WPStaging
25
  * @package WPStaging
26
  */
27
- final class WPStaging {
28
-
29
- /**
30
- * Plugin version
31
- */
32
- const VERSION = "2.0.4";
33
-
34
- /**
35
- * Plugin name
36
- */
37
- const NAME = "WP Staging";
38
-
39
- /**
40
- * Plugin slug
41
- */
42
- const SLUG = "wp-staging";
43
-
44
- /**
45
- * Compatible WP Version
46
- */
47
- const WP_COMPATIBLE = "4.8";
48
-
49
- /**
50
- * Slug: Either wp-staging or wp-staging-pro
51
- * @var string
52
- */
53
- public $slug;
54
-
55
- /**
56
- * Absolute plugin path
57
- * @var string
58
- */
59
- public $pluginPath;
60
-
61
- /**
62
- * Services
63
- * @var array
64
- */
65
- private $services;
66
-
67
- /**
68
- * Singleton instance
69
- * @var WPStaging
70
- */
71
- private static $instance;
72
-
73
- /**
74
- * WPStaging constructor.
75
- */
76
- private function __construct() {
77
-
78
- $file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . self::SLUG . ".php";
79
-
80
- $this->registerMain();
81
- $this->registerNamespaces();
82
- $this->loadLanguages();
83
- $this->loadDependencies();
84
- $this->defineHooks();
85
-
86
- // Licensing stuff be loaded in wpstg core to make cron hook available from frontpage
87
- $this->licensing();
88
-
89
- // Activation Hook
90
- register_activation_hook( $file, array($this, "onActivation") );
91
- }
92
-
93
- /**
94
- * Method to be executed upon activation of the plugin
95
- */
96
- public function onActivation() {
97
- $Activation = new \WPStaging\Backend\Activation\Activation();
98
- $Activation->install_dependancies();
99
- }
100
-
101
- public function registerMain() {
102
  // Slug of the plugin
103
- $this->slug = plugin_basename( dirname( dirname( dirname( __FILE__ ) ) ) );
104
 
105
  // absolute path to the main plugin dir
106
- $this->pluginPath = plugin_dir_path( dirname( dirname( __FILE__ ) ) );
107
 
108
- // URL to apps folder
109
  $this->url = plugin_dir_url( dirname( __FILE__ ) );
110
-
111
- // URL to backend public folder folder
112
  $this->backend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Backend/public/";
113
-
114
- // URL to frontend public folder folder
115
  $this->frontend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Frontend/public/";
116
- }
117
-
118
- /**
119
- * Define Hooks
120
- */
121
- public function defineHooks() {
122
- $loader = $this->get( "loader" );
123
- $loader->addAction( "admin_enqueue_scripts", $this, "enqueueElements", 100 );
124
- $loader->addAction( "wp_enqueue_scripts", $this, "enqueueElements", 100 );
125
- $this->addIntervals();
126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
- /**
129
- * Add new cron time event "weekly"
130
- */
131
- public function addIntervals(){
132
- $interval = new Cron();
133
- }
134
-
135
- /**
136
- * Scripts and Styles
137
- * @param string $hook
138
- */
139
- public function enqueueElements( $hook ) {
140
-
141
- // Load this css file on frontend and backend on all pages if current site is a staging site
142
- if( $this->isStagingSite() ) {
143
- wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", $this->getVersion() );
144
- }
145
-
146
- $availablePages = array(
147
- "toplevel_page_wpstg_clone",
148
- "wp-staging_page_wpstg-settings",
149
- "wp-staging_page_wpstg-tools",
150
- "wp-staging_page_wpstg-license"
151
- );
152
-
153
- // Load these css and js files only on wp staging admin pages
154
- if( !in_array( $hook, $availablePages ) || !is_admin() ) {
155
- return;
156
- }
157
-
158
- // Load admin js files
159
- wp_enqueue_script(
160
- "wpstg-admin-script", $this->backend_url . "js/wpstg-admin.js", array("jquery"), $this->getVersion(), false
161
- );
162
-
163
- // Load admin css files
164
- wp_enqueue_style(
165
- "wpstg-admin", $this->backend_url . "css/wpstg-admin.css", $this->getVersion()
166
- );
167
-
168
- wp_localize_script( "wpstg-admin-script", "wpstg", array(
169
- "nonce" => wp_create_nonce( "wpstg_ajax_nonce" ),
170
- "mu_plugin_confirmation" => __(
171
- "If confirmed we will install an additional WordPress 'Must Use' plugin. "
172
- . "This plugin will allow us to control which plugins are loaded during "
173
- . "WP Staging specific operations. Do you wish to continue?", "wpstg"
174
- ),
175
- "plugin_compatibility_settings_problem" => __(
176
- "A problem occurred when trying to change the plugin compatibility setting.", "wpstg"
177
- ),
178
- "saved" => __( "Saved", "The settings were saved successfully", "wpstg" ),
179
- "status" => __( "Status", "Current request status", "wpstg" ),
180
- "response" => __( "Response", "The message the server responded with", "wpstg" ),
181
- "blacklist_problem" => __(
182
- "A problem occurred when trying to add plugins to backlist.", "wpstg"
183
- ),
184
- "cpuLoad" => $this->getCPULoadSetting(),
185
- "settings" => ( object ) array() // TODO add settings?
186
- ) );
187
- }
188
-
189
- /**
190
- * Caching and logging folder
191
- *
192
- * @return string
193
- */
194
- public static function getContentDir() {
195
- $wp_upload_dir = wp_upload_dir();
196
- $path = $wp_upload_dir['basedir'] . '/wp-staging';
197
- wp_mkdir_p( $path );
198
- return apply_filters( 'wpstg_get_upload_dir', $path . DIRECTORY_SEPARATOR );
199
- }
200
-
201
- /**
202
- * Register used namespaces
203
- */
204
- private function registerNamespaces() {
205
- $autoloader = new Autoloader();
206
- $this->set( "autoloader", $autoloader );
207
-
208
- //wp_die($this->pluginPath . 'apps' . DIRECTORY_SEPARATOR);
209
- // Autoloader
210
- $autoloader->registerNamespaces( array(
211
- "WPStaging" => array(
212
- $this->pluginPath . 'apps' . DIRECTORY_SEPARATOR,
213
- $this->pluginPath . 'apps' . DIRECTORY_SEPARATOR . 'Core' . DIRECTORY_SEPARATOR,
214
- //$this->pluginPath . 'apps' . DIRECTORY_SEPARATOR . 'Backend' . DIRECTORY_SEPARATOR
215
- )
216
- ) );
217
-
218
- // Register namespaces
219
- $autoloader->register();
220
- }
221
-
222
- /**
223
- * Get Instance
224
- * @return WPStaging
225
- */
226
- public static function getInstance() {
227
- if( null === static::$instance ) {
228
- static::$instance = new static();
229
- }
230
-
231
- return static::$instance;
232
- }
233
-
234
- /**
235
- * Prevent cloning
236
- * @return void
237
- */
238
- private function __clone() {
239
-
240
- }
241
-
242
- /**
243
- * Prevent unserialization
244
- * @return void
245
- */
246
- private function __wakeup() {
247
-
248
- }
249
-
250
- /**
251
- * Load Dependencies
252
- */
253
- private function loadDependencies() {
254
- // Set loader
255
- $this->set( "loader", new Loader() );
256
-
257
- // Set cache
258
- $this->set( "cache", new Cache() );
259
-
260
- // Set logger
261
- $this->set( "logger", new Logger() );
262
-
263
- // Set settings
264
- $this->set( "settings", new Settings() );
265
-
266
- // Set Administrator
267
- if( is_admin() ) {
268
- new Administrator( $this );
269
- } else {
270
- new Frontend( $this );
271
- }
272
- }
273
-
274
- /**
275
- * Execute Plugin
276
- */
277
- public function run() {
278
- $this->get( "loader" )->run();
279
- }
280
-
281
- /**
282
- * Set a variable to DI with given name
283
- * @param string $name
284
- * @param mixed $variable
285
- * @return $this
286
- */
287
- public function set( $name, $variable ) {
288
- // It is a function
289
- if( is_callable( $variable ) )
290
- $variable = $variable();
291
-
292
- // Add it to services
293
- $this->services[$name] = $variable;
294
-
295
- return $this;
296
- }
297
-
298
- /**
299
- * Get given name index from DI
300
- * @param string $name
301
- * @return mixed|null
302
- */
303
- public function get( $name ) {
304
- return (isset( $this->services[$name] )) ? $this->services[$name] : null;
305
- }
306
-
307
- /**
308
- * @return string
309
- */
310
- public function getVersion() {
311
- return self::VERSION;
312
- }
313
-
314
- /**
315
- * @return string
316
- */
317
- public function getName() {
318
- return self::NAME;
319
- }
320
-
321
- /**
322
- * @return string
323
- */
324
- public static function getSlug() {
325
- return plugin_basename( dirname( dirname( dirname( __FILE__ ) ) ) );
326
- }
327
-
328
- /**
329
- * Get path to main plugin file
330
- * @return string
331
- */
332
- public function getPath() {
333
- return dirname( dirname( __FILE__ ) );
334
- }
335
-
336
- /**
337
- * Get main plugin url
338
- * @return type
339
- */
340
- public function getUrl() {
341
- return plugin_dir_url( dirname( __FILE__ ) );
342
- }
343
-
344
- /**
345
- * @return array|mixed|object
346
- */
347
- public function getCPULoadSetting() {
348
- $options = $this->get( "settings" );
349
- $setting = $options->getCpuLoad();
350
-
351
- switch ( $setting ) {
352
- case "high":
353
- $cpuLoad = 0;
354
- break;
355
-
356
- case "medium":
357
- $cpuLoad = 1000;
358
- break;
359
-
360
- case "low":
361
- $cpuLoad = 3000;
362
- break;
363
-
364
- case "default":
365
- default:
366
- $cpuLoad = 1000;
367
- }
368
-
369
- return $cpuLoad;
370
- }
371
-
372
- /**
373
- * Load language file
374
- */
375
- public function loadLanguages() {
376
- $languagesDirectory = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR;
377
- $languagesDirectory.= "vars" . DIRECTORY_SEPARATOR . "languages" . DIRECTORY_SEPARATOR;
378
-
379
- // Set filter for plugins languages directory
380
- $languagesDirectory = apply_filters( "wpstg_languages_directory", $languagesDirectory );
381
-
382
- // Traditional WP plugin locale filter
383
- $locale = apply_filters( "plugin_locale", get_locale(), "wpstg" );
384
- $moFile = sprintf( '%1$s-%2$s.mo', "wpstg", $locale );
385
-
386
- // Setup paths to current locale file
387
- $moFileLocal = $languagesDirectory . $moFile;
388
- $moFileGlobal = WP_LANG_DIR . DIRECTORY_SEPARATOR . "wpstg" . DIRECTORY_SEPARATOR . $moFile;
389
-
390
- // Global file (/wp-content/languages/WPSTG)
391
- if( file_exists( $moFileGlobal ) ) {
392
- load_textdomain( "wpstg", $moFileGlobal );
393
- }
394
- // Local file (/wp-content/plugins/wp-staging/languages/)
395
- elseif( file_exists( $moFileLocal ) ) {
396
- load_textdomain( "wpstg", $moFileGlobal );
397
- }
398
- // Default file
399
- else {
400
- load_plugin_textdomain( "wpstg", false, $languagesDirectory );
401
- }
402
- }
403
-
404
- /**
405
- * Check if it is a staging site
406
- * @return bool
407
- */
408
- private function isStagingSite() {
409
- return ("true" === get_option( "wpstg_is_staging_site" ));
410
- }
411
-
412
- /**
413
- * Initialize licensing functions
414
- * @return boolean
415
- */
416
- private function licensing() {
417
- // Add licensing stuff if class exists
418
- if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
419
- $licensing = new Backend\Pro\Licensing\Licensing();
420
- }
421
- return false;
422
- }
423
-
424
- }
1
  <?php
 
2
  namespace WPStaging;
3
 
4
  // No Direct Access
5
+ if (!defined("WPINC"))
6
+ {
7
+ die;
8
  }
9
 
10
  // Ensure to include autoloader class
18
  use WPStaging\Utils\Loader;
19
  use WPStaging\Utils\Logger;
20
  use WPStaging\DI\InjectionAware;
 
21
 
22
  /**
23
  * Class WPStaging
24
  * @package WPStaging
25
  */
26
+ final class WPStaging
27
+ {
28
+
29
+ /**
30
+ * Plugin version
31
+ */
32
+ const VERSION = "2.0.3";
33
+
34
+ /**
35
+ * Plugin name
36
+ */
37
+ const NAME = "WP Staging";
38
+
39
+ /**
40
+ * Plugin slug
41
+ */
42
+ const SLUG = "wp-staging";
43
+
44
+ /**
45
+ * Compatible WP Version
46
+ */
47
+ const WP_COMPATIBLE = "4.7.4";
48
+
49
+ /**
50
+ * Slug: Either wp-staging or wp-staging-pro
51
+ * @var string
52
+ */
53
+ public $slug;
54
+
55
+ /**
56
+ * Absolute plugin path
57
+ * @var string
58
+ */
59
+ public $pluginPath;
60
+
61
+
62
+ /**
63
+ * Services
64
+ * @var array
65
+ */
66
+ private $services;
67
+
68
+ /**
69
+ * Singleton instance
70
+ * @var WPStaging
71
+ */
72
+ private static $instance;
73
+
74
+ /**
75
+ * WPStaging constructor.
76
+ */
77
+ private function __construct()
78
+ {
79
+
80
+ $file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . self::SLUG . ".php";
81
+
82
+ // Activation Hook
83
+ register_activation_hook($file, array($this, "onActivation"));
84
+
85
+ $this->registerMain();
86
+ $this->registerNamespaces();
87
+ $this->loadLanguages();
88
+ $this->loadDependencies();
89
+ $this->defineHooks();
90
+ }
91
+
92
+
93
+ public function registerMain() {
 
 
 
 
 
 
 
94
  // Slug of the plugin
95
+ $this->slug = plugin_basename(dirname(dirname(dirname(__FILE__))));
96
 
97
  // absolute path to the main plugin dir
98
+ $this->pluginPath = plugin_dir_path( dirname(dirname(__FILE__)));
99
 
100
+ // URL to apps folder
101
  $this->url = plugin_dir_url( dirname( __FILE__ ) );
102
+
103
+ // URL to backend public folder folder
104
  $this->backend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Backend/public/";
105
+
106
+ // URL to frontend public folder folder
107
  $this->frontend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Frontend/public/";
108
+ }
109
+
110
+ /**
111
+ * Define Hooks
112
+ */
113
+ public function defineHooks()
114
+ {
115
+ $loader = $this->get("loader");
116
+ $loader->addAction("admin_enqueue_scripts", $this, "enqueueElements", 100);
117
+ $loader->addAction("wp_enqueue_scripts", $this, "enqueueElements", 100);
118
+ }
119
+
120
+ /**
121
+ * Scripts and Styles
122
+ * @param string $hook
123
+ */
124
+ public function enqueueElements($hook)
125
+ {
126
+
127
+ // Load this css file on frontend and backend on all pages if current site is a staging site
128
+ if( $this->isStagingSite() ) {
129
+ wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", $this->getVersion() );
130
+ }
131
+
132
+ $availablePages = array(
133
+ "toplevel_page_wpstg_clone",
134
+ "wp-staging_page_wpstg-settings",
135
+ "wp-staging_page_wpstg-tools"
136
+ );
137
+
138
+ // Load these css and js files only on wp staging admin pages
139
+ if (!in_array($hook, $availablePages) || !is_admin())
140
+ {
141
+ return;
142
+ }
143
+
144
+ // Load admin js files
145
+ wp_enqueue_script(
146
+ "wpstg-admin-script",
147
+ $this->backend_url . "js/wpstg-admin.js",
148
+ array("jquery"),
149
+ $this->getVersion(),
150
+ false
151
+ );
152
+
153
+ // Load admin css files
154
+ wp_enqueue_style(
155
+ "wpstg-admin",
156
+ $this->backend_url . "css/wpstg-admin.css",
157
+ $this->getVersion()
158
+ );
159
+
160
+ wp_localize_script("wpstg-admin-script", "wpstg", array(
161
+ "nonce" => wp_create_nonce("wpstg_ajax_nonce"),
162
+ "mu_plugin_confirmation" => __(
163
+ "If confirmed we will install an additional WordPress 'Must Use' plugin. "
164
+ . "This plugin will allow us to control which plugins are loaded during "
165
+ . "WP Staging specific operations. Do you wish to continue?",
166
+ "wpstg"
167
+ ),
168
+ "plugin_compatibility_settings_problem" => __(
169
+ "A problem occurred when trying to change the plugin compatibility setting.",
170
+ "wpstg"
171
+ ),
172
+ "saved" => __("Saved", "The settings were saved successfully", "wpstg"),
173
+ "status" => __("Status", "Current request status", "wpstg"),
174
+ "response" => __("Response", "The message the server responded with", "wpstg"),
175
+ "blacklist_problem" => __(
176
+ "A problem occurred when trying to add plugins to backlist.",
177
+ "wpstg"
178
+ ),
179
+ "cpuLoad" => $this->getCPULoadSetting(),
180
+ "settings" => (object) array() // TODO add settings?
181
+ ));
182
+ }
183
+
184
+ /**
185
+ * Method to be executed upon activation of the plugin
186
+ */
187
+ public function onActivation()
188
+ {
189
+ // To do
190
+ }
191
+ /**
192
+ * Caching and logging folder
193
+ *
194
+ * @return string
195
+ */
196
+ public static function getContentDir(){
197
+ $wp_upload_dir = wp_upload_dir();
198
+ $path = $wp_upload_dir['basedir'] . '/wp-staging';
199
+ wp_mkdir_p( $path );
200
+ return apply_filters( 'wpstg_get_upload_dir', $path . DIRECTORY_SEPARATOR );
201
+ }
202
+
203
+
204
+ /**
205
+ * Register used namespaces
206
+ */
207
+ private function registerNamespaces()
208
+ {
209
+ $autoloader = new Autoloader();
210
+ $this->set("autoloader", $autoloader);
211
+
212
+ //wp_die($this->pluginPath . 'apps' . DIRECTORY_SEPARATOR);
213
+
214
+ // Autoloader
215
+ $autoloader->registerNamespaces(array(
216
+ "WPStaging" => array(
217
+ $this->pluginPath . 'apps' . DIRECTORY_SEPARATOR,
218
+ $this->pluginPath . 'apps' . DIRECTORY_SEPARATOR . 'Core' . DIRECTORY_SEPARATOR
219
+ )
220
+ ));
221
+
222
+ // Register namespaces
223
+ $autoloader->register();
224
+ }
225
+
226
+ /**
227
+ * Get Instance
228
+ * @return WPStaging
229
+ */
230
+ public static function getInstance()
231
+ {
232
+ if (null === static::$instance)
233
+ {
234
+ static::$instance = new static();
235
+ }
236
+
237
+ return static::$instance;
238
+ }
239
+
240
+ /**
241
+ * Prevent cloning
242
+ * @return void
243
+ */
244
+ private function __clone()
245
+ {}
246
+
247
+ /**
248
+ * Prevent unserialization
249
+ * @return void
250
+ */
251
+ private function __wakeup()
252
+ {}
253
+
254
+ /**
255
+ * Load Dependencies
256
+ */
257
+ private function loadDependencies()
258
+ {
259
+ // Set loader
260
+ $this->set("loader", new Loader());
261
+
262
+ // Set cache
263
+ $this->set("cache", new Cache());
264
+
265
+ // Set logger
266
+ $this->set("logger", new Logger());
267
+
268
+ // Set settings
269
+ $this->set("settings", new Settings());
270
+
271
+ // Set Administrator
272
+ if (is_admin())
273
+ {
274
+ new Administrator($this);
275
+ }
276
+ else
277
+ {
278
+ new Frontend($this);
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Execute Plugin
284
+ */
285
+ public function run()
286
+ {
287
+ $this->get("loader")->run();
288
+ }
289
+
290
+ /**
291
+ * Set a variable to DI with given name
292
+ * @param string $name
293
+ * @param mixed $variable
294
+ * @return $this
295
+ */
296
+ public function set($name, $variable)
297
+ {
298
+ // It is a function
299
+ if (is_callable($variable)) $variable = $variable();
300
+
301
+ // Add it to services
302
+ $this->services[$name] = $variable;
303
+
304
+ return $this;
305
+ }
306
+
307
+ /**
308
+ * Get given name index from DI
309
+ * @param string $name
310
+ * @return mixed|null
311
+ */
312
+ public function get($name)
313
+ {
314
+ return (isset($this->services[$name])) ? $this->services[$name] : null;
315
+ }
316
+
317
+ /**
318
+ * @return string
319
+ */
320
+ public function getVersion()
321
+ {
322
+ return self::VERSION;
323
+ }
324
+
325
+ /**
326
+ * @return string
327
+ */
328
+ public function getName()
329
+ {
330
+ return self::NAME;
331
+ }
332
+
333
+ /**
334
+ * @return string
335
+ */
336
+ public static function getSlug()
337
+ {
338
+ return plugin_basename(dirname(dirname(dirname(__FILE__))));
339
+ }
340
+
341
+ /**
342
+ * Get path to main plugin file
343
+ * @return string
344
+ */
345
+ public function getPath(){
346
+ return dirname(dirname(__FILE__));
347
+ }
348
+ /**
349
+ * Get main plugin url
350
+ * @return type
351
+ */
352
+ public function getUrl(){
353
+ return plugin_dir_url(dirname(__FILE__));
354
+ }
355
+
356
+ /**
357
+ * @return array|mixed|object
358
+ */
359
+ public function getCPULoadSetting()
360
+ {
361
+ $options = $this->get("settings");
362
+ $setting = $options->getCpuLoad();
363
+
364
+ switch ($setting)
365
+ {
366
+ case "high":
367
+ $cpuLoad = 0;
368
+ break;
369
+
370
+ case "medium":
371
+ $cpuLoad = 1000;
372
+ break;
373
+
374
+ case "low":
375
+ $cpuLoad = 3000;
376
+ break;
377
+
378
+ case "default":
379
+ default:
380
+ $cpuLoad = 1000;
381
+ }
382
+
383
+ return $cpuLoad;
384
+ }
385
+
386
+ /**
387
+ * Load language file
388
+ */
389
+ public function loadLanguages()
390
+ {
391
+ $languagesDirectory = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR;
392
+ $languagesDirectory.= "vars" . DIRECTORY_SEPARATOR . "languages" . DIRECTORY_SEPARATOR;
393
+
394
+ // Set filter for plugins languages directory
395
+ $languagesDirectory = apply_filters("wpstg_languages_directory", $languagesDirectory);
396
+
397
+ // Traditional WP plugin locale filter
398
+ $locale = apply_filters("plugin_locale", get_locale(), "wpstg");
399
+ $moFile = sprintf('%1$s-%2$s.mo', "wpstg", $locale);
400
+
401
+ // Setup paths to current locale file
402
+ $moFileLocal = $languagesDirectory . $moFile;
403
+ $moFileGlobal = WP_LANG_DIR . DIRECTORY_SEPARATOR . "wpstg" . DIRECTORY_SEPARATOR . $moFile;
404
+
405
+ // Global file (/wp-content/languages/WPSTG)
406
+ if (file_exists($moFileGlobal))
407
+ {
408
+ load_textdomain("wpstg", $moFileGlobal);
409
+ }
410
+ // Local file (/wp-content/plugins/wp-staging/languages/)
411
+ elseif (file_exists($moFileLocal))
412
+ {
413
+ load_textdomain("wpstg", $moFileGlobal);
414
+ }
415
+ // Default file
416
+ else
417
+ {
418
+ load_plugin_textdomain("wpstg", false, $languagesDirectory);
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Check if it is a staging site
424
+ * @return bool
425
+ */
426
+ private function isStagingSite()
427
+ {
428
+ return ("true" === get_option("wpstg_is_staging_site"));
429
+ }
430
 
431
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -8,28 +8,31 @@ License: GPLv2 or later
8
  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: 4.8
12
- Stable tag: 2.0.4
13
 
14
  A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
15
 
16
  == Description ==
17
 
18
- <strong>This cloning and staging plugin is well tested but work in progress. <br><br>
19
- If you find any issue, please open a [support ticket](https://wp-staging.com/support/ "support ticket").
20
  </strong>
21
  <br /><br />
22
- <strong>Note: </strong> For pushing plugins and theme files to live site, check out [https://wp-staging.com/](https://wp-staging.com/ "WP Staging Pro")
23
- <br /><br />
 
 
 
24
  <blockquote>
25
  <h4> WP Staging for WordPress Migration </h4>
26
  This duplicator plugin allows you to create an staging or development environment in seconds* <br /> <br />
27
- It creates a clone of your website into a subfolder of your main WordPress installation including an entire copy of your database.
28
- This sounds pretty simple and yes it is! All the hard time-consumptive database and file copying stuff including url replacements is done in the background.
29
  <br /> <br />
30
  I created this plugin because all other solutions are way too complex, overloaded with dozens of options or having server requirements which are not available on most shared hosting solutions.
31
  All these reasons prevent user from testing new plugins and updates first before installing them on their live website, so its time to release a plugin which has the potential to be merged into everyone´s wordpress workflow.
32
- <br /><br />
33
  <p><small><em>* Time of creation depends on size of your database and file size</em></small></p>
34
  </blockquote>
35
 
@@ -140,11 +143,10 @@ https://wp-staging.com
140
  == Changelog ==
141
 
142
 
143
- = 2.0.4 =
144
- * New: Major version - Complete rewrite of the code base
145
  * New: Batch processing allows to clone even huge sites without any timeouts
146
  * New: Preparation for WP QUADS PRO with ability to copy file changes back to live site
147
- * New: Bypass (broken) third party plugins during wp staging related ajax requests to prevent processing errors. Use a mu plugin for this.
148
 
149
  = 1.1.6 =
150
  * New: Add download link to WP Staging Beta Version 2.0.1
8
  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: 4.7
12
+ Stable tag: 2.0.3
13
 
14
  A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
15
 
16
  == Description ==
17
 
18
+ <strong>This cloning and staging plugin is well tested but still work in progress! <br>
19
+ If you find a bug please open a ticket in the [support request](https://wordpress.org/support/plugin/wp-staging/ "support forum"). Any issues will be fixed asap!
20
  </strong>
21
  <br /><br />
22
+ <strong>Note: </strong> This plugin is not able to push back your changes to the live site at the moment!
23
+ Please let us know your most requested feature and use our quick poll. It only takes one minute of your time: [Start the poll](https://docs.google.com/forms/d/e/1FAIpQLScZ-dO5WffV3xObn16LwG05tr1HrADD_8L4wbTxPHqoPssVcg/viewform?c=0&w=1&usp=mail_form_link "wp staging poll")
24
+ <br /> <br />
25
+
26
+
27
  <blockquote>
28
  <h4> WP Staging for WordPress Migration </h4>
29
  This duplicator plugin allows you to create an staging or development environment in seconds* <br /> <br />
30
+ It creates a file clone of your website into a subfolder of your current WordPress installation with an entire copy of your database.
31
+ This sounds pretty simple and yes it is! All the hard time consumptive database and file copy stuff including url replacements is done in the background.
32
  <br /> <br />
33
  I created this plugin because all other solutions are way too complex, overloaded with dozens of options or having server requirements which are not available on most shared hosting solutions.
34
  All these reasons prevent user from testing new plugins and updates first before installing them on their live website, so its time to release a plugin which has the potential to be merged into everyone´s wordpress workflow.
35
+ <br /> <br />
36
  <p><small><em>* Time of creation depends on size of your database and file size</em></small></p>
37
  </blockquote>
38
 
143
  == Changelog ==
144
 
145
 
146
+ = 2.0.3 =
147
+ * New: Complete rewrite of the code base
148
  * New: Batch processing allows to clone even huge sites without any timeouts
149
  * New: Preparation for WP QUADS PRO with ability to copy file changes back to live site
 
150
 
151
  = 1.1.6 =
152
  * New: Add download link to WP Staging Beta Version 2.0.1
uninstall.php CHANGED
@@ -1,9 +1,5 @@
1
  <?php
2
 
3
- namespace WPStaging\Backend;
4
-
5
- use WPStaging\Backend\Optimizer\Optimizer;
6
-
7
  /**
8
  * Uninstall WP-Staging
9
  *
@@ -18,33 +14,10 @@ if( !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
18
  exit;
19
  }
20
 
21
- class uninstall {
22
-
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
-
39
- // Delete our must use plugin
40
- $this->deleteMuPlugin();
41
-
42
- $this->init();
43
- }
44
-
45
- private function init() {
46
  $options = json_decode( json_encode( get_option( "wpstg_settings", array() ) ) );
47
 
 
48
  if( isset( $options->unInstallOnDelete ) && '1' === $options->unInstallOnDelete ) {
49
  // Delete options
50
  delete_option( "wpstg_version_upgraded_from" );
@@ -53,37 +26,15 @@ if( isset( $options->unInstallOnDelete ) && '1' === $options->unInstallOnDelete
53
  delete_option( "wpstg_firsttime" );
54
  delete_option( "wpstg_is_staging_site" );
55
  delete_option( "wpstg_settings" );
56
-
57
- /* Do not delete these fields without actually deleting the staging site
58
- * @create a delete routine which deletes the staging sites first
59
- */
60
- //delete_option( "wpstg_existing_clones" );
61
- //delete_option( "wpstg_existing_clones_beta" );
62
-
63
  // Old wpstg 1.3 options for admin notices
64
  delete_option( "wpstg_start_poll" );
65
  delete_option( "wpstg_hide_beta" );
66
  delete_option( "wpstg_RatingDiv" );
67
-
68
- // New 2.x options for admin notices
69
  delete_option( "wpstg_poll" );
70
  delete_option( "wpstg_rating" );
71
  delete_option( "wpstg_beta" );
72
-
73
- // Delete events
74
- wp_clear_scheduled_hook( 'wpstg_weekly_event' );
75
-
76
- }
77
- }
78
-
79
- /**
80
- * delete MuPlugin
81
- */
82
- private function deleteMuPlugin() {
83
- $optimizer = new Optimizer;
84
- $optimizer->unstallOptimizer();
85
- }
86
-
87
  }
88
 
89
- new uninstall();
1
  <?php
2
 
 
 
 
 
3
  /**
4
  * Uninstall WP-Staging
5
  *
14
  exit;
15
  }
16
 
17
+ // Get options
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  $options = json_decode( json_encode( get_option( "wpstg_settings", array() ) ) );
19
 
20
+ // No need to delete
21
  if( isset( $options->unInstallOnDelete ) && '1' === $options->unInstallOnDelete ) {
22
  // Delete options
23
  delete_option( "wpstg_version_upgraded_from" );
26
  delete_option( "wpstg_firsttime" );
27
  delete_option( "wpstg_is_staging_site" );
28
  delete_option( "wpstg_settings" );
29
+ delete_option( "wpstg_existing_clones" );
30
+ delete_option( "wpstg_existing_clones_beta" );
 
 
 
 
 
31
  // Old wpstg 1.3 options for admin notices
32
  delete_option( "wpstg_start_poll" );
33
  delete_option( "wpstg_hide_beta" );
34
  delete_option( "wpstg_RatingDiv" );
35
+ // New ones
 
36
  delete_option( "wpstg_poll" );
37
  delete_option( "wpstg_rating" );
38
  delete_option( "wpstg_beta" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
 
wp-staging.php CHANGED
@@ -6,7 +6,7 @@
6
  * Description: Create a staging clone site for testing & developing
7
  * Author: WP-Staging, René Hermenau, Ilgıt Yıldırım
8
  * Author URI: https://wordpress.org/plugins/wp-staging
9
- * Version: 2.0.4
10
  * Text Domain: wpstg
11
  * Domain Path: /languages/
12
 
@@ -35,38 +35,17 @@ if (!defined("WPINC"))
35
  die;
36
  }
37
 
38
- // Plugin Folder Path
39
- if( !defined( 'WPSTG_PLUGIN_DIR' ) ) {
40
- define( 'WPSTG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
41
- }
42
- // Plugin Folder URL
43
- if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
44
- define( 'WPSTG_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
45
- }
46
-
47
- //require_once WPSTG_PLUGIN_DIR . 'apps/Backend/Install/install.php';
48
-
49
- /**
50
- * Path to main WP Staging class
51
- * Make sure to not redeclare class in case free version has been installed previosly
52
- */
53
- if (!class_exists( 'WPStaging\WPStaging' )){
54
- require_once plugin_dir_path(__FILE__) . "apps/Core/WPStaging.php";
55
- }
56
 
57
  $wpStaging = \WPStaging\WPStaging::getInstance();
58
 
59
- /**
60
- * Load a few important WP globals into WPStaging class to make them available via dependancy injection
61
- */
62
-
63
- // Wordpress DB Object
64
  if (isset($wpdb))
65
  {
66
  $wpStaging->set("wpdb", $wpdb);
67
  }
68
 
69
- // WordPress Filter Object
70
  if (isset($wp_filter))
71
  {
72
  $wpStaging->set("wp_filter", function() use(&$wp_filter) {
@@ -74,7 +53,4 @@ if (isset($wp_filter))
74
  });
75
  }
76
 
77
- /**
78
- * Inititalize WPStaging
79
- */
80
  $wpStaging->run();
6
  * Description: Create a staging clone site for testing & developing
7
  * Author: WP-Staging, René Hermenau, Ilgıt Yıldırım
8
  * Author URI: https://wordpress.org/plugins/wp-staging
9
+ * Version: 2.0.3
10
  * Text Domain: wpstg
11
  * Domain Path: /languages/
12
 
35
  die;
36
  }
37
 
38
+ require_once plugin_dir_path(__FILE__) . "apps/Core/WPStaging.php";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  $wpStaging = \WPStaging\WPStaging::getInstance();
41
 
42
+ // Load WP globals into WPStaging
 
 
 
 
43
  if (isset($wpdb))
44
  {
45
  $wpStaging->set("wpdb", $wpdb);
46
  }
47
 
48
+
49
  if (isset($wp_filter))
50
  {
51
  $wpStaging->set("wp_filter", function() use(&$wp_filter) {
53
  });
54
  }
55
 
 
 
 
56
  $wpStaging->run();