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

Version Description

Download this release

Release Info

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

Code changes from version 2.0.4 to 2.0.1

Files changed (42) hide show
  1. CHANGELOG.md +0 -0
  2. CONTRIBUTING.md +38 -0
  3. README.md +32 -0
  4. apps/Backend/Activation/Activation.php +0 -58
  5. apps/Backend/Administrator.php +604 -611
  6. apps/Backend/Modules/Jobs/Cloning.php +3 -5
  7. apps/Backend/Modules/Jobs/Delete.php +36 -64
  8. apps/Backend/Modules/Jobs/Delete_deprecated.php +0 -397
  9. apps/Backend/Modules/Jobs/Delete_new.php +0 -382
  10. apps/Backend/Modules/Jobs/Delete_old.php +4 -4
  11. apps/Backend/Modules/Jobs/Directories.php +82 -151
  12. apps/Backend/Modules/Jobs/Finish.php +22 -3
  13. apps/Backend/Modules/Jobs/Job.php +12 -47
  14. apps/Backend/Modules/Jobs/Scan.php +18 -49
  15. apps/Backend/Modules/Optimizer.php +141 -0
  16. apps/Backend/Modules/Views/Forms/Settings.php +2 -1
  17. apps/Backend/Notices/Notices.php +53 -62
  18. apps/Backend/Optimizer/Optimizer.php +0 -45
  19. apps/Backend/Optimizer/wp-staging-optimizer.php +0 -120
  20. apps/Backend/Pluginmeta/Pluginmeta.php +0 -69
  21. apps/Backend/Upgrade/Upgrade.php +37 -127
  22. apps/Backend/public/css/wpstg-admin.css +7 -39
  23. apps/Backend/public/img/wpstaging-banner200x400-tryout.gif +0 -0
  24. apps/Backend/public/img/wpstaging-banner200x400.gif +0 -0
  25. apps/Backend/public/js/wpstg-admin.js +452 -507
  26. apps/Backend/views/_includes/header.php +1 -1
  27. apps/Backend/views/_includes/messages/wp-version-compatible-message.php +1 -1
  28. apps/Backend/views/clone/ajax/delete-confirmation.php +1 -1
  29. apps/Backend/views/clone/ajax/scan.php +7 -10
  30. apps/Backend/views/clone/ajax/start.php +1 -1
  31. apps/Backend/views/clone/index.php +1 -1
  32. apps/Backend/views/clone/single-site/index.php +1 -2
  33. apps/Backend/views/settings/index.php +2 -2
  34. apps/Backend/views/tools/index.php +1 -1
  35. apps/Core/Cron/Cron.php +0 -46
  36. apps/Core/Utils/Cache.php +1 -1
  37. apps/Core/Utils/Logger.php +1 -3
  38. apps/Core/WPStaging.php +386 -401
  39. apps/Frontend/Frontend.php +1 -0
  40. readme.txt +62 -40
  41. uninstall.php +4 -54
  42. wp-staging.php +5 -29
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 DELETED
@@ -1,58 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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;
@@ -21,618 +21,611 @@ use WPStaging\Backend\Modules\Views\Tabs\Tabs;
21
  use WPStaging\Backend\Notices\Notices;
22
  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;
21
  use WPStaging\Backend\Notices\Notices;
22
  use WPStaging\DI\InjectionAware;
23
  use WPStaging\Backend\Modules\Views\Forms\Settings as FormSettings;
 
24
  use WPStaging\WPStaging;
 
 
25
 
26
  /**
27
  * Class Administrator
28
  * @package WPStaging\Backend
29
  */
30
+ class Administrator extends InjectionAware
31
+ {
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $path;
37
+
38
+ /**
39
+ * @var string
40
+ */
41
+ private $url;
42
+
43
+ /**
44
+ * Initialize class
45
+ */
46
+ public function initialize()
47
+ {
48
+ $this->defineHooks();
49
+
50
+ // Path to backend
51
+ $this->path = plugin_dir_path(__FILE__);
52
+
53
+ // URL to public backend folder
54
+ $this->url = plugin_dir_url(__FILE__) . "public/";
55
+
56
+ }
57
+
58
+ /**
59
+ * Define Hooks
60
+ */
61
+ private function defineHooks()
62
+ {
63
+ // Get loader
64
+ $loader = $this->di->get("loader");
65
+
66
+ $loader->addAction("admin_menu", $this, "addMenu", 10);
67
+ $loader->addAction("admin_init", $this, "setOptionFormElements");
68
+ $loader->addAction("admin_init", $this, "upgrade");
69
+ $loader->addAction("admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload");
70
+ $loader->addAction("admin_post_wpstg_export", $this, "export");
71
+ $loader->addAction("admin_post_wpstg_import_settings", $this, "import");
72
+ $loader->addAction("admin_notices", $this, "messages");
73
+
74
+ // Settings
75
+ $settings = $this->di->get("settings");
76
+
77
+ // Optimizer is ON
78
+ if ($settings->isOptimizer())
79
+ {
80
+ $optimizer = new Optimizer($this->di);
81
+
82
+ $loader->addAction("admin_init", $optimizer, "compatibility", 1);
83
+ $loader->addFilter("option_active_plugins", $optimizer, "excludedPlugins");
84
+ $loader->addFilter("site_option_active_sitewide_plugins", $optimizer, "excludedPlugins");
85
+ }
86
+
87
+ // Ajax Requests
88
+ $loader->addAction("wp_ajax_wpstg_overview", $this, "ajaxOverview");
89
+ $loader->addAction("wp_ajax_wpstg_scanning", $this, "ajaxScan");
90
+ $loader->addAction("wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName");
91
+ $loader->addAction("wp_ajax_wpstg_cloning", $this, "ajaxStartClone");
92
+ $loader->addAction("wp_ajax_wpstg_clone_database", $this, "ajaxCloneDatabase");
93
+ $loader->addAction("wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories");
94
+ $loader->addAction("wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles");
95
+ $loader->addAction("wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData");
96
+ $loader->addAction("wp_ajax_wpstg_clone_finish", $this, "ajaxFinish");
97
+ $loader->addAction("wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation");
98
+ $loader->addAction("wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone");
99
+ $loader->addAction("wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone");
100
+ $loader->addAction("wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll");
101
+ $loader->addAction("wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating");
102
+ $loader->addAction("wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta");
103
+ $loader->addAction("wp_ajax_wpstg_logs", $this, "ajaxLogs");
104
+ $loader->addAction("wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace");
105
+ }
106
+
107
+ /**
108
+ * Register options form elements
109
+ */
110
+ public function setOptionFormElements()
111
+ {
112
+ register_setting("wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions"));
113
+ }
114
+
115
+ /**
116
+ * Upgrade routine
117
+ */
118
+ public function upgrade(){
119
+ $upgrade = new Upgrade\Upgrade();
120
+ $upgrade->doUpgrade();
121
+ }
122
+
123
+ /**
124
+ * Sanitize options data and delete the cache
125
+ * @param array $data
126
+ * @return array
127
+ */
128
+ public function sanitizeOptions($data = array())
129
+ {
130
+ $sanitized = $this->sanitizeData($data);
131
+
132
+ add_settings_error("wpstg-notices", '', __("Settings updated.", "wpstg"), "updated");
133
+
134
+ // Return sanitized data
135
+ //return $sanitized;
136
+ return apply_filters("wpstg-settings", $sanitized, $data);
137
+ }
138
+
139
+ /**
140
+ * @param array $data
141
+ * @return array
142
+ */
143
+ private function sanitizeData($data = array())
144
+ {
145
+ $sanitized = array();
146
+
147
+ foreach ($data as $key => $value)
148
+ {
149
+ $sanitized[$key] = (is_array($value)) ? $this->sanitizeData($value) : htmlspecialchars($value);
150
+ }
151
+
152
+ return $sanitized;
153
+ }
154
+
155
+ /**
156
+ * Add Admin Menu(s)
157
+ */
158
+ public function addMenu()
159
+ {
160
+ // Main WP Staging Menu
161
+ add_menu_page(
162
+ "WP-Staging",
163
+ __("WP Staging", "wpstg"),
164
+ "manage_options",
165
+ "wpstg_clone",
166
+ array($this, "getClonePage"),
167
+ "dashicons-hammer"
168
+ );
169
+
170
+ // Page: Clone
171
+ add_submenu_page(
172
+ "wpstg_clone",
173
+ __("WP Staging Jobs", "wpstg"),
174
+ __("Start", "wpstg"),
175
+ "manage_options",
176
+ "wpstg_clone",
177
+ array($this, "getClonePage")
178
+ );
179
+
180
+ // Page: Settings
181
+ add_submenu_page(
182
+ "wpstg_clone",
183
+ __("WP Staging Settings", "wpstg"),
184
+ __("Settings", "wpstg"),
185
+ "manage_options",
186
+ "wpstg-settings",
187
+ array($this, "getSettingsPage")
188
+ );
189
+
190
+ // Page: Tools
191
+ add_submenu_page(
192
+ "wpstg_clone",
193
+ __("WP Staging Tools", "wpstg"),
194
+ __("Tools", "wpstg"),
195
+ "manage_options",
196
+ "wpstg-tools",
197
+ array($this, "getToolsPage")
198
+ );
199
+ }
200
+
201
+ /**
202
+ * Settings Page
203
+ */
204
+ public function getSettingsPage()
205
+ {
206
+ // Tabs
207
+ $tabs = new Tabs(array(
208
+ "general" => __("General", "wpstg")
209
+ ));
210
+
211
+
212
+ $this->di
213
+ // Set tabs
214
+ ->set("tabs", $tabs)
215
+ // Forms
216
+ ->set("forms", new FormSettings($tabs));
217
+
218
+ require_once "{$this->path}views/settings/index.php";
219
+ }
220
+
221
+ /**
222
+ * Clone Page
223
+ */
224
+ public function getClonePage()
225
+ {
226
+ // Existing clones
227
+ $availableClones = get_option("wpstg_existing_clones", array());
228
+
229
+ require_once "{$this->path}views/clone/index.php";
230
+ }
231
+
232
+ /**
233
+ * Tools Page
234
+ */
235
+ public function getToolsPage()
236
+ {
237
+ // Tabs
238
+ $tabs = new Tabs(array(
239
+ "import_export" => __("Import/Export", "wpstg"),
240
+ "system_info" => __("System Info", "wpstg")
241
+ ));
242
+
243
+ $this->di->set("tabs", $tabs);
244
+
245
+ $this->di->set("systemInfo", new SystemInfo($this->di));
246
+
247
+ require_once "{$this->path}views/tools/index.php";
248
+ }
249
+
250
+ /**
251
+ * System Information Download
252
+ */
253
+ public function systemInfoDownload()
254
+ {
255
+ if (!current_user_can("update_plugins"))
256
+ {
257
+ return;
258
+ }
259
+
260
+ nocache_headers();
261
+ header("Content-Type: text/plain");
262
+ header("Content-Disposition: attachment; filename='wpstg-system-info.txt'");
263
+ echo wp_strip_all_tags(new SystemInfo($this->di));
264
+ }
265
+
266
+ /**
267
+ * Import JSON settings file
268
+ */
269
+ public function import()
270
+ {
271
+ if (empty($_POST["wpstg_import_nonce"]))
272
+ {
273
+ return;
274
+ }
275
+
276
+ if (!wp_verify_nonce($_POST["wpstg_import_nonce"], "wpstg_import_nonce"))
277
+ {
278
+ return;
279
+ }
280
+
281
+ if (!current_user_can("update_plugins"))
282
+ {
283
+ return;
284
+ }
285
+
286
+ $fileExtension = explode('.', $_FILES["import_file"]["name"]);
287
+ $fileExtension = end($fileExtension);
288
+ if ("json" !== $fileExtension)
289
+ {
290
+ wp_die("Please upload a valid .json file", "wpstg");
291
+ }
292
+
293
+
294
+ $importFile = $_FILES["import_file"]["tmp_name"];
295
+
296
+ if (empty($importFile))
297
+ {
298
+ wp_die(__("Please upload a file to import", "wpstg"));
299
+ }
300
+
301
+ update_option("wpstg_settings", json_decode(file_get_contents($importFile, true)));
302
+
303
+ wp_safe_redirect(admin_url("admin.php?page=wpstg-tools&amp;wpstg-message=settings-imported"));
304
+
305
+ return;
306
+ }
307
+
308
+ /**
309
+ * Export settings to JSON file
310
+ */
311
+ public function export()
312
+ {
313
+ if (empty($_POST["wpstg_export_nonce"]))
314
+ {
315
+ return;
316
+ }
317
+
318
+ if (!wp_verify_nonce($_POST["wpstg_export_nonce"], "wpstg_export_nonce"))
319
+ {
320
+ return;
321
+ }
322
+
323
+ if (!current_user_can("manage_options"))
324
+ {
325
+ return;
326
+ }
327
+
328
+ $settings = get_option("wpstg_settings", array());
329
+
330
+ ignore_user_abort(true);
331
+
332
+ if (!in_array("set_time_limit", explode(',', ini_get("disable_functions"))) && !@ini_get("safe_mode"))
333
+ {
334
+ set_time_limit(0);
335
+ }
336
+
337
+ $fileName = apply_filters("wpstg_settings_export_filename", "wpstg-settings-export-" . date("m-d-Y")) . ".json";
338
+
339
+ nocache_headers();
340
+ header("Content-Type: application/json; charset=utf-8");
341
+ header("Content-Disposition: attachment; filename={$fileName}");
342
+ header("Expires: 0");
343
+
344
+ echo json_encode($settings);
345
+ }
346
+
347
+
348
+ /**
349
+ * Render a view file
350
+ * @param string $file
351
+ * @param array $vars
352
+ * @return string
353
+ */
354
+ public function render($file, $vars = array())
355
+ {
356
+ $fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
357
+ $fullPath = str_replace(array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php");
358
+
359
+ if (!file_exists($fullPath) || !is_readable($fullPath))
360
+ {
361
+ return "Can't render : {$fullPath} either file doesn't exist or can't read it";
362
+ }
363
+
364
+ $contents = @file_get_contents($fullPath);
365
+
366
+ // Variables are set
367
+ if (count($vars) > 0)
368
+ {
369
+ $vars = array_combine(
370
+ array_map(function ($key)
371
+ {
372
  return "{{" . $key . "}}";
373
+ },
374
+ array_keys($vars)
375
+ ),
376
+ $vars
377
+ );
378
+
379
+ $contents = str_replace(array_keys($vars), array_values($vars), $contents);
380
+ }
381
+
382
+ return $contents;
383
+ }
384
+
385
+ /**
386
+ * Ajax Overview
387
+ */
388
+ public function ajaxOverview()
389
+ {
390
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
391
+
392
+ // Existing clones
393
+ $availableClones = get_option("wpstg_existing_clones", array());
394
+
395
+ require_once "{$this->path}views/clone/ajax/single-overview.php";
396
+
397
+ wp_die();
398
+ }
399
+
400
+ /**
401
+ * Ajax Scan
402
+ */
403
+ public function ajaxScan()
404
+ {
405
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
406
+
407
+ // Scan
408
+ $scan = new Scan();
409
+ $scan->start();
410
+
411
+ // Get Options
412
+ $options = $scan->getOptions();
413
+
414
+ require_once "{$this->path}views/clone/ajax/scan.php";
415
+
416
+ wp_die();
417
+ }
418
+
419
+ /**
420
+ * Ajax Check Clone Name
421
+ */
422
+ public function ajaxCheckCloneName()
423
+ {
424
+ $cloneName = sanitize_key($_POST["cloneID"]);
425
+ $cloneNameLength = strlen($cloneName);
426
+ $clones = get_option("wpstg_existing_clones", array());
427
+
428
+ // Check clone name length
429
+ if ($cloneNameLength < 1 || $cloneNameLength > 16)
430
+ {
431
+ echo wp_send_json(array(
432
+ "status" => "failed",
433
+ "message" => "Clone name must be between 1 - 16 characters"
434
+ ));
435
+ }
436
+ elseif (array_key_exists($cloneName, $clones))
437
+ {
438
+ echo wp_send_json(array(
439
+ "status" => "failed",
440
+ "message" => "Clone name is already in use, please choose an another clone name"
441
+ ));
442
+ }
443
+
444
+ echo wp_send_json(array("status" => "success"));
445
+ }
446
+
447
+ /**
448
+ * Ajax Start Clone (Basically just layout and saving data)
449
+ */
450
+ public function ajaxStartClone()
451
+ {
452
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
453
+
454
+ $cloning = new Cloning();
455
+
456
+ if (!$cloning->save())
457
+ {
458
+ wp_die();
459
+ }
460
+
461
+ require_once "{$this->path}views/clone/ajax/start.php";
462
+
463
+ wp_die();
464
+ }
465
+
466
+ /**
467
+ * Ajax Clone Database
468
+ */
469
+ public function ajaxCloneDatabase()
470
+ {
471
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
472
+
473
+ $cloning = new Cloning();
474
+
475
+ wp_send_json($cloning->start());
476
+ }
477
+
478
+ /**
479
+ * Ajax Prepare Directories (get listing of files)
480
+ */
481
+ public function ajaxPrepareDirectories()
482
+ {
483
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
484
+
485
+ $cloning = new Cloning();
486
+
487
+ wp_send_json($cloning->start());
488
+ }
489
+
490
+ /**
491
+ * Ajax Clone Files
492
+ */
493
+ public function ajaxCopyFiles()
494
+ {
495
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
496
+
497
+ $cloning = new Cloning();
498
+
499
+ wp_send_json($cloning->start());
500
+ }
501
+
502
+ /**
503
+ * Ajax Replace Data
504
+ */
505
+ public function ajaxReplaceData()
506
+ {
507
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
508
+
509
+ $cloning = new Cloning();
510
+
511
+ wp_send_json($cloning->start());
512
+ }
513
+
514
+ /**
515
+ * Ajax Finish
516
+ */
517
+ public function ajaxFinish()
518
+ {
519
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
520
+
521
+ $cloning = new Cloning();
522
+
523
+ wp_send_json($cloning->start());
524
+ }
525
+
526
+ /**
527
+ * Ajax Delete Confirmation
528
+ */
529
+ public function ajaxDeleteConfirmation()
530
+ {
531
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
532
+
533
+ $delete = new Delete();
534
+ $delete->setData();
535
+
536
+ $clone = $delete->getClone();
537
+
538
+ require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
539
+
540
+ wp_die();
541
+ }
542
+
543
+ /**
544
+ * Delete clone
545
+ */
546
+ public function ajaxDeleteClone()
547
+ {
548
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
549
+
550
+ $delete = new Delete();
551
+ wp_send_json($delete->start());
552
+ }
553
+
554
+ /**
555
+ * Delete clone
556
+ */
557
+ public function ajaxCancelClone()
558
+ {
559
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
560
+
561
+ $cancel = new Cancel();
562
+ wp_send_json($cancel->start());
563
+ }
564
+
565
+ /**
566
+ * Admin Messages
567
+ */
568
+ public function messages()
569
+ {
570
+ $notice = new Notices($this->path, $this->url);
571
+
572
+ $run = $notice->messages();
573
+ }
574
+
575
+ /**
576
+ * Ajax Hide Poll
577
+ * @return mixed boolean | json
578
+ */
579
+ public function ajaxHidePoll()
580
+ {
581
+ if( false !== update_option( "wpstg_poll", "no" ) ) {
582
+ wp_send_json( true );
583
+ }
584
+ return wp_send_json();
585
+ }
586
+
587
+ /**
588
+ * Ajax Hide Rating
589
+ * @return mixed bool | json
590
+ */
591
+ public function ajaxHideRating()
592
+ {
593
+ if( false !== update_option( "wpstg_rating", "no" ) ) {
594
+ wp_send_json( true );
595
+ }
596
+ return wp_send_json();
597
+ }
598
+
599
+ /**
600
+ * Ajax Hide Beta
601
+ */
602
+ public function ajaxHideBeta()
603
+ {
604
+ wp_send_json(update_option("wpstg_beta", "no"));
605
+ }
606
+
607
+ /**
608
+ * Clone logs
609
+ */
610
+ public function ajaxLogs()
611
+ {
612
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
613
+
614
+ $logs = new Logs();
615
+ wp_send_json($logs->start());
616
+ }
617
+
618
+ /**
619
+ * Ajax Checks Free Disk Space
620
+ */
621
+ public function ajaxCheckFreeSpace()
622
+ {
623
+ check_ajax_referer("wpstg_ajax_nonce", "nonce");
624
+
625
+ $scan = new Scan();
626
+ return $scan->hasFreeDiskSpace();
627
+ }
628
+
629
+
630
+
631
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Modules/Jobs/Cloning.php CHANGED
@@ -59,8 +59,8 @@ class Cloning extends Job
59
  }
60
 
61
  // Extra Directories
62
- if (isset($_POST["extraDirectories"]) && !empty($_POST["extraDirectories"]) )
63
- {
64
  $this->options->extraDirectories = $_POST["extraDirectories"];
65
  }
66
 
@@ -71,9 +71,7 @@ class Cloning extends Job
71
  );
72
 
73
  array_unshift($this->options->directoriesToCopy, ABSPATH);
74
-
75
- //var_dump($this->options->directoriesToCopy);
76
-
77
  // Delete files to copy listing
78
  $this->cache->delete("files_to_copy");
79
 
59
  }
60
 
61
  // Extra Directories
62
+ if (isset($_POST["extraDirectories"]) && strlen($_POST["extraDirectories"]) > 0)
63
+ {
64
  $this->options->extraDirectories = $_POST["extraDirectories"];
65
  }
66
 
71
  );
72
 
73
  array_unshift($this->options->directoriesToCopy, ABSPATH);
74
+
 
 
75
  // Delete files to copy listing
76
  $this->cache->delete("files_to_copy");
77
 
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
 
@@ -70,16 +70,24 @@ class Delete extends Job
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
 
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()
@@ -396,7 +370,7 @@ class Delete extends Job
396
  */
397
  public function deleteFinish()
398
  {
399
- $existingClones = get_option("wpstg_existing_clones_beta", array());
400
 
401
  // Check if clones still exist
402
  $this->log("Verifying existing clones...");
@@ -409,7 +383,7 @@ class Delete extends Job
409
  }
410
  $this->log("Existing clones verified!");
411
 
412
- if (false === update_option("wpstg_existing_clones_beta", $existingClones))
413
  {
414
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
415
  }
@@ -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
 
70
  $name = $_POST["clone"];
71
  }
72
 
73
+ $clones = get_option("wpstg_existing_clones", 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
 
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()
370
  */
371
  public function deleteFinish()
372
  {
373
+ $existingClones = get_option("wpstg_existing_clones", array());
374
 
375
  // Check if clones still exist
376
  $this->log("Verifying existing clones...");
383
  }
384
  $this->log("Existing clones verified!");
385
 
386
+ if (false === update_option("wpstg_existing_clones", $existingClones))
387
  {
388
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
389
  }
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
  /**
@@ -70,7 +70,7 @@ class Delete_old extends Job
70
  $name = $_POST["clone"];
71
  }
72
 
73
- $clones = get_option("wpstg_existing_clones_beta", array());
74
 
75
  if (empty($clones) || !isset($clones[$name]))
76
  {
@@ -340,7 +340,7 @@ class Delete_old extends Job
340
  */
341
  public function deleteFinish()
342
  {
343
- $existingClones = get_option("wpstg_existing_clones_beta", array());
344
 
345
  // Check if clones still exist
346
  $this->log("Verifying existing clones...");
@@ -353,7 +353,7 @@ class Delete_old extends Job
353
  }
354
  $this->log("Existing clones verified!");
355
 
356
- if (false === update_option("wpstg_existing_clones_beta", $existingClones))
357
  {
358
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
359
  }
10
  * Class Delete
11
  * @package WPStaging\Backend\Modules\Jobs
12
  */
13
+ class Delete extends Job
14
  {
15
 
16
  /**
70
  $name = $_POST["clone"];
71
  }
72
 
73
+ $clones = get_option("wpstg_existing_clones", array());
74
 
75
  if (empty($clones) || !isset($clones[$name]))
76
  {
340
  */
341
  public function deleteFinish()
342
  {
343
+ $existingClones = get_option("wpstg_existing_clones", array());
344
 
345
  // Check if clones still exist
346
  $this->log("Verifying existing clones...");
353
  }
354
  $this->log("Existing clones verified!");
355
 
356
+ if (false === update_option("wpstg_existing_clones", $existingClones))
357
  {
358
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
359
  }
apps/Backend/Modules/Jobs/Directories.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
-
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
  // No Direct Access
6
- if( !defined( "WPINC" ) ) {
 
7
  die;
8
  }
9
 
@@ -13,8 +13,8 @@ use WPStaging\WPStaging;
13
  * Class Files
14
  * @package WPStaging\Backend\Modules\Directories
15
  */
16
- class Directories extends JobExecutable {
17
-
18
  /**
19
  * @var array
20
  */
@@ -28,8 +28,9 @@ class Directories extends JobExecutable {
28
  /**
29
  * Initialize
30
  */
31
- public function initialize() {
32
- $this->total = count( $this->options->directoriesToCopy );
 
33
  $this->getFiles();
34
  }
35
 
@@ -37,26 +38,30 @@ class Directories extends JobExecutable {
37
  * Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
38
  * @return void
39
  */
40
- protected function calculateTotalSteps() {
 
41
  $this->options->totalSteps = $this->total;
42
  }
43
 
44
  /**
45
  * Get Root Files
46
  */
47
- protected function getRootFiles() {
48
- if( 1 < $this->options->totalFiles ) {
 
 
49
  return;
50
  }
51
 
52
- $this->getFilesFromDirectory( ABSPATH );
53
  }
54
 
55
  /**
56
  * Start Module
57
  * @return object
58
  */
59
- public function start() {
 
60
  // Root files
61
  $this->getRootFiles();
62
 
@@ -66,7 +71,7 @@ class Directories extends JobExecutable {
66
  // Save option, progress
67
  $this->saveProgress();
68
 
69
- return ( object ) $this->response;
70
  }
71
 
72
  /**
@@ -74,10 +79,12 @@ class Directories extends JobExecutable {
74
  * Returns false when over threshold limits are hit or when the job is done, true otherwise
75
  * @return bool
76
  */
77
- protected function execute() {
 
78
  // No job left to execute
79
- if( $this->isFinished() ) {
80
- $this->prepareResponse( true, false );
 
81
  return false;
82
  }
83
 
@@ -85,8 +92,9 @@ class Directories extends JobExecutable {
85
  $directory = $this->options->directoriesToCopy[$this->options->currentStep];
86
 
87
  // Get files recursively
88
- if( !$this->getFilesFromSubDirectories( $directory ) ) {
89
- $this->prepareResponse( false, false );
 
90
  return false;
91
  }
92
 
@@ -104,52 +112,57 @@ class Directories extends JobExecutable {
104
  * Checks Whether There is Any Job to Execute or Not
105
  * @return bool
106
  */
107
- private function isFinished() {
 
108
  return (
109
- $this->options->currentStep > $this->total ||
110
- empty( $this->options->directoriesToCopy ) ||
111
- !isset( $this->options->directoriesToCopy[$this->options->currentStep] )
112
- );
113
  }
114
 
115
  /**
116
  * @param $path
117
  * @return bool
118
  */
119
- protected function getFilesFromSubDirectories( $path ) {
 
120
  $this->totalRecursion++;
121
 
122
- if( $this->isOverThreshold() ) {
 
123
  //$this->saveProgress();
124
 
125
  return false;
126
  }
127
 
128
- $this->log( "Scanning {$path} for its sub-directories and files" );
129
 
130
- $directories = new \DirectoryIterator( $path );
131
 
132
- foreach ( $directories as $directory ) {
133
-
134
-
135
  // Not a valid directory
136
- if( false === ($path = $this->getPath( $directory )) ) {
 
137
  continue;
138
  }
139
 
140
  // Excluded directory
141
- if( $this->isDirectoryExcluded( $directory->getRealPath() ) ) {
 
142
  continue;
143
  }
144
 
145
  // This directory is already scanned
146
- if( in_array( $path, $this->options->scannedDirectories ) ) {
 
147
  continue;
148
  }
149
 
150
  // Save all files
151
  $dir = ABSPATH . $path . DIRECTORY_SEPARATOR;
152
- $this->getFilesFromDirectory( $dir );
153
 
154
  // Add scanned directory listing
155
  $this->options->scannedDirectories[] = $dir;
@@ -165,35 +178,32 @@ class Directories extends JobExecutable {
165
  * @param $directory
166
  * @return bool
167
  */
168
- protected function getFilesFromDirectory( $directory ) {
 
169
  $this->totalRecursion++;
170
-
171
  // Save all files
172
- $files = array_diff( scandir( $directory ), array('.', "..") );
173
 
174
- foreach ( $files as $file ) {
 
175
  $fullPath = $directory . $file;
176
 
177
- if( is_dir( $fullPath ) && !in_array( $fullPath, $this->options->directoriesToCopy ) && !$this->isDirectoryExcluded( $fullPath ) ) {
 
178
  $this->options->directoriesToCopy[] = $fullPath;
179
-
180
- return $this->getFilesFromSubDirectories( $fullPath );
181
  //continue;
182
  }
183
 
184
- if( !is_file( $fullPath ) || in_array( $fullPath, $this->files ) ) {
 
185
  continue;
186
  }
187
 
188
  $this->options->totalFiles++;
189
 
190
  $this->files[] = $fullPath;
191
-
192
- /**
193
- * Test and measure if its faster to copy at the same time while the array with folders is generated
194
- */
195
- //$this->copy($fullPath);
196
-
197
  }
198
  }
199
 
@@ -202,21 +212,13 @@ class Directories extends JobExecutable {
202
  * @param \SplFileInfo $directory
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
 
@@ -224,13 +226,15 @@ class Directories extends JobExecutable {
224
  }
225
 
226
  /**
227
- * Check if directory is excluded from copying
228
  * @param string $directory
229
  * @return bool
230
  */
231
- protected function isDirectoryExcluded( $directory ) {
232
- foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
233
- if( strpos( $directory, $excludedDirectory ) === 0 && !$this->isExtraDirectory( $directory ) ) {
 
 
 
234
  return true;
235
  }
236
  }
@@ -238,112 +242,39 @@ class Directories extends JobExecutable {
238
  return false;
239
  }
240
 
241
- /**
242
- * Check if directory is an extra directory and should be copied
243
- * @param string $directory
244
- * @return boolean
245
- */
246
- protected function isExtraDirectory( $directory ) {
247
- foreach ( $this->options->extraDirectories as $extraDirectory ) {
248
- if( strpos( $directory, $extraDirectory ) === 0 ) {
249
- return true;
250
- }
251
- }
252
-
253
- return false;
254
- }
255
-
256
  /**
257
  * Save files
258
  * @return bool
259
  */
260
- protected function saveProgress() {
 
261
  $this->saveOptions();
262
 
263
- $fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
264
- $files = implode( PHP_EOL, $this->files );
265
 
266
- if( strlen( $files ) > 0 ) {
 
267
  //$files .= PHP_EOL;
268
  }
269
 
270
- return (false !== @file_put_contents( $fileName, $files ));
271
  }
272
 
273
  /**
274
  * Get files
275
  * @return void
276
  */
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
- }
284
-
285
- $this->files = explode( PHP_EOL, $this->files );
286
- }
287
-
288
- /**
289
- * Copy File using PHP (Only for testing)
290
- * @param string $file
291
- * @param string $destination
292
- * @return bool
293
- *
294
- * @deprecated since version 2.0.2
295
- */
296
- protected function copy($file)
297
- {
298
-
299
- if( $this->isOverThreshold() ) {
300
- return false;
301
- }
302
-
303
- // Failed to get destination
304
- if (false === ($destination = $this->getDestination($file)))
305
- {
306
- //$this->log("Can't get the destination of {$file}");
307
- //return false;
308
- }
309
-
310
- // Attempt to copy
311
- if (!@copy($file, $destination))
312
- {
313
- //$this->log("Failed to copy file to destination: {$file} -> {$destination}", Logger::TYPE_ERROR);
314
- //return false;
315
- }
316
-
317
- //$this->log("Copy {$file} -> {$destination}", Logger::TYPE_INFO);
318
-
319
- // Not finished
320
- return true;
321
- }
322
-
323
-
324
- /**
325
- * (only for testing)
326
- * Gets destination file and checks if the directory exists, if it does not attempts to create it.
327
- * If creating destination directory fails, it returns false, gives destination full path otherwise
328
- * @param string $file
329
- * @return bool|string
330
- *
331
- * @deprecated
332
- */
333
- private function getDestination($file)
334
  {
335
- $destination = ABSPATH . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR;
336
- $relativePath = str_replace(ABSPATH, null, $file);
337
- $destinationPath = $destination . $relativePath;
338
- $destinationDirectory = dirname($destinationPath);
339
 
340
- if (!is_dir($destinationDirectory) && !@mkdir($destinationDirectory, 0775, true))
341
  {
342
- $this->log("Destination directory doesn't exist; {$destinationDirectory}", Logger::TYPE_ERROR);
343
- //return false;
344
  }
345
 
346
- return $destinationPath;
347
  }
348
-
349
- }
1
  <?php
 
2
  namespace WPStaging\Backend\Modules\Jobs;
3
 
4
  // No Direct Access
5
+ if (!defined("WPINC"))
6
+ {
7
  die;
8
  }
9
 
13
  * Class Files
14
  * @package WPStaging\Backend\Modules\Directories
15
  */
16
+ class Directories extends JobExecutable
17
+ {
18
  /**
19
  * @var array
20
  */
28
  /**
29
  * Initialize
30
  */
31
+ public function initialize()
32
+ {
33
+ $this->total = count($this->options->directoriesToCopy);
34
  $this->getFiles();
35
  }
36
 
38
  * Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
39
  * @return void
40
  */
41
+ protected function calculateTotalSteps()
42
+ {
43
  $this->options->totalSteps = $this->total;
44
  }
45
 
46
  /**
47
  * Get Root Files
48
  */
49
+ protected function getRootFiles()
50
+ {
51
+ if (1 < $this->options->totalFiles)
52
+ {
53
  return;
54
  }
55
 
56
+ $this->getFilesFromDirectory(ABSPATH);
57
  }
58
 
59
  /**
60
  * Start Module
61
  * @return object
62
  */
63
+ public function start()
64
+ {
65
  // Root files
66
  $this->getRootFiles();
67
 
71
  // Save option, progress
72
  $this->saveProgress();
73
 
74
+ return (object) $this->response;
75
  }
76
 
77
  /**
79
  * Returns false when over threshold limits are hit or when the job is done, true otherwise
80
  * @return bool
81
  */
82
+ protected function execute()
83
+ {
84
  // No job left to execute
85
+ if ($this->isFinished())
86
+ {
87
+ $this->prepareResponse(true, false);
88
  return false;
89
  }
90
 
92
  $directory = $this->options->directoriesToCopy[$this->options->currentStep];
93
 
94
  // Get files recursively
95
+ if (!$this->getFilesFromSubDirectories($directory))
96
+ {
97
+ $this->prepareResponse(false, false);
98
  return false;
99
  }
100
 
112
  * Checks Whether There is Any Job to Execute or Not
113
  * @return bool
114
  */
115
+ private function isFinished()
116
+ {
117
  return (
118
+ $this->options->currentStep > $this->total ||
119
+ empty($this->options->directoriesToCopy) ||
120
+ !isset($this->options->directoriesToCopy[$this->options->currentStep])
121
+ );
122
  }
123
 
124
  /**
125
  * @param $path
126
  * @return bool
127
  */
128
+ protected function getFilesFromSubDirectories($path)
129
+ {
130
  $this->totalRecursion++;
131
 
132
+ if ($this->isOverThreshold())
133
+ {
134
  //$this->saveProgress();
135
 
136
  return false;
137
  }
138
 
139
+ $this->log("Scanning {$path} for its sub-directories and files");
140
 
141
+ $directories = new \DirectoryIterator($path);
142
 
143
+ foreach($directories as $directory)
144
+ {
 
145
  // Not a valid directory
146
+ if (false === ($path = $this->getPath($directory)))
147
+ {
148
  continue;
149
  }
150
 
151
  // Excluded directory
152
+ if ($this->isDirectoryExcluded($directory->getRealPath()))
153
+ {
154
  continue;
155
  }
156
 
157
  // This directory is already scanned
158
+ if (in_array($path, $this->options->scannedDirectories))
159
+ {
160
  continue;
161
  }
162
 
163
  // Save all files
164
  $dir = ABSPATH . $path . DIRECTORY_SEPARATOR;
165
+ $this->getFilesFromDirectory($dir);
166
 
167
  // Add scanned directory listing
168
  $this->options->scannedDirectories[] = $dir;
178
  * @param $directory
179
  * @return bool
180
  */
181
+ protected function getFilesFromDirectory($directory)
182
+ {
183
  $this->totalRecursion++;
184
+
185
  // Save all files
186
+ $files = array_diff(scandir($directory), array('.', ".."));
187
 
188
+ foreach ($files as $file)
189
+ {
190
  $fullPath = $directory . $file;
191
 
192
+ if (is_dir($fullPath) && !in_array($fullPath, $this->options->directoriesToCopy) && !$this->isDirectoryExcluded($fullPath))
193
+ {
194
  $this->options->directoriesToCopy[] = $fullPath;
195
+ return $this->getFilesFromSubDirectories($fullPath);
 
196
  //continue;
197
  }
198
 
199
+ if (!is_file($fullPath) || in_array($fullPath, $this->files))
200
+ {
201
  continue;
202
  }
203
 
204
  $this->options->totalFiles++;
205
 
206
  $this->files[] = $fullPath;
 
 
 
 
 
 
207
  }
208
  }
209
 
212
  * @param \SplFileInfo $directory
213
  * @return string|false
214
  */
215
+ protected function getPath($directory)
216
+ {
217
+ $path = str_replace(ABSPATH, null, $directory->getRealPath());
 
 
 
 
 
 
 
 
 
218
 
219
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
220
+ if (!$directory->isDir() || strlen($path) < 1 || strpos($directory->getRealPath(), ABSPATH) !== 0)
221
+ {
222
  return false;
223
  }
224
 
226
  }
227
 
228
  /**
 
229
  * @param string $directory
230
  * @return bool
231
  */
232
+ protected function isDirectoryExcluded($directory)
233
+ {
234
+ foreach ($this->options->excludedDirectories as $excludedDirectory)
235
+ {
236
+ if (strpos($directory, $excludedDirectory) === 0)
237
+ {
238
  return true;
239
  }
240
  }
242
  return false;
243
  }
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  /**
246
  * Save files
247
  * @return bool
248
  */
249
+ protected function saveProgress()
250
+ {
251
  $this->saveOptions();
252
 
253
+ $fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
254
+ $files = implode(PHP_EOL, $this->files);
255
 
256
+ if (strlen($files) > 0)
257
+ {
258
  //$files .= PHP_EOL;
259
  }
260
 
261
+ return (false !== @file_put_contents($fileName, $files));
262
  }
263
 
264
  /**
265
  * Get files
266
  * @return void
267
  */
268
+ protected function getFiles()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  {
270
+ $fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
 
 
 
271
 
272
+ if (false === ($this->files = file_get_contents($fileName)))
273
  {
274
+ $this->files = array();
275
+ return;
276
  }
277
 
278
+ $this->files = explode(PHP_EOL, $this->files);
279
  }
280
+ }
 
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,10 +214,22 @@ 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))
214
  {
215
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
216
  return false;
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
+ // $array = json_decode(json_encode($this->options->existingClones[$this->options->clone], JSON_FORCE_OBJECT), false);
220
+ //
221
+ // var_dump($this->options->existingClones[$this->options->clone]);
222
+ // echo '###########################';
223
+ // var_dump($this->options->existingClones);
224
+ // echo '###########################';
225
+ // var_dump($array);
226
+ // echo '###########################';
227
+ //
228
+ // die();
229
+
230
+ //wp_die(var_dump($this->options->existingClones));
231
 
232
+ if (false === update_option("wpstg_existing_clones", $this->options->existingClones))
233
  {
234
  $this->log("Failed to save {$this->options->clone}'s clone job data to database'");
235
  return false;
apps/Backend/Modules/Jobs/Job.php CHANGED
@@ -49,22 +49,19 @@ abstract class Job implements JobInterface
49
  protected $settings;
50
 
51
  /**
52
- * System total maximum memory consumption
53
  * @var int
54
  */
55
  protected $maxMemoryLimit;
56
-
57
  /**
58
- * Script maximum memory consumption
59
  * @var int
60
  */
61
- protected $memoryLimit;
62
 
63
  /**
64
  * @var int
65
  */
66
- protected $maxExecutionTime;
67
-
68
 
69
  /**
70
  * @var int
@@ -95,7 +92,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
  {
@@ -177,8 +173,7 @@ abstract class Job implements JobInterface
177
  */
178
  protected function setLimits()
179
  {
180
-
181
- if (!isset($this->settings->cpuLoad))
182
  {
183
  $this->settings->cpuLoad = "medium";
184
  }
@@ -189,15 +184,15 @@ abstract class Job implements JobInterface
189
  switch($this->settings->cpuLoad)
190
  {
191
  case "medium":
192
- //$memoryLimit= $memoryLimit / 2; // 0.4
193
- $timeLimit = $timeLimit / 2;
194
  break;
195
  case "low":
196
- //$memoryLimit= $memoryLimit / 4; // 0.2
197
  $timeLimit = $timeLimit / 4;
198
  break;
199
 
200
- case "fast": // 0.8
201
  default:
202
  break;
203
  }
@@ -306,12 +301,9 @@ abstract class Job implements JobInterface
306
  // Check if the memory is over threshold
307
  $usedMemory = (int) @memory_get_usage(true);
308
 
309
- $this->debugLog('Used Memory: ' . $this->formatBytes( $usedMemory ) . ' Max Memory Limit: ' . $this->formatBytes( $this->maxMemoryLimit ) . ' Max Script Memory Limit: ' . $this->formatBytes( $this->memoryLimit), Logger::TYPE_DEBUG );
310
-
311
  if ($usedMemory >= $this->memoryLimit)
312
  {
313
- $this->log('Used Memory: ' . $this->formatBytes($usedMemory) . ' Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script memory limit: ' . $this->formatBytes( $this->memoryLimit ) );
314
- $this->resetMemory();
315
  return true;
316
  }
317
 
@@ -328,6 +320,7 @@ abstract class Job implements JobInterface
328
  if ($time >= $this->executionLimit)
329
  {
330
  //$this->log('RESET TIME');
 
331
  return true;
332
  }
333
 
@@ -338,6 +331,7 @@ abstract class Job implements JobInterface
338
  * Attempt to reset memory
339
  * @return bool
340
  *
 
341
  */
342
  protected function resetMemory()
343
  {
@@ -346,7 +340,6 @@ abstract class Job implements JobInterface
346
  // Failed to set
347
  if (false === ini_set("memory_limit", $this->formatBytes($newMemoryLimit)))
348
  {
349
- $this->log('Can not free some memory', Logger::TYPE_CRITICAL);
350
  return false;
351
  }
352
 
@@ -425,40 +418,12 @@ 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);
436
- $this->hasLoggedFileNameSet = true;
437
- }
438
-
439
- $this->logger->add($msg, $type);
440
- }
441
- /**
442
- * @param string $msg
443
- * @param string $type
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);
455
  $this->hasLoggedFileNameSet = true;
456
  }
457
 
458
-
459
- if (isset($this->settings->debugMode)){
460
- $this->logger->add($msg, $type);
461
- }
462
-
463
  }
464
  }
49
  protected $settings;
50
 
51
  /**
 
52
  * @var int
53
  */
54
  protected $maxMemoryLimit;
55
+
56
  /**
 
57
  * @var int
58
  */
59
+ protected $maxExecutionTime;
60
 
61
  /**
62
  * @var int
63
  */
64
+ protected $memoryLimit;
 
65
 
66
  /**
67
  * @var int
92
  $this->start = $this->time();
93
  $this->maxMemoryLimit = $this->getMemoryInBytes(@ini_get("memory_limit"));
94
  $this->maxExecutionTime = (int) ini_get("max_execution_time");
 
95
 
96
  if ($this->maxExecutionTime < 1)
97
  {
173
  */
174
  protected function setLimits()
175
  {
176
+ if (!isset($this->settings->wpstg_cpu_load))
 
177
  {
178
  $this->settings->cpuLoad = "medium";
179
  }
184
  switch($this->settings->cpuLoad)
185
  {
186
  case "medium":
187
+ $memoryLimit= $memoryLimit / 2;
188
+ $timeLimit = $timeLimit / 2;
189
  break;
190
  case "low":
191
+ $memoryLimit= $memoryLimit / 4;
192
  $timeLimit = $timeLimit / 4;
193
  break;
194
 
195
+ case "default":
196
  default:
197
  break;
198
  }
301
  // Check if the memory is over threshold
302
  $usedMemory = (int) @memory_get_usage(true);
303
 
 
 
304
  if ($usedMemory >= $this->memoryLimit)
305
  {
306
+ $this->log('RESET MEMORY');
 
307
  return true;
308
  }
309
 
320
  if ($time >= $this->executionLimit)
321
  {
322
  //$this->log('RESET TIME');
323
+ //return (!$this->resetTime());
324
  return true;
325
  }
326
 
331
  * Attempt to reset memory
332
  * @return bool
333
  *
334
+ * @deprecated since version 2.0.0
335
  */
336
  protected function resetMemory()
337
  {
340
  // Failed to set
341
  if (false === ini_set("memory_limit", $this->formatBytes($newMemoryLimit)))
342
  {
 
343
  return false;
344
  }
345
 
418
  */
419
  protected function log($msg, $type = Logger::TYPE_INFO)
420
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
422
  {
423
  $this->logger->setFileName($this->options->clone);
424
  $this->hasLoggedFileNameSet = true;
425
  }
426
 
427
+ $this->logger->add($msg, $type);
 
 
 
 
428
  }
429
  }
apps/Backend/Modules/Jobs/Scan.php CHANGED
@@ -49,7 +49,7 @@ class Scan extends Job
49
  {
50
  // Basic Options
51
  $this->options->root = str_replace(array("\\", '/'), DIRECTORY_SEPARATOR, ABSPATH);
52
- $this->options->existingClones = get_option("wpstg_existing_clones_beta", array());
53
  $this->options->current = null;
54
 
55
  if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones))
@@ -92,14 +92,14 @@ class Scan extends Job
92
  */
93
  public function formatSize($bytes, $precision = 2)
94
  {
95
- if ((double) $bytes < 1)
96
  {
97
  return '';
98
  }
99
 
100
  $units = array('B', "KB", "MB", "GB", "TB");
101
 
102
- $bytes = (double) $bytes;
103
  $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
104
  $pow = pow(1000, $base - floor($base)); // Same rule for 1000
105
 
@@ -165,33 +165,24 @@ class Scan extends Job
165
  * Returns null when can't run disk_free_space function one way or another
166
  * @return bool|null
167
  */
168
- public function hasFreeDiskSpace() {
169
- if( !function_exists( "disk_free_space" ) ) {
170
- return null;
171
- }
172
-
173
- $freeSpace = @disk_free_space( ABSPATH );
174
-
175
- if( false === $freeSpace ) {
176
- $data = array(
177
- 'freespace' => false,
178
- 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
179
- );
180
- echo json_encode($data);
181
- die();
182
- }
183
 
 
184
 
185
- $data = array(
186
- 'freespace' => $this->formatSize($freeSpace),
187
- 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
188
- );
189
 
190
- echo json_encode( $data );
191
- die();
192
- }
193
 
194
- /**
195
  * Get Database Tables
196
  */
197
  protected function getTables()
@@ -285,18 +276,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
  }
@@ -360,18 +343,4 @@ class Scan extends Job
360
 
361
  return $this->objDirectories->size($path);
362
  }
363
-
364
- /**
365
- * Get total size of a directory including all its subdirectories
366
- * @param string $dir
367
- * @return int
368
- */
369
- function getDirectorySizeInclSubdirs( $dir ) {
370
- $size = 0;
371
- foreach ( glob( rtrim( $dir, '/' ) . '/*', GLOB_NOSORT ) as $each ) {
372
- $size += is_file( $each ) ? filesize( $each ) : $this->getDirectorySizeInclSubdirs( $each );
373
- }
374
- return $size;
375
- }
376
-
377
  }
49
  {
50
  // Basic Options
51
  $this->options->root = str_replace(array("\\", '/'), DIRECTORY_SEPARATOR, ABSPATH);
52
+ $this->options->existingClones = get_option("wpstg_existing_clones", array());
53
  $this->options->current = null;
54
 
55
  if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones))
92
  */
93
  public function formatSize($bytes, $precision = 2)
94
  {
95
+ if ((int) $bytes < 1)
96
  {
97
  return '';
98
  }
99
 
100
  $units = array('B', "KB", "MB", "GB", "TB");
101
 
102
+ $bytes = (int) $bytes;
103
  $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
104
  $pow = pow(1000, $base - floor($base)); // Same rule for 1000
105
 
165
  * Returns null when can't run disk_free_space function one way or another
166
  * @return bool|null
167
  */
168
+ public function hasFreeDiskSpace()
169
+ {
170
+ if (!function_exists("disk_free_space"))
171
+ {
172
+ return null;
173
+ }
 
 
 
 
 
 
 
 
 
174
 
175
+ $freeSpace = @disk_free_space(ABSPATH);
176
 
177
+ if (false === $freeSpace)
178
+ {
179
+ return null;
180
+ }
181
 
182
+ return ($freeSpace >= $this->getDirectorySize(ABSPATH));
183
+ }
 
184
 
185
+ /**
186
  * Get Database Tables
187
  */
188
  protected function getTables()
276
  */
277
  protected function getPath($directory)
278
  {
 
 
 
 
 
 
 
 
279
  $path = str_replace(ABSPATH, null, $directory->getRealPath());
280
 
281
  // Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
282
+ if (!$directory->isDir() || strlen($path) < 1 || strpos($directory->getRealPath(), ABSPATH) !== 0)
283
  {
284
  return false;
285
  }
343
 
344
  return $this->objDirectories->size($path);
345
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  }
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/Modules/Views/Forms/Settings.php CHANGED
@@ -85,6 +85,7 @@ class Settings
85
  $element = new Select(
86
  "wpstg_settings[cpuLoad]",
87
  array(
 
88
  "high" => "High (fast)",
89
  "medium" => "Medium (average)",
90
  "low" => "Low (slow)"
@@ -93,7 +94,7 @@ class Settings
93
 
94
  $this->form["general"]->add(
95
  $element->setLabel("CPU load priority")
96
- ->setDefault(isset($settings->cpuLoad) ? $settings->cpuLoad : "fast")
97
  );
98
 
99
  // Optimizer
85
  $element = new Select(
86
  "wpstg_settings[cpuLoad]",
87
  array(
88
+ "default" => "Default",
89
  "high" => "High (fast)",
90
  "medium" => "Medium (average)",
91
  "low" => "Low (slow)"
94
 
95
  $this->form["general"]->add(
96
  $element->setLabel("CPU load priority")
97
+ ->setDefault(isset($settings->cpuLoad) ? $settings->cpuLoad : "default")
98
  );
99
 
100
  // Optimizer
apps/Backend/Notices/Notices.php CHANGED
@@ -2,12 +2,13 @@
2
 
3
  namespace WPStaging\Backend\Notices;
4
 
5
- /*
6
  * Admin Notices | Warnings | Messages
7
  */
8
 
9
  // No Direct Access
10
- if( !defined( "WPINC" ) ) {
 
11
  die;
12
  }
13
 
@@ -17,7 +18,8 @@ use WPStaging\WPStaging;
17
  * Class Notices
18
  * @package WPStaging\Backend\Notices
19
  */
20
- class Notices {
 
21
 
22
  /**
23
  * @var string
@@ -29,119 +31,108 @@ class Notices {
29
  */
30
  private $url;
31
 
32
- public function __construct( $path, $url ) {
 
33
  $this->path = $path;
34
- $this->url = $url;
35
  }
36
-
37
  /**
38
  * Check whether the page is admin page or not
39
  * @return bool
40
  */
41
- private function isAdminPage() {
42
- $currentPage = (isset( $_GET["page"] )) ? $_GET["page"] : null;
 
43
 
44
  $availablePages = array(
45
  "wpstg-settings", "wpstg-addons", "wpstg-tools", "wpstg-clone", "wpstg_clone"
46
  );
47
 
48
- if( !is_admin() || !did_action( "wp_loaded" ) || !in_array( $currentPage, $availablePages, true ) ) {
 
49
  return false;
50
  }
51
 
52
  return true;
53
  }
54
-
55
  /**
56
  * Check if notice should be shown after certain days of installation
57
  * @param int $days default 10
58
  * @return bool
59
  */
60
- private function canShow( $option, $days = 10 ) {
61
-
62
- if( empty( $option ) ) {
 
63
  return false;
64
  }
65
-
66
- $installDate = new \DateTime( get_option( "wpstg_installDate" ) );
67
- $now = new \DateTime( "now" );
68
 
69
  // Get days difference
70
- $difference = $now->diff( $installDate )->days;
71
-
72
- return ($days <= $difference && "no" !== get_option( $option ));
73
-
74
  return false;
75
  }
76
 
77
- public function messages() {
78
-
79
- $this->plugin_deactivated_notice();
80
-
81
  // Display messages to only admins, only on admin panel
82
- if( !current_user_can( "update_plugins" ) || !$this->isAdminPage() ) {
 
83
  return;
84
  }
85
 
86
- $viewsNoticesPath = "{$this->path}views/_includes/messages/";
87
-
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 ) ) {
 
98
  require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
99
  }
100
  // Staging directory is not writable
101
- if( !wp_is_writable( get_home_path() ) ) {
 
102
  require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
103
  }
104
 
105
  // Version Control
106
- if( version_compare( WPStaging::WP_COMPATIBLE, get_bloginfo( "version" ), "<" ) ) {
 
107
  require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
108
  }
109
 
110
  // Beta
111
- if( false === get_option( "wpstg_beta" ) || "no" !== get_option( "wpstg_beta" ) ) {
 
112
  require_once "{$viewsNoticesPath}beta.php";
113
  }
114
 
115
  // WP Staging Pro and Free can not be activated both
116
- if( false !== ( $deactivatedNoticeID = get_transient( "wp_staging_deactivated_notice_id" ) ) ) {
 
117
  require_once "{$viewsNoticesPath}transient.php";
118
- delete_transient( "wp_staging_deactivated_notice_id" );
119
  }
120
 
121
- if( $this->canShow( "wpstg_rating", 7 ) ) {
 
122
  require_once "{$viewsNoticesPath}rating.php";
123
- }
124
-
125
- }
126
 
127
- /**
128
- * Show a message when pro or free plugin becomes deactivated
129
- *
130
- * @return void
131
- */
132
- private function plugin_deactivated_notice() {
133
- if( false !== ( $deactivated_notice_id = get_transient( 'wp_staging_deactivated_notice_id' ) ) ) {
134
- if( '1' === $deactivated_notice_id ) {
135
- $message = __( "WP Staging and WP Staging Pro cannot both be active. We've automatically deactivated WP Staging.", 'wpstg' );
136
- } else {
137
- $message = __( "WP Staging and WP Staging Pro cannot both be active. We've automatically deactivated WP Staging Pro.", 'wpstg' );
138
- }
139
- ?>
140
- <div class="updated notice is-dismissible" style="border-left: 4px solid #ffba00;">
141
- <p><?php echo esc_html( $message ); ?></p>
142
- </div> <?php
143
- delete_transient( 'wp_staging_deactivated_notice_id' );
144
  }
145
  }
146
-
147
- }
2
 
3
  namespace WPStaging\Backend\Notices;
4
 
5
+ /*
6
  * Admin Notices | Warnings | Messages
7
  */
8
 
9
  // No Direct Access
10
+ if (!defined("WPINC"))
11
+ {
12
  die;
13
  }
14
 
18
  * Class Notices
19
  * @package WPStaging\Backend\Notices
20
  */
21
+ class Notices
22
+ {
23
 
24
  /**
25
  * @var string
31
  */
32
  private $url;
33
 
34
+ public function __construct($path, $url)
35
+ {
36
  $this->path = $path;
37
+ $this->url = $url;
38
  }
39
+
40
  /**
41
  * Check whether the page is admin page or not
42
  * @return bool
43
  */
44
+ private function isAdminPage()
45
+ {
46
+ $currentPage = (isset($_GET["page"])) ? $_GET["page"] : null;
47
 
48
  $availablePages = array(
49
  "wpstg-settings", "wpstg-addons", "wpstg-tools", "wpstg-clone", "wpstg_clone"
50
  );
51
 
52
+ if (!is_admin() || !did_action("wp_loaded") || !in_array($currentPage, $availablePages, true))
53
+ {
54
  return false;
55
  }
56
 
57
  return true;
58
  }
59
+
60
  /**
61
  * Check if notice should be shown after certain days of installation
62
  * @param int $days default 10
63
  * @return bool
64
  */
65
+ private function canShow($option, $days = 10)
66
+ {
67
+
68
+ if (empty($option)){
69
  return false;
70
  }
71
+
72
+ $installDate= new \DateTime(get_option("wpstg_installDate"));
73
+ $now = new \DateTime("now");
74
 
75
  // Get days difference
76
+ $difference = $now->diff($installDate)->days;
77
+
78
+ return ($days <= $difference && "no" !== get_option($option));
79
+
80
  return false;
81
  }
82
 
83
+ public function messages()
84
+ {
 
 
85
  // Display messages to only admins, only on admin panel
86
+ if (!current_user_can("update_plugins") || !$this->isAdminPage())
87
+ {
88
  return;
89
  }
90
 
91
+ $viewsNoticesPath = "{$this->path}views/_includes/messages/";
 
 
92
 
93
+ $varsDirectory = \WPStaging\WPStaging::getContentDir();
94
+
95
+
96
+ // Poll
97
+ if ($this->canShow("wpstg_poll", 7))
98
+ {
99
  require_once "{$viewsNoticesPath}poll.php";
100
+ }
101
+
102
  // Cache directory in uploads is not writable
103
+ if (!wp_is_writable($varsDirectory))
104
+ {
105
  require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
106
  }
107
  // Staging directory is not writable
108
+ if (!wp_is_writable(get_home_path()))
109
+ {
110
  require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
111
  }
112
 
113
  // Version Control
114
+ if (version_compare(WPStaging::WP_COMPATIBLE, get_bloginfo("version"), "<"))
115
+ {
116
  require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
117
  }
118
 
119
  // Beta
120
+ if (false === get_option("wpstg_beta") || "no" !== get_option("wpstg_beta"))
121
+ {
122
  require_once "{$viewsNoticesPath}beta.php";
123
  }
124
 
125
  // WP Staging Pro and Free can not be activated both
126
+ if (false !== ( $deactivatedNoticeID = get_transient("wp_staging_deactivated_notice_id") ))
127
+ {
128
  require_once "{$viewsNoticesPath}transient.php";
129
+ delete_transient("wp_staging_deactivated_notice_id");
130
  }
131
 
132
+ if ($this->canShow("wpstg_rating", 7))
133
+ {
134
  require_once "{$viewsNoticesPath}rating.php";
 
 
 
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
  }
138
+ }
 
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/Pluginmeta/Pluginmeta.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
-
3
- namespace WPStaging\Backend\Pluginmeta;
4
-
5
- /*
6
- * Admin Plugins Meta Data
7
- */
8
-
9
- // No Direct Access
10
- if( !defined( "WPINC" ) ) {
11
- die;
12
- }
13
-
14
- use WPStaging\WPStaging;
15
-
16
-
17
- class Pluginmeta {
18
-
19
- public function __construct() {
20
- $this->defineHooks();
21
- }
22
-
23
- /**
24
- * Define Hooks
25
- */
26
- public function defineHooks() {
27
- add_filter( 'plugin_row_meta', array($this, 'rowMeta'), 10, 2 );
28
- add_filter( 'plugin_action_links', array($this,'actionLinks'), 10, 2 );
29
-
30
- }
31
-
32
- /**
33
- * Plugins row action links
34
- *
35
- * @author Michael Cannon <mc@aihr.us>
36
- * @since 0.9.0
37
- * @param array $links already defined action links
38
- * @param string $file plugin file path and name being processed
39
- * @return array $links
40
- */
41
- public function actionLinks( $links, $file ) {
42
- $settings_link = '<a href="' . admin_url( 'admin.php?page=wpstg-settings' ) . '">' . esc_html__( 'Settings', 'wpstg' ) . '</a>';
43
- if( $file == 'wp-staging/wp-staging.php' || $file == 'wp-staging-pro/wp-staging-pro.php')
44
- array_unshift( $links, $settings_link );
45
- return $links;
46
- }
47
-
48
- /**
49
- * Plugin row meta links
50
- *
51
- * @author Michael Cannon <mc@aihr.us>
52
- * @since 2.0
53
- * @param array $input already defined meta links
54
- * @param string $file plugin file path and name being processed
55
- * @return array $input
56
- */
57
- public function rowMeta( $input, $file ) {
58
- if( $file != 'wp-staging/wp-staging.php' && $file != 'wp-staging-pro/wp-staging-pro.php'){
59
- return $input;
60
- }
61
-
62
- $links = array(
63
- '<a href="' . admin_url( 'admin.php?page=wpstg_clone' ) . '">' . esc_html__( 'Start Now', 'wpstg' ) . '</a>',
64
- );
65
- $input = array_merge( $input, $links );
66
- return $input;
67
- }
68
-
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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;
@@ -31,80 +26,29 @@ class Upgrade {
31
  * @var obj
32
  */
33
  private $clones;
34
-
35
- /**
36
- * Clone data
37
- * @var obj
38
- */
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() {
108
  // Write some default vars
109
  add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
110
  }
@@ -127,90 +71,56 @@ class Upgrade {
127
  }
128
 
129
  /**
130
- * Create a new db option for beta version 2.0.2
131
- * @return bool
132
- */
133
- private function upgradeClonesBeta() {
134
-
135
- // Copy old data to new option
136
- //update_option( 'wpstg_existing_clones_beta', $this->clones );
137
-
138
- $new = array();
139
-
140
- if( empty( $this->clones ) ) {
141
- return false;
142
- }
143
-
144
-
145
- foreach ( $this->clones as $key => &$value ) {
146
-
147
- // Skip the rest of the loop if data is already compatible to wpstg 2.0.2
148
- if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
149
- continue;
150
- }
151
-
152
- $new[$value]['directoryName'] = $value;
153
- $new[$value]['path'] = get_home_path() . $value;
154
- $new[$value]['url'] = get_home_url() . "/" . $value;
155
- $new[$value]['number'] = $key + 1;
156
- $new[$value]['version'] = $this->previousVersion;
157
- }
158
- unset( $value );
159
-
160
- if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
161
- $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
162
- }
163
- }
164
-
165
- /**
166
- * Convert clone data from wpstg 1.x to wpstg 2.x
167
- * Only use this later when wpstg 2.x is ready for production
168
  */
169
- private function upgradeClones() {
170
 
171
  $new = array();
172
-
173
- if( empty( $this->clones ) ) {
174
  return false;
175
  }
176
 
177
  foreach ( $this->clones as $key => &$value ) {
178
-
179
  // Skip the rest of the loop if data is already compatible to wpstg 2.0.1
180
  if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
181
  continue;
182
- }
183
  $new[$value]['directoryName'] = $value;
184
  $new[$value]['path'] = get_home_path() . $value;
185
  $new[$value]['url'] = get_home_url() . "/" . $value;
186
- $new[$value]['number'] = $key + 1;
187
  $new[$value]['version'] = $this->previousVersion;
 
188
  }
189
- unset( $value );
 
190
 
191
- if( empty( $new ) || false === update_option( 'wpstg_existing_clones', $new ) ) {
192
  $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
 
193
  }
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() {
201
- $poll = get_option( "wpstg_start_poll", false );
202
- $beta = get_option( "wpstg_hide_beta", false );
203
- $rating = get_option( "wpstg_RatingDiv", false );
204
-
205
- if( $poll && $poll === "no" ) {
206
- update_option( 'wpstg_poll', 'no' );
207
- }
208
- if( $beta && $beta === "yes" ) {
209
- update_option( 'wpstg_beta', 'no' );
210
- }
211
- if( $rating && $rating === 'yes' ) {
212
- update_option( 'wpstg_rating', 'no' );
213
- }
214
  }
215
 
216
  }
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;
26
  * @var obj
27
  */
28
  private $clones;
29
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  private $logger;
31
 
32
  public function __construct() {
 
 
 
 
 
33
  $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
 
 
34
  $this->clones = get_option( "wpstg_existing_clones", array() );
 
 
 
 
 
35
  $this->logger = new Logger;
36
  }
37
 
38
  public function doUpgrade() {
39
+ // Previous version lower than 2.0.0 or new install
40
+ if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.0', '<' ) ) {
41
+ $this->newInstall();
42
+ $this->upgradeV1();
 
 
 
 
 
 
 
 
 
43
  $this->upgradeNotices();
44
  }
45
+ $this->setVersion();
46
  }
47
+
48
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  * Upgrade routine for new install
50
  */
51
+ private function newInstall(){
52
  // Write some default vars
53
  add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
54
  }
71
  }
72
 
73
  /**
74
+ * Convert clone data from wpstg 1.x to wpstg 2.0.1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  */
76
+ private function upgradeV1() {
77
 
78
  $new = array();
79
+
80
+ if (empty($this->clones)){
81
  return false;
82
  }
83
 
84
  foreach ( $this->clones as $key => &$value ) {
85
+
86
  // Skip the rest of the loop if data is already compatible to wpstg 2.0.1
87
  if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
88
  continue;
89
+ }
90
  $new[$value]['directoryName'] = $value;
91
  $new[$value]['path'] = get_home_path() . $value;
92
  $new[$value]['url'] = get_home_url() . "/" . $value;
93
+ $new[$value]['number'] = $key+1;
94
  $new[$value]['version'] = $this->previousVersion;
95
+
96
  }
97
+ unset($value);
98
+ //var_dump( $new );
99
 
100
+ if( empty($new) || false === update_option( 'wpstg_existing_clones', $new ) ) {
101
  $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
102
+ //wp_die('error');
103
  }
104
  }
105
+
106
  /**
107
+ * Upgrade Notices Db options from wpstg 1.3 -> 2.0.1
108
  * Fix some logical db options
109
  */
110
+ private function upgradeNotices(){
111
+ $poll = get_option( "wpstg_start_poll", false );
112
+ $beta = get_option( "wpstg_hide_beta", false );
113
+ $rating = get_option( "wpstg_RatingDiv", false );
114
+
115
+ if ($poll && $poll === "no"){
116
+ update_option('wpstg_poll', 'no');
117
+ }
118
+ if ($beta && $beta === "yes"){
119
+ update_option('wpstg_beta', 'no');
120
+ }
121
+ if ($rating && $rating === 'yes'){
122
+ update_option('wpstg_rating', 'no');
123
+ }
124
  }
125
 
126
  }
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,42 +371,17 @@ 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,
407
  #wpstg-removing-clone.loading::after {
408
  background: rgba(255, 255, 255, .7);
409
- content: 'Loading... may take a while for huge websites';
410
  display: block;
411
  width: 100%;
412
  height: 100%;
@@ -605,16 +580,13 @@ 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;
612
- font-size: 12px;
613
- line-height: 15px;
614
  border: 1px solid #FFF;
615
  background-color: black;
616
- color: #c0c0c0;
617
- padding:3px;
618
  white-space: nowrap;
619
  margin-top: 15px;
620
  }
@@ -704,8 +676,4 @@ color:#777777;
704
 
705
  .wpstg-share-button-twitter .share:active,.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active {
706
  background-color:#353535;
707
- }
708
-
709
- #wpstg-check-space {
710
- margin-left:8px;
711
  }
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,
382
  #wpstg-removing-clone.loading::after {
383
  background: rgba(255, 255, 255, .7);
384
+ content: 'LOADING May take little bit longer for large sites... ';
385
  display: block;
386
  width: 100%;
387
  height: 100%;
580
 
581
  #wpstg-log-details{
582
  height: 300px;
 
583
  overflow: scroll;
584
+ max-width: 650px;
585
+ font-size: 11px;
 
 
586
  border: 1px solid #FFF;
587
  background-color: black;
588
+ color: white;
589
+ padding:10px;
590
  white-space: nowrap;
591
  margin-top: 15px;
592
  }
676
 
677
  .wpstg-share-button-twitter .share:active,.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active {
678
  background-color:#353535;
 
 
 
 
679
  }
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
@@ -1,21 +1,21 @@
1
  "use strict";
2
 
3
- var WPStaging = (function ($)
4
  {
5
- var that = {
6
- isCancelled: false,
7
- isFinished: false,
8
- getLogs: false
9
- },
10
- cache = {elements: []},
11
- timeout, ajaxSpinner;
12
 
13
  /**
14
  * Get / Set Cache for Selector
15
  * @param {String} selector
16
  * @returns {*}
17
  */
18
- cache.get = function (selector)
19
  {
20
  // It is already cached!
21
  if ($.inArray(selector, cache.elements) !== -1)
@@ -33,7 +33,7 @@ var WPStaging = (function ($)
33
  * Refreshes given cache
34
  * @param {String} selector
35
  */
36
- cache.refresh = function (selector)
37
  {
38
  selector.elements[selector] = jQuery(selector);
39
  };
@@ -42,15 +42,15 @@ var WPStaging = (function ($)
42
  * Show and Log Error Message
43
  * @param {String} message
44
  */
45
- var showError = function (message)
46
  {
47
  cache.get("#wpstg-try-again").css("display", "inline-block");
48
  cache.get("#wpstg-cancel-cloning").text("Reset");
49
  cache.get("#wpstg-cloning-result").text("Fail");
50
  cache.get("#wpstg-error-wrapper").show();
51
  cache.get("#wpstg-error-details")
52
- .show()
53
- .html(message);
54
 
55
  cache.get("#wpstg-loader").hide();
56
  };
@@ -58,12 +58,12 @@ var WPStaging = (function ($)
58
  /**
59
  * Common Elements
60
  */
61
- var elements = function ()
62
  {
63
- var $workFlow = cache.get("#wpstg-workflow"),
64
- isAllChecked = true,
65
- urlSpinner = ajaxurl.replace("/admin-ajax.php", '') + "/images/spinner",
66
- timer;
67
 
68
  if (2 < window.devicePixelRatio)
69
  {
@@ -75,198 +75,200 @@ var WPStaging = (function ($)
75
  ajaxSpinner = "<img src=''" + urlSpinner + "' alt='' class='ajax-spinner general-spinner' />";
76
 
77
  $workFlow
78
- // Check / Un-check Database Tables
79
- .on("click", ".wpstg-button-unselect", function (e) {
80
- e.preventDefault();
81
 
82
- if (false === isAllChecked)
83
- {
84
- cache.get(".wpstg-db-table-checkboxes").prop("checked", true);
85
- cache.get(".wpstg-button-unselect").text("Un-check All");
86
- isAllChecked = true;
87
- }
88
- else
89
- {
90
- cache.get(".wpstg-db-table-checkboxes").prop("checked", false);
91
- cache.get(".wpstg-button-unselect").text("Check All");
92
- isAllChecked = false;
93
- }
94
- })
95
- // Expand Directories
96
- .on("click", ".wpstg-expand-dirs", function (e) {
97
- e.preventDefault();
98
 
99
- var $this = $(this);
100
 
101
- if (!$this.hasClass("disabled"))
102
- {
103
- $this.siblings(".wpstg-subdir").slideToggle();
104
- }
105
- })
106
- // When a Directory is Selected
107
- .on("change", ".wpstg-check-dir", function () {
108
- var $directory = $(this).parent(".wpstg-dir");
109
 
110
- if (this.checked)
111
- {
112
- $directory.parents(".wpstg-dir").children(".wpstg-check-dir").prop("checked", true);
113
- $directory.find(".wpstg-expand-dirs").removeClass("disabled");
114
- $directory.find(".wpstg-subdir .wpstg-check-dir").prop("checked", true);
115
- }
116
- else
117
- {
118
- $directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
119
- $directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
120
- $directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
121
- $directory.children(".wpstg-subdir").slideUp();
122
- }
123
- })
124
- // Check the max length of the clone name and if the clone name already exists
125
- .on("keyup", "#wpstg-new-clone-id", function () {
126
 
127
- // This request was already sent, clear it up!
128
- if ("number" === typeof (timer))
129
- {
130
- clearInterval(timer);
131
- }
132
 
133
- var cloneID = this.value;
134
 
135
- timer = setTimeout(
136
- function () {
137
- ajax(
138
- {
139
- action: "wpstg_check_clone",
140
- cloneID: cloneID
141
- },
142
- function (response)
 
 
143
  {
144
- if (response.status === "success")
145
- {
146
- cache.get("#wpstg-new-clone-id").removeClass("wpstg-error-input");
147
- cache.get("#wpstg-start-cloning").removeAttr("disabled");
148
- cache.get("#wpstg-clone-id-error").text('').hide();
149
- }
150
- else
151
- {
152
- cache.get("#wpstg-new-clone-id").addClass("wpstg-error-input");
153
- cache.get("#wpstg-start-cloning").prop("disabled", true);
154
- cache.get("#wpstg-clone-id-error").text(response.message).show();
155
- }
156
  }
157
- );
158
- },
159
- 500
160
- );
161
- })
162
- // Restart cloning process
163
- .on("click", "#wpstg-start-cloning", function () {
164
- that.isCancelled = false;
165
- that.getLogs = false;
166
- })
167
- // Display logs
168
- .on("click", "#wpstg-show-log-button", function (e) {
169
- e.preventDefault();
170
- var $logDetails = cache.get("#wpstg-log-details");
 
 
 
 
 
 
 
171
 
172
- $logDetails.toggle();
173
 
174
- logscroll();
175
 
176
- that.getLogs = (false === that.getLogs);
177
- });
178
 
179
  cloneActions();
180
  };
181
-
182
 
183
  /**
184
  * Clone actions
185
  */
186
- var cloneActions = function ()
187
  {
188
  var $workFlow = cache.get("#wpstg-workflow");
189
 
190
  $workFlow
191
- // Cancel cloning
192
- .on("click", "#wpstg-cancel-cloning", function () {
193
- if (!confirm("Are you sure you want to cancel cloning process?"))
194
- {
195
- return false;
196
- }
197
 
198
- var $this = $(this);
199
 
200
- $("#wpstg-try-again, #wpstg-home-link").hide();
201
- $this.prop("disabled", true);
202
 
203
- that.isCancelled = true;
204
 
205
- $("#wpstg-cloning-result").text("Please wait...this can take up a while.");
206
- $("#wpstg-loader, #wpstg-show-log-button").hide();
207
 
208
- $this.parent().append(ajaxSpinner);
209
 
210
- cancelCloning();
211
- })
212
- // Delete clone - confirmation
213
- .on("click", ".wpstg-remove-clone[data-clone]", function (e) {
214
- e.preventDefault();
215
-
216
- var $existingClones = cache.get("#wpstg-existing-clones");
217
 
218
- $workFlow.removeClass('active');
219
 
220
- cache.get("#wpstg-loader").show();
 
 
221
 
222
- ajax(
223
- {
224
- action: "wpstg_confirm_delete_clone",
225
- nonce: wpstg.nonce,
226
- clone: $(this).data("clone")
227
- },
228
- function (response)
229
  {
230
  cache.get("#wpstg-removing-clone").html(response);
231
 
232
  $existingClones.children("img").remove();
233
-
234
  cache.get("#wpstg-loader").hide();
235
  },
236
- "HTML"
237
- );
238
- })
239
- // Delete clone - confirmed
240
- .on("click", "#wpstg-remove-clone", function (e) {
241
- e.preventDefault();
242
-
243
- cache.get("#wpstg-removing-clone").addClass("loading");
244
-
245
- cache.get("#wpstg-loader").show();
246
-
247
- deleteClone($(this).data("clone"));
248
- })
249
- // Cancel deleting clone
250
- .on("click", "#wpstg-cancel-removing", function (e) {
251
- e.preventDefault();
252
- $(".wpstg-clone").removeClass("active");
253
- cache.get("#wpstg-removing-clone").html('');
254
- })
255
- // Edit
256
- .on("click", ".wpstg-execute-clone", function (e) {
257
- e.preventDefault();
258
-
259
- var clone = $(this).data("clone");
260
-
261
- $workFlow.addClass("loading");
262
-
263
- ajax(
264
- {
265
- action: "wpstg_scanning",
266
- clone: clone,
267
- nonce: wpstg.nonce
268
- },
269
- function (response)
 
 
270
  {
271
  if (response.length < 1)
272
  {
@@ -276,13 +278,13 @@ var WPStaging = (function ($)
276
  $workFlow.removeClass("loading").html(response);
277
 
278
  cache.get(".wpstg-current-step")
279
- .removeClass("wpstg-current-step")
280
- .next("li")
281
- .addClass("wpstg-current-step");
282
  },
283
- "HTML"
284
- );
285
- });
286
  };
287
 
288
  /**
@@ -292,9 +294,9 @@ var WPStaging = (function ($)
292
  * @param {String} dataType
293
  * @param {Boolean} showErrors
294
  */
295
- var ajax = function (data, callback, dataType, showErrors)
296
  {
297
- if ("undefined" === typeof (dataType))
298
  {
299
  dataType = "json";
300
  }
@@ -305,12 +307,12 @@ var WPStaging = (function ($)
305
  }
306
 
307
  $.ajax({
308
- url: ajaxurl,
309
- type: "POST",
310
- dataType: dataType,
311
- cache: false,
312
- data: data,
313
- error: function (xhr, textStatus, errorThrown) {
314
  console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
315
  console.log(textStatus);
316
 
@@ -320,24 +322,24 @@ var WPStaging = (function ($)
320
  }
321
 
322
  showError(
323
- "Fatal Error: This should not happen but is most often caused by other plugins. " +
324
- "Try first the option 'Optimizer' in WP Staging->Settings and try again. " +
325
- "If this does not help, enable " +
326
- "<a href='https://codex.wordpress.org/Debugging_in_WordPress' target='_blank'>wordpress debug mode</a> " +
327
- "to find out which plugin is causing this."
328
- );
329
  },
330
- success: function (data) {
331
- if ("function" === typeof (callback))
332
  {
333
  callback(data);
334
  }
335
  },
336
- statusCode: {
337
- 404: function () {
338
  showError("Something went wrong; can't find ajax request URL!");
339
  },
340
- 500: function () {
341
  showError("Something went wrong; internal server error while processing the request!");
342
  }
343
  }
@@ -347,76 +349,77 @@ var WPStaging = (function ($)
347
  /**
348
  * Next / Previous Step Clicks to Navigate Through Staging Job
349
  */
350
- var stepButtons = function ()
351
  {
352
  var $workFlow = cache.get("#wpstg-workflow");
353
 
354
  $workFlow
355
- // Next Button
356
- .on("click", ".wpstg-next-step-link", function (e) {
357
- e.preventDefault();
358
 
359
- var $this = $(this),
360
- isScan = false;
361
 
362
- // Button is disabled
363
- if ($this.attr("disabled"))
364
- {
365
- return false;
366
- }
367
 
368
- // Add loading overlay
369
- $workFlow.addClass("loading");
370
 
371
- // Prepare data
372
- that.data = {
373
- action: $this.data("action"),
374
- nonce: wpstg.nonce
375
- };
376
 
377
- // Cloning data
378
- getCloningData();
379
 
380
- console.log(that.data);
381
 
382
- isScan = ("wpstg_scanning" === that.action);
 
383
 
384
- // Send ajax request
385
- ajax(
386
- that.data,
387
- function (response) {
388
 
389
- if (response.length < 1)
390
- {
391
- showError("Something went wrong, please try again");
392
- }
393
 
394
- // Styling of elements
395
- $workFlow.removeClass("loading").html(response);
396
 
397
- cache.get(".wpstg-current-step")
398
- .removeClass("wpstg-current-step")
399
- .next("li")
400
- .addClass("wpstg-current-step");
401
 
402
- // Start cloning
403
- that.startCloning();
404
- },
405
- "HTML"
406
- );
407
- })
408
- // Previous Button
409
- .on("click", ".wpstg-prev-step-link", function (e) {
410
- e.preventDefault();
411
- loadOverview();
412
- });
413
  };
414
 
415
  /**
416
  * Get Excluded (Unchecked) Database Tables
417
  * @returns {Array}
418
  */
419
- var getExcludedTables = function ()
420
  {
421
  var excludedTables = [];
422
 
@@ -431,7 +434,7 @@ var WPStaging = (function ($)
431
  * Get Included Directories
432
  * @returns {Array}
433
  */
434
- var getIncludedDirectories = function ()
435
  {
436
  var includedDirectories = [];
437
 
@@ -450,7 +453,7 @@ var WPStaging = (function ($)
450
  * Get Excluded Directories
451
  * @returns {Array}
452
  */
453
- var getExcludedDirectories = function ()
454
  {
455
  var excludedDirectories = [];
456
 
@@ -465,89 +468,68 @@ var WPStaging = (function ($)
465
  return excludedDirectories;
466
  };
467
 
468
- /**
469
- * Get Included Extra Directories
470
- * @returns {Array}
471
- */
472
- var getIncludedExtraDirectories = function ()
473
- {
474
- var extraDirectories = [];
475
-
476
- if (!$("#wpstg_extraDirectories").val()) {
477
- return extraDirectories;
478
- }
479
-
480
- var extraDirectories = $("#wpstg_extraDirectories").val().split(/\r?\n/);
481
- console.log(extraDirectories);
482
-
483
- //excludedDirectories.push($this.val());
484
-
485
- return extraDirectories;
486
- };
487
-
488
-
489
-
490
  /**
491
  * Get Cloning Step Data
492
  */
493
- var getCloningData = function ()
494
  {
495
  if ("wpstg_cloning" !== that.data.action)
496
  {
497
  return;
498
  }
499
 
500
- that.data.cloneID = $("#wpstg-new-clone-id").val() || new Date().getTime().toString();
501
- that.data.excludedTables = getExcludedTables();
502
- that.data.includedDirectories = getIncludedDirectories();
503
- that.data.excludedDirectories = getExcludedDirectories();
504
- //that.data.extraDirectories = $("#wpstg_extraDirectories").val() || null;
505
- that.data.extraDirectories = getIncludedExtraDirectories();
506
- console.log(that.data);
507
-
508
  };
509
 
510
  /**
511
  * Loads Overview (first step) of Staging Job
512
  */
513
- var loadOverview = function ()
514
  {
515
  var $workFlow = cache.get("#wpstg-workflow");
516
 
517
  $workFlow.addClass("loading");
518
 
519
  ajax(
520
- {
521
- action: "wpstg_overview",
522
- nonce: wpstg.nonce
523
- },
524
- function (response) {
525
-
526
- if (response.length < 1)
527
  {
528
- showError("Something went wrong, please try again");
529
- }
 
 
530
 
531
- var $currentStep = cache.get(".wpstg-current-step");
 
 
 
532
 
533
- // Styling of elements
534
- $workFlow.removeClass("loading").html(response);
535
 
536
- },
537
- "HTML"
538
- );
 
 
 
 
 
 
 
539
  };
540
 
541
  /**
542
  * Tabs
543
  */
544
- var tabs = function ()
545
  {
546
- cache.get("#wpstg-workflow").on("click", ".wpstg-tab-header", function (e) {
547
  e.preventDefault();
548
 
549
- var $this = $(this),
550
- $section = cache.get($this.data("id"));
551
 
552
  $this.toggleClass("expand");
553
 
@@ -568,49 +550,42 @@ var WPStaging = (function ($)
568
  * Delete Clone
569
  * @param {String} clone
570
  */
571
- var deleteClone = function (clone)
572
  {
573
-
574
  ajax(
 
 
 
 
 
 
 
 
 
 
575
  {
576
- action: "wpstg_delete_clone",
577
- clone: clone,
578
- nonce: wpstg.nonce,
579
- excludedTables: getExcludedTables(),
580
- deleteDir: $("#deleteDirectory:checked").val()
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
  };
609
 
610
  /**
611
  * Cancel Cloning Process
612
  */
613
- var cancelCloning = function ()
614
  {
615
  if (true === that.isFinished)
616
  {
@@ -618,32 +593,32 @@ var WPStaging = (function ($)
618
  }
619
 
620
  ajax(
621
- {
622
- action: "wpstg_cancel_clone",
623
- clone: that.data.cloneID,
624
- nonce: wpstg.nonce
625
- },
626
- function (response)
627
- {
628
- if (true !== response)
629
  {
630
- cancelCloning();
631
- return;
632
- }
 
 
 
 
 
 
 
 
633
 
634
- // Load overview
635
- loadOverview();
636
- }
637
  );
638
  };
639
-
640
  /**
641
  * Scroll the window log to bottom
642
  * @returns void
643
  */
644
  var logscroll = function () {
645
  var $div = cache.get("#wpstg-log-details");
646
- if ("undefined" !== typeof ($div[0])) {
647
  $div.scrollTop($div[0].scrollHeight);
648
  }
649
  }
@@ -655,19 +630,17 @@ 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>');
671
  }
672
  }
673
  logscroll();
@@ -677,7 +650,7 @@ var WPStaging = (function ($)
677
  /**
678
  * Optimizer
679
  */
680
- var optimizer = function ()
681
  {
682
  var $optimizer = cache.get('input[name="wpstg_settings\[optimizer\]"]');
683
 
@@ -685,7 +658,7 @@ var WPStaging = (function ($)
685
  optimizerAction($optimizer.is(':checked'));
686
 
687
  // On action
688
- $optimizer.on('change', function () {
689
  optimizerAction(this.checked);
690
  });
691
 
@@ -701,46 +674,34 @@ var WPStaging = (function ($)
701
  }
702
  };
703
 
704
- var checkDiskSpace = function () {
705
- cache.get("#wpstg-check-space").on("click", function (e) {
706
- cache.get("#wpstg-loader").show();
707
- console.log("check disk space");
708
- ajax(
709
- {
710
- action: "wpstg_check_disk_space",
711
- nonce: wpstg.nonce
712
- },
713
- function (response)
714
- {
715
- if (false === response)
716
- {
717
- cache.get("#wpstg-clone-id-error").text('Can not detect disk space').show();
718
- cache.get("#wpstg-loader").hide();
719
- return;
720
- }
721
-
722
- // Not enough disk space
723
- cache.get("#wpstg-clone-id-error").text('Available free disk space ' + response.freespace + ' | Estimated necessary disk space: ' + response.usedspace).show();
724
- cache.get("#wpstg-loader").hide();
725
- },
726
- "json",
727
- false
728
- );
729
- });
730
-
731
- }
732
-
733
  /**
734
  * Start Cloning Process
735
  * @type {Function}
736
  */
737
- that.startCloning = (function () {
738
-
739
- // Register function for checking disk space
740
- checkDiskSpace();
741
-
742
  if ("wpstg_cloning" !== that.data.action)
743
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
  return;
745
  }
746
 
@@ -756,9 +717,7 @@ var WPStaging = (function ($)
756
  cache.get("#wpstg-loader").show();
757
 
758
  // Clone Database
759
- setTimeout(function () {
760
- cloneDatabase();
761
- }, wpstg.cpuLoad);
762
  }
763
 
764
  // Step 1: Clone Database
@@ -775,20 +734,20 @@ var WPStaging = (function ($)
775
  }
776
 
777
  setTimeout(
778
- function () {
779
- ajax(
780
- {
781
- action: "wpstg_clone_database",
782
- nonce: wpstg.nonce
783
- },
784
- function (response) {
785
  // Add percentage
786
- if ("undefined" !== typeof (response.percentage))
787
  {
788
  cache.get("#wpstg-db-progress").width(response.percentage + '%');
789
  }
790
  // Add Log
791
- if ("undefined" !== typeof (response.last_msg))
792
  {
793
  getLogs(response.last_msg);
794
  }
@@ -796,23 +755,19 @@ var WPStaging = (function ($)
796
  // Continue clone DB
797
  if (false === response.status)
798
  {
799
- setTimeout(function () {
800
- cloneDatabase();
801
- }, wpstg.cpuLoad);
802
  }
803
  // Next Step
804
  else if (true === response.status)
805
  {
806
- //console.log('prepareDirectories ' + response.status);
807
- setTimeout(function () {
808
- prepareDirectories();
809
- }, wpstg.cpuLoad);
810
  }
811
  }
812
- );
813
- },
814
- 500
815
  );
 
 
 
816
  }
817
 
818
  // Step 2: Prepare Directories
@@ -829,30 +784,28 @@ var WPStaging = (function ($)
829
  }
830
 
831
  setTimeout(
832
- function () {
833
- ajax(
834
- {
835
- action: "wpstg_clone_prepare_directories",
836
- nonce: wpstg.nonce
837
- },
838
- function (response) {
839
  // Add percentage
840
- if ("undefined" !== typeof (response.percentage))
841
  {
842
  cache.get("#wpstg-directories-progress").width(response.percentage + '%');
843
  }
844
 
845
  // Add Log
846
- if ("undefined" !== typeof (response.last_msg))
847
  {
848
  getLogs(response.last_msg);
849
  }
850
 
851
  if (false === response.status)
852
  {
853
- setTimeout(function () {
854
- prepareDirectories();
855
- }, wpstg.cpuLoad);
856
  }
857
  else if (true === response.status)
858
  {
@@ -860,10 +813,10 @@ var WPStaging = (function ($)
860
  cloneFiles();
861
  }
862
  }
863
- );
864
- },
865
- 500
866
  );
 
 
 
867
  }
868
 
869
  // Step 3: Clone Files
@@ -880,36 +833,32 @@ var WPStaging = (function ($)
880
  }
881
 
882
  ajax(
883
- {
884
- action: "wpstg_clone_files",
885
- nonce: wpstg.nonce
886
- },
887
- function (response) {
888
- // Add percentage
889
- if ("undefined" !== typeof (response.percentage))
890
  {
891
- cache.get("#wpstg-files-progress").width(response.percentage + '%');
892
- }
893
-
894
- // Add Log
895
- if ("undefined" !== typeof (response.last_msg))
896
- {
897
- getLogs(response.last_msg);
898
- }
 
 
 
 
 
 
 
899
 
900
- if (false === response.status)
901
- {
902
- setTimeout(function () {
903
- cloneFiles();
904
- }, wpstg.cpuLoad);
905
- }
906
- else if (true === response.status)
907
- {
908
- setTimeout(function () {
909
- replaceData();
910
- }, wpstg.cpuLoad);
911
  }
912
- }
913
  );
914
  }
915
 
@@ -927,34 +876,32 @@ var WPStaging = (function ($)
927
  }
928
 
929
  ajax(
930
- {
931
- action: "wpstg_clone_replace_data",
932
- nonce: wpstg.nonce
933
- },
934
- function (response) {
935
- // Add percentage
936
- if ("undefined" !== typeof (response.percentage))
937
  {
938
- cache.get("#wpstg-links-progress").width(response.percentage + '%');
939
- }
940
-
941
- // Add Log
942
- if ("undefined" !== typeof (response.last_msg))
943
- {
944
- getLogs(response.last_msg);
945
- }
 
 
 
 
 
 
 
946
 
947
- if (false === response.status)
948
- {
949
- setTimeout(function () {
950
- replaceData();
951
- }, wpstg.cpuLoad);
952
- }
953
- else if (true === response.status)
954
- {
955
- finish();
956
  }
957
- }
958
  );
959
  }
960
 
@@ -973,43 +920,43 @@ var WPStaging = (function ($)
973
  }
974
 
975
  ajax(
976
- {
977
- action: "wpstg_clone_finish",
978
- nonce: wpstg.nonce
979
- },
980
- function (response)
981
- {
982
- // Invalid response
983
- if ("object" !== typeof (response))
984
  {
985
- showError(
 
 
 
 
 
 
 
 
986
  "Couldn't finish the cloning process properly. " +
987
  "Your clone has been copied but failed to do clean up and " +
988
  "saving its records to the database." +
989
  "Please contact support and provide your logs."
990
- );
991
 
992
- return;
993
- }
994
 
995
- console.log("Cloning process finished");
996
 
997
- var $link1 = cache.get("#wpstg-clone-url-1");
998
- var $link = cache.get("#wpstg-clone-url");
999
 
1000
- cache.get("#wpstg_staging_name").html(that.data.cloneID);
1001
- cache.get("#wpstg-finished-result").show();
1002
- cache.get("#wpstg-cancel-cloning").prop("disabled", true);
1003
- $link1.attr("href", $link1.attr("href") + '/' + response.directoryName);
1004
- $link1.append('/' + response.directoryName);
1005
- $link.attr("href", $link.attr("href") + '/' + response.directoryName);
1006
- cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
1007
 
1008
- // Finished
1009
- that.isFinished = true;
1010
 
1011
- finish();
1012
- }
1013
  );
1014
  }
1015
  });
@@ -1052,7 +999,7 @@ var WPStaging = (function ($)
1052
  * Initiation
1053
  * @type {Function}
1054
  */
1055
- that.init = (function () {
1056
  //console.log("Initiating WPStaging...");
1057
  loadOverview();
1058
  elements();
@@ -1065,13 +1012,11 @@ var WPStaging = (function ($)
1065
  * Ajax call
1066
  * @type {ajax}
1067
  */
1068
- that.ajax = ajax;
1069
- that.showError = showError;
1070
- that.getLogs = getLogs;
1071
 
1072
  return that;
1073
  })(jQuery);
1074
 
1075
- jQuery(document).ready(function () {
1076
  WPStaging.init();
1077
  });
1
  "use strict";
2
 
3
+ var WPStaging = (function($)
4
  {
5
+ var that = {
6
+ isCancelled : false,
7
+ isFinished : false,
8
+ getLogs : false
9
+ },
10
+ cache = {elements : []},
11
+ timeout, ajaxSpinner;
12
 
13
  /**
14
  * Get / Set Cache for Selector
15
  * @param {String} selector
16
  * @returns {*}
17
  */
18
+ cache.get = function(selector)
19
  {
20
  // It is already cached!
21
  if ($.inArray(selector, cache.elements) !== -1)
33
  * Refreshes given cache
34
  * @param {String} selector
35
  */
36
+ cache.refresh = function(selector)
37
  {
38
  selector.elements[selector] = jQuery(selector);
39
  };
42
  * Show and Log Error Message
43
  * @param {String} message
44
  */
45
+ var showError = function(message)
46
  {
47
  cache.get("#wpstg-try-again").css("display", "inline-block");
48
  cache.get("#wpstg-cancel-cloning").text("Reset");
49
  cache.get("#wpstg-cloning-result").text("Fail");
50
  cache.get("#wpstg-error-wrapper").show();
51
  cache.get("#wpstg-error-details")
52
+ .show()
53
+ .html(message);
54
 
55
  cache.get("#wpstg-loader").hide();
56
  };
58
  /**
59
  * Common Elements
60
  */
61
+ var elements = function()
62
  {
63
+ var $workFlow = cache.get("#wpstg-workflow"),
64
+ isAllChecked = true,
65
+ urlSpinner = ajaxurl.replace("/admin-ajax.php", '') + "/images/spinner",
66
+ timer;
67
 
68
  if (2 < window.devicePixelRatio)
69
  {
75
  ajaxSpinner = "<img src=''" + urlSpinner + "' alt='' class='ajax-spinner general-spinner' />";
76
 
77
  $workFlow
78
+ // Check / Un-check Database Tables
79
+ .on("click", ".wpstg-button-unselect", function (e) {
80
+ e.preventDefault();
81
 
82
+ if (false === isAllChecked)
83
+ {
84
+ cache.get(".wpstg-db-table-checkboxes").prop("checked", true);
85
+ cache.get(".wpstg-button-unselect").text("Un-check All");
86
+ isAllChecked = true;
87
+ }
88
+ else
89
+ {
90
+ cache.get(".wpstg-db-table-checkboxes").prop("checked", false);
91
+ cache.get(".wpstg-button-unselect").text("Check All");
92
+ isAllChecked = false;
93
+ }
94
+ })
95
+ // Expand Directories
96
+ .on("click", ".wpstg-expand-dirs", function (e) {
97
+ e.preventDefault();
98
 
99
+ var $this = $(this);
100
 
101
+ if (!$this.hasClass("disabled"))
102
+ {
103
+ $this.siblings(".wpstg-subdir").slideToggle();
104
+ }
105
+ })
106
+ // When a Directory is Selected
107
+ .on("change", ".wpstg-check-dir", function () {
108
+ var $directory = $(this).parent(".wpstg-dir");
109
 
110
+ if (this.checked)
111
+ {
112
+ $directory.parents(".wpstg-dir").children(".wpstg-check-dir").prop("checked", true);
113
+ $directory.find(".wpstg-expand-dirs").removeClass("disabled");
114
+ $directory.find(".wpstg-subdir .wpstg-check-dir").prop("checked", true);
115
+ }
116
+ else
117
+ {
118
+ $directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
119
+ $directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
120
+ $directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
121
+ $directory.children(".wpstg-subdir").slideUp();
122
+ }
123
+ })
124
+ // Check the max length of the clone name and if the clone name already exists
125
+ .on("keyup", "#wpstg-new-clone-id", function () {
126
 
127
+ // This request was already sent, clear it up!
128
+ if ("number" === typeof(timer))
129
+ {
130
+ clearInterval(timer);
131
+ }
132
 
133
+ var cloneID = this.value;
134
 
135
+ timer = setTimeout(
136
+ function() {
137
+ ajax(
138
+ {
139
+ action : "wpstg_check_clone",
140
+ cloneID : cloneID
141
+ },
142
+ function(response)
143
+ {
144
+ if (response.status === "success")
145
  {
146
+ cache.get("#wpstg-new-clone-id").removeClass("wpstg-error-input");
147
+ cache.get("#wpstg-start-cloning").removeAttr("disabled");
148
+ cache.get("#wpstg-clone-id-error").text('').hide();
 
 
 
 
 
 
 
 
 
149
  }
150
+ else
151
+ {
152
+ cache.get("#wpstg-new-clone-id").addClass("wpstg-error-input");
153
+ cache.get("#wpstg-start-cloning").prop("disabled", true);
154
+ cache.get("#wpstg-clone-id-error").text(response.message).show();
155
+ }
156
+ }
157
+ );
158
+ },
159
+ 500
160
+ );
161
+ })
162
+ // Restart cloning process
163
+ .on("click", "#wpstg-start-cloning", function() {
164
+ that.isCancelled= false;
165
+ that.getLogs = false;
166
+ })
167
+ // Display logs
168
+ .on("click", "#wpstg-show-log-button", function (e) {
169
+ e.preventDefault();
170
+ var $logDetails = cache.get("#wpstg-log-details");
171
 
172
+ $logDetails.toggle();
173
 
174
+ logscroll();
175
 
176
+ that.getLogs = (false === that.getLogs);
177
+ });
178
 
179
  cloneActions();
180
  };
181
+
182
 
183
  /**
184
  * Clone actions
185
  */
186
+ var cloneActions = function()
187
  {
188
  var $workFlow = cache.get("#wpstg-workflow");
189
 
190
  $workFlow
191
+ // Cancel cloning
192
+ .on("click", "#wpstg-cancel-cloning", function() {
193
+ if (!confirm("Are you sure you want to cancel cloning process?"))
194
+ {
195
+ return false;
196
+ }
197
 
198
+ var $this = $(this);
199
 
200
+ $("#wpstg-try-again, #wpstg-home-link").hide();
201
+ $this.prop("disabled", true);
202
 
203
+ that.isCancelled = true;
204
 
205
+ $("#wpstg-cloning-result").text("Please wait...this can take up to a minute");
206
+ $("#wpstg-loader, #wpstg-show-log-button").hide();
207
 
208
+ $this.parent().append(ajaxSpinner);
209
 
210
+ cancelCloning();
211
+ })
212
+ // Delete clone - confirmation
213
+ .on("click", ".wpstg-remove-clone[data-clone]", function(e) {
214
+ e.preventDefault();
 
 
215
 
216
+ var $existingClones = cache.get("#wpstg-existing-clones");
217
 
218
+ $workFlow.removeClass('active');
219
+
220
+ cache.get("#wpstg-loader").show();
221
 
222
+ ajax(
223
+ {
224
+ action : "wpstg_confirm_delete_clone",
225
+ nonce : wpstg.nonce,
226
+ clone : $(this).data("clone")
227
+ },
228
+ function(response)
229
  {
230
  cache.get("#wpstg-removing-clone").html(response);
231
 
232
  $existingClones.children("img").remove();
233
+
234
  cache.get("#wpstg-loader").hide();
235
  },
236
+ "HTML"
237
+ );
238
+ })
239
+ // Delete clone - confirmed
240
+ .on("click", "#wpstg-remove-clone", function (e) {
241
+ e.preventDefault();
242
+
243
+ cache.get("#wpstg-removing-clone").addClass("loading");
244
+
245
+ //$this.parent().append(ajaxSpinner);
246
+
247
+ cache.get("#wpstg-loader").show();
248
+
249
+ deleteClone($(this).data("clone"));
250
+ })
251
+ // Cancel deleting clone
252
+ .on("click", "#wpstg-cancel-removing", function (e) {
253
+ e.preventDefault();
254
+ $(".wpstg-clone").removeClass("active");
255
+ cache.get("#wpstg-removing-clone").html('');
256
+ })
257
+ // Edit
258
+ .on("click", ".wpstg-execute-clone", function (e) {
259
+ e.preventDefault();
260
+
261
+ var clone = $(this).data("clone");
262
+
263
+ $workFlow.addClass("loading");
264
+
265
+ ajax(
266
+ {
267
+ action : "wpstg_scanning",
268
+ clone : clone,
269
+ nonce : wpstg.nonce
270
+ },
271
+ function(response)
272
  {
273
  if (response.length < 1)
274
  {
278
  $workFlow.removeClass("loading").html(response);
279
 
280
  cache.get(".wpstg-current-step")
281
+ .removeClass("wpstg-current-step")
282
+ .next("li")
283
+ .addClass("wpstg-current-step");
284
  },
285
+ "HTML"
286
+ );
287
+ });
288
  };
289
 
290
  /**
294
  * @param {String} dataType
295
  * @param {Boolean} showErrors
296
  */
297
+ var ajax = function(data, callback, dataType, showErrors)
298
  {
299
+ if ("undefined" === typeof(dataType))
300
  {
301
  dataType = "json";
302
  }
307
  }
308
 
309
  $.ajax({
310
+ url : ajaxurl,
311
+ type : "POST",
312
+ dataType : dataType,
313
+ cache : false,
314
+ data : data,
315
+ error : function(xhr, textStatus, errorThrown) {
316
  console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
317
  console.log(textStatus);
318
 
322
  }
323
 
324
  showError(
325
+ "Fatal Error: This should not happen but is most often caused by other plugins. " +
326
+ "Try first the option 'Optimizer' in WP Staging->Settings and try again. " +
327
+ "If this does not help, enable " +
328
+ "<a href='https://codex.wordpress.org/Debugging_in_WordPress' target='_blank'>wordpress debug mode</a> " +
329
+ "to find out which plugin is causing this."
330
+ );
331
  },
332
+ success : function(data) {
333
+ if ("function" === typeof(callback))
334
  {
335
  callback(data);
336
  }
337
  },
338
+ statusCode : {
339
+ 404: function() {
340
  showError("Something went wrong; can't find ajax request URL!");
341
  },
342
+ 500: function() {
343
  showError("Something went wrong; internal server error while processing the request!");
344
  }
345
  }
349
  /**
350
  * Next / Previous Step Clicks to Navigate Through Staging Job
351
  */
352
+ var stepButtons = function()
353
  {
354
  var $workFlow = cache.get("#wpstg-workflow");
355
 
356
  $workFlow
357
+ // Next Button
358
+ .on("click", ".wpstg-next-step-link", function(e) {
359
+ e.preventDefault();
360
 
361
+ var $this = $(this),
362
+ isScan = false;
363
 
364
+ // Button is disabled
365
+ if ($this.attr("disabled"))
366
+ {
367
+ return false;
368
+ }
369
 
370
+ // Add loading overlay
371
+ $workFlow.addClass("loading");
372
 
373
+ // Prepare data
374
+ that.data = {
375
+ action : $this.data("action"),
376
+ nonce : wpstg.nonce
377
+ };
378
 
379
+ // Cloning data
380
+ getCloningData();
381
 
382
+ console.log(that.data);
383
 
384
+ isScan = ("wpstg_scanning" === that.action);
385
+ console.log(isScan);
386
 
387
+ // Send ajax request
388
+ ajax(
389
+ that.data,
390
+ function(response) {
391
 
392
+ if (response.length < 1)
393
+ {
394
+ showError("Something went wrong, please try again");
395
+ }
396
 
397
+ // Styling of elements
398
+ $workFlow.removeClass("loading").html(response);
399
 
400
+ cache.get(".wpstg-current-step")
401
+ .removeClass("wpstg-current-step")
402
+ .next("li")
403
+ .addClass("wpstg-current-step");
404
 
405
+ // Start cloning
406
+ that.startCloning();
407
+ },
408
+ "HTML"
409
+ );
410
+ })
411
+ // Previous Button
412
+ .on("click", ".wpstg-prev-step-link", function(e) {
413
+ e.preventDefault();
414
+ loadOverview();
415
+ });
416
  };
417
 
418
  /**
419
  * Get Excluded (Unchecked) Database Tables
420
  * @returns {Array}
421
  */
422
+ var getExcludedTables = function()
423
  {
424
  var excludedTables = [];
425
 
434
  * Get Included Directories
435
  * @returns {Array}
436
  */
437
+ var getIncludedDirectories = function()
438
  {
439
  var includedDirectories = [];
440
 
453
  * Get Excluded Directories
454
  * @returns {Array}
455
  */
456
+ var getExcludedDirectories = function()
457
  {
458
  var excludedDirectories = [];
459
 
468
  return excludedDirectories;
469
  };
470
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
  /**
472
  * Get Cloning Step Data
473
  */
474
+ var getCloningData = function()
475
  {
476
  if ("wpstg_cloning" !== that.data.action)
477
  {
478
  return;
479
  }
480
 
481
+ that.data.cloneID = $("#wpstg-new-clone-id").val() || new Date().getTime().toString();
482
+ that.data.excludedTables = getExcludedTables();
483
+ that.data.includedDirectories = getIncludedDirectories();
484
+ that.data.excludedDirectories = getExcludedDirectories();
485
+ that.data.extraDirectories = $("#wpstg_extraDirectories").val() || null;
 
 
 
486
  };
487
 
488
  /**
489
  * Loads Overview (first step) of Staging Job
490
  */
491
+ var loadOverview = function()
492
  {
493
  var $workFlow = cache.get("#wpstg-workflow");
494
 
495
  $workFlow.addClass("loading");
496
 
497
  ajax(
 
 
 
 
 
 
 
498
  {
499
+ action : "wpstg_overview",
500
+ nonce : wpstg.nonce
501
+ },
502
+ function(response) {
503
 
504
+ if (response.length < 1)
505
+ {
506
+ showError("Something went wrong, please try again");
507
+ }
508
 
509
+ var $currentStep = cache.get(".wpstg-current-step");
 
510
 
511
+ // Styling of elements
512
+ $workFlow.removeClass("loading").html(response);
513
+
514
+ $currentStep
515
+ .removeClass("wpstg-current-step")
516
+ .next("li")
517
+ .addClass("wpstg-current-step");
518
+ },
519
+ "HTML"
520
+ );
521
  };
522
 
523
  /**
524
  * Tabs
525
  */
526
+ var tabs = function()
527
  {
528
+ cache.get("#wpstg-workflow").on("click", ".wpstg-tab-header", function(e) {
529
  e.preventDefault();
530
 
531
+ var $this = $(this),
532
+ $section = cache.get($this.data("id"));
533
 
534
  $this.toggleClass("expand");
535
 
550
  * Delete Clone
551
  * @param {String} clone
552
  */
553
+ var deleteClone = function(clone)
554
  {
555
+
556
  ajax(
557
+ {
558
+ action : "wpstg_delete_clone",
559
+ clone : clone,
560
+ nonce : wpstg.nonce,
561
+ excludedTables : getExcludedTables(),
562
+ deleteDir : $("#deleteDirectory:checked").val()
563
+ },
564
+ function(response)
565
+ {
566
+ if (true !== response)
567
  {
568
+ deleteClone(clone);
569
+ return;
570
+ }
 
 
 
 
 
 
 
571
 
572
+ cache.get("#wpstg-removing-clone").removeClass("loading").html('');
573
+ $(".wpstg-clone#" + clone).remove();
574
 
575
+ if ($(".wpstg-clone").length < 1)
576
+ {
577
+ cache.get("#wpstg-existing-clones").find("h3").text('');
 
 
 
 
578
  }
579
+
580
+ cache.get("#wpstg-loader").hide();
581
  }
 
 
 
 
 
 
 
 
582
  );
583
  };
584
 
585
  /**
586
  * Cancel Cloning Process
587
  */
588
+ var cancelCloning = function()
589
  {
590
  if (true === that.isFinished)
591
  {
593
  }
594
 
595
  ajax(
 
 
 
 
 
 
 
 
596
  {
597
+ action : "wpstg_cancel_clone",
598
+ clone : that.data.cloneID,
599
+ nonce : wpstg.nonce
600
+ },
601
+ function(response)
602
+ {
603
+ if (true !== response)
604
+ {
605
+ cancelCloning();
606
+ return;
607
+ }
608
 
609
+ // Load overview
610
+ loadOverview();
611
+ }
612
  );
613
  };
614
+
615
  /**
616
  * Scroll the window log to bottom
617
  * @returns void
618
  */
619
  var logscroll = function () {
620
  var $div = cache.get("#wpstg-log-details");
621
+ if ("undefined" !== typeof($div[0])){
622
  $div.scrollTop($div[0].scrollHeight);
623
  }
624
  }
630
  */
631
  var getLogs = function (log)
632
  {
633
+
634
+
635
+
636
  if (log != null && "undefined" !== typeof (log)) {
637
  if (log.constructor === Array) {
638
  $.each(log, function (index, value) {
 
639
  //console.log(index, value);
640
+ cache.get("#wpstg-log-details").append(value.type + ' ' + value.date + ' ' + value.message + '</br>');
 
 
 
 
641
  })
642
  } else {
643
+ cache.get("#wpstg-log-details").append(log.type + ' ' + log.date + ' ' + log.message + '</br>');
644
  }
645
  }
646
  logscroll();
650
  /**
651
  * Optimizer
652
  */
653
+ var optimizer = function()
654
  {
655
  var $optimizer = cache.get('input[name="wpstg_settings\[optimizer\]"]');
656
 
658
  optimizerAction($optimizer.is(':checked'));
659
 
660
  // On action
661
+ $optimizer.on('change', function(){
662
  optimizerAction(this.checked);
663
  });
664
 
674
  }
675
  };
676
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
  /**
678
  * Start Cloning Process
679
  * @type {Function}
680
  */
681
+ that.startCloning = (function() {
 
 
 
 
682
  if ("wpstg_cloning" !== that.data.action)
683
  {
684
+ console.log("check disk space");
685
+ ajax(
686
+ {
687
+ action: "wpstg_check_disk_space",
688
+ nonce: wpstg.nonce
689
+ },
690
+ function(response)
691
+ {
692
+ if (false !== response)
693
+ {
694
+ cache.get("#wpstg-clone-id-error").hide();
695
+ return;
696
+ }
697
+
698
+ // Not enough disk space
699
+ cache.get("#wpstg-clone-id-error").show();
700
+ },
701
+ "json",
702
+ false
703
+ );
704
+
705
  return;
706
  }
707
 
717
  cache.get("#wpstg-loader").show();
718
 
719
  // Clone Database
720
+ setTimeout(function() {cloneDatabase();}, wpstg.cpuLoad);
 
 
721
  }
722
 
723
  // Step 1: Clone Database
734
  }
735
 
736
  setTimeout(
737
+ function() {
738
+ ajax(
739
+ {
740
+ action : "wpstg_clone_database",
741
+ nonce : wpstg.nonce
742
+ },
743
+ function(response) {
744
  // Add percentage
745
+ if ("undefined" !== typeof(response.percentage))
746
  {
747
  cache.get("#wpstg-db-progress").width(response.percentage + '%');
748
  }
749
  // Add Log
750
+ if ("undefined" !== typeof(response.last_msg))
751
  {
752
  getLogs(response.last_msg);
753
  }
755
  // Continue clone DB
756
  if (false === response.status)
757
  {
758
+ setTimeout(function() {cloneDatabase();}, wpstg.cpuLoad);
 
 
759
  }
760
  // Next Step
761
  else if (true === response.status)
762
  {
763
+ console.log('prepareDirectories' + response.status);
764
+ setTimeout(function() {prepareDirectories();}, wpstg.cpuLoad);
 
 
765
  }
766
  }
 
 
 
767
  );
768
+ },
769
+ 500
770
+ );
771
  }
772
 
773
  // Step 2: Prepare Directories
784
  }
785
 
786
  setTimeout(
787
+ function() {
788
+ ajax(
789
+ {
790
+ action : "wpstg_clone_prepare_directories",
791
+ nonce : wpstg.nonce
792
+ },
793
+ function(response) {
794
  // Add percentage
795
+ if ("undefined" !== typeof(response.percentage))
796
  {
797
  cache.get("#wpstg-directories-progress").width(response.percentage + '%');
798
  }
799
 
800
  // Add Log
801
+ if ("undefined" !== typeof(response.last_msg))
802
  {
803
  getLogs(response.last_msg);
804
  }
805
 
806
  if (false === response.status)
807
  {
808
+ setTimeout(function() {prepareDirectories();}, wpstg.cpuLoad);
 
 
809
  }
810
  else if (true === response.status)
811
  {
813
  cloneFiles();
814
  }
815
  }
 
 
 
816
  );
817
+ },
818
+ 500
819
+ );
820
  }
821
 
822
  // Step 3: Clone Files
833
  }
834
 
835
  ajax(
 
 
 
 
 
 
 
836
  {
837
+ action : "wpstg_clone_files",
838
+ nonce : wpstg.nonce
839
+ },
840
+ function(response) {
841
+ // Add percentage
842
+ if ("undefined" !== typeof(response.percentage))
843
+ {
844
+ cache.get("#wpstg-files-progress").width(response.percentage + '%');
845
+ }
846
+
847
+ // Add Log
848
+ if ("undefined" !== typeof (response.last_msg))
849
+ {
850
+ getLogs(response.last_msg);
851
+ }
852
 
853
+ if (false === response.status)
854
+ {
855
+ setTimeout(function() {cloneFiles();}, wpstg.cpuLoad);
856
+ }
857
+ else if (true === response.status)
858
+ {
859
+ setTimeout(function() {replaceData();}, wpstg.cpuLoad);
860
+ }
 
 
 
861
  }
 
862
  );
863
  }
864
 
876
  }
877
 
878
  ajax(
 
 
 
 
 
 
 
879
  {
880
+ action : "wpstg_clone_replace_data",
881
+ nonce : wpstg.nonce
882
+ },
883
+ function(response) {
884
+ // Add percentage
885
+ if ("undefined" !== typeof(response.percentage))
886
+ {
887
+ cache.get("#wpstg-links-progress").width(response.percentage + '%');
888
+ }
889
+
890
+ // Add Log
891
+ if ("undefined" !== typeof (response.last_msg))
892
+ {
893
+ getLogs(response.last_msg);
894
+ }
895
 
896
+ if (false === response.status)
897
+ {
898
+ setTimeout(function() {replaceData();}, wpstg.cpuLoad);
899
+ }
900
+ else if (true === response.status)
901
+ {
902
+ finish();
903
+ }
 
904
  }
 
905
  );
906
  }
907
 
920
  }
921
 
922
  ajax(
 
 
 
 
 
 
 
 
923
  {
924
+ action : "wpstg_clone_finish",
925
+ nonce : wpstg.nonce
926
+ },
927
+ function(response)
928
+ {
929
+ // Invalid response
930
+ if ("object" !== typeof(response))
931
+ {
932
+ showError(
933
  "Couldn't finish the cloning process properly. " +
934
  "Your clone has been copied but failed to do clean up and " +
935
  "saving its records to the database." +
936
  "Please contact support and provide your logs."
937
+ );
938
 
939
+ return;
940
+ }
941
 
942
+ console.log("Cloning process finished");
943
 
944
+ var $link1 = cache.get("#wpstg-clone-url-1");
945
+ var $link = cache.get("#wpstg-clone-url");
946
 
947
+ cache.get("#wpstg_staging_name").html(that.data.cloneID);
948
+ cache.get("#wpstg-finished-result").show();
949
+ cache.get("#wpstg-cancel-cloning").prop("disabled", true);
950
+ $link1.attr("href", $link1.attr("href") + '/' + response.directoryName);
951
+ $link1.append('/' + response.directoryName);
952
+ $link.attr("href", $link.attr("href") + '/' + response.directoryName);
953
+ cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
954
 
955
+ // Finished
956
+ that.isFinished = true;
957
 
958
+ finish();
959
+ }
960
  );
961
  }
962
  });
999
  * Initiation
1000
  * @type {Function}
1001
  */
1002
+ that.init = (function() {
1003
  //console.log("Initiating WPStaging...");
1004
  loadOverview();
1005
  elements();
1012
  * Ajax call
1013
  * @type {ajax}
1014
  */
1015
+ that.ajax = ajax;
 
 
1016
 
1017
  return that;
1018
  })(jQuery);
1019
 
1020
+ jQuery(document).ready(function() {
1021
  WPStaging.init();
1022
  });
apps/Backend/views/_includes/header.php CHANGED
@@ -3,7 +3,7 @@
3
  </span>
4
 
5
  <span class="wpstg-version">
6
- <?php if (WPStaging\WPStaging::getSlug() === "wp-staging-pro") echo "Pro" ?> Version <?php echo \WPStaging\WPStaging::VERSION ?>
7
  </span>
8
 
9
  <div class="wpstg-header">
3
  </span>
4
 
5
  <span class="wpstg-version">
6
+ <?php if (\WPStaging\WPStaging::SLUG === "wp-staging-pro") echo "Pro" ?> Version <?php echo \WPStaging\WPStaging::VERSION ?>
7
  </span>
8
 
9
  <div class="wpstg-header">
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
 
@@ -61,7 +61,7 @@
61
  <?php echo $scan->directoryListing()?>
62
 
63
  <h4 style="margin:10px 0 10px 0">
64
- <?php echo __("Extra directories to copy", "wpstg")?>
65
  </h4>
66
 
67
  <textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:250px;"></textarea>
@@ -69,8 +69,9 @@
69
  <span>
70
  <?php
71
  echo __(
72
- "Enter one folder path per line.<br>".
73
- "Folders must start with absolute path: " . $options->root,
 
74
  "wpstg"
75
  )
76
  ?>
@@ -80,9 +81,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>
@@ -114,6 +113,4 @@
114
  echo __("Start Cloning", "wpstg");
115
  }
116
  ?>
117
- </button>
118
-
119
- <a href="#" id="wpstg-check-space"><?php _e('Check Disk Space', 'wpstg'); ?></a>
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
 
61
  <?php echo $scan->directoryListing()?>
62
 
63
  <h4 style="margin:10px 0 10px 0">
64
+ <?php echo __("Extra Directories / Files", "wpstg")?>
65
  </h4>
66
 
67
  <textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:250px;"></textarea>
69
  <span>
70
  <?php
71
  echo __(
72
+ "Add additional extra directories you'd like to clone to your staging site<br>".
73
+ "You must write full path of the directory / file<br>".
74
+ "Full path must start with " . $options->root,
75
  "wpstg"
76
  )
77
  ?>
81
  <p>
82
  <span>
83
  <?php
84
+ echo __("Files will be copied into subfolder of: ", "wpstg") . $options->root
 
 
85
  ?>
86
  </span>
87
  </p>
113
  echo __("Start Cloning", "wpstg");
114
  }
115
  ?>
116
+ </button>
 
 
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/settings/index.php CHANGED
@@ -202,13 +202,13 @@
202
  </td>
203
  </tr>
204
  <!-- Deactivated -->
205
- <tr class="row">
206
  <td class="row th">
207
  <div class="col-title">
208
  <?php echo $form->label("wpstg_settings[debugMode]")?>
209
  <span class="description">
210
  This will enable an extended debug mode which creates additional entries
211
- in <strong>wp-content/uploads/wp-staging/logs/logfile.log</strong>.
212
  Please enable this when we ask you to do so.
213
  </span>
214
  </div>
202
  </td>
203
  </tr>
204
  <!-- Deactivated -->
205
+ <tr class="row" style="display: none;">
206
  <td class="row th">
207
  <div class="col-title">
208
  <?php echo $form->label("wpstg_settings[debugMode]")?>
209
  <span class="description">
210
  This will enable an extended debug mode which creates additional entries
211
+ in <strong>wp-content/wp-staging/logs</strong>.
212
  Please enable this when we ask you to do so.
213
  </span>
214
  </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/Utils/Cache.php CHANGED
@@ -70,7 +70,7 @@ class Cache
70
  // If cache directory doesn't exists, create it
71
  if (!is_dir($this->cacheDir) && !@mkdir($this->cacheDir, 0775, true))
72
  {
73
- throw new \Exception("Failed to create cache directory " . $this->cacheDir . '! Make sure folder permission is 755 and owner is correct. Should be www-data or similar.');
74
  }
75
  }
76
 
70
  // If cache directory doesn't exists, create it
71
  if (!is_dir($this->cacheDir) && !@mkdir($this->cacheDir, 0775, true))
72
  {
73
+ throw new \Exception("Failed to create cache directory!");
74
  }
75
  }
76
 
apps/Core/Utils/Logger.php CHANGED
@@ -24,8 +24,6 @@ class Logger
24
  const TYPE_WARNING = "WARNING";
25
 
26
  const TYPE_INFO = "INFO";
27
-
28
- const TYPE_DEBUG = "DEBUG";
29
 
30
  /**
31
  * Log directory (full path)
@@ -100,7 +98,7 @@ class Logger
100
  * @param string $type
101
  */
102
  public function add($message, $type = self::TYPE_ERROR)
103
- {
104
  $this->messages[] = array(
105
  "type" => $type,
106
  "date" => date("Y/m/d H:i:s"),
24
  const TYPE_WARNING = "WARNING";
25
 
26
  const TYPE_INFO = "INFO";
 
 
27
 
28
  /**
29
  * Log directory (full path)
98
  * @param string $type
99
  */
100
  public function add($message, $type = self::TYPE_ERROR)
101
+ {
102
  $this->messages[] = array(
103
  "type" => $type,
104
  "date" => date("Y/m/d H:i:s"),
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,392 @@ 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.1";
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
+ /**
51
+ * Services
52
+ * @var array
53
+ */
54
+ private $services;
55
+
56
+ /**
57
+ * Singleton instance
58
+ * @var WPStaging
59
+ */
60
+ private static $instance;
61
+
62
+ /**
63
+ * WPStaging constructor.
64
+ */
65
+ private function __construct()
66
+ {
67
+ $file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . self::SLUG . ".php";
68
+
69
+ // Activation Hook
70
+ register_activation_hook($file, array($this, "onActivation"));
71
+
72
+ $this->registerNamespaces();
73
+ $this->loadLanguages();
74
+ $this->loadDependencies();
75
+ $this->defineHooks();
76
+
77
+ // URL to apps folder
78
+ $this->url = plugin_dir_url( dirname(__FILE__) );
79
+
80
+ // URL to backend public folder folder
81
+ $this->backend_url = plugin_dir_url( dirname(__FILE__) ) . "Backend/public/";
82
+
83
+ // URL to frontend public folder folder
84
+ $this->frontend_url = plugin_dir_url( dirname(__FILE__) ) . "Frontend/public/";
85
+ }
86
+
87
+ /**
88
+ * Define Hooks
89
+ */
90
+ public function defineHooks()
91
+ {
92
+ $loader = $this->get("loader");
93
+ $loader->addAction("admin_enqueue_scripts", $this, "enqueueElements", 100);
94
+ $loader->addAction("wp_enqueue_scripts", $this, "enqueueElements", 100);
95
+ }
96
+
97
+ /**
98
+ * Scripts and Styles
99
+ * @param string $hook
100
+ */
101
+ public function enqueueElements($hook)
102
+ {
103
+
104
+ // Load this css file on frontend and backend on all pages if current site is a staging site
105
+ if( $this->isStagingSite() ) {
106
+ wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", $this->getVersion() );
107
+ }
108
+
109
+ $availablePages = array(
110
+ "toplevel_page_wpstg_clone",
111
+ "wp-staging_page_wpstg-settings",
112
+ "wp-staging_page_wpstg-tools"
113
+ );
114
+
115
+ // Load these css and js files only on wp staging admin pages
116
+ if (!in_array($hook, $availablePages) || !is_admin())
117
+ {
118
+ return;
119
+ }
120
+
121
+ // Load admin js files
122
+ wp_enqueue_script(
123
+ "wpstg-admin-script",
124
+ $this->backend_url . "js/wpstg-admin.js",
125
+ array("jquery"),
126
+ $this->getVersion(),
127
+ false
128
+ );
129
+
130
+ // Load admin css files
131
+ wp_enqueue_style(
132
+ "wpstg-admin",
133
+ $this->backend_url . "css/wpstg-admin.css",
134
+ $this->getVersion()
135
+ );
136
+
137
+ wp_localize_script("wpstg-admin-script", "wpstg", array(
138
+ "nonce" => wp_create_nonce("wpstg_ajax_nonce"),
139
+ "mu_plugin_confirmation" => __(
140
+ "If confirmed we will install an additional WordPress 'Must Use' plugin. "
141
+ . "This plugin will allow us to control which plugins are loaded during "
142
+ . "WP Staging specific operations. Do you wish to continue?",
143
+ "wpstg"
144
+ ),
145
+ "plugin_compatibility_settings_problem" => __(
146
+ "A problem occurred when trying to change the plugin compatibility setting.",
147
+ "wpstg"
148
+ ),
149
+ "saved" => __("Saved", "The settings were saved successfully", "wpstg"),
150
+ "status" => __("Status", "Current request status", "wpstg"),
151
+ "response" => __("Response", "The message the server responded with", "wpstg"),
152
+ "blacklist_problem" => __(
153
+ "A problem occurred when trying to add plugins to backlist.",
154
+ "wpstg"
155
+ ),
156
+ "cpuLoad" => $this->getCPULoadSetting(),
157
+ "settings" => (object) array() // TODO add settings?
158
+ ));
159
+ }
160
+
161
+ /**
162
+ * Method to be executed upon activation of the plugin
163
+ */
164
+ public function onActivation()
165
+ {
166
+
167
+ }
168
+ /**
169
+ * Caching and logging folder
170
+ *
171
+ * @return string
172
+ */
173
+ public static function getContentDir(){
174
+ $wp_upload_dir = wp_upload_dir();
175
+ $path = $wp_upload_dir['basedir'] . '/wp-staging';
176
+ wp_mkdir_p( $path );
177
+ return apply_filters( 'wpstg_get_upload_dir', $path . DIRECTORY_SEPARATOR );
178
+ }
179
+
180
+
181
+ /**
182
+ * Register used namespaces
183
+ */
184
+ private function registerNamespaces()
185
+ {
186
+ $autoloader = new Autoloader();
187
+ $this->set("autoloader", $autoloader);
188
+
189
+ // Base directory
190
+ $dir = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . "apps" . DIRECTORY_SEPARATOR;
191
+
192
+ // Autoloader
193
+ $autoloader->registerNamespaces(array(
194
+ "WPStaging" => array(
195
+ $dir,
196
+ $dir . "Core" . DIRECTORY_SEPARATOR
197
+ )
198
+ ));
199
+
200
+ // Register namespaces
201
+ $autoloader->register();
202
+ }
203
+
204
+ /**
205
+ * Get Instance
206
+ * @return WPStaging
207
+ */
208
+ public static function getInstance()
209
+ {
210
+ if (null === static::$instance)
211
+ {
212
+ static::$instance = new static();
213
+ }
214
+
215
+ return static::$instance;
216
+ }
217
+
218
+ /**
219
+ * Prevent cloning
220
+ * @return void
221
+ */
222
+ private function __clone()
223
+ {}
224
+
225
+ /**
226
+ * Prevent unserialization
227
+ * @return void
228
+ */
229
+ private function __wakeup()
230
+ {}
231
+
232
+ /**
233
+ * Load Dependencies
234
+ */
235
+ private function loadDependencies()
236
+ {
237
+ // Set loader
238
+ $this->set("loader", new Loader());
239
+
240
+ // Set cache
241
+ $this->set("cache", new Cache());
242
+
243
+ // Set logger
244
+ $this->set("logger", new Logger());
245
+
246
+ // Set settings
247
+ $this->set("settings", new Settings());
248
+
249
+ // Set Administrator
250
+ if (is_admin())
251
+ {
252
+ new Administrator($this);
253
+ }
254
+ else
255
+ {
256
+ new Frontend($this);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Execute Plugin
262
+ */
263
+ public function run()
264
+ {
265
+ $this->get("loader")->run();
266
+ }
267
+
268
+ /**
269
+ * Set a variable to DI with given name
270
+ * @param string $name
271
+ * @param mixed $variable
272
+ * @return $this
273
+ */
274
+ public function set($name, $variable)
275
+ {
276
+ // It is a function
277
+ if (is_callable($variable)) $variable = $variable();
278
+
279
+ // Add it to services
280
+ $this->services[$name] = $variable;
281
+
282
+ return $this;
283
+ }
284
+
285
+ /**
286
+ * Get given name index from DI
287
+ * @param string $name
288
+ * @return mixed|null
289
+ */
290
+ public function get($name)
291
+ {
292
+ return (isset($this->services[$name])) ? $this->services[$name] : null;
293
+ }
294
+
295
+ /**
296
+ * @return string
297
+ */
298
+ public function getVersion()
299
+ {
300
+ return self::VERSION;
301
+ }
302
+
303
+ /**
304
+ * @return string
305
+ */
306
+ public function getName()
307
+ {
308
+ return self::NAME;
309
+ }
310
+
311
+ /**
312
+ * @return string
313
+ */
314
+ public function getSlug()
315
+ {
316
+ return self::SLUG;
317
+ }
318
+
319
+ /**
320
+ * Get path to main plugin file
321
+ * @return string
322
+ */
323
+ public function getPath(){
324
+ return dirname(dirname(__FILE__));
325
+ }
326
+ /**
327
+ * Get main plugin url
328
+ * @return type
329
+ */
330
+ public function getUrl(){
331
+ return plugin_dir_url(dirname(__FILE__));
332
+ }
333
+
334
+ /**
335
+ * @return array|mixed|object
336
+ */
337
+ public function getCPULoadSetting()
338
+ {
339
+ $options = $this->get("settings");
340
+ $setting = $options->getCpuLoad();
341
+
342
+ switch ($setting)
343
+ {
344
+ case "high":
345
+ $cpuLoad = 0;
346
+ break;
347
+
348
+ case "medium":
349
+ $cpuLoad = 1000;
350
+ break;
351
+
352
+ case "low":
353
+ $cpuLoad = 3000;
354
+ break;
355
+
356
+ case "default":
357
+ default:
358
+ $cpuLoad = 1000;
359
+ }
360
+
361
+ return $cpuLoad;
362
+ }
363
+
364
+ /**
365
+ * Load language file
366
+ */
367
+ public function loadLanguages()
368
+ {
369
+ $languagesDirectory = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR;
370
+ $languagesDirectory.= "vars" . DIRECTORY_SEPARATOR . "languages" . DIRECTORY_SEPARATOR;
371
+
372
+ // Set filter for plugins languages directory
373
+ $languagesDirectory = apply_filters("wpstg_languages_directory", $languagesDirectory);
374
+
375
+ // Traditional WP plugin locale filter
376
+ $locale = apply_filters("plugin_locale", get_locale(), "wpstg");
377
+ $moFile = sprintf('%1$s-%2$s.mo', "wpstg", $locale);
378
+
379
+ // Setup paths to current locale file
380
+ $moFileLocal = $languagesDirectory . $moFile;
381
+ $moFileGlobal = WP_LANG_DIR . DIRECTORY_SEPARATOR . "wpstg" . DIRECTORY_SEPARATOR . $moFile;
382
+
383
+ // Global file (/wp-content/languages/WPSTG)
384
+ if (file_exists($moFileGlobal))
385
+ {
386
+ load_textdomain("wpstg", $moFileGlobal);
387
+ }
388
+ // Local file (/wp-content/plugins/wp-staging/languages/)
389
+ elseif (file_exists($moFileLocal))
390
+ {
391
+ load_textdomain("wpstg", $moFileGlobal);
392
+ }
393
+ // Default file
394
+ else
395
+ {
396
+ load_plugin_textdomain("wpstg", false, $languagesDirectory);
397
+ }
398
+ }
399
+
400
+ /**
401
+ * Check if it is a staging site
402
+ * @return bool
403
+ */
404
+ private function isStagingSite()
405
+ {
406
+ return ("true" === get_option("wpstg_is_staging_site"));
407
+ }
408
 
409
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Frontend/Frontend.php CHANGED
@@ -35,6 +35,7 @@ class Frontend extends InjectionAware
35
 
36
  $loader->addAction("init", $this, "checkPermissions");
37
  $loader->addFilter("wp_before_admin_bar_render", $this, "changeSiteName");
 
38
  }
39
 
40
  /**
35
 
36
  $loader->addAction("init", $this, "checkPermissions");
37
  $loader->addFilter("wp_before_admin_bar_render", $this, "changeSiteName");
38
+ //$loader->addAction("wp_enqueue_scripts", $this, "enqueueElements", 10);
39
  }
40
 
41
  /**
readme.txt CHANGED
@@ -8,28 +8,32 @@ 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
 
@@ -123,7 +127,7 @@ After installation goto the settings page 'Staging' and do your adjustments ther
123
 
124
 
125
  == Official Site ==
126
- https://wp-staging.com
127
 
128
  == Installation ==
129
  1. Download the file "wp-staging" , unzip and place it in your wp-content/plugins/wp-staging folder. You can alternatively upload and install it via the WordPress plugin backend.
@@ -139,33 +143,6 @@ https://wp-staging.com
139
 
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
151
-
152
- = 1.1.5 =
153
- * Fix: Admin notice is throwing a false positive write permission error
154
- * New: Move log folder to wp-content/uploads/wp-staging/logs
155
- * New: Tested up to WP 4.7.3
156
-
157
- = 1.1.4 =
158
- * Fix: Fatal error Unsupported operand types
159
-
160
- = 1.1.3 =
161
- * New: Tested up to wp 4.7.2
162
- * Fix: Arrows in drop down for folder selection are distorted
163
- * Tweak: Show working log as default to make debugging easier
164
-
165
- = 1.1.2 =
166
- * Fix: Settings are not deleted when plugin is removed
167
- * Fix: Staging site is available for non administrators
168
-
169
  = 1.1.1 =
170
  * Fix: Change rating url
171
 
@@ -221,9 +198,54 @@ https://wp-staging.com
221
  * Fix: $db_helper undefined message
222
  * Fix: Skip non utf8 encoded files during copying process
223
 
224
- Complete changelog: [https://wp-staging.com/changelog.txt](https://wp-staging.com/changelog.txt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
  == Upgrade Notice ==
227
 
228
- = 2.0.2 =
229
- 2.0.2 * New: Batch processing allows to clone even huge sites without any timeouts
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.1
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:
24
+ [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")
25
+ <br /> <br />
26
+
27
+
28
  <blockquote>
29
  <h4> WP Staging for WordPress Migration </h4>
30
  This duplicator plugin allows you to create an staging or development environment in seconds* <br /> <br />
31
+ It creates a file clone of your website into a subfolder of your current WordPress installation with an entire copy of your database.
32
+ 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.
33
  <br /> <br />
34
  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.
35
  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.
36
+ <br /> <br />
37
  <p><small><em>* Time of creation depends on size of your database and file size</em></small></p>
38
  </blockquote>
39
 
127
 
128
 
129
  == Official Site ==
130
+
131
 
132
  == Installation ==
133
  1. Download the file "wp-staging" , unzip and place it in your wp-content/plugins/wp-staging folder. You can alternatively upload and install it via the WordPress plugin backend.
143
 
144
  == Changelog ==
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  = 1.1.1 =
147
  * Fix: Change rating url
148
 
198
  * Fix: $db_helper undefined message
199
  * Fix: Skip non utf8 encoded files during copying process
200
 
201
+ = 0.9.9 =
202
+ * Fix: Use back ticks for table names to prevent copy errors when table names are containing hyphens or similar special characters
203
+ * New: Load option to reduce cpu load and to lower the risk of killed ajax calls because of security flooding mechanism (Prevent 405 errors: not allowed)
204
+ * Tweak: Load non minified js file when WPSTG debug mode is enabled
205
+
206
+ = 0.9.8 =
207
+ * New: Tested up to WP 4.4
208
+ * New: New debug mode in settings
209
+ * Tweak: Check if url's in staging's wp-config.php needs a replacement and do so.
210
+ * Fix: Prevent fatal error and end of copying process. Make sure files are writable before trying to copy them
211
+
212
+ = 0.9.7 =
213
+ * Fix: Change backend link to https://wordpress.org/plugins/wp-staging/ when using an outdated version of the plugin
214
+ * New: Tested up to WP 4.3.1
215
+
216
+ = 0.9.6 =
217
+ * New: Show notice when there is not enough disk space for a clone
218
+ * Fix: PHP Error on 32bit systems: "disk_free_space(): Value too large for defined data type"
219
+ * Fix: Copying process of larges files gets interupted sometimes due undefined variable
220
+ * Fix: Define width and height for the system info export formular
221
+ * Fix: Cannot redeclare deleteDirectory()
222
+
223
+ = 0.9.5 =
224
+ * Fix: Option for cloning sites which are moved into a subdirectory was not working on several systems
225
+ * New: WordPress Migration tested up to WP 4.3
226
+
227
+ = 0.9.4 =
228
+ * Fix: Large files are copied partly
229
+ * Fix: js error xhr.statusText not defined
230
+ * New: Option for cloning sites which are moved into a subdirectory. Read more: https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
231
+ * New: Create an alternative copy method for large files
232
+ * New: Add new author WP-Staging to the readme.txt and to the wordpress repository
233
+
234
+ = 0.9.3 =
235
+ * Fix: Rating container is not shown because of wrong wordpress option name
236
+ * Tweak: Change color of the rating links
237
+
238
+ = 0.9.2 =
239
+ * Fix: A conflict with the plugin WP Migrate DB (Pro)
240
+ * Fix: Limit the staging name to maximum of 16 characters for migration process
241
+
242
+ = 0.9.1 =
243
+ * Fix: Change search and replace function for table wp_options when running migration. This prevented on some sites the moving of serialized theme data
244
+
245
+ = 0.9 =
246
+ * New: Release
247
 
248
  == Upgrade Notice ==
249
 
250
+ = 1.1.0 =
251
+ 1.1.0 <strong>Compatible up to WP 4.6</strong>
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,14 @@ 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
  // Old wpstg 1.3 options for admin notices
31
  delete_option( "wpstg_start_poll" );
32
  delete_option( "wpstg_hide_beta" );
33
  delete_option( "wpstg_RatingDiv" );
34
+ // New ones
 
35
  delete_option( "wpstg_poll" );
36
  delete_option( "wpstg_rating" );
37
  delete_option( "wpstg_beta" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
 
wp-staging.php CHANGED
@@ -2,11 +2,11 @@
2
 
3
  /**
4
  * Plugin Name: WP Staging
5
- * Plugin URI: https://wordpress.org/plugins/wp-staging
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();
2
 
3
  /**
4
  * Plugin Name: WP Staging
5
+ * Plugin URI: wordpress.org/plugins/wp-staging
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.1
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();