Version Description
- Fix: Cancel Cloning button not working
- Fix: Limit max execution time to a maximum of 30sec to prevent high memory consumption and script timeouts
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.0.6 |
Comparing to | |
See all releases |
Code changes from version 2.0.1 to 2.0.6
- CHANGELOG.md +0 -0
- CONTRIBUTING.md +0 -38
- LICENSE.txt → LICENSE +70 -10
- README.md +0 -32
- apps/Backend/Activation/Activation.php +61 -0
- apps/Backend/Activation/Welcome.php +44 -0
- apps/Backend/Administrator.php +624 -604
- apps/Backend/Modules/Jobs/Cloning.php +9 -3
- apps/Backend/Modules/Jobs/Data.php +1 -1
- apps/Backend/Modules/Jobs/Database.php +4 -0
- apps/Backend/Modules/Jobs/Delete.php +67 -38
- apps/Backend/Modules/Jobs/Delete_deprecated.php +397 -0
- apps/Backend/Modules/Jobs/Delete_new.php +382 -0
- apps/Backend/Modules/Jobs/Delete_old.php +4 -4
- apps/Backend/Modules/Jobs/Directories.php +155 -82
- apps/Backend/Modules/Jobs/Finish.php +3 -22
- apps/Backend/Modules/Jobs/Job.php +54 -13
- apps/Backend/Modules/Jobs/JobExecutable.php +1 -1
- apps/Backend/Modules/Jobs/Scan.php +49 -18
- apps/Backend/Modules/Optimizer.php +0 -141
- apps/Backend/Modules/Views/Forms/Settings.php +1 -2
- apps/Backend/Notices/Notices.php +62 -53
- apps/Backend/Optimizer/Optimizer.php +45 -0
- apps/Backend/Optimizer/wp-staging-optimizer.php +120 -0
- apps/Backend/Pluginmeta/Pluginmeta.php +69 -0
- apps/Backend/Upgrade/Upgrade.php +125 -37
- apps/Backend/public/css/wpstg-admin.css +100 -7
- apps/Backend/public/img/wpstaging-banner200x400-tryout.gif +0 -0
- apps/Backend/public/img/wpstaging-banner200x400.gif +0 -0
- apps/Backend/public/js/wpstg-admin.js +514 -450
- apps/Backend/views/_includes/header.php +1 -1
- apps/Backend/views/_includes/messages/beta.php +2 -2
- apps/Backend/views/_includes/messages/rating.php +2 -0
- apps/Backend/views/_includes/messages/wp-version-compatible-message.php +1 -1
- apps/Backend/views/clone/ajax/delete-confirmation.php +1 -1
- apps/Backend/views/clone/ajax/scan.php +10 -7
- apps/Backend/views/clone/ajax/start.php +1 -1
- apps/Backend/views/clone/index.php +1 -1
- apps/Backend/views/clone/single-site/index.php +2 -1
- apps/Backend/views/settings/index.php +2 -2
- apps/Backend/views/tools/index.php +1 -1
- apps/Backend/views/welcome/welcome.php +15 -0
- apps/Core/Cron/Cron.php +46 -0
- apps/Core/Utils/Cache.php +1 -1
- apps/Core/Utils/Logger.php +3 -1
- apps/Core/WPStaging.php +402 -386
- apps/Frontend/Frontend.php +0 -1
- readme.txt +235 -251
- uninstall.php +89 -39
- wp-staging.php +80 -56
CHANGELOG.md
DELETED
File without changes
|
CONTRIBUTING.md
DELETED
@@ -1,38 +0,0 @@
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LICENSE.txt → LICENSE
RENAMED
@@ -1,13 +1,12 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
-
51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
6 |
|
|
|
|
|
7 |
Everyone is permitted to copy and distribute verbatim copies
|
8 |
of this license document, but changing it is not allowed.
|
9 |
|
10 |
-
|
11 |
|
12 |
The licenses for most software are designed to take away your
|
13 |
freedom to share and change it. By contrast, the GNU General Public
|
@@ -16,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
|
16 |
General Public License applies to most of the Free Software
|
17 |
Foundation's software and to any other program whose authors commit to
|
18 |
using it. (Some other Free Software Foundation software is covered by
|
19 |
-
the GNU
|
20 |
your programs, too.
|
21 |
|
22 |
When we speak of free software, we are referring to freedom, not
|
@@ -57,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|
57 |
The precise terms and conditions for copying, distribution and
|
58 |
modification follow.
|
59 |
|
60 |
-
|
61 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
|
63 |
0. This License applies to any program or other work which contains
|
@@ -121,6 +120,7 @@ distribute the same sections as part of a whole which is a work based
|
|
121 |
on the Program, the distribution of the whole must be on the terms of
|
122 |
this License, whose permissions for other licensees extend to the
|
123 |
entire whole, and thus to each and every part regardless of who wrote it.
|
|
|
124 |
Thus, it is not the intent of this section to claim rights or contest
|
125 |
your rights to work written entirely by you; rather, the intent is to
|
126 |
exercise the right to control the distribution of derivative or
|
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
|
255 |
of preserving the free status of all derivatives of our free software and
|
256 |
of promoting the sharing and reuse of software generally.
|
257 |
|
258 |
-
|
259 |
|
260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
@@ -277,4 +277,64 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
POSSIBILITY OF SUCH DAMAGES.
|
279 |
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
|
|
|
|
|
|
3 |
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
Everyone is permitted to copy and distribute verbatim copies
|
7 |
of this license document, but changing it is not allowed.
|
8 |
|
9 |
+
Preamble
|
10 |
|
11 |
The licenses for most software are designed to take away your
|
12 |
freedom to share and change it. By contrast, the GNU General Public
|
15 |
General Public License applies to most of the Free Software
|
16 |
Foundation's software and to any other program whose authors commit to
|
17 |
using it. (Some other Free Software Foundation software is covered by
|
18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
19 |
your programs, too.
|
20 |
|
21 |
When we speak of free software, we are referring to freedom, not
|
56 |
The precise terms and conditions for copying, distribution and
|
57 |
modification follow.
|
58 |
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
|
62 |
0. This License applies to any program or other work which contains
|
120 |
on the Program, the distribution of the whole must be on the terms of
|
121 |
this License, whose permissions for other licensees extend to the
|
122 |
entire whole, and thus to each and every part regardless of who wrote it.
|
123 |
+
|
124 |
Thus, it is not the intent of this section to claim rights or contest
|
125 |
your rights to work written entirely by you; rather, the intent is to
|
126 |
exercise the right to control the distribution of derivative or
|
255 |
of preserving the free status of all derivatives of our free software and
|
256 |
of promoting the sharing and reuse of software generally.
|
257 |
|
258 |
+
NO WARRANTY
|
259 |
|
260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
POSSIBILITY OF SUCH DAMAGES.
|
279 |
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
282 |
+
How to Apply These Terms to Your New Programs
|
283 |
+
|
284 |
+
If you develop a new program, and you want it to be of the greatest
|
285 |
+
possible use to the public, the best way to achieve this is to make it
|
286 |
+
free software which everyone can redistribute and change under these terms.
|
287 |
+
|
288 |
+
To do so, attach the following notices to the program. It is safest
|
289 |
+
to attach them to the start of each source file to most effectively
|
290 |
+
convey the exclusion of warranty; and each file should have at least
|
291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
292 |
+
|
293 |
+
{description}
|
294 |
+
Copyright (C) {year} {fullname}
|
295 |
+
|
296 |
+
This program is free software; you can redistribute it and/or modify
|
297 |
+
it under the terms of the GNU General Public License as published by
|
298 |
+
the Free Software Foundation; either version 2 of the License, or
|
299 |
+
(at your option) any later version.
|
300 |
+
|
301 |
+
This program is distributed in the hope that it will be useful,
|
302 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
303 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
304 |
+
GNU General Public License for more details.
|
305 |
+
|
306 |
+
You should have received a copy of the GNU General Public License along
|
307 |
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
308 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
309 |
+
|
310 |
+
Also add information on how to contact you by electronic and paper mail.
|
311 |
+
|
312 |
+
If the program is interactive, make it output a short notice like this
|
313 |
+
when it starts in an interactive mode:
|
314 |
+
|
315 |
+
Gnomovision version 69, Copyright (C) year name of author
|
316 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
317 |
+
This is free software, and you are welcome to redistribute it
|
318 |
+
under certain conditions; type `show c' for details.
|
319 |
+
|
320 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
321 |
+
parts of the General Public License. Of course, the commands you use may
|
322 |
+
be called something other than `show w' and `show c'; they could even be
|
323 |
+
mouse-clicks or menu items--whatever suits your program.
|
324 |
+
|
325 |
+
You should also get your employer (if you work as a programmer) or your
|
326 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
327 |
+
necessary. Here is a sample; alter the names:
|
328 |
+
|
329 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
330 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
331 |
+
|
332 |
+
{signature of Ty Coon}, 1 April 1989
|
333 |
+
Ty Coon, President of Vice
|
334 |
+
|
335 |
+
This General Public License does not permit incorporating your program into
|
336 |
+
proprietary programs. If your program is a subroutine library, you may
|
337 |
+
consider it more useful to permit linking proprietary applications with the
|
338 |
+
library. If this is what you want to do, use the GNU Lesser General
|
339 |
+
Public License instead of this License.
|
340 |
+
|
README.md
DELETED
@@ -1,32 +0,0 @@
|
|
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
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
// Add the transient to redirect for class Welcome (not for multisites)
|
58 |
+
set_transient( 'wpstg_activation_redirect', true, 3600 );
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
apps/Backend/Activation/Welcome.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Backend\Activation;
|
4 |
+
|
5 |
+
// No Direct Access
|
6 |
+
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
class Welcome {
|
11 |
+
|
12 |
+
public function __construct() {
|
13 |
+
add_action( 'admin_init', array( $this, 'welcome' ) );
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Sends user to the welcome page on first activation of WPSTG as well as each
|
20 |
+
* time WPSTG is upgraded to a new version
|
21 |
+
*
|
22 |
+
* @access public
|
23 |
+
* @since 1.0.1
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
public function welcome() {
|
27 |
+
// Bail if no activation redirect
|
28 |
+
if ( false === get_transient( 'wpstg_activation_redirect' ) ){
|
29 |
+
return;
|
30 |
+
}
|
31 |
+
|
32 |
+
// Delete the redirect transient
|
33 |
+
delete_transient( 'wpstg_activation_redirect' );
|
34 |
+
|
35 |
+
// Bail if activating from network, or bulk
|
36 |
+
if ( is_network_admin() || isset( $_GET['activate-multi'] ) ){
|
37 |
+
return;
|
38 |
+
}
|
39 |
+
|
40 |
+
wp_safe_redirect( admin_url( 'admin.php?page=wpstg-welcome' ) ); exit;
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
}
|
apps/Backend/Administrator.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging\Backend;
|
3 |
|
4 |
// No Direct Access
|
5 |
-
if
|
6 |
-
|
7 |
-
die;
|
8 |
}
|
9 |
|
10 |
use WPStaging\Backend\Modules\Jobs\Cancel;
|
@@ -21,611 +21,631 @@ 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\WPStaging;
|
|
|
|
|
25 |
|
26 |
/**
|
27 |
* Class Administrator
|
28 |
* @package WPStaging\Backend
|
29 |
*/
|
30 |
-
class Administrator extends InjectionAware
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
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 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
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 |
+
$Welcome = new Activation\Welcome();
|
78 |
+
|
79 |
+
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
|
80 |
+
$loader->addAction( "admin_menu", $this, "addMenu", 10 );
|
81 |
+
$loader->addAction( "admin_init", $this, "setOptionFormElements" );
|
82 |
+
$loader->addAction( "admin_init", $this, "upgrade" );
|
83 |
+
$loader->addAction( "admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload" );
|
84 |
+
$loader->addAction( "admin_post_wpstg_export", $this, "export" );
|
85 |
+
$loader->addAction( "admin_post_wpstg_import_settings", $this, "import" );
|
86 |
+
$loader->addAction( "admin_notices", $this, "messages" );
|
87 |
+
|
88 |
+
// Settings
|
89 |
+
$settings = $this->di->get( "settings" );
|
90 |
+
|
91 |
+
// Optimizer is ON
|
92 |
+
if( $settings->isOptimizer() ) {
|
93 |
+
$optimizer = new Optimizer( $this->di );
|
94 |
+
|
95 |
+
$loader->addAction( "admin_init", $optimizer, "compatibility", 1 );
|
96 |
+
$loader->addFilter( "option_active_plugins", $optimizer, "excludedPlugins" );
|
97 |
+
$loader->addFilter( "site_option_active_sitewide_plugins", $optimizer, "excludedPlugins" );
|
98 |
+
}
|
99 |
+
|
100 |
+
// Ajax Requests
|
101 |
+
$loader->addAction( "wp_ajax_wpstg_overview", $this, "ajaxOverview" );
|
102 |
+
$loader->addAction( "wp_ajax_wpstg_scanning", $this, "ajaxScan" );
|
103 |
+
$loader->addAction( "wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName" );
|
104 |
+
$loader->addAction( "wp_ajax_wpstg_cloning", $this, "ajaxStartClone" );
|
105 |
+
$loader->addAction( "wp_ajax_wpstg_clone_database", $this, "ajaxCloneDatabase" );
|
106 |
+
$loader->addAction( "wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories" );
|
107 |
+
$loader->addAction( "wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles" );
|
108 |
+
$loader->addAction( "wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData" );
|
109 |
+
$loader->addAction( "wp_ajax_wpstg_clone_finish", $this, "ajaxFinish" );
|
110 |
+
$loader->addAction( "wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation" );
|
111 |
+
$loader->addAction( "wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone" );
|
112 |
+
$loader->addAction( "wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone" );
|
113 |
+
$loader->addAction( "wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll" );
|
114 |
+
$loader->addAction( "wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating" );
|
115 |
+
$loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
|
116 |
+
$loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
|
117 |
+
$loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
|
118 |
+
|
119 |
+
// Ajax hooks pro Version
|
120 |
+
$loader->addAction( "wp_ajax_wpstg_start_processing", $this, "ajaxProcessing" );
|
121 |
+
$loader->addAction( "wp_ajax_wpstg_push_changes", $this, "ajaxPushChanges" );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Register options form elements
|
126 |
+
*/
|
127 |
+
public function setOptionFormElements() {
|
128 |
+
register_setting( "wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions") );
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Upgrade routine
|
133 |
+
*/
|
134 |
+
public function upgrade() {
|
135 |
+
$upgrade = new Upgrade\Upgrade();
|
136 |
+
$upgrade->doUpgrade();
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Sanitize options data and delete the cache
|
141 |
+
* @param array $data
|
142 |
+
* @return array
|
143 |
+
*/
|
144 |
+
public function sanitizeOptions( $data = array() ) {
|
145 |
+
$sanitized = $this->sanitizeData( $data );
|
146 |
+
|
147 |
+
add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wpstg" ), "updated" );
|
148 |
+
|
149 |
+
// Return sanitized data
|
150 |
+
//return $sanitized;
|
151 |
+
return apply_filters( "wpstg-settings", $sanitized, $data );
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* @param array $data
|
156 |
+
* @return array
|
157 |
+
*/
|
158 |
+
private function sanitizeData( $data = array() ) {
|
159 |
+
$sanitized = array();
|
160 |
+
|
161 |
+
foreach ( $data as $key => $value ) {
|
162 |
+
$sanitized[$key] = (is_array( $value )) ? $this->sanitizeData( $value ) : htmlspecialchars( $value );
|
163 |
+
}
|
164 |
+
|
165 |
+
return $sanitized;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Add Admin Menu(s)
|
170 |
+
*/
|
171 |
+
public function addMenu() {
|
172 |
+
|
173 |
+
$logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
|
174 |
+
|
175 |
+
// Main WP Staging Menu
|
176 |
+
add_menu_page(
|
177 |
+
"WP-Staging", __( "WP Staging", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
|
178 |
+
);
|
179 |
+
|
180 |
+
// Page: Clone
|
181 |
+
add_submenu_page(
|
182 |
+
"wpstg_clone", __( "WP Staging Jobs", "wpstg" ), __( "Start", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
|
183 |
+
);
|
184 |
+
|
185 |
+
// Page: Settings
|
186 |
+
add_submenu_page(
|
187 |
+
"wpstg_clone", __( "WP Staging Settings", "wpstg" ), __( "Settings", "wpstg" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
|
188 |
+
);
|
189 |
+
|
190 |
+
// Page: Tools
|
191 |
+
add_submenu_page(
|
192 |
+
"wpstg_clone", __( "WP Staging Tools", "wpstg" ), __( "Tools", "wpstg" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
|
193 |
+
);
|
194 |
+
// Page: Tools
|
195 |
+
add_submenu_page(
|
196 |
+
"wpstg_clone", __( "WP Staging Welcome", "wpstg" ), __( "Get WP Staging Pro", "wpstg" ), "manage_options", "wpstg-welcome", array($this, "getWelcomePage")
|
197 |
+
);
|
198 |
+
|
199 |
+
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
|
200 |
+
// Page: License
|
201 |
+
add_submenu_page(
|
202 |
+
"wpstg_clone", __( "WP Staging License", "wpstg" ), __( "License", "wpstg" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
|
203 |
+
);
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Settings Page
|
209 |
+
*/
|
210 |
+
public function getSettingsPage() {
|
211 |
+
// Tabs
|
212 |
+
$tabs = new Tabs( array(
|
213 |
+
"general" => __( "General", "wpstg" )
|
214 |
+
) );
|
215 |
+
|
216 |
+
|
217 |
+
$this->di
|
218 |
+
// Set tabs
|
219 |
+
->set( "tabs", $tabs )
|
220 |
+
// Forms
|
221 |
+
->set( "forms", new FormSettings( $tabs ) );
|
222 |
+
|
223 |
+
require_once "{$this->path}views/settings/index.php";
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Clone Page
|
228 |
+
*/
|
229 |
+
public function getClonePage() {
|
230 |
+
// Existing clones
|
231 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
232 |
+
|
233 |
+
require_once "{$this->path}views/clone/index.php";
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Welcome Page
|
238 |
+
*/
|
239 |
+
public function getWelcomePage() {
|
240 |
+
require_once "{$this->path}views/welcome/welcome.php";
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Tools Page
|
245 |
+
*/
|
246 |
+
public function getToolsPage() {
|
247 |
+
// Tabs
|
248 |
+
$tabs = new Tabs( array(
|
249 |
+
"import_export" => __( "Import/Export", "wpstg" ),
|
250 |
+
"system_info" => __( "System Info", "wpstg" )
|
251 |
+
) );
|
252 |
+
|
253 |
+
$this->di->set( "tabs", $tabs );
|
254 |
+
|
255 |
+
$this->di->set( "systemInfo", new SystemInfo( $this->di ) );
|
256 |
+
|
257 |
+
require_once "{$this->path}views/tools/index.php";
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* System Information Download
|
262 |
+
*/
|
263 |
+
public function systemInfoDownload() {
|
264 |
+
if( !current_user_can( "update_plugins" ) ) {
|
265 |
+
return;
|
266 |
+
}
|
267 |
+
|
268 |
+
nocache_headers();
|
269 |
+
header( "Content-Type: text/plain" );
|
270 |
+
header( "Content-Disposition: attachment; filename='wpstg-system-info.txt'" );
|
271 |
+
echo wp_strip_all_tags( new SystemInfo( $this->di ) );
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Import JSON settings file
|
276 |
+
*/
|
277 |
+
public function import() {
|
278 |
+
if( empty( $_POST["wpstg_import_nonce"] ) ) {
|
279 |
+
return;
|
280 |
+
}
|
281 |
+
|
282 |
+
if( !wp_verify_nonce( $_POST["wpstg_import_nonce"], "wpstg_import_nonce" ) ) {
|
283 |
+
return;
|
284 |
+
}
|
285 |
+
|
286 |
+
if( !current_user_can( "update_plugins" ) ) {
|
287 |
+
return;
|
288 |
+
}
|
289 |
+
|
290 |
+
$fileExtension = explode( '.', $_FILES["import_file"]["name"] );
|
291 |
+
$fileExtension = end( $fileExtension );
|
292 |
+
if( "json" !== $fileExtension ) {
|
293 |
+
wp_die( "Please upload a valid .json file", "wpstg" );
|
294 |
+
}
|
295 |
+
|
296 |
+
|
297 |
+
$importFile = $_FILES["import_file"]["tmp_name"];
|
298 |
+
|
299 |
+
if( empty( $importFile ) ) {
|
300 |
+
wp_die( __( "Please upload a file to import", "wpstg" ) );
|
301 |
+
}
|
302 |
+
|
303 |
+
update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
|
304 |
+
|
305 |
+
wp_safe_redirect( admin_url( "admin.php?page=wpstg-tools&wpstg-message=settings-imported" ) );
|
306 |
+
|
307 |
+
return;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Export settings to JSON file
|
312 |
+
*/
|
313 |
+
public function export() {
|
314 |
+
if( empty( $_POST["wpstg_export_nonce"] ) ) {
|
315 |
+
return;
|
316 |
+
}
|
317 |
+
|
318 |
+
if( !wp_verify_nonce( $_POST["wpstg_export_nonce"], "wpstg_export_nonce" ) ) {
|
319 |
+
return;
|
320 |
+
}
|
321 |
+
|
322 |
+
if( !current_user_can( "manage_options" ) ) {
|
323 |
+
return;
|
324 |
+
}
|
325 |
+
|
326 |
+
$settings = get_option( "wpstg_settings", array() );
|
327 |
+
|
328 |
+
ignore_user_abort( true );
|
329 |
+
|
330 |
+
if( !in_array( "set_time_limit", explode( ',', ini_get( "disable_functions" ) ) ) && !@ini_get( "safe_mode" ) ) {
|
331 |
+
set_time_limit( 0 );
|
332 |
+
}
|
333 |
+
|
334 |
+
$fileName = apply_filters( "wpstg_settings_export_filename", "wpstg-settings-export-" . date( "m-d-Y" ) ) . ".json";
|
335 |
+
|
336 |
+
nocache_headers();
|
337 |
+
header( "Content-Type: application/json; charset=utf-8" );
|
338 |
+
header( "Content-Disposition: attachment; filename={$fileName}" );
|
339 |
+
header( "Expires: 0" );
|
340 |
+
|
341 |
+
echo json_encode( $settings );
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Render a view file
|
346 |
+
* @param string $file
|
347 |
+
* @param array $vars
|
348 |
+
* @return string
|
349 |
+
*/
|
350 |
+
public function render( $file, $vars = array() ) {
|
351 |
+
$fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
|
352 |
+
$fullPath = str_replace( array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php" );
|
353 |
+
|
354 |
+
if( !file_exists( $fullPath ) || !is_readable( $fullPath ) ) {
|
355 |
+
return "Can't render : {$fullPath} either file doesn't exist or can't read it";
|
356 |
+
}
|
357 |
+
|
358 |
+
$contents = @file_get_contents( $fullPath );
|
359 |
+
|
360 |
+
// Variables are set
|
361 |
+
if( count( $vars ) > 0 ) {
|
362 |
+
$vars = array_combine(
|
363 |
+
array_map( function ($key) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
364 |
return "{{" . $key . "}}";
|
365 |
+
}, array_keys( $vars )
|
366 |
+
), $vars
|
367 |
+
);
|
368 |
+
|
369 |
+
$contents = str_replace( array_keys( $vars ), array_values( $vars ), $contents );
|
370 |
+
}
|
371 |
+
|
372 |
+
return $contents;
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Ajax Overview
|
377 |
+
*/
|
378 |
+
public function ajaxOverview() {
|
379 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
380 |
+
|
381 |
+
// Existing clones
|
382 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
383 |
+
|
384 |
+
// Get license data
|
385 |
+
$license = get_option( 'wpstg_license_status' );
|
386 |
+
|
387 |
+
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
|
388 |
+
require_once "{$this->path}Pro/views/single-overview-pro.php";
|
389 |
+
} else {
|
390 |
+
require_once "{$this->path}views/clone/ajax/single-overview.php";
|
391 |
+
}
|
392 |
+
|
393 |
+
wp_die();
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Ajax Scan
|
398 |
+
*/
|
399 |
+
public function ajaxScan() {
|
400 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
401 |
+
|
402 |
+
// Scan
|
403 |
+
$scan = new Scan();
|
404 |
+
$scan->start();
|
405 |
+
|
406 |
+
// Get Options
|
407 |
+
$options = $scan->getOptions();
|
408 |
+
|
409 |
+
require_once "{$this->path}views/clone/ajax/scan.php";
|
410 |
+
|
411 |
+
wp_die();
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Ajax Check Clone Name
|
416 |
+
*/
|
417 |
+
public function ajaxCheckCloneName() {
|
418 |
+
$cloneName = sanitize_key( $_POST["cloneID"] );
|
419 |
+
$cloneNameLength = strlen( $cloneName );
|
420 |
+
$clones = get_option( "wpstg_existing_clones_beta", array() );
|
421 |
+
|
422 |
+
// Check clone name length
|
423 |
+
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
|
424 |
+
echo wp_send_json( array(
|
425 |
+
"status" => "failed",
|
426 |
+
"message" => "Clone name must be between 1 - 16 characters"
|
427 |
+
) );
|
428 |
+
} elseif( array_key_exists( $cloneName, $clones ) ) {
|
429 |
+
echo wp_send_json( array(
|
430 |
+
"status" => "failed",
|
431 |
+
"message" => "Clone name is already in use, please choose an another clone name"
|
432 |
+
) );
|
433 |
+
}
|
434 |
+
|
435 |
+
echo wp_send_json( array("status" => "success") );
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Ajax Start Clone (Basically just layout and saving data)
|
440 |
+
*/
|
441 |
+
public function ajaxStartClone() {
|
442 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
443 |
+
|
444 |
+
$cloning = new Cloning();
|
445 |
+
|
446 |
+
if( !$cloning->save() ) {
|
447 |
+
wp_die();
|
448 |
+
}
|
449 |
+
|
450 |
+
require_once "{$this->path}views/clone/ajax/start.php";
|
451 |
+
|
452 |
+
wp_die();
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Ajax Clone Database
|
457 |
+
*/
|
458 |
+
public function ajaxCloneDatabase() {
|
459 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
460 |
+
|
461 |
+
$cloning = new Cloning();
|
462 |
+
|
463 |
+
wp_send_json( $cloning->start() );
|
464 |
+
}
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Ajax Prepare Directories (get listing of files)
|
468 |
+
*/
|
469 |
+
public function ajaxPrepareDirectories() {
|
470 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
471 |
+
|
472 |
+
$cloning = new Cloning();
|
473 |
+
|
474 |
+
wp_send_json( $cloning->start() );
|
475 |
+
}
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Ajax Clone Files
|
479 |
+
*/
|
480 |
+
public function ajaxCopyFiles() {
|
481 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
482 |
+
|
483 |
+
$cloning = new Cloning();
|
484 |
+
|
485 |
+
wp_send_json( $cloning->start() );
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Ajax Replace Data
|
490 |
+
*/
|
491 |
+
public function ajaxReplaceData() {
|
492 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
493 |
+
|
494 |
+
$cloning = new Cloning();
|
495 |
+
|
496 |
+
wp_send_json( $cloning->start() );
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Ajax Finish
|
501 |
+
*/
|
502 |
+
public function ajaxFinish() {
|
503 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
504 |
+
|
505 |
+
$cloning = new Cloning();
|
506 |
+
|
507 |
+
wp_send_json( $cloning->start() );
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Ajax Delete Confirmation
|
512 |
+
*/
|
513 |
+
public function ajaxDeleteConfirmation() {
|
514 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
515 |
+
|
516 |
+
$delete = new Delete();
|
517 |
+
$delete->setData();
|
518 |
+
|
519 |
+
$clone = $delete->getClone();
|
520 |
+
|
521 |
+
require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
|
522 |
+
|
523 |
+
wp_die();
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Delete clone
|
528 |
+
*/
|
529 |
+
public function ajaxDeleteClone() {
|
530 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
531 |
+
|
532 |
+
$delete = new Delete();
|
533 |
+
wp_send_json( $delete->start() );
|
534 |
+
}
|
535 |
+
|
536 |
+
/**
|
537 |
+
* Delete clone
|
538 |
+
*/
|
539 |
+
public function ajaxCancelClone() {
|
540 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
541 |
+
|
542 |
+
$cancel = new Cancel();
|
543 |
+
wp_send_json( $cancel->start() );
|
544 |
+
}
|
545 |
+
|
546 |
+
/**
|
547 |
+
* Admin Messages
|
548 |
+
*/
|
549 |
+
public function messages() {
|
550 |
+
$notice = new Notices( $this->path, $this->url );
|
551 |
+
|
552 |
+
$run = $notice->messages();
|
553 |
+
}
|
554 |
+
|
555 |
+
/**
|
556 |
+
* Ajax Hide Poll
|
557 |
+
* @return mixed boolean | json
|
558 |
+
*/
|
559 |
+
public function ajaxHidePoll() {
|
560 |
+
if( false !== update_option( "wpstg_poll", "no" ) ) {
|
561 |
+
wp_send_json( true );
|
562 |
+
}
|
563 |
+
return wp_send_json();
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Ajax Hide Rating
|
568 |
+
* @return mixed bool | json
|
569 |
+
*/
|
570 |
+
public function ajaxHideRating() {
|
571 |
+
if( false !== update_option( "wpstg_rating", "no" ) ) {
|
572 |
+
wp_send_json( true );
|
573 |
+
}
|
574 |
+
return wp_send_json();
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Ajax Hide Beta
|
579 |
+
*/
|
580 |
+
public function ajaxHideBeta() {
|
581 |
+
wp_send_json( update_option( "wpstg_beta", "no" ) );
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Clone logs
|
586 |
+
*/
|
587 |
+
public function ajaxLogs() {
|
588 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
589 |
+
|
590 |
+
$logs = new Logs();
|
591 |
+
wp_send_json( $logs->start() );
|
592 |
+
}
|
593 |
+
|
594 |
+
/**
|
595 |
+
* Ajax Checks Free Disk Space
|
596 |
+
*/
|
597 |
+
public function ajaxCheckFreeSpace() {
|
598 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
599 |
+
|
600 |
+
$scan = new Scan();
|
601 |
+
return $scan->hasFreeDiskSpace();
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Ajax Start Push Changes Process
|
606 |
+
*/
|
607 |
+
public function ajaxProcessing() {
|
608 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
609 |
+
|
610 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
|
611 |
+
return false;
|
612 |
+
}
|
613 |
+
|
614 |
+
// Scan
|
615 |
+
$scan = new Pro\Modules\Jobs\Scan();
|
616 |
+
$scan->start();
|
617 |
+
|
618 |
+
// Get Options
|
619 |
+
$options = $scan->getOptions();
|
620 |
+
|
621 |
+
require_once "{$this->path}Pro/views/scan.php";
|
622 |
+
|
623 |
+
wp_die();
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Ajax Start Pushing. Needs wp quads pro)
|
628 |
+
*/
|
629 |
+
public function ajaxPushChanges() {
|
630 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
631 |
+
|
632 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Processing' ) ) {
|
633 |
+
return false;
|
634 |
+
}
|
635 |
+
// Start the process
|
636 |
+
$processing = new Processing();
|
637 |
+
wp_send_json( $processing->start() );
|
638 |
+
}
|
639 |
+
|
640 |
+
/**
|
641 |
+
* License Page
|
642 |
+
*/
|
643 |
+
public function getLicensePage() {
|
644 |
+
|
645 |
+
// Get license data
|
646 |
+
$license = get_option( 'wpstg_license_status' );
|
647 |
+
|
648 |
+
require_once "{$this->path}Pro/views/licensing.php";
|
649 |
+
}
|
650 |
+
|
651 |
+
}
|
apps/Backend/Modules/Jobs/Cloning.php
CHANGED
@@ -3,6 +3,10 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
3 |
|
4 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
5 |
|
|
|
|
|
|
|
|
|
6 |
/**
|
7 |
* Class Cloning
|
8 |
* @package WPStaging\Backend\Modules\Jobs
|
@@ -59,8 +63,8 @@ class Cloning extends Job
|
|
59 |
}
|
60 |
|
61 |
// Extra Directories
|
62 |
-
if (isset($_POST["extraDirectories"]) &&
|
63 |
-
{
|
64 |
$this->options->extraDirectories = $_POST["extraDirectories"];
|
65 |
}
|
66 |
|
@@ -71,7 +75,9 @@ class Cloning extends Job
|
|
71 |
);
|
72 |
|
73 |
array_unshift($this->options->directoriesToCopy, ABSPATH);
|
74 |
-
|
|
|
|
|
75 |
// Delete files to copy listing
|
76 |
$this->cache->delete("files_to_copy");
|
77 |
|
3 |
|
4 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
5 |
|
6 |
+
//ini_set('display_startup_errors', 1);
|
7 |
+
//ini_set('display_errors', 1);
|
8 |
+
//error_reporting(-1);
|
9 |
+
|
10 |
/**
|
11 |
* Class Cloning
|
12 |
* @package WPStaging\Backend\Modules\Jobs
|
63 |
}
|
64 |
|
65 |
// Extra Directories
|
66 |
+
if (isset($_POST["extraDirectories"]) && !empty($_POST["extraDirectories"]) )
|
67 |
+
{
|
68 |
$this->options->extraDirectories = $_POST["extraDirectories"];
|
69 |
}
|
70 |
|
75 |
);
|
76 |
|
77 |
array_unshift($this->options->directoriesToCopy, ABSPATH);
|
78 |
+
|
79 |
+
//var_dump($this->options->directoriesToCopy);
|
80 |
+
|
81 |
// Delete files to copy listing
|
82 |
$this->cache->delete("files_to_copy");
|
83 |
|
apps/Backend/Modules/Jobs/Data.php
CHANGED
@@ -164,7 +164,7 @@ class Data extends JobExecutable
|
|
164 |
*/
|
165 |
protected function step1()
|
166 |
{
|
167 |
-
$this->log( "Updating siteurl and homeurl in {$this->prefix}options {$this->db->last_error}", Logger::
|
168 |
|
169 |
$result = $this->db->query(
|
170 |
$this->db->prepare(
|
164 |
*/
|
165 |
protected function step1()
|
166 |
{
|
167 |
+
$this->log( "Updating siteurl and homeurl in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_INFO );
|
168 |
|
169 |
$result = $this->db->query(
|
170 |
$this->db->prepare(
|
apps/Backend/Modules/Jobs/Database.php
CHANGED
@@ -1,6 +1,10 @@
|
|
1 |
<?php
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
|
|
|
|
|
|
|
|
4 |
// No Direct Access
|
5 |
if (!defined("WPINC"))
|
6 |
{
|
1 |
<?php
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
4 |
+
//ini_set('display_startup_errors', 1);
|
5 |
+
//ini_set('display_errors', 1);
|
6 |
+
//error_reporting(-1);
|
7 |
+
|
8 |
// No Direct Access
|
9 |
if (!defined("WPINC"))
|
10 |
{
|
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,24 +70,16 @@ class Delete extends Job
|
|
70 |
$name = $_POST["clone"];
|
71 |
}
|
72 |
|
73 |
-
$clones = get_option("
|
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,10 +93,6 @@ class Delete extends Job
|
|
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,8 +107,8 @@ class Delete extends Job
|
|
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,6 +130,7 @@ class Delete extends Job
|
|
142 |
return round($pow, $precision) . ' ' . $units[(int) floor($base)];
|
143 |
}
|
144 |
|
|
|
145 |
/**
|
146 |
* @return false
|
147 |
*/
|
@@ -178,25 +167,27 @@ class Delete extends Job
|
|
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 |
-
|
191 |
-
|
192 |
-
|
193 |
-
"nextDirectoryToDelete" => $this->clone->path
|
194 |
-
);
|
195 |
|
196 |
-
|
197 |
-
|
|
|
|
|
|
|
|
|
198 |
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
200 |
* @return bool
|
201 |
*/
|
202 |
private function updateJob()
|
@@ -269,8 +260,43 @@ class Delete extends Job
|
|
269 |
$length = strlen($needle);
|
270 |
return (substr($haystack, 0, $length) === $needle);
|
271 |
}
|
272 |
-
|
273 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
* Delete Directories
|
275 |
*/
|
276 |
public function deleteDirectory()
|
@@ -294,8 +320,9 @@ class Delete extends Job
|
|
294 |
public function isDirectoryDeletingFinished()
|
295 |
{
|
296 |
return (
|
|
|
297 |
(false === $this->forceDeleteDirectories && (!isset($_POST["deleteDir"]) || '1' !== $_POST["deleteDir"])) ||
|
298 |
-
|
299 |
);
|
300 |
}
|
301 |
|
@@ -370,7 +397,7 @@ class Delete extends Job
|
|
370 |
*/
|
371 |
public function deleteFinish()
|
372 |
{
|
373 |
-
$existingClones = get_option("
|
374 |
|
375 |
// Check if clones still exist
|
376 |
$this->log("Verifying existing clones...");
|
@@ -383,7 +410,7 @@ class Delete extends Job
|
|
383 |
}
|
384 |
$this->log("Existing clones verified!");
|
385 |
|
386 |
-
if (false === update_option("
|
387 |
{
|
388 |
$this->log("Failed to save {$this->options->clone}'s clone job data to database'");
|
389 |
}
|
@@ -392,6 +419,8 @@ class Delete extends Job
|
|
392 |
$this->cache->delete("delete_job_{$this->clone->name}");
|
393 |
$this->cache->delete("delete_directories_{$this->clone->name}");
|
394 |
|
395 |
-
return true;
|
|
|
|
|
396 |
}
|
397 |
}
|
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_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 |
{
|
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 |
|
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 |
return round($pow, $precision) . ' ' . $units[(int) floor($base)];
|
131 |
}
|
132 |
|
133 |
+
|
134 |
/**
|
135 |
* @return false
|
136 |
*/
|
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 |
$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()
|
320 |
public function isDirectoryDeletingFinished()
|
321 |
{
|
322 |
return (
|
323 |
+
!is_dir($this->clone->path) ||
|
324 |
(false === $this->forceDeleteDirectories && (!isset($_POST["deleteDir"]) || '1' !== $_POST["deleteDir"])) ||
|
325 |
+
ABSPATH === $this->job->nextDirectoryToDelete
|
326 |
);
|
327 |
}
|
328 |
|
397 |
*/
|
398 |
public function deleteFinish()
|
399 |
{
|
400 |
+
$existingClones = get_option("wpstg_existing_clones_beta", array());
|
401 |
|
402 |
// Check if clones still exist
|
403 |
$this->log("Verifying existing clones...");
|
410 |
}
|
411 |
$this->log("Existing clones verified!");
|
412 |
|
413 |
+
if (false === update_option("wpstg_existing_clones_beta", $existingClones))
|
414 |
{
|
415 |
$this->log("Failed to save {$this->options->clone}'s clone job data to database'");
|
416 |
}
|
419 |
$this->cache->delete("delete_job_{$this->clone->name}");
|
420 |
$this->cache->delete("delete_directories_{$this->clone->name}");
|
421 |
|
422 |
+
//return true;
|
423 |
+
$response = array('delete' => 'finished');
|
424 |
+
wp_die(json_encode($response));
|
425 |
}
|
426 |
}
|
apps/Backend/Modules/Jobs/Delete_deprecated.php
ADDED
@@ -0,0 +1,397 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
14 |
{
|
15 |
|
16 |
/**
|
@@ -70,7 +70,7 @@ class Delete extends Job
|
|
70 |
$name = $_POST["clone"];
|
71 |
}
|
72 |
|
73 |
-
$clones = get_option("
|
74 |
|
75 |
if (empty($clones) || !isset($clones[$name]))
|
76 |
{
|
@@ -340,7 +340,7 @@ class Delete extends Job
|
|
340 |
*/
|
341 |
public function deleteFinish()
|
342 |
{
|
343 |
-
$existingClones = get_option("
|
344 |
|
345 |
// Check if clones still exist
|
346 |
$this->log("Verifying existing clones...");
|
@@ -353,7 +353,7 @@ class Delete extends Job
|
|
353 |
}
|
354 |
$this->log("Existing clones verified!");
|
355 |
|
356 |
-
if (false === update_option("
|
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_old extends Job
|
14 |
{
|
15 |
|
16 |
/**
|
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 |
*/
|
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 |
}
|
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 |
}
|
apps/Backend/Modules/Jobs/Directories.php
CHANGED
@@ -1,9 +1,13 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
|
|
|
|
|
|
|
|
4 |
// No Direct Access
|
5 |
-
if
|
6 |
-
{
|
7 |
die;
|
8 |
}
|
9 |
|
@@ -13,8 +17,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,9 +32,8 @@ class Directories extends JobExecutable
|
|
28 |
/**
|
29 |
* Initialize
|
30 |
*/
|
31 |
-
public function initialize()
|
32 |
-
|
33 |
-
$this->total = count($this->options->directoriesToCopy);
|
34 |
$this->getFiles();
|
35 |
}
|
36 |
|
@@ -38,30 +41,26 @@ class Directories extends JobExecutable
|
|
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,7 +70,7 @@ class Directories extends JobExecutable
|
|
71 |
// Save option, progress
|
72 |
$this->saveProgress();
|
73 |
|
74 |
-
return (object) $this->response;
|
75 |
}
|
76 |
|
77 |
/**
|
@@ -79,12 +78,10 @@ class Directories extends JobExecutable
|
|
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
|
86 |
-
|
87 |
-
$this->prepareResponse(true, false);
|
88 |
return false;
|
89 |
}
|
90 |
|
@@ -92,9 +89,8 @@ class Directories extends JobExecutable
|
|
92 |
$directory = $this->options->directoriesToCopy[$this->options->currentStep];
|
93 |
|
94 |
// Get files recursively
|
95 |
-
if
|
96 |
-
|
97 |
-
$this->prepareResponse(false, false);
|
98 |
return false;
|
99 |
}
|
100 |
|
@@ -112,57 +108,52 @@ class Directories extends JobExecutable
|
|
112 |
* Checks Whether There is Any Job to Execute or Not
|
113 |
* @return bool
|
114 |
*/
|
115 |
-
private function isFinished()
|
116 |
-
{
|
117 |
return (
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
* @param $path
|
126 |
* @return bool
|
127 |
*/
|
128 |
-
protected function getFilesFromSubDirectories($path)
|
129 |
-
{
|
130 |
$this->totalRecursion++;
|
131 |
|
132 |
-
if
|
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
|
147 |
-
{
|
148 |
continue;
|
149 |
}
|
150 |
|
151 |
// Excluded directory
|
152 |
-
if
|
153 |
-
{
|
154 |
continue;
|
155 |
}
|
156 |
|
157 |
// This directory is already scanned
|
158 |
-
if
|
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,32 +169,35 @@ class Directories extends JobExecutable
|
|
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
|
193 |
-
{
|
194 |
$this->options->directoriesToCopy[] = $fullPath;
|
195 |
-
|
|
|
196 |
//continue;
|
197 |
}
|
198 |
|
199 |
-
if
|
200 |
-
{
|
201 |
continue;
|
202 |
}
|
203 |
|
204 |
$this->options->totalFiles++;
|
205 |
|
206 |
$this->files[] = $fullPath;
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
}
|
209 |
|
@@ -212,13 +206,21 @@ class Directories extends JobExecutable
|
|
212 |
* @param \SplFileInfo $directory
|
213 |
* @return string|false
|
214 |
*/
|
215 |
-
protected function getPath($directory)
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
// Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
|
220 |
-
if
|
221 |
-
{
|
222 |
return false;
|
223 |
}
|
224 |
|
@@ -226,15 +228,13 @@ class Directories extends JobExecutable
|
|
226 |
}
|
227 |
|
228 |
/**
|
|
|
229 |
* @param string $directory
|
230 |
* @return bool
|
231 |
*/
|
232 |
-
protected function isDirectoryExcluded($directory)
|
233 |
-
|
234 |
-
|
235 |
-
{
|
236 |
-
if (strpos($directory, $excludedDirectory) === 0)
|
237 |
-
{
|
238 |
return true;
|
239 |
}
|
240 |
}
|
@@ -242,39 +242,112 @@ class Directories extends JobExecutable
|
|
242 |
return false;
|
243 |
}
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
/**
|
246 |
* Save files
|
247 |
* @return bool
|
248 |
*/
|
249 |
-
protected function saveProgress()
|
250 |
-
{
|
251 |
$this->saveOptions();
|
252 |
|
253 |
-
$fileName
|
254 |
-
$files
|
255 |
|
256 |
-
if
|
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
|
273 |
-
{
|
274 |
$this->files = array();
|
275 |
return;
|
276 |
}
|
277 |
|
278 |
-
$this->files = explode(PHP_EOL, $this->files);
|
279 |
}
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
|
3 |
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
|
5 |
+
//ini_set('display_startup_errors', 1);
|
6 |
+
//ini_set('display_errors', 1);
|
7 |
+
//error_reporting(-1);
|
8 |
+
|
9 |
// No Direct Access
|
10 |
+
if( !defined( "WPINC" ) ) {
|
|
|
11 |
die;
|
12 |
}
|
13 |
|
17 |
* Class Files
|
18 |
* @package WPStaging\Backend\Modules\Directories
|
19 |
*/
|
20 |
+
class Directories extends JobExecutable {
|
21 |
+
|
22 |
/**
|
23 |
* @var array
|
24 |
*/
|
32 |
/**
|
33 |
* Initialize
|
34 |
*/
|
35 |
+
public function initialize() {
|
36 |
+
$this->total = count( $this->options->directoriesToCopy );
|
|
|
37 |
$this->getFiles();
|
38 |
}
|
39 |
|
41 |
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
42 |
* @return void
|
43 |
*/
|
44 |
+
protected function calculateTotalSteps() {
|
|
|
45 |
$this->options->totalSteps = $this->total;
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* Get Root Files
|
50 |
*/
|
51 |
+
protected function getRootFiles() {
|
52 |
+
if( 1 < $this->options->totalFiles ) {
|
|
|
|
|
53 |
return;
|
54 |
}
|
55 |
|
56 |
+
$this->getFilesFromDirectory( ABSPATH );
|
57 |
}
|
58 |
|
59 |
/**
|
60 |
* Start Module
|
61 |
* @return object
|
62 |
*/
|
63 |
+
public function start() {
|
|
|
64 |
// Root files
|
65 |
$this->getRootFiles();
|
66 |
|
70 |
// Save option, progress
|
71 |
$this->saveProgress();
|
72 |
|
73 |
+
return ( object ) $this->response;
|
74 |
}
|
75 |
|
76 |
/**
|
78 |
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
79 |
* @return bool
|
80 |
*/
|
81 |
+
protected function execute() {
|
|
|
82 |
// No job left to execute
|
83 |
+
if( $this->isFinished() ) {
|
84 |
+
$this->prepareResponse( true, false );
|
|
|
85 |
return false;
|
86 |
}
|
87 |
|
89 |
$directory = $this->options->directoriesToCopy[$this->options->currentStep];
|
90 |
|
91 |
// Get files recursively
|
92 |
+
if( !$this->getFilesFromSubDirectories( $directory ) ) {
|
93 |
+
$this->prepareResponse( false, false );
|
|
|
94 |
return false;
|
95 |
}
|
96 |
|
108 |
* Checks Whether There is Any Job to Execute or Not
|
109 |
* @return bool
|
110 |
*/
|
111 |
+
private function isFinished() {
|
|
|
112 |
return (
|
113 |
+
$this->options->currentStep > $this->total ||
|
114 |
+
empty( $this->options->directoriesToCopy ) ||
|
115 |
+
!isset( $this->options->directoriesToCopy[$this->options->currentStep] )
|
116 |
+
);
|
117 |
}
|
118 |
|
119 |
/**
|
120 |
* @param $path
|
121 |
* @return bool
|
122 |
*/
|
123 |
+
protected function getFilesFromSubDirectories( $path ) {
|
|
|
124 |
$this->totalRecursion++;
|
125 |
|
126 |
+
if( $this->isOverThreshold() ) {
|
|
|
127 |
//$this->saveProgress();
|
128 |
|
129 |
return false;
|
130 |
}
|
131 |
|
132 |
+
$this->log( "Scanning {$path} for its sub-directories and files" );
|
133 |
|
134 |
+
$directories = new \DirectoryIterator( $path );
|
135 |
|
136 |
+
foreach ( $directories as $directory ) {
|
137 |
+
|
138 |
+
|
139 |
// Not a valid directory
|
140 |
+
if( false === ($path = $this->getPath( $directory )) ) {
|
|
|
141 |
continue;
|
142 |
}
|
143 |
|
144 |
// Excluded directory
|
145 |
+
if( $this->isDirectoryExcluded( $directory->getRealPath() ) ) {
|
|
|
146 |
continue;
|
147 |
}
|
148 |
|
149 |
// This directory is already scanned
|
150 |
+
if( in_array( $path, $this->options->scannedDirectories ) ) {
|
|
|
151 |
continue;
|
152 |
}
|
153 |
|
154 |
// Save all files
|
155 |
$dir = ABSPATH . $path . DIRECTORY_SEPARATOR;
|
156 |
+
$this->getFilesFromDirectory( $dir );
|
157 |
|
158 |
// Add scanned directory listing
|
159 |
$this->options->scannedDirectories[] = $dir;
|
169 |
* @param $directory
|
170 |
* @return bool
|
171 |
*/
|
172 |
+
protected function getFilesFromDirectory( $directory ) {
|
|
|
173 |
$this->totalRecursion++;
|
174 |
+
|
175 |
// Save all files
|
176 |
+
$files = array_diff( scandir( $directory ), array('.', "..") );
|
177 |
|
178 |
+
foreach ( $files as $file ) {
|
|
|
179 |
$fullPath = $directory . $file;
|
180 |
|
181 |
+
if( is_dir( $fullPath ) && !in_array( $fullPath, $this->options->directoriesToCopy ) && !$this->isDirectoryExcluded( $fullPath ) ) {
|
|
|
182 |
$this->options->directoriesToCopy[] = $fullPath;
|
183 |
+
|
184 |
+
return $this->getFilesFromSubDirectories( $fullPath );
|
185 |
//continue;
|
186 |
}
|
187 |
|
188 |
+
if( !is_file( $fullPath ) || in_array( $fullPath, $this->files ) ) {
|
|
|
189 |
continue;
|
190 |
}
|
191 |
|
192 |
$this->options->totalFiles++;
|
193 |
|
194 |
$this->files[] = $fullPath;
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Test and measure if its faster to copy at the same time while the array with folders is generated
|
198 |
+
*/
|
199 |
+
//$this->copy($fullPath);
|
200 |
+
|
201 |
}
|
202 |
}
|
203 |
|
206 |
* @param \SplFileInfo $directory
|
207 |
* @return string|false
|
208 |
*/
|
209 |
+
protected function getPath( $directory ) {
|
210 |
+
|
211 |
+
/*
|
212 |
+
* Do not follow root path like src/web/..
|
213 |
+
* This must be done before \SplFileInfo->isDir() is used!
|
214 |
+
* Prevents open base dir restriction fatal errors
|
215 |
+
*/
|
216 |
+
if (strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
|
217 |
+
return false;
|
218 |
+
}
|
219 |
+
|
220 |
+
$path = str_replace( ABSPATH, null, $directory->getRealPath() );
|
221 |
|
222 |
// Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
|
223 |
+
if( !$directory->isDir() || strlen( $path ) < 1 ) {
|
|
|
224 |
return false;
|
225 |
}
|
226 |
|
228 |
}
|
229 |
|
230 |
/**
|
231 |
+
* Check if directory is excluded from copying
|
232 |
* @param string $directory
|
233 |
* @return bool
|
234 |
*/
|
235 |
+
protected function isDirectoryExcluded( $directory ) {
|
236 |
+
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
|
237 |
+
if( strpos( $directory, $excludedDirectory ) === 0 && !$this->isExtraDirectory( $directory ) ) {
|
|
|
|
|
|
|
238 |
return true;
|
239 |
}
|
240 |
}
|
242 |
return false;
|
243 |
}
|
244 |
|
245 |
+
/**
|
246 |
+
* Check if directory is an extra directory and should be copied
|
247 |
+
* @param string $directory
|
248 |
+
* @return boolean
|
249 |
+
*/
|
250 |
+
protected function isExtraDirectory( $directory ) {
|
251 |
+
foreach ( $this->options->extraDirectories as $extraDirectory ) {
|
252 |
+
if( strpos( $directory, $extraDirectory ) === 0 ) {
|
253 |
+
return true;
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
return false;
|
258 |
+
}
|
259 |
+
|
260 |
/**
|
261 |
* Save files
|
262 |
* @return bool
|
263 |
*/
|
264 |
+
protected function saveProgress() {
|
|
|
265 |
$this->saveOptions();
|
266 |
|
267 |
+
$fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
268 |
+
$files = implode( PHP_EOL, $this->files );
|
269 |
|
270 |
+
if( strlen( $files ) > 0 ) {
|
|
|
271 |
//$files .= PHP_EOL;
|
272 |
}
|
273 |
|
274 |
+
return (false !== @file_put_contents( $fileName, $files ));
|
275 |
}
|
276 |
|
277 |
/**
|
278 |
* Get files
|
279 |
* @return void
|
280 |
*/
|
281 |
+
protected function getFiles() {
|
282 |
+
$fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
|
|
283 |
|
284 |
+
if( false === ($this->files = @file_get_contents( $fileName )) ) {
|
|
|
285 |
$this->files = array();
|
286 |
return;
|
287 |
}
|
288 |
|
289 |
+
$this->files = explode( PHP_EOL, $this->files );
|
290 |
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Copy File using PHP (Only for testing)
|
294 |
+
* @param string $file
|
295 |
+
* @param string $destination
|
296 |
+
* @return bool
|
297 |
+
*
|
298 |
+
* @deprecated since version 2.0.2
|
299 |
+
*/
|
300 |
+
protected function copy($file)
|
301 |
+
{
|
302 |
+
|
303 |
+
if( $this->isOverThreshold() ) {
|
304 |
+
return false;
|
305 |
+
}
|
306 |
+
|
307 |
+
// Failed to get destination
|
308 |
+
if (false === ($destination = $this->getDestination($file)))
|
309 |
+
{
|
310 |
+
//$this->log("Can't get the destination of {$file}");
|
311 |
+
//return false;
|
312 |
+
}
|
313 |
+
|
314 |
+
// Attempt to copy
|
315 |
+
if (!@copy($file, $destination))
|
316 |
+
{
|
317 |
+
//$this->log("Failed to copy file to destination: {$file} -> {$destination}", Logger::TYPE_ERROR);
|
318 |
+
//return false;
|
319 |
+
}
|
320 |
+
|
321 |
+
//$this->log("Copy {$file} -> {$destination}", Logger::TYPE_INFO);
|
322 |
+
|
323 |
+
// Not finished
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
|
327 |
+
|
328 |
+
/**
|
329 |
+
* (only for testing)
|
330 |
+
* Gets destination file and checks if the directory exists, if it does not attempts to create it.
|
331 |
+
* If creating destination directory fails, it returns false, gives destination full path otherwise
|
332 |
+
* @param string $file
|
333 |
+
* @return bool|string
|
334 |
+
*
|
335 |
+
* @deprecated
|
336 |
+
*/
|
337 |
+
private function getDestination($file)
|
338 |
+
{
|
339 |
+
$destination = ABSPATH . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR;
|
340 |
+
$relativePath = str_replace(ABSPATH, null, $file);
|
341 |
+
$destinationPath = $destination . $relativePath;
|
342 |
+
$destinationDirectory = dirname($destinationPath);
|
343 |
+
|
344 |
+
if (!is_dir($destinationDirectory) && !@mkdir($destinationDirectory, 0775, true))
|
345 |
+
{
|
346 |
+
$this->log("Destination directory doesn't exist; {$destinationDirectory}", Logger::TYPE_ERROR);
|
347 |
+
//return false;
|
348 |
+
}
|
349 |
+
|
350 |
+
return $destinationPath;
|
351 |
+
}
|
352 |
+
|
353 |
+
}
|
apps/Backend/Modules/Jobs/Finish.php
CHANGED
@@ -187,14 +187,7 @@ class Finish extends Job
|
|
187 |
{
|
188 |
// Check if clones still exist
|
189 |
$this->log("Verifying existing clones...");
|
190 |
-
|
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,22 +207,10 @@ class Finish extends Job
|
|
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("
|
233 |
{
|
234 |
$this->log("Failed to save {$this->options->clone}'s clone job data to database'");
|
235 |
return false;
|
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 |
"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;
|
apps/Backend/Modules/Jobs/Job.php
CHANGED
@@ -49,19 +49,22 @@ abstract class Job implements JobInterface
|
|
49 |
protected $settings;
|
50 |
|
51 |
/**
|
|
|
52 |
* @var int
|
53 |
*/
|
54 |
protected $maxMemoryLimit;
|
55 |
-
|
56 |
/**
|
|
|
57 |
* @var int
|
58 |
*/
|
59 |
-
protected $
|
60 |
|
61 |
/**
|
62 |
* @var int
|
63 |
*/
|
64 |
-
protected $
|
|
|
65 |
|
66 |
/**
|
67 |
* @var int
|
@@ -92,12 +95,19 @@ abstract class Job implements JobInterface
|
|
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 |
{
|
98 |
$this->maxExecutionTime = 30;
|
99 |
}
|
100 |
|
|
|
101 |
// Services
|
102 |
$this->cache = new Cache(-1, \WPStaging\WPStaging::getContentDir());
|
103 |
$this->logger = WPStaging::getInstance()->get("logger");
|
@@ -173,7 +183,8 @@ abstract class Job implements JobInterface
|
|
173 |
*/
|
174 |
protected function setLimits()
|
175 |
{
|
176 |
-
|
|
|
177 |
{
|
178 |
$this->settings->cpuLoad = "medium";
|
179 |
}
|
@@ -184,15 +195,15 @@ abstract class Job implements JobInterface
|
|
184 |
switch($this->settings->cpuLoad)
|
185 |
{
|
186 |
case "medium":
|
187 |
-
|
188 |
-
$timeLimit = $timeLimit / 2;
|
189 |
break;
|
190 |
case "low":
|
191 |
-
|
192 |
$timeLimit = $timeLimit / 4;
|
193 |
break;
|
194 |
|
195 |
-
case "
|
196 |
default:
|
197 |
break;
|
198 |
}
|
@@ -301,9 +312,12 @@ abstract class Job implements JobInterface
|
|
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('
|
|
|
307 |
return true;
|
308 |
}
|
309 |
|
@@ -316,11 +330,10 @@ abstract class Job implements JobInterface
|
|
316 |
// Check if execution time is over threshold
|
317 |
///$time = round($this->start + $this->time(), 4);
|
318 |
$time = round($this->time() - $this->start, 4);
|
319 |
-
|
320 |
if ($time >= $this->executionLimit)
|
321 |
{
|
322 |
//$this->log('RESET TIME');
|
323 |
-
//return (!$this->resetTime());
|
324 |
return true;
|
325 |
}
|
326 |
|
@@ -331,7 +344,6 @@ abstract class Job implements JobInterface
|
|
331 |
* Attempt to reset memory
|
332 |
* @return bool
|
333 |
*
|
334 |
-
* @deprecated since version 2.0.0
|
335 |
*/
|
336 |
protected function resetMemory()
|
337 |
{
|
@@ -340,6 +352,7 @@ abstract class Job implements JobInterface
|
|
340 |
// Failed to set
|
341 |
if (false === ini_set("memory_limit", $this->formatBytes($newMemoryLimit)))
|
342 |
{
|
|
|
343 |
return false;
|
344 |
}
|
345 |
|
@@ -418,12 +431,40 @@ abstract class Job implements JobInterface
|
|
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 |
}
|
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 |
$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) 30;
|
99 |
+
|
100 |
+
if ($this->maxExecutionTime > 30)
|
101 |
+
{
|
102 |
+
$this->maxExecutionTime = 30;
|
103 |
+
}
|
104 |
|
105 |
if ($this->maxExecutionTime < 1)
|
106 |
{
|
107 |
$this->maxExecutionTime = 30;
|
108 |
}
|
109 |
|
110 |
+
|
111 |
// Services
|
112 |
$this->cache = new Cache(-1, \WPStaging\WPStaging::getContentDir());
|
113 |
$this->logger = WPStaging::getInstance()->get("logger");
|
183 |
*/
|
184 |
protected function setLimits()
|
185 |
{
|
186 |
+
|
187 |
+
if (!isset($this->settings->cpuLoad))
|
188 |
{
|
189 |
$this->settings->cpuLoad = "medium";
|
190 |
}
|
195 |
switch($this->settings->cpuLoad)
|
196 |
{
|
197 |
case "medium":
|
198 |
+
//$memoryLimit= $memoryLimit / 2; // 0.4
|
199 |
+
$timeLimit = $timeLimit / 2;
|
200 |
break;
|
201 |
case "low":
|
202 |
+
//$memoryLimit= $memoryLimit / 4; // 0.2
|
203 |
$timeLimit = $timeLimit / 4;
|
204 |
break;
|
205 |
|
206 |
+
case "fast": // 0.8
|
207 |
default:
|
208 |
break;
|
209 |
}
|
312 |
// Check if the memory is over threshold
|
313 |
$usedMemory = (int) @memory_get_usage(true);
|
314 |
|
315 |
+
$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 );
|
316 |
+
|
317 |
if ($usedMemory >= $this->memoryLimit)
|
318 |
{
|
319 |
+
$this->log('Used Memory: ' . $this->formatBytes($usedMemory) . ' Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script memory limit: ' . $this->formatBytes( $this->memoryLimit ) );
|
320 |
+
$this->resetMemory();
|
321 |
return true;
|
322 |
}
|
323 |
|
330 |
// Check if execution time is over threshold
|
331 |
///$time = round($this->start + $this->time(), 4);
|
332 |
$time = round($this->time() - $this->start, 4);
|
333 |
+
$this->debugLog( 'Execution time: ' . $time . ' Execution Limit' . $this->executionLimit );
|
334 |
if ($time >= $this->executionLimit)
|
335 |
{
|
336 |
//$this->log('RESET TIME');
|
|
|
337 |
return true;
|
338 |
}
|
339 |
|
344 |
* Attempt to reset memory
|
345 |
* @return bool
|
346 |
*
|
|
|
347 |
*/
|
348 |
protected function resetMemory()
|
349 |
{
|
352 |
// Failed to set
|
353 |
if (false === ini_set("memory_limit", $this->formatBytes($newMemoryLimit)))
|
354 |
{
|
355 |
+
$this->log('Can not free some memory', Logger::TYPE_CRITICAL);
|
356 |
return false;
|
357 |
}
|
358 |
|
431 |
*/
|
432 |
protected function log($msg, $type = Logger::TYPE_INFO)
|
433 |
{
|
434 |
+
|
435 |
+
if (!isset($this->options->clone)){
|
436 |
+
$this->options->clone = date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
|
437 |
+
}
|
438 |
+
|
439 |
if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
|
440 |
{
|
441 |
$this->logger->setFileName($this->options->clone);
|
442 |
$this->hasLoggedFileNameSet = true;
|
443 |
}
|
444 |
+
|
445 |
$this->logger->add($msg, $type);
|
446 |
}
|
447 |
+
/**
|
448 |
+
* @param string $msg
|
449 |
+
* @param string $type
|
450 |
+
*/
|
451 |
+
protected function debugLog($msg, $type = Logger::TYPE_INFO)
|
452 |
+
{
|
453 |
+
|
454 |
+
if (!isset($this->options->clone)){
|
455 |
+
$this->options->clone = date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
|
456 |
+
}
|
457 |
+
|
458 |
+
if (false === $this->hasLoggedFileNameSet && 0 < strlen($this->options->clone))
|
459 |
+
{
|
460 |
+
$this->logger->setFileName($this->options->clone);
|
461 |
+
$this->hasLoggedFileNameSet = true;
|
462 |
+
}
|
463 |
+
|
464 |
+
|
465 |
+
if (isset($this->settings->debugMode)){
|
466 |
+
$this->logger->add($msg, $type);
|
467 |
+
}
|
468 |
+
|
469 |
+
}
|
470 |
}
|
apps/Backend/Modules/Jobs/JobExecutable.php
CHANGED
@@ -39,7 +39,7 @@ abstract class JobExecutable extends Job
|
|
39 |
|
40 |
/**
|
41 |
* Prepare Response Array
|
42 |
-
* @param bool $status
|
43 |
* @param bool $incrementCurrentStep
|
44 |
* @return array
|
45 |
*/
|
39 |
|
40 |
/**
|
41 |
* Prepare Response Array
|
42 |
+
* @param bool $status false when the job is not done
|
43 |
* @param bool $incrementCurrentStep
|
44 |
* @return array
|
45 |
*/
|
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("
|
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 ((
|
96 |
{
|
97 |
return '';
|
98 |
}
|
99 |
|
100 |
$units = array('B', "KB", "MB", "GB", "TB");
|
101 |
|
102 |
-
$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,24 +165,33 @@ 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 |
-
|
170 |
-
|
171 |
-
|
172 |
-
return null;
|
173 |
-
}
|
174 |
|
175 |
-
|
176 |
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
181 |
|
182 |
-
return ($freeSpace >= $this->getDirectorySize(ABSPATH));
|
183 |
-
}
|
184 |
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
* Get Database Tables
|
187 |
*/
|
188 |
protected function getTables()
|
@@ -276,10 +285,18 @@ class Scan extends Job
|
|
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
|
283 |
{
|
284 |
return false;
|
285 |
}
|
@@ -343,4 +360,18 @@ class Scan extends Job
|
|
343 |
|
344 |
return $this->objDirectories->size($path);
|
345 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
}
|
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 |
*/
|
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 |
* 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 |
*/
|
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 |
|
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 |
}
|
apps/Backend/Modules/Optimizer.php
DELETED
@@ -1,141 +0,0 @@
|
|
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,7 +85,6 @@ class Settings
|
|
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,7 +93,7 @@ class Settings
|
|
94 |
|
95 |
$this->form["general"]->add(
|
96 |
$element->setLabel("CPU load priority")
|
97 |
-
->setDefault(isset($settings->cpuLoad) ? $settings->cpuLoad : "
|
98 |
);
|
99 |
|
100 |
// Optimizer
|
85 |
$element = new Select(
|
86 |
"wpstg_settings[cpuLoad]",
|
87 |
array(
|
|
|
88 |
"high" => "High (fast)",
|
89 |
"medium" => "Medium (average)",
|
90 |
"low" => "Low (slow)"
|
93 |
|
94 |
$this->form["general"]->add(
|
95 |
$element->setLabel("CPU load priority")
|
96 |
+
->setDefault(isset($settings->cpuLoad) ? $settings->cpuLoad : "fast")
|
97 |
);
|
98 |
|
99 |
// Optimizer
|
apps/Backend/Notices/Notices.php
CHANGED
@@ -2,13 +2,12 @@
|
|
2 |
|
3 |
namespace WPStaging\Backend\Notices;
|
4 |
|
5 |
-
/*
|
6 |
* Admin Notices | Warnings | Messages
|
7 |
*/
|
8 |
|
9 |
// No Direct Access
|
10 |
-
if
|
11 |
-
{
|
12 |
die;
|
13 |
}
|
14 |
|
@@ -18,8 +17,7 @@ use WPStaging\WPStaging;
|
|
18 |
* Class Notices
|
19 |
* @package WPStaging\Backend\Notices
|
20 |
*/
|
21 |
-
class Notices
|
22 |
-
{
|
23 |
|
24 |
/**
|
25 |
* @var string
|
@@ -31,108 +29,119 @@ class Notices
|
|
31 |
*/
|
32 |
private $url;
|
33 |
|
34 |
-
public function __construct($path, $url)
|
35 |
-
{
|
36 |
$this->path = $path;
|
37 |
-
$this->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
|
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
|
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
|
87 |
-
{
|
88 |
return;
|
89 |
}
|
90 |
|
91 |
-
$viewsNoticesPath
|
92 |
|
93 |
-
$varsDirectory
|
94 |
-
|
95 |
-
|
96 |
-
// Poll
|
97 |
-
if
|
98 |
-
{
|
99 |
require_once "{$viewsNoticesPath}poll.php";
|
100 |
-
}
|
101 |
-
|
102 |
// Cache directory in uploads is not writable
|
103 |
-
if
|
104 |
-
{
|
105 |
require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
|
106 |
}
|
107 |
// Staging directory is not writable
|
108 |
-
if
|
109 |
-
{
|
110 |
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
111 |
}
|
112 |
|
113 |
// Version Control
|
114 |
-
if
|
115 |
-
{
|
116 |
require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
|
117 |
}
|
118 |
|
119 |
// Beta
|
120 |
-
if
|
121 |
-
{
|
122 |
require_once "{$viewsNoticesPath}beta.php";
|
123 |
}
|
124 |
|
125 |
// WP Staging Pro and Free can not be activated both
|
126 |
-
if
|
127 |
-
{
|
128 |
require_once "{$viewsNoticesPath}transient.php";
|
129 |
-
delete_transient("wp_staging_deactivated_notice_id");
|
130 |
}
|
131 |
|
132 |
-
if
|
133 |
-
{
|
134 |
require_once "{$viewsNoticesPath}rating.php";
|
|
|
|
|
|
|
135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
}
|
137 |
}
|
138 |
-
|
|
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 |
* Class Notices
|
18 |
* @package WPStaging\Backend\Notices
|
19 |
*/
|
20 |
+
class Notices {
|
|
|
21 |
|
22 |
/**
|
23 |
* @var string
|
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 |
+
}
|
apps/Backend/Optimizer/Optimizer.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
@@ -7,7 +7,10 @@ use WPStaging\Utils\Logger;
|
|
7 |
|
8 |
/**
|
9 |
* Upgrade Class
|
|
|
|
|
10 |
*/
|
|
|
11 |
// No Direct Access
|
12 |
if( !defined( "WPINC" ) ) {
|
13 |
die;
|
@@ -16,7 +19,7 @@ if( !defined( "WPINC" ) ) {
|
|
16 |
class Upgrade {
|
17 |
|
18 |
/**
|
19 |
-
|
20 |
* @var string
|
21 |
*/
|
22 |
private $previousVersion;
|
@@ -26,29 +29,80 @@ class Upgrade {
|
|
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 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
$this->upgradeNotices();
|
44 |
}
|
45 |
-
$this->setVersion();
|
46 |
}
|
47 |
-
|
48 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
* Upgrade routine for new install
|
50 |
*/
|
51 |
-
private function
|
52 |
// Write some default vars
|
53 |
add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
|
54 |
}
|
@@ -71,56 +125,90 @@ class Upgrade {
|
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
-
*
|
|
|
75 |
*/
|
76 |
-
private function
|
|
|
|
|
|
|
77 |
|
78 |
$new = array();
|
79 |
-
|
80 |
-
if
|
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.
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
108 |
* Fix some logical db options
|
109 |
*/
|
110 |
-
private function upgradeNotices(){
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
}
|
125 |
|
126 |
}
|
7 |
|
8 |
/**
|
9 |
* Upgrade Class
|
10 |
+
* This must be loaded on every page init to ensure all settings are
|
11 |
+
* adjusted correctly and to run any upgrade process if necessary.
|
12 |
*/
|
13 |
+
|
14 |
// No Direct Access
|
15 |
if( !defined( "WPINC" ) ) {
|
16 |
die;
|
19 |
class Upgrade {
|
20 |
|
21 |
/**
|
22 |
+
* Previous Version number
|
23 |
* @var string
|
24 |
*/
|
25 |
private $previousVersion;
|
29 |
* @var obj
|
30 |
*/
|
31 |
private $clones;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Clone data
|
35 |
+
* @var obj
|
36 |
+
*/
|
37 |
+
private $clonesBeta;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Cron data
|
41 |
+
* @var obj
|
42 |
+
*/
|
43 |
+
private $cron;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Logger
|
47 |
+
* @var obj
|
48 |
+
*/
|
49 |
private $logger;
|
50 |
|
51 |
public function __construct() {
|
52 |
+
|
53 |
+
// add wpstg_weekly_event to cron events
|
54 |
+
$this->cron = new \WPStaging\Cron\Cron;
|
55 |
+
|
56 |
+
// Previous version
|
57 |
$this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
|
58 |
+
|
59 |
+
// Options earlier than version 2.0.0
|
60 |
$this->clones = get_option( "wpstg_existing_clones", array() );
|
61 |
+
|
62 |
+
// Current options
|
63 |
+
$this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
|
64 |
+
|
65 |
+
// Logger
|
66 |
$this->logger = new Logger;
|
67 |
}
|
68 |
|
69 |
public function doUpgrade() {
|
70 |
+
$this->upgrade2_0_3();
|
71 |
+
//$this->upgrade2_0_4();
|
72 |
+
$this->setVersion();
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Upgrade method 2.0.3
|
77 |
+
*/
|
78 |
+
public function upgrade2_0_3() {
|
79 |
+
// Previous version lower than 2.0.2 or new install
|
80 |
+
if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
|
81 |
+
$this->upgradeOptions();
|
82 |
+
$this->upgradeClonesBeta();
|
83 |
$this->upgradeNotices();
|
84 |
}
|
|
|
85 |
}
|
86 |
+
|
87 |
/**
|
88 |
+
* Upgrade method 2.0.4
|
89 |
+
*/
|
90 |
+
// public function upgrade2_0_4() {
|
91 |
+
// if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.4', '<' ) ) {
|
92 |
+
//
|
93 |
+
// // Register cron job.
|
94 |
+
// $this->cron->schedule_event();
|
95 |
+
//
|
96 |
+
// // Install Optimizer
|
97 |
+
// $optimizer = new Optimizer();
|
98 |
+
// $optimizer->installOptimizer();
|
99 |
+
// }
|
100 |
+
// }
|
101 |
+
|
102 |
+
/**
|
103 |
* Upgrade routine for new install
|
104 |
*/
|
105 |
+
private function upgradeOptions() {
|
106 |
// Write some default vars
|
107 |
add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
|
108 |
}
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
+
* Create a new db option for beta version 2.0.2
|
129 |
+
* @return bool
|
130 |
*/
|
131 |
+
private function upgradeClonesBeta() {
|
132 |
+
|
133 |
+
// Copy old data to new option
|
134 |
+
//update_option( 'wpstg_existing_clones_beta', $this->clones );
|
135 |
|
136 |
$new = array();
|
137 |
+
|
138 |
+
if( empty( $this->clones ) ) {
|
139 |
return false;
|
140 |
}
|
141 |
|
142 |
+
|
143 |
foreach ( $this->clones as $key => &$value ) {
|
144 |
+
|
145 |
+
// Skip the rest of the loop if data is already compatible to wpstg 2.0.2
|
146 |
if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
|
147 |
continue;
|
148 |
+
}
|
149 |
+
|
150 |
$new[$value]['directoryName'] = $value;
|
151 |
$new[$value]['path'] = get_home_path() . $value;
|
152 |
$new[$value]['url'] = get_home_url() . "/" . $value;
|
153 |
+
$new[$value]['number'] = $key + 1;
|
154 |
$new[$value]['version'] = $this->previousVersion;
|
155 |
+
}
|
156 |
+
unset( $value );
|
157 |
+
|
158 |
+
if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
|
159 |
+
$this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Convert clone data from wpstg 1.x to wpstg 2.x
|
165 |
+
* Only use this later when wpstg 2.x is ready for production
|
166 |
+
*/
|
167 |
+
private function upgradeClones() {
|
168 |
+
|
169 |
+
$new = array();
|
170 |
|
171 |
+
if( empty( $this->clones ) ) {
|
172 |
+
return false;
|
173 |
}
|
|
|
|
|
174 |
|
175 |
+
foreach ( $this->clones as $key => &$value ) {
|
176 |
+
|
177 |
+
// Skip the rest of the loop if data is already compatible to wpstg 2.0.1
|
178 |
+
if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
|
179 |
+
continue;
|
180 |
+
}
|
181 |
+
$new[$value]['directoryName'] = $value;
|
182 |
+
$new[$value]['path'] = get_home_path() . $value;
|
183 |
+
$new[$value]['url'] = get_home_url() . "/" . $value;
|
184 |
+
$new[$value]['number'] = $key + 1;
|
185 |
+
$new[$value]['version'] = $this->previousVersion;
|
186 |
+
}
|
187 |
+
unset( $value );
|
188 |
+
|
189 |
+
if( empty( $new ) || false === update_option( 'wpstg_existing_clones', $new ) ) {
|
190 |
$this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
|
|
|
191 |
}
|
192 |
}
|
193 |
+
|
194 |
/**
|
195 |
+
* Upgrade Notices db options from wpstg 1.3 -> 2.0.1
|
196 |
* Fix some logical db options
|
197 |
*/
|
198 |
+
private function upgradeNotices() {
|
199 |
+
$poll = get_option( "wpstg_start_poll", false );
|
200 |
+
$beta = get_option( "wpstg_hide_beta", false );
|
201 |
+
$rating = get_option( "wpstg_RatingDiv", false );
|
202 |
+
|
203 |
+
if( $poll && $poll === "no" ) {
|
204 |
+
update_option( 'wpstg_poll', 'no' );
|
205 |
+
}
|
206 |
+
if( $beta && $beta === "yes" ) {
|
207 |
+
update_option( 'wpstg_beta', 'no' );
|
208 |
+
}
|
209 |
+
if( $rating && $rating === 'yes' ) {
|
210 |
+
update_option( 'wpstg_rating', 'no' );
|
211 |
+
}
|
212 |
}
|
213 |
|
214 |
}
|
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,17 +371,42 @@ color:#777777;
|
|
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: '
|
385 |
display: block;
|
386 |
width: 100%;
|
387 |
height: 100%;
|
@@ -580,13 +605,16 @@ color:#777777;
|
|
580 |
|
581 |
#wpstg-log-details{
|
582 |
height: 300px;
|
|
|
583 |
overflow: scroll;
|
584 |
-
max-width: 650px
|
585 |
-
font-
|
|
|
|
|
586 |
border: 1px solid #FFF;
|
587 |
background-color: black;
|
588 |
-
color:
|
589 |
-
padding:
|
590 |
white-space: nowrap;
|
591 |
margin-top: 15px;
|
592 |
}
|
@@ -676,4 +704,69 @@ color:#777777;
|
|
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 |
}
|
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-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 |
|
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 |
|
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 |
+
}
|
712 |
+
|
713 |
+
/* welcome screen */
|
714 |
+
.wpstg-button.green {
|
715 |
+
display: inline-block;
|
716 |
+
background-color: #83c11f;
|
717 |
+
padding: 10px;
|
718 |
+
min-width: 170px;
|
719 |
+
color: white;
|
720 |
+
font-size: 16px;
|
721 |
+
text-decoration: none;
|
722 |
+
text-align: center;
|
723 |
+
margin-top: 20px;
|
724 |
+
}
|
725 |
+
#wpstg-welcome li {
|
726 |
+
font-size: 18px;
|
727 |
+
line-height: 29px;
|
728 |
+
position: relative;
|
729 |
+
padding-left: 23px;
|
730 |
+
list-style: none!important;
|
731 |
+
}
|
732 |
+
#wpstg-welcome {
|
733 |
+
margin-top:20px;
|
734 |
+
margin-right: 20px;
|
735 |
+
background-color: white;
|
736 |
+
}
|
737 |
+
.wpstg-heading-pro {
|
738 |
+
color: #0080ff;
|
739 |
+
font-weight: bold;
|
740 |
+
}
|
741 |
+
.wpstg-h2 {
|
742 |
+
margin-top: 0px;
|
743 |
+
margin-bottom: 1.2rem;
|
744 |
+
font-size: 30px;
|
745 |
+
line-height: 2.5rem;
|
746 |
+
}
|
747 |
+
#wpstg-welcome li:before {
|
748 |
+
width: 1em;
|
749 |
+
height: 100%;
|
750 |
+
background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;
|
751 |
+
background-size: contain;
|
752 |
+
content: "";
|
753 |
+
position: absolute;
|
754 |
+
top: 0;
|
755 |
+
left: 0;
|
756 |
+
color: #77b227;
|
757 |
+
}
|
758 |
+
.wpstg-h1 {
|
759 |
+
font-size: 2.75em;
|
760 |
+
margin-bottom: 1.35rem;
|
761 |
+
font-size: 2.5em;
|
762 |
+
line-height: 3.68rem;
|
763 |
+
letter-spacing: normal;
|
764 |
+
}
|
765 |
+
#wpstg-welcome h2 {
|
766 |
+
margin: 0 0 15px;
|
767 |
+
}
|
768 |
+
#wpstg-welcome .wpstg-footer {
|
769 |
+
clear: both;
|
770 |
+
margin-top: 20px;
|
771 |
+
font-style: italic;
|
772 |
}
|
apps/Backend/public/img/wpstaging-banner200x400-tryout.gif
ADDED
Binary file
|
apps/Backend/public/img/wpstaging-banner200x400.gif
ADDED
Binary file
|
apps/Backend/public/js/wpstg-admin.js
CHANGED
@@ -1,21 +1,22 @@
|
|
1 |
"use strict";
|
2 |
|
3 |
-
var WPStaging = (function($)
|
4 |
{
|
5 |
-
var that
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
12 |
|
13 |
/**
|
14 |
* Get / Set Cache for Selector
|
15 |
* @param {String} selector
|
16 |
* @returns {*}
|
17 |
*/
|
18 |
-
cache.get
|
19 |
{
|
20 |
// It is already cached!
|
21 |
if ($.inArray(selector, cache.elements) !== -1)
|
@@ -33,7 +34,7 @@ var WPStaging = (function($)
|
|
33 |
* Refreshes given cache
|
34 |
* @param {String} selector
|
35 |
*/
|
36 |
-
cache.refresh
|
37 |
{
|
38 |
selector.elements[selector] = jQuery(selector);
|
39 |
};
|
@@ -42,15 +43,15 @@ var WPStaging = (function($)
|
|
42 |
* Show and Log Error Message
|
43 |
* @param {String} message
|
44 |
*/
|
45 |
-
var showError
|
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 |
-
|
53 |
-
|
54 |
|
55 |
cache.get("#wpstg-loader").hide();
|
56 |
};
|
@@ -58,12 +59,12 @@ var WPStaging = (function($)
|
|
58 |
/**
|
59 |
* Common Elements
|
60 |
*/
|
61 |
-
var elements
|
62 |
{
|
63 |
-
var $workFlow
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
|
68 |
if (2 < window.devicePixelRatio)
|
69 |
{
|
@@ -75,200 +76,198 @@ var WPStaging = (function($)
|
|
75 |
ajaxSpinner = "<img src=''" + urlSpinner + "' alt='' class='ajax-spinner general-spinner' />";
|
76 |
|
77 |
$workFlow
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
-
|
100 |
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
|
133 |
-
|
134 |
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
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 |
-
|
153 |
-
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
}
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
)
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
var $logDetails = cache.get("#wpstg-log-details");
|
171 |
|
172 |
-
|
173 |
|
174 |
-
|
175 |
|
176 |
-
|
177 |
-
|
178 |
|
179 |
cloneActions();
|
180 |
};
|
181 |
-
|
182 |
|
183 |
/**
|
184 |
* Clone actions
|
185 |
*/
|
186 |
-
var cloneActions
|
187 |
{
|
188 |
var $workFlow = cache.get("#wpstg-workflow");
|
189 |
|
190 |
$workFlow
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
|
198 |
-
|
199 |
|
200 |
-
|
201 |
-
|
202 |
|
203 |
-
|
204 |
|
205 |
-
|
206 |
-
|
207 |
|
208 |
-
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
|
216 |
-
|
217 |
|
218 |
-
|
219 |
-
|
220 |
-
cache.get("#wpstg-loader").show();
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
229 |
{
|
230 |
cache.get("#wpstg-removing-clone").html(response);
|
231 |
|
232 |
$existingClones.children("img").remove();
|
233 |
-
|
234 |
cache.get("#wpstg-loader").hide();
|
235 |
},
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
},
|
271 |
-
function(response)
|
272 |
{
|
273 |
if (response.length < 1)
|
274 |
{
|
@@ -278,13 +277,13 @@ var WPStaging = (function($)
|
|
278 |
$workFlow.removeClass("loading").html(response);
|
279 |
|
280 |
cache.get(".wpstg-current-step")
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
},
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
};
|
289 |
|
290 |
/**
|
@@ -294,9 +293,9 @@ var WPStaging = (function($)
|
|
294 |
* @param {String} dataType
|
295 |
* @param {Boolean} showErrors
|
296 |
*/
|
297 |
-
var ajax
|
298 |
{
|
299 |
-
if ("undefined" === typeof(dataType))
|
300 |
{
|
301 |
dataType = "json";
|
302 |
}
|
@@ -307,12 +306,12 @@ var WPStaging = (function($)
|
|
307 |
}
|
308 |
|
309 |
$.ajax({
|
310 |
-
url
|
311 |
-
type
|
312 |
-
dataType
|
313 |
-
cache
|
314 |
-
data
|
315 |
-
error
|
316 |
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
317 |
console.log(textStatus);
|
318 |
|
@@ -322,24 +321,23 @@ var WPStaging = (function($)
|
|
322 |
}
|
323 |
|
324 |
showError(
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
);
|
331 |
},
|
332 |
-
success
|
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,77 +347,76 @@ var WPStaging = (function($)
|
|
349 |
/**
|
350 |
* Next / Previous Step Clicks to Navigate Through Staging Job
|
351 |
*/
|
352 |
-
var stepButtons
|
353 |
{
|
354 |
var $workFlow = cache.get("#wpstg-workflow");
|
355 |
|
356 |
$workFlow
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
|
361 |
-
|
362 |
-
|
363 |
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
|
370 |
-
|
371 |
-
|
372 |
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
|
379 |
-
|
380 |
-
|
381 |
|
382 |
-
|
383 |
|
384 |
-
|
385 |
-
console.log(isScan);
|
386 |
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
|
397 |
-
|
398 |
-
|
399 |
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
};
|
417 |
|
418 |
/**
|
419 |
* Get Excluded (Unchecked) Database Tables
|
420 |
* @returns {Array}
|
421 |
*/
|
422 |
-
var getExcludedTables = function()
|
423 |
{
|
424 |
var excludedTables = [];
|
425 |
|
@@ -434,7 +431,7 @@ var WPStaging = (function($)
|
|
434 |
* Get Included Directories
|
435 |
* @returns {Array}
|
436 |
*/
|
437 |
-
var getIncludedDirectories = function()
|
438 |
{
|
439 |
var includedDirectories = [];
|
440 |
|
@@ -453,7 +450,7 @@ var WPStaging = (function($)
|
|
453 |
* Get Excluded Directories
|
454 |
* @returns {Array}
|
455 |
*/
|
456 |
-
var getExcludedDirectories = function()
|
457 |
{
|
458 |
var excludedDirectories = [];
|
459 |
|
@@ -468,68 +465,89 @@ var WPStaging = (function($)
|
|
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
|
482 |
-
that.data.excludedTables
|
483 |
-
that.data.includedDirectories
|
484 |
-
that.data.excludedDirectories
|
485 |
-
that.data.extraDirectories = $("#wpstg_extraDirectories").val() || null;
|
|
|
|
|
|
|
486 |
};
|
487 |
|
488 |
/**
|
489 |
* Loads Overview (first step) of Staging Job
|
490 |
*/
|
491 |
-
var loadOverview
|
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 |
-
|
507 |
-
|
|
|
|
|
508 |
|
509 |
-
|
|
|
|
|
|
|
510 |
|
511 |
-
|
512 |
-
$workFlow.removeClass("loading").html(response);
|
513 |
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
);
|
521 |
};
|
522 |
|
523 |
/**
|
524 |
* Tabs
|
525 |
*/
|
526 |
-
var tabs
|
527 |
{
|
528 |
-
cache.get("#wpstg-workflow").on("click", ".wpstg-tab-header", function(e) {
|
529 |
e.preventDefault();
|
530 |
|
531 |
-
var $this
|
532 |
-
|
533 |
|
534 |
$this.toggleClass("expand");
|
535 |
|
@@ -550,42 +568,49 @@ var WPStaging = (function($)
|
|
550 |
* Delete Clone
|
551 |
* @param {String} clone
|
552 |
*/
|
553 |
-
var deleteClone
|
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 |
-
|
569 |
-
|
570 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
571 |
|
572 |
-
|
573 |
-
|
574 |
|
575 |
-
|
576 |
-
|
577 |
-
|
|
|
|
|
|
|
|
|
578 |
}
|
579 |
-
|
580 |
-
cache.get("#wpstg-loader").hide();
|
581 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
582 |
);
|
583 |
};
|
584 |
|
585 |
/**
|
586 |
* Cancel Cloning Process
|
587 |
*/
|
588 |
-
var cancelCloning
|
589 |
{
|
590 |
if (true === that.isFinished)
|
591 |
{
|
@@ -593,32 +618,41 @@ var WPStaging = (function($)
|
|
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 |
-
|
606 |
-
|
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,17 +664,19 @@ var WPStaging = (function($)
|
|
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 |
-
|
|
|
|
|
|
|
|
|
641 |
})
|
642 |
} else {
|
643 |
-
cache.get("#wpstg-log-details").append(log.type + ' ' + log.date + ' ' + log.message + '</br>');
|
644 |
}
|
645 |
}
|
646 |
logscroll();
|
@@ -650,7 +686,7 @@ var WPStaging = (function($)
|
|
650 |
/**
|
651 |
* Optimizer
|
652 |
*/
|
653 |
-
var optimizer
|
654 |
{
|
655 |
var $optimizer = cache.get('input[name="wpstg_settings\[optimizer\]"]');
|
656 |
|
@@ -658,7 +694,7 @@ var WPStaging = (function($)
|
|
658 |
optimizerAction($optimizer.is(':checked'));
|
659 |
|
660 |
// On action
|
661 |
-
$optimizer.on('change', function(){
|
662 |
optimizerAction(this.checked);
|
663 |
});
|
664 |
|
@@ -674,34 +710,46 @@ var WPStaging = (function($)
|
|
674 |
}
|
675 |
};
|
676 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
677 |
/**
|
678 |
* Start Cloning Process
|
679 |
* @type {Function}
|
680 |
*/
|
681 |
-
that.startCloning
|
|
|
|
|
|
|
|
|
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,7 +765,9 @@ var WPStaging = (function($)
|
|
717 |
cache.get("#wpstg-loader").show();
|
718 |
|
719 |
// Clone Database
|
720 |
-
setTimeout(function() {
|
|
|
|
|
721 |
}
|
722 |
|
723 |
// Step 1: Clone Database
|
@@ -734,20 +784,20 @@ var WPStaging = (function($)
|
|
734 |
}
|
735 |
|
736 |
setTimeout(
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
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,19 +805,23 @@ var WPStaging = (function($)
|
|
755 |
// Continue clone DB
|
756 |
if (false === response.status)
|
757 |
{
|
758 |
-
setTimeout(function() {
|
|
|
|
|
759 |
}
|
760 |
// Next Step
|
761 |
else if (true === response.status)
|
762 |
{
|
763 |
-
console.log('prepareDirectories' + response.status);
|
764 |
-
setTimeout(function() {
|
|
|
|
|
765 |
}
|
766 |
}
|
|
|
|
|
|
|
767 |
);
|
768 |
-
},
|
769 |
-
500
|
770 |
-
);
|
771 |
}
|
772 |
|
773 |
// Step 2: Prepare Directories
|
@@ -784,28 +838,30 @@ var WPStaging = (function($)
|
|
784 |
}
|
785 |
|
786 |
setTimeout(
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
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() {
|
|
|
|
|
809 |
}
|
810 |
else if (true === response.status)
|
811 |
{
|
@@ -813,10 +869,10 @@ var WPStaging = (function($)
|
|
813 |
cloneFiles();
|
814 |
}
|
815 |
}
|
|
|
|
|
|
|
816 |
);
|
817 |
-
},
|
818 |
-
500
|
819 |
-
);
|
820 |
}
|
821 |
|
822 |
// Step 3: Clone Files
|
@@ -833,32 +889,36 @@ var WPStaging = (function($)
|
|
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 |
-
|
851 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
852 |
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
|
|
|
|
|
|
861 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
862 |
);
|
863 |
}
|
864 |
|
@@ -876,32 +936,34 @@ var WPStaging = (function($)
|
|
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 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
|
|
895 |
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
else if (true === response.status)
|
901 |
-
{
|
902 |
-
finish();
|
903 |
-
}
|
904 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
905 |
);
|
906 |
}
|
907 |
|
@@ -920,43 +982,43 @@ var WPStaging = (function($)
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
940 |
-
|
941 |
|
942 |
-
|
943 |
|
944 |
-
|
945 |
-
|
946 |
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
|
955 |
-
|
956 |
-
|
957 |
|
958 |
-
|
959 |
-
|
960 |
);
|
961 |
}
|
962 |
});
|
@@ -999,7 +1061,7 @@ var WPStaging = (function($)
|
|
999 |
* Initiation
|
1000 |
* @type {Function}
|
1001 |
*/
|
1002 |
-
that.init
|
1003 |
//console.log("Initiating WPStaging...");
|
1004 |
loadOverview();
|
1005 |
elements();
|
@@ -1012,11 +1074,13 @@ var WPStaging = (function($)
|
|
1012 |
* Ajax call
|
1013 |
* @type {ajax}
|
1014 |
*/
|
1015 |
-
that.ajax
|
|
|
|
|
1016 |
|
1017 |
return that;
|
1018 |
})(jQuery);
|
1019 |
|
1020 |
-
jQuery(document).ready(function() {
|
1021 |
WPStaging.init();
|
1022 |
});
|
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 |
+
ajaxurl = ("undefined" !== typeof wpstg.ajaxurl) ? wpstg.ajaxurl : ajaxurl;
|
13 |
|
14 |
/**
|
15 |
* Get / Set Cache for Selector
|
16 |
* @param {String} selector
|
17 |
* @returns {*}
|
18 |
*/
|
19 |
+
cache.get = function (selector)
|
20 |
{
|
21 |
// It is already cached!
|
22 |
if ($.inArray(selector, cache.elements) !== -1)
|
34 |
* Refreshes given cache
|
35 |
* @param {String} selector
|
36 |
*/
|
37 |
+
cache.refresh = function (selector)
|
38 |
{
|
39 |
selector.elements[selector] = jQuery(selector);
|
40 |
};
|
43 |
* Show and Log Error Message
|
44 |
* @param {String} message
|
45 |
*/
|
46 |
+
var showError = function (message)
|
47 |
{
|
48 |
cache.get("#wpstg-try-again").css("display", "inline-block");
|
49 |
cache.get("#wpstg-cancel-cloning").text("Reset");
|
50 |
cache.get("#wpstg-cloning-result").text("Fail");
|
51 |
cache.get("#wpstg-error-wrapper").show();
|
52 |
cache.get("#wpstg-error-details")
|
53 |
+
.show()
|
54 |
+
.html(message);
|
55 |
|
56 |
cache.get("#wpstg-loader").hide();
|
57 |
};
|
59 |
/**
|
60 |
* Common Elements
|
61 |
*/
|
62 |
+
var elements = function ()
|
63 |
{
|
64 |
+
var $workFlow = cache.get("#wpstg-workflow"),
|
65 |
+
isAllChecked = true,
|
66 |
+
urlSpinner = ajaxurl.replace("/admin-ajax.php", '') + "/images/spinner",
|
67 |
+
timer;
|
68 |
|
69 |
if (2 < window.devicePixelRatio)
|
70 |
{
|
76 |
ajaxSpinner = "<img src=''" + urlSpinner + "' alt='' class='ajax-spinner general-spinner' />";
|
77 |
|
78 |
$workFlow
|
79 |
+
// Check / Un-check Database Tables
|
80 |
+
.on("click", ".wpstg-button-unselect", function (e) {
|
81 |
+
e.preventDefault();
|
82 |
|
83 |
+
if (false === isAllChecked)
|
84 |
+
{
|
85 |
+
cache.get(".wpstg-db-table-checkboxes").prop("checked", true);
|
86 |
+
cache.get(".wpstg-button-unselect").text("Un-check All");
|
87 |
+
isAllChecked = true;
|
88 |
+
}
|
89 |
+
else
|
90 |
+
{
|
91 |
+
cache.get(".wpstg-db-table-checkboxes").prop("checked", false);
|
92 |
+
cache.get(".wpstg-button-unselect").text("Check All");
|
93 |
+
isAllChecked = false;
|
94 |
+
}
|
95 |
+
})
|
96 |
+
// Expand Directories
|
97 |
+
.on("click", ".wpstg-expand-dirs", function (e) {
|
98 |
+
e.preventDefault();
|
99 |
|
100 |
+
var $this = $(this);
|
101 |
|
102 |
+
if (!$this.hasClass("disabled"))
|
103 |
+
{
|
104 |
+
$this.siblings(".wpstg-subdir").slideToggle();
|
105 |
+
}
|
106 |
+
})
|
107 |
+
// When a Directory is Selected
|
108 |
+
.on("change", ".wpstg-check-dir", function () {
|
109 |
+
var $directory = $(this).parent(".wpstg-dir");
|
110 |
|
111 |
+
if (this.checked)
|
112 |
+
{
|
113 |
+
$directory.parents(".wpstg-dir").children(".wpstg-check-dir").prop("checked", true);
|
114 |
+
$directory.find(".wpstg-expand-dirs").removeClass("disabled");
|
115 |
+
$directory.find(".wpstg-subdir .wpstg-check-dir").prop("checked", true);
|
116 |
+
}
|
117 |
+
else
|
118 |
+
{
|
119 |
+
$directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
|
120 |
+
$directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
|
121 |
+
$directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
|
122 |
+
$directory.children(".wpstg-subdir").slideUp();
|
123 |
+
}
|
124 |
+
})
|
125 |
+
// Check the max length of the clone name and if the clone name already exists
|
126 |
+
.on("keyup", "#wpstg-new-clone-id", function () {
|
127 |
|
128 |
+
// This request was already sent, clear it up!
|
129 |
+
if ("number" === typeof (timer))
|
130 |
+
{
|
131 |
+
clearInterval(timer);
|
132 |
+
}
|
133 |
|
134 |
+
var cloneID = this.value;
|
135 |
|
136 |
+
timer = setTimeout(
|
137 |
+
function () {
|
138 |
+
ajax(
|
139 |
+
{
|
140 |
+
action: "wpstg_check_clone",
|
141 |
+
cloneID: cloneID
|
142 |
+
},
|
143 |
+
function (response)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
{
|
145 |
+
if (response.status === "success")
|
146 |
+
{
|
147 |
+
cache.get("#wpstg-new-clone-id").removeClass("wpstg-error-input");
|
148 |
+
cache.get("#wpstg-start-cloning").removeAttr("disabled");
|
149 |
+
cache.get("#wpstg-clone-id-error").text('').hide();
|
150 |
+
}
|
151 |
+
else
|
152 |
+
{
|
153 |
+
cache.get("#wpstg-new-clone-id").addClass("wpstg-error-input");
|
154 |
+
cache.get("#wpstg-start-cloning").prop("disabled", true);
|
155 |
+
cache.get("#wpstg-clone-id-error").text(response.message).show();
|
156 |
+
}
|
157 |
}
|
158 |
+
);
|
159 |
+
},
|
160 |
+
500
|
161 |
+
);
|
162 |
+
})
|
163 |
+
// Restart cloning process
|
164 |
+
.on("click", "#wpstg-start-cloning", function () {
|
165 |
+
that.isCancelled = false;
|
166 |
+
that.getLogs = false;
|
167 |
+
})
|
168 |
+
// Display logs
|
169 |
+
.on("click", "#wpstg-show-log-button", function (e) {
|
170 |
+
e.preventDefault();
|
171 |
+
var $logDetails = cache.get("#wpstg-log-details");
|
|
|
172 |
|
173 |
+
$logDetails.toggle();
|
174 |
|
175 |
+
logscroll();
|
176 |
|
177 |
+
that.getLogs = (false === that.getLogs);
|
178 |
+
});
|
179 |
|
180 |
cloneActions();
|
181 |
};
|
182 |
+
|
183 |
|
184 |
/**
|
185 |
* Clone actions
|
186 |
*/
|
187 |
+
var cloneActions = function ()
|
188 |
{
|
189 |
var $workFlow = cache.get("#wpstg-workflow");
|
190 |
|
191 |
$workFlow
|
192 |
+
// Cancel cloning
|
193 |
+
.on("click", "#wpstg-cancel-cloning", function () {
|
194 |
+
if (!confirm("Are you sure you want to cancel cloning process?"))
|
195 |
+
{
|
196 |
+
return false;
|
197 |
+
}
|
198 |
|
199 |
+
var $this = $(this);
|
200 |
|
201 |
+
$("#wpstg-try-again, #wpstg-home-link").hide();
|
202 |
+
$this.prop("disabled", true);
|
203 |
|
204 |
+
that.isCancelled = true;
|
205 |
|
206 |
+
$("#wpstg-cloning-result").text("Please wait...this can take up a while.");
|
207 |
+
$("#wpstg-loader, #wpstg-show-log-button").hide();
|
208 |
|
209 |
+
$this.parent().append(ajaxSpinner);
|
210 |
|
211 |
+
cancelCloning();
|
212 |
+
})
|
213 |
+
// Delete clone - confirmation
|
214 |
+
.on("click", ".wpstg-remove-clone[data-clone]", function (e) {
|
215 |
+
e.preventDefault();
|
216 |
|
217 |
+
var $existingClones = cache.get("#wpstg-existing-clones");
|
218 |
|
219 |
+
$workFlow.removeClass('active');
|
|
|
|
|
220 |
|
221 |
+
cache.get("#wpstg-loader").show();
|
222 |
+
|
223 |
+
ajax(
|
224 |
+
{
|
225 |
+
action: "wpstg_confirm_delete_clone",
|
226 |
+
nonce: wpstg.nonce,
|
227 |
+
clone: $(this).data("clone")
|
228 |
+
},
|
229 |
+
function (response)
|
230 |
{
|
231 |
cache.get("#wpstg-removing-clone").html(response);
|
232 |
|
233 |
$existingClones.children("img").remove();
|
234 |
+
|
235 |
cache.get("#wpstg-loader").hide();
|
236 |
},
|
237 |
+
"HTML"
|
238 |
+
);
|
239 |
+
})
|
240 |
+
// Delete clone - confirmed
|
241 |
+
.on("click", "#wpstg-remove-clone", function (e) {
|
242 |
+
e.preventDefault();
|
243 |
+
|
244 |
+
cache.get("#wpstg-removing-clone").addClass("loading");
|
245 |
+
|
246 |
+
cache.get("#wpstg-loader").show();
|
247 |
+
|
248 |
+
deleteClone($(this).data("clone"));
|
249 |
+
})
|
250 |
+
// Cancel deleting clone
|
251 |
+
.on("click", "#wpstg-cancel-removing", function (e) {
|
252 |
+
e.preventDefault();
|
253 |
+
$(".wpstg-clone").removeClass("active");
|
254 |
+
cache.get("#wpstg-removing-clone").html('');
|
255 |
+
})
|
256 |
+
// Edit
|
257 |
+
.on("click", ".wpstg-execute-clone", function (e) {
|
258 |
+
e.preventDefault();
|
259 |
+
|
260 |
+
var clone = $(this).data("clone");
|
261 |
+
|
262 |
+
$workFlow.addClass("loading");
|
263 |
+
|
264 |
+
ajax(
|
265 |
+
{
|
266 |
+
action: "wpstg_scanning",
|
267 |
+
clone: clone,
|
268 |
+
nonce: wpstg.nonce
|
269 |
+
},
|
270 |
+
function (response)
|
|
|
|
|
271 |
{
|
272 |
if (response.length < 1)
|
273 |
{
|
277 |
$workFlow.removeClass("loading").html(response);
|
278 |
|
279 |
cache.get(".wpstg-current-step")
|
280 |
+
.removeClass("wpstg-current-step")
|
281 |
+
.next("li")
|
282 |
+
.addClass("wpstg-current-step");
|
283 |
},
|
284 |
+
"HTML"
|
285 |
+
);
|
286 |
+
});
|
287 |
};
|
288 |
|
289 |
/**
|
293 |
* @param {String} dataType
|
294 |
* @param {Boolean} showErrors
|
295 |
*/
|
296 |
+
var ajax = function (data, callback, dataType, showErrors)
|
297 |
{
|
298 |
+
if ("undefined" === typeof (dataType))
|
299 |
{
|
300 |
dataType = "json";
|
301 |
}
|
306 |
}
|
307 |
|
308 |
$.ajax({
|
309 |
+
url: ajaxurl,
|
310 |
+
type: "POST",
|
311 |
+
dataType: dataType,
|
312 |
+
cache: false,
|
313 |
+
data: data,
|
314 |
+
error: function (xhr, textStatus, errorThrown) {
|
315 |
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
316 |
console.log(textStatus);
|
317 |
|
321 |
}
|
322 |
|
323 |
showError(
|
324 |
+
"Fatal Unknown Error. This should not happen." +
|
325 |
+
"Please again. If this does not help, " +
|
326 |
+
"<a href='https://wordpress.org/support/plugin/wp-staging' target='_blank'>Open a ticket</a> " +
|
327 |
+
"in the WP Staging support forum."
|
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 |
/**
|
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 |
* Get Included Directories
|
432 |
* @returns {Array}
|
433 |
*/
|
434 |
+
var getIncludedDirectories = function ()
|
435 |
{
|
436 |
var includedDirectories = [];
|
437 |
|
450 |
* Get Excluded Directories
|
451 |
* @returns {Array}
|
452 |
*/
|
453 |
+
var getExcludedDirectories = function ()
|
454 |
{
|
455 |
var excludedDirectories = [];
|
456 |
|
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 |
* 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 |
}
|
619 |
|
620 |
ajax(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
621 |
{
|
622 |
+
action: "wpstg_cancel_clone",
|
623 |
+
clone: that.data.cloneID,
|
624 |
+
nonce: wpstg.nonce
|
625 |
+
},
|
626 |
+
function (response)
|
627 |
+
{
|
628 |
+
|
629 |
+
|
630 |
+
if( response && "undefined" !== typeof(response.delete) && response.delete === "finished"){
|
631 |
// Load overview
|
632 |
loadOverview();
|
633 |
+
return;
|
634 |
+
}
|
635 |
+
|
636 |
+
if (true !== response)
|
637 |
+
{
|
638 |
+
// continue
|
639 |
+
cancelCloning();
|
640 |
+
return;
|
641 |
}
|
642 |
+
|
643 |
+
// Load overview
|
644 |
+
loadOverview();
|
645 |
+
}
|
646 |
);
|
647 |
};
|
648 |
+
|
649 |
/**
|
650 |
* Scroll the window log to bottom
|
651 |
* @returns void
|
652 |
*/
|
653 |
var logscroll = function () {
|
654 |
var $div = cache.get("#wpstg-log-details");
|
655 |
+
if ("undefined" !== typeof ($div[0])) {
|
656 |
$div.scrollTop($div[0].scrollHeight);
|
657 |
}
|
658 |
}
|
664 |
*/
|
665 |
var getLogs = function (log)
|
666 |
{
|
|
|
|
|
|
|
667 |
if (log != null && "undefined" !== typeof (log)) {
|
668 |
if (log.constructor === Array) {
|
669 |
$.each(log, function (index, value) {
|
670 |
+
|
671 |
//console.log(index, value);
|
672 |
+
if (value.type === 'ERROR'){
|
673 |
+
cache.get("#wpstg-log-details").append('<span style="color:red;">[' + value.type + ']</span>-'+ '[' + value.date + '] ' + value.message + '</br>');
|
674 |
+
} else {
|
675 |
+
cache.get("#wpstg-log-details").append('[' + value.type + ']-'+ '[' + value.date + '] ' + value.message + '</br>');
|
676 |
+
}
|
677 |
})
|
678 |
} else {
|
679 |
+
cache.get("#wpstg-log-details").append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
|
680 |
}
|
681 |
}
|
682 |
logscroll();
|
686 |
/**
|
687 |
* Optimizer
|
688 |
*/
|
689 |
+
var optimizer = function ()
|
690 |
{
|
691 |
var $optimizer = cache.get('input[name="wpstg_settings\[optimizer\]"]');
|
692 |
|
694 |
optimizerAction($optimizer.is(':checked'));
|
695 |
|
696 |
// On action
|
697 |
+
$optimizer.on('change', function () {
|
698 |
optimizerAction(this.checked);
|
699 |
});
|
700 |
|
710 |
}
|
711 |
};
|
712 |
|
713 |
+
var checkDiskSpace = function () {
|
714 |
+
cache.get("#wpstg-check-space").on("click", function (e) {
|
715 |
+
cache.get("#wpstg-loader").show();
|
716 |
+
console.log("check disk space");
|
717 |
+
ajax(
|
718 |
+
{
|
719 |
+
action: "wpstg_check_disk_space",
|
720 |
+
nonce: wpstg.nonce
|
721 |
+
},
|
722 |
+
function (response)
|
723 |
+
{
|
724 |
+
if (false === response)
|
725 |
+
{
|
726 |
+
cache.get("#wpstg-clone-id-error").text('Can not detect disk space').show();
|
727 |
+
cache.get("#wpstg-loader").hide();
|
728 |
+
return;
|
729 |
+
}
|
730 |
+
|
731 |
+
// Not enough disk space
|
732 |
+
cache.get("#wpstg-clone-id-error").text('Available free disk space ' + response.freespace + ' | Estimated necessary disk space: ' + response.usedspace).show();
|
733 |
+
cache.get("#wpstg-loader").hide();
|
734 |
+
},
|
735 |
+
"json",
|
736 |
+
false
|
737 |
+
);
|
738 |
+
});
|
739 |
+
|
740 |
+
}
|
741 |
+
|
742 |
/**
|
743 |
* Start Cloning Process
|
744 |
* @type {Function}
|
745 |
*/
|
746 |
+
that.startCloning = (function () {
|
747 |
+
|
748 |
+
// Register function for checking disk space
|
749 |
+
checkDiskSpace();
|
750 |
+
|
751 |
if ("wpstg_cloning" !== that.data.action)
|
752 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
753 |
return;
|
754 |
}
|
755 |
|
765 |
cache.get("#wpstg-loader").show();
|
766 |
|
767 |
// Clone Database
|
768 |
+
setTimeout(function () {
|
769 |
+
cloneDatabase();
|
770 |
+
}, wpstg.cpuLoad);
|
771 |
}
|
772 |
|
773 |
// Step 1: Clone Database
|
784 |
}
|
785 |
|
786 |
setTimeout(
|
787 |
+
function () {
|
788 |
+
ajax(
|
789 |
+
{
|
790 |
+
action: "wpstg_clone_database",
|
791 |
+
nonce: wpstg.nonce
|
792 |
+
},
|
793 |
+
function (response) {
|
794 |
// Add percentage
|
795 |
+
if ("undefined" !== typeof (response.percentage))
|
796 |
{
|
797 |
cache.get("#wpstg-db-progress").width(response.percentage + '%');
|
798 |
}
|
799 |
// Add Log
|
800 |
+
if ("undefined" !== typeof (response.last_msg))
|
801 |
{
|
802 |
getLogs(response.last_msg);
|
803 |
}
|
805 |
// Continue clone DB
|
806 |
if (false === response.status)
|
807 |
{
|
808 |
+
setTimeout(function () {
|
809 |
+
cloneDatabase();
|
810 |
+
}, wpstg.cpuLoad);
|
811 |
}
|
812 |
// Next Step
|
813 |
else if (true === response.status)
|
814 |
{
|
815 |
+
//console.log('prepareDirectories ' + response.status);
|
816 |
+
setTimeout(function () {
|
817 |
+
prepareDirectories();
|
818 |
+
}, wpstg.cpuLoad);
|
819 |
}
|
820 |
}
|
821 |
+
);
|
822 |
+
},
|
823 |
+
500
|
824 |
);
|
|
|
|
|
|
|
825 |
}
|
826 |
|
827 |
// Step 2: Prepare Directories
|
838 |
}
|
839 |
|
840 |
setTimeout(
|
841 |
+
function () {
|
842 |
+
ajax(
|
843 |
+
{
|
844 |
+
action: "wpstg_clone_prepare_directories",
|
845 |
+
nonce: wpstg.nonce
|
846 |
+
},
|
847 |
+
function (response) {
|
848 |
// Add percentage
|
849 |
+
if ("undefined" !== typeof (response.percentage))
|
850 |
{
|
851 |
cache.get("#wpstg-directories-progress").width(response.percentage + '%');
|
852 |
}
|
853 |
|
854 |
// Add Log
|
855 |
+
if ("undefined" !== typeof (response.last_msg))
|
856 |
{
|
857 |
getLogs(response.last_msg);
|
858 |
}
|
859 |
|
860 |
if (false === response.status)
|
861 |
{
|
862 |
+
setTimeout(function () {
|
863 |
+
prepareDirectories();
|
864 |
+
}, wpstg.cpuLoad);
|
865 |
}
|
866 |
else if (true === response.status)
|
867 |
{
|
869 |
cloneFiles();
|
870 |
}
|
871 |
}
|
872 |
+
);
|
873 |
+
},
|
874 |
+
500
|
875 |
);
|
|
|
|
|
|
|
876 |
}
|
877 |
|
878 |
// Step 3: Clone Files
|
889 |
}
|
890 |
|
891 |
ajax(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
892 |
{
|
893 |
+
action: "wpstg_clone_files",
|
894 |
+
nonce: wpstg.nonce
|
895 |
+
},
|
896 |
+
function (response) {
|
897 |
+
// Add percentage
|
898 |
+
if ("undefined" !== typeof (response.percentage))
|
899 |
+
{
|
900 |
+
cache.get("#wpstg-files-progress").width(response.percentage + '%');
|
901 |
+
}
|
902 |
|
903 |
+
// Add Log
|
904 |
+
if ("undefined" !== typeof (response.last_msg))
|
905 |
+
{
|
906 |
+
getLogs(response.last_msg);
|
907 |
+
}
|
908 |
+
|
909 |
+
if (false === response.status)
|
910 |
+
{
|
911 |
+
setTimeout(function () {
|
912 |
+
cloneFiles();
|
913 |
+
}, wpstg.cpuLoad);
|
914 |
}
|
915 |
+
else if (true === response.status)
|
916 |
+
{
|
917 |
+
setTimeout(function () {
|
918 |
+
replaceData();
|
919 |
+
}, wpstg.cpuLoad);
|
920 |
+
}
|
921 |
+
}
|
922 |
);
|
923 |
}
|
924 |
|
936 |
}
|
937 |
|
938 |
ajax(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
939 |
{
|
940 |
+
action: "wpstg_clone_replace_data",
|
941 |
+
nonce: wpstg.nonce
|
942 |
+
},
|
943 |
+
function (response) {
|
944 |
+
// Add percentage
|
945 |
+
if ("undefined" !== typeof (response.percentage))
|
946 |
+
{
|
947 |
+
cache.get("#wpstg-links-progress").width(response.percentage + '%');
|
948 |
+
}
|
949 |
|
950 |
+
// Add Log
|
951 |
+
if ("undefined" !== typeof (response.last_msg))
|
952 |
+
{
|
953 |
+
getLogs(response.last_msg);
|
|
|
|
|
|
|
|
|
954 |
}
|
955 |
+
|
956 |
+
if (false === response.status)
|
957 |
+
{
|
958 |
+
setTimeout(function () {
|
959 |
+
replaceData();
|
960 |
+
}, wpstg.cpuLoad);
|
961 |
+
}
|
962 |
+
else if (true === response.status)
|
963 |
+
{
|
964 |
+
finish();
|
965 |
+
}
|
966 |
+
}
|
967 |
);
|
968 |
}
|
969 |
|
982 |
}
|
983 |
|
984 |
ajax(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
985 |
{
|
986 |
+
action: "wpstg_clone_finish",
|
987 |
+
nonce: wpstg.nonce
|
988 |
+
},
|
989 |
+
function (response)
|
990 |
+
{
|
991 |
+
// Invalid response
|
992 |
+
if ("object" !== typeof (response))
|
993 |
+
{
|
994 |
+
showError(
|
995 |
"Couldn't finish the cloning process properly. " +
|
996 |
"Your clone has been copied but failed to do clean up and " +
|
997 |
"saving its records to the database." +
|
998 |
"Please contact support and provide your logs."
|
999 |
+
);
|
1000 |
|
1001 |
+
return;
|
1002 |
+
}
|
1003 |
|
1004 |
+
console.log("Cloning process finished");
|
1005 |
|
1006 |
+
var $link1 = cache.get("#wpstg-clone-url-1");
|
1007 |
+
var $link = cache.get("#wpstg-clone-url");
|
1008 |
|
1009 |
+
cache.get("#wpstg_staging_name").html(that.data.cloneID);
|
1010 |
+
cache.get("#wpstg-finished-result").show();
|
1011 |
+
cache.get("#wpstg-cancel-cloning").prop("disabled", true);
|
1012 |
+
$link1.attr("href", $link1.attr("href") + '/' + response.directoryName);
|
1013 |
+
$link1.append('/' + response.directoryName);
|
1014 |
+
$link.attr("href", $link.attr("href") + '/' + response.directoryName);
|
1015 |
+
cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
|
1016 |
|
1017 |
+
// Finished
|
1018 |
+
that.isFinished = true;
|
1019 |
|
1020 |
+
finish();
|
1021 |
+
}
|
1022 |
);
|
1023 |
}
|
1024 |
});
|
1061 |
* Initiation
|
1062 |
* @type {Function}
|
1063 |
*/
|
1064 |
+
that.init = (function () {
|
1065 |
//console.log("Initiating WPStaging...");
|
1066 |
loadOverview();
|
1067 |
elements();
|
1074 |
* Ajax call
|
1075 |
* @type {ajax}
|
1076 |
*/
|
1077 |
+
that.ajax = ajax;
|
1078 |
+
that.showError = showError;
|
1079 |
+
that.getLogs = getLogs;
|
1080 |
|
1081 |
return that;
|
1082 |
})(jQuery);
|
1083 |
|
1084 |
+
jQuery(document).ready(function () {
|
1085 |
WPStaging.init();
|
1086 |
});
|
apps/Backend/views/_includes/header.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
</span>
|
4 |
|
5 |
<span class="wpstg-version">
|
6 |
-
<?php if (
|
7 |
</span>
|
8 |
|
9 |
<div class="wpstg-header">
|
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">
|
apps/Backend/views/_includes/messages/beta.php
CHANGED
@@ -10,9 +10,9 @@
|
|
10 |
<a href="https://wordpress.org/plugins/backwpup/" target="_blank">BackWPup</a>
|
11 |
</p>
|
12 |
<p>
|
13 |
-
I am not responsible for any damages
|
14 |
<br>
|
15 |
-
|
16 |
</p>
|
17 |
<ul>
|
18 |
<li>
|
10 |
<a href="https://wordpress.org/plugins/backwpup/" target="_blank">BackWPup</a>
|
11 |
</p>
|
12 |
<p>
|
13 |
+
I am not responsible for any damages you do to your site;)
|
14 |
<br>
|
15 |
+
Create a full backup first.
|
16 |
</p>
|
17 |
<ul>
|
18 |
<li>
|
apps/Backend/views/_includes/messages/rating.php
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
<p>
|
3 |
Awesome, you've been using <strong>WP Staging </strong> for more than 1 week.
|
4 |
May I ask you to give it a <strong>5-star</strong> rating on Wordpress?
|
|
|
|
|
5 |
</p>
|
6 |
|
7 |
<p>
|
2 |
<p>
|
3 |
Awesome, you've been using <strong>WP Staging </strong> for more than 1 week.
|
4 |
May I ask you to give it a <strong>5-star</strong> rating on Wordpress?
|
5 |
+
<br><br>
|
6 |
+
P.S. Looking for a way to copy plugins and theme files from staging to live site? Try out <a href="https://wp-staging.com" target="_blank">WP Staging Pro</a> <br>
|
7 |
</p>
|
8 |
|
9 |
<p>
|
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://
|
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://wp-staging.com', 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"
|
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"></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 __('
|
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
|
65 |
</h4>
|
66 |
|
67 |
<textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:250px;"></textarea>
|
@@ -69,9 +69,8 @@
|
|
69 |
<span>
|
70 |
<?php
|
71 |
echo __(
|
72 |
-
"
|
73 |
-
"
|
74 |
-
"Full path must start with " . $options->root,
|
75 |
"wpstg"
|
76 |
)
|
77 |
?>
|
@@ -81,7 +80,9 @@
|
|
81 |
<p>
|
82 |
<span>
|
83 |
<?php
|
84 |
-
|
|
|
|
|
85 |
?>
|
86 |
</span>
|
87 |
</p>
|
@@ -113,4 +114,6 @@
|
|
113 |
echo __("Start Cloning", "wpstg");
|
114 |
}
|
115 |
?>
|
116 |
-
</button>
|
|
|
|
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 |
<?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 |
<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 |
<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 |
echo __("Start Cloning", "wpstg");
|
115 |
}
|
116 |
?>
|
117 |
+
</button>
|
118 |
+
|
119 |
+
<a href="#" id="wpstg-check-space"><?php _e('Check Disk Space', 'wpstg'); ?></a>
|
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;">
|
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;display:none;">
|
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="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="wpstg-nav-tab-wrapper"></h2>
|
6 |
|
7 |
<?php
|
8 |
do_action("wpstg_notifications");
|
apps/Backend/views/clone/single-site/index.php
CHANGED
@@ -16,4 +16,5 @@
|
|
16 |
</li>
|
17 |
</ul>
|
18 |
|
19 |
-
<div id="wpstg-workflow"></div>
|
|
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>
|
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/wp-staging/logs</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">
|
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>
|
apps/Backend/views/tools/index.php
CHANGED
@@ -24,7 +24,7 @@
|
|
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"?>
|
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"?>
|
apps/Backend/views/welcome/welcome.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="" id="wpstg-welcome">
|
2 |
+
<div style="border: 2px solid white;padding: 20px;margin-bottom:20px;">
|
3 |
+
<h2 class="wpstg-h2">
|
4 |
+
<span class="wpstg-heading-pro"><?php _e( 'WP Staging Pro', 'wpstg' ); ?></span><?php _e( ' - Copy Themes & Plugins from Staging to Live Site', 'wpstg' ); ?>
|
5 |
+
</h2>
|
6 |
+
<li><strong>Cloning</strong> - <?php _e( 'Create a clone of your website with a simple click', 'wpstg' ); ?></li>
|
7 |
+
<li><strong>Push Changes</strong> - <?php _e( 'Copy plugin and theme files from staging to live site', 'wpstg' ); ?></li>
|
8 |
+
<li><strong>Authentication</strong> - <?php _e( 'Staging Site is available to authenticated users only', 'wpstg' ); ?></li>
|
9 |
+
<li><strong>High Performance</strong> - <?php _e( 'Cloning process is fast and does not slow down website loading', 'wpstg' ); ?></li>
|
10 |
+
<li><strong>Secure</strong> - <?php _e( 'WP Staging is coded well for protection of your data', 'wpstg' ); ?></li>
|
11 |
+
<a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP Staging Pro</a>
|
12 |
+
<a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" style="margin-left:30px;">Skip - Start Cloning</a>
|
13 |
+
<div class="wpstg-footer"> <?php _e( 'Comes with our 30-day no questions asked money back guarantee', 'wpstg' ); ?></div>
|
14 |
+
</div>
|
15 |
+
</div>
|
apps/Core/Cron/Cron.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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!
|
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 " . $this->cacheDir . '! Make sure folder permission is 755 and owner is correct. Should be www-data or similar.');
|
74 |
}
|
75 |
}
|
76 |
|
apps/Core/Utils/Logger.php
CHANGED
@@ -24,6 +24,8 @@ class Logger
|
|
24 |
const TYPE_WARNING = "WARNING";
|
25 |
|
26 |
const TYPE_INFO = "INFO";
|
|
|
|
|
27 |
|
28 |
/**
|
29 |
* Log directory (full path)
|
@@ -98,7 +100,7 @@ class Logger
|
|
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"),
|
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 |
* @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"),
|
apps/Core/WPStaging.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging;
|
3 |
|
4 |
// No Direct Access
|
5 |
-
if
|
6 |
-
|
7 |
-
die;
|
8 |
}
|
9 |
|
10 |
// Ensure to include autoloader class
|
@@ -18,392 +18,408 @@ use WPStaging\Utils\Cache;
|
|
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 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
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.6";
|
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 |
+
"wp-staging_page_wpstg-welcome",
|
152 |
+
);
|
153 |
+
|
154 |
+
// Load these css and js files only on wp staging admin pages
|
155 |
+
if( !in_array( $hook, $availablePages ) || !is_admin() ) {
|
156 |
+
return;
|
157 |
+
}
|
158 |
+
|
159 |
+
// Load admin js files
|
160 |
+
wp_enqueue_script(
|
161 |
+
"wpstg-admin-script", $this->backend_url . "js/wpstg-admin.js", array("jquery"), $this->getVersion(), false
|
162 |
+
);
|
163 |
+
|
164 |
+
// Load admin css files
|
165 |
+
wp_enqueue_style(
|
166 |
+
"wpstg-admin", $this->backend_url . "css/wpstg-admin.css", $this->getVersion()
|
167 |
+
);
|
168 |
+
|
169 |
+
wp_localize_script( "wpstg-admin-script", "wpstg", array(
|
170 |
+
"ajaxurl" => admin_url( 'admin-ajax.php' ),
|
171 |
+
"nonce" => wp_create_nonce( "wpstg_ajax_nonce" ),
|
172 |
+
"mu_plugin_confirmation" => __(
|
173 |
+
"If confirmed we will install an additional WordPress 'Must Use' plugin. "
|
174 |
+
. "This plugin will allow us to control which plugins are loaded during "
|
175 |
+
. "WP Staging specific operations. Do you wish to continue?", "wpstg"
|
176 |
+
),
|
177 |
+
"plugin_compatibility_settings_problem" => __(
|
178 |
+
"A problem occurred when trying to change the plugin compatibility setting.", "wpstg"
|
179 |
+
),
|
180 |
+
"saved" => __( "Saved", "The settings were saved successfully", "wpstg" ),
|
181 |
+
"status" => __( "Status", "Current request status", "wpstg" ),
|
182 |
+
"response" => __( "Response", "The message the server responded with", "wpstg" ),
|
183 |
+
"blacklist_problem" => __(
|
184 |
+
"A problem occurred when trying to add plugins to backlist.", "wpstg"
|
185 |
+
),
|
186 |
+
"cpuLoad" => $this->getCPULoadSetting(),
|
187 |
+
"settings" => ( object ) array() // TODO add settings?
|
188 |
+
) );
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Caching and logging folder
|
193 |
+
*
|
194 |
+
* @return string
|
195 |
+
*/
|
196 |
+
public static function getContentDir() {
|
197 |
+
$wp_upload_dir = wp_upload_dir();
|
198 |
+
$path = $wp_upload_dir['basedir'] . '/wp-staging';
|
199 |
+
wp_mkdir_p( $path );
|
200 |
+
return apply_filters( 'wpstg_get_upload_dir', $path . DIRECTORY_SEPARATOR );
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Register used namespaces
|
205 |
+
*/
|
206 |
+
private function registerNamespaces() {
|
207 |
+
$autoloader = new Autoloader();
|
208 |
+
$this->set( "autoloader", $autoloader );
|
209 |
+
|
210 |
+
//wp_die($this->pluginPath . 'apps' . DIRECTORY_SEPARATOR);
|
211 |
+
// Autoloader
|
212 |
+
$autoloader->registerNamespaces( array(
|
213 |
+
"WPStaging" => array(
|
214 |
+
$this->pluginPath . 'apps' . DIRECTORY_SEPARATOR,
|
215 |
+
$this->pluginPath . 'apps' . DIRECTORY_SEPARATOR . 'Core' . DIRECTORY_SEPARATOR,
|
216 |
+
)
|
217 |
+
) );
|
218 |
+
|
219 |
+
// Register namespaces
|
220 |
+
$autoloader->register();
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Get Instance
|
225 |
+
* @return WPStaging
|
226 |
+
*/
|
227 |
+
public static function getInstance() {
|
228 |
+
if( null === static::$instance ) {
|
229 |
+
static::$instance = new static();
|
230 |
+
}
|
231 |
+
|
232 |
+
return static::$instance;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Prevent cloning
|
237 |
+
* @return void
|
238 |
+
*/
|
239 |
+
private function __clone() {
|
240 |
+
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Prevent unserialization
|
245 |
+
* @return void
|
246 |
+
*/
|
247 |
+
private function __wakeup() {
|
248 |
+
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Load Dependencies
|
253 |
+
*/
|
254 |
+
private function loadDependencies() {
|
255 |
+
// Set loader
|
256 |
+
$this->set( "loader", new Loader() );
|
257 |
+
|
258 |
+
// Set cache
|
259 |
+
$this->set( "cache", new Cache() );
|
260 |
+
|
261 |
+
// Set logger
|
262 |
+
$this->set( "logger", new Logger() );
|
263 |
+
|
264 |
+
// Set settings
|
265 |
+
$this->set( "settings", new Settings() );
|
266 |
+
|
267 |
+
// Set Administrator
|
268 |
+
if( is_admin() ) {
|
269 |
+
new Administrator( $this );
|
270 |
+
} else {
|
271 |
+
new Frontend( $this );
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Execute Plugin
|
277 |
+
*/
|
278 |
+
public function run() {
|
279 |
+
$this->get( "loader" )->run();
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Set a variable to DI with given name
|
284 |
+
* @param string $name
|
285 |
+
* @param mixed $variable
|
286 |
+
* @return $this
|
287 |
+
*/
|
288 |
+
public function set( $name, $variable ) {
|
289 |
+
// It is a function
|
290 |
+
if( is_callable( $variable ) )
|
291 |
+
$variable = $variable();
|
292 |
+
|
293 |
+
// Add it to services
|
294 |
+
$this->services[$name] = $variable;
|
295 |
+
|
296 |
+
return $this;
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Get given name index from DI
|
301 |
+
* @param string $name
|
302 |
+
* @return mixed|null
|
303 |
+
*/
|
304 |
+
public function get( $name ) {
|
305 |
+
return (isset( $this->services[$name] )) ? $this->services[$name] : null;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @return string
|
310 |
+
*/
|
311 |
+
public function getVersion() {
|
312 |
+
return self::VERSION;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* @return string
|
317 |
+
*/
|
318 |
+
public function getName() {
|
319 |
+
return self::NAME;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
public static function getSlug() {
|
326 |
+
return plugin_basename( dirname( dirname( dirname( __FILE__ ) ) ) );
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Get path to main plugin file
|
331 |
+
* @return string
|
332 |
+
*/
|
333 |
+
public function getPath() {
|
334 |
+
return dirname( dirname( __FILE__ ) );
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Get main plugin url
|
339 |
+
* @return type
|
340 |
+
*/
|
341 |
+
public function getUrl() {
|
342 |
+
return plugin_dir_url( dirname( __FILE__ ) );
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* @return array|mixed|object
|
347 |
+
*/
|
348 |
+
public function getCPULoadSetting() {
|
349 |
+
$options = $this->get( "settings" );
|
350 |
+
$setting = $options->getCpuLoad();
|
351 |
+
|
352 |
+
switch ( $setting ) {
|
353 |
+
case "high":
|
354 |
+
$cpuLoad = 0;
|
355 |
+
break;
|
356 |
+
|
357 |
+
case "medium":
|
358 |
+
$cpuLoad = 1000;
|
359 |
+
break;
|
360 |
+
|
361 |
+
case "low":
|
362 |
+
$cpuLoad = 3000;
|
363 |
+
break;
|
364 |
+
|
365 |
+
case "default":
|
366 |
+
default:
|
367 |
+
$cpuLoad = 1000;
|
368 |
+
}
|
369 |
+
|
370 |
+
return $cpuLoad;
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Load language file
|
375 |
+
*/
|
376 |
+
public function loadLanguages() {
|
377 |
+
$languagesDirectory = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR;
|
378 |
+
$languagesDirectory.= "vars" . DIRECTORY_SEPARATOR . "languages" . DIRECTORY_SEPARATOR;
|
379 |
+
|
380 |
+
// Set filter for plugins languages directory
|
381 |
+
$languagesDirectory = apply_filters( "wpstg_languages_directory", $languagesDirectory );
|
382 |
+
|
383 |
+
// Traditional WP plugin locale filter
|
384 |
+
$locale = apply_filters( "plugin_locale", get_locale(), "wpstg" );
|
385 |
+
$moFile = sprintf( '%1$s-%2$s.mo', "wpstg", $locale );
|
386 |
+
|
387 |
+
// Setup paths to current locale file
|
388 |
+
$moFileLocal = $languagesDirectory . $moFile;
|
389 |
+
$moFileGlobal = WP_LANG_DIR . DIRECTORY_SEPARATOR . "wpstg" . DIRECTORY_SEPARATOR . $moFile;
|
390 |
+
|
391 |
+
// Global file (/wp-content/languages/WPSTG)
|
392 |
+
if( file_exists( $moFileGlobal ) ) {
|
393 |
+
load_textdomain( "wpstg", $moFileGlobal );
|
394 |
+
}
|
395 |
+
// Local file (/wp-content/plugins/wp-staging/languages/)
|
396 |
+
elseif( file_exists( $moFileLocal ) ) {
|
397 |
+
load_textdomain( "wpstg", $moFileGlobal );
|
398 |
+
}
|
399 |
+
// Default file
|
400 |
+
else {
|
401 |
+
load_plugin_textdomain( "wpstg", false, $languagesDirectory );
|
402 |
+
}
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Check if it is a staging site
|
407 |
+
* @return bool
|
408 |
+
*/
|
409 |
+
private function isStagingSite() {
|
410 |
+
return ("true" === get_option( "wpstg_is_staging_site" ));
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* Initialize licensing functions
|
415 |
+
* @return boolean
|
416 |
+
*/
|
417 |
+
private function licensing() {
|
418 |
+
// Add licensing stuff if class exists
|
419 |
+
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
|
420 |
+
$licensing = new Backend\Pro\Licensing\Licensing();
|
421 |
+
}
|
422 |
+
return false;
|
423 |
+
}
|
424 |
+
|
425 |
+
}
|
apps/Frontend/Frontend.php
CHANGED
@@ -35,7 +35,6 @@ class Frontend extends InjectionAware
|
|
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 |
/**
|
35 |
|
36 |
$loader->addAction("init", $this, "checkPermissions");
|
37 |
$loader->addFilter("wp_before_admin_bar_render", $this, "changeSiteName");
|
|
|
38 |
}
|
39 |
|
40 |
/**
|
readme.txt
CHANGED
@@ -1,251 +1,235 @@
|
|
1 |
-
=== WP Staging - DB & File Duplicator & Migration ===
|
2 |
-
|
3 |
-
Author URL: https://wordpress.org/plugins/wp-staging
|
4 |
-
Plugin URL: https://wordpress.org/plugins/wp-staging
|
5 |
-
Contributors: ReneHermi, WP-Staging
|
6 |
-
Donate link: https://wordpress.org/plugins/wp-staging
|
7 |
-
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.
|
12 |
-
Stable tag: 2.0.
|
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
|
19 |
-
If you find
|
20 |
-
</strong>
|
21 |
-
<br /><br />
|
22 |
-
<strong>Note: </strong>
|
23 |
-
|
24 |
-
|
25 |
-
<
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
<
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
*
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
*
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
=
|
150 |
-
* New:
|
151 |
-
* New:
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
*
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
* Fix:
|
173 |
-
*
|
174 |
-
|
175 |
-
|
176 |
-
*
|
177 |
-
|
178 |
-
= 1.0
|
179 |
-
*
|
180 |
-
*
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
*
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
* Fix:
|
195 |
-
* Fix:
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
*
|
200 |
-
|
201 |
-
|
202 |
-
*
|
203 |
-
*
|
204 |
-
* Tweak:
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
*
|
209 |
-
*
|
210 |
-
* Fix:
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
*
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
*
|
219 |
-
*
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
* Fix:
|
225 |
-
*
|
226 |
-
|
227 |
-
|
228 |
-
* Fix:
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
= 0.
|
235 |
-
*
|
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>
|
1 |
+
=== WP Staging - DB & File Duplicator & Migration ===
|
2 |
+
|
3 |
+
Author URL: https://wordpress.org/plugins/wp-staging
|
4 |
+
Plugin URL: https://wordpress.org/plugins/wp-staging
|
5 |
+
Contributors: ReneHermi, WP-Staging
|
6 |
+
Donate link: https://wordpress.org/plugins/wp-staging
|
7 |
+
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.6
|
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 |
+
|
36 |
+
WP Staging helps you to prevent your website from being broken or unavailable because of installing untested plugin updates!
|
37 |
+
|
38 |
+
[youtube https://www.youtube.com/watch?v=Ye3fC6cdB3A]
|
39 |
+
|
40 |
+
= Main Features =
|
41 |
+
|
42 |
+
* <strong>Easy: </strong> Staging migration applicable for everyone. No configuration needed!
|
43 |
+
* <strong>Fast: </strong> Migration process lasts only a few seconds or minutes, depending on the site's size and server I/O power
|
44 |
+
* <strong>Safe: </strong> Access to staging site is granted for administrators only.
|
45 |
+
<br /><br />
|
46 |
+
<strong>More safe:</strong>
|
47 |
+
<br>
|
48 |
+
* Admin bar reflects that you are working on a staging site
|
49 |
+
* Extensive logging if duplication and migration process fails.
|
50 |
+
|
51 |
+
= What does not work or is not tested when running wordpress migration? =
|
52 |
+
|
53 |
+
* Wordpress migration of wordpress multisites (not tested)
|
54 |
+
* WordPress duplicating process on windows server (not tested but will probably work)
|
55 |
+
Edit: Duplication on windows server seems to be working well: [Read more](https://wordpress.org/support/topic/wont-copy-files?replies=5 "Read more")
|
56 |
+
|
57 |
+
|
58 |
+
<strong>Change your workflow of updating themes and plugins data:</strong>
|
59 |
+
|
60 |
+
1. Use WP Staging for migration of a production website to a clone site for staging purposes
|
61 |
+
2. Customize theme, configuration and plugins or install new plugins
|
62 |
+
3. Test everything on your staging site first
|
63 |
+
4. Everything running as expected? You are on the save side for migration of all these modifications to your production site!
|
64 |
+
|
65 |
+
|
66 |
+
<h3> Why should i use a staging website? </h3>
|
67 |
+
|
68 |
+
Plugin updates and theme customizations should be tested on a staging platform first. Its recommended to have the staging platform on the same server where the production website is located.
|
69 |
+
When you run a plugin update or plan to install a new one, it is a necessary task to check first the modifications on a clone of your production website.
|
70 |
+
This makes sure that any modifications is working on your website without throwing unexpected errors or preventing your site from loading. (Better known as the wordpress blank page error)
|
71 |
+
|
72 |
+
Testing a plugin update before installing it in live environment isn´t done very often by most user because existing staging solutions are too complex and need a lot of time to create a
|
73 |
+
up-to-date copy of your website.
|
74 |
+
|
75 |
+
Some people are also afraid of installing plugins updates because they follow the rule "never touch a running system" with having in mind that untested updates are increasing the risk of breaking their site.
|
76 |
+
I totally understand this and i am guilty as well here, but unfortunately this leads to one of the main reasons why WordPress installations are often outdated, not updated at all and unsecure due to this non-update behavior.
|
77 |
+
|
78 |
+
<strong> I think its time to change this, so i created "WP Staging" for WordPress migration of staging sites</strong>
|
79 |
+
|
80 |
+
<h3> Can´t i just use my local wordpress development copy for testing like xampp / lampp? </h3>
|
81 |
+
|
82 |
+
Nope! If your local hardware and software environment is not a 100% exact clone of your production server there is NO guarantee that every aspect
|
83 |
+
of your local copy is working on your live website exactely as you would expect it.
|
84 |
+
There are some obvious things like differences in the config of php and the server you are running but even such non obvious settings like the amount of ram or the
|
85 |
+
the cpu performance can lead to unexpected results on your production website.
|
86 |
+
There are dozens of other possible cause of failure which can not be handled well when you are testing your changes on a local staging platform.
|
87 |
+
|
88 |
+
This is were WP Staging steps in... Site cloning and staging site creation simplified!
|
89 |
+
|
90 |
+
<h3>I just want to migrate the database from one installation to another</h3>
|
91 |
+
If you want to migrate your local database to a already existing production site you can use a tool like WP Migrate DB.
|
92 |
+
WP Staging is only for creating a staging site with latest data from your production site. So it goes the opposite way of WP Migrate DB.
|
93 |
+
Both tools are excellent cooperating eachother.
|
94 |
+
|
95 |
+
<h3>What are the benefits compared to a plugin like Duplicator?</h3>
|
96 |
+
At first, i love the [Duplicator plugin](https://wordpress.org/plugins/duplicator/ "Duplicator plugin"). Duplicator is a great tool for migrating from development site to production one or from production site to development one.
|
97 |
+
The downside is that Duplicator needs adjustments, manually interventions and prerequirements for this. Duplicator also needs some skills to be able to create a development / staging site, where WP Staging does not need more than a click from you.
|
98 |
+
However, Duplicator is best placed to be a tool for first-time creation of your production site. This is something where it is very handy and powerful.
|
99 |
+
|
100 |
+
So, if you have created a local or webhosted development site and you need to migrate this site the first time to your production domain than you are doing nothing wrong with using
|
101 |
+
the Duplicator plugin! If you need all you latest production data like posts, updated plugins, theme data and styles in a testing environment than i recommend to use WP Staging instead!
|
102 |
+
|
103 |
+
= I need you feedback =
|
104 |
+
This plugin has been done in hundreds of hours to work on even the smallest shared webhosting package but i am limited in testing this only on a handful of different server so i need your help:
|
105 |
+
Please open a [support request](https://wordpress.org/support/plugin/wp-staging/ "support request") and describe your problem exactely. In wp-content/wp-staging/logs you find extended logfiles. Have a look at them and let me know the error-thrown lines.
|
106 |
+
|
107 |
+
|
108 |
+
= Important =
|
109 |
+
|
110 |
+
Per default the staging site will have permalinks disabled because the staging site will be cloned into a subfolder and regular permalinks are not working
|
111 |
+
without doing changes to your .htaccess or nginx.conf.
|
112 |
+
In the majority of cases this is abolutely fine for a staging platform and you still will be able to test new plugins and do some theme changes on your staging platform.
|
113 |
+
If you need the same permalink stucture on your staging platform as you have in your prodcution website you have to create a custom .htaccess for apache webserver
|
114 |
+
or to adjust your nginx.conf.
|
115 |
+
|
116 |
+
|
117 |
+
= How to install and setup? =
|
118 |
+
Install it via the admin dashboard and to 'Plugins', click 'Add New' and search the plugins for 'Staging'. Install the plugin with 'Install Now'.
|
119 |
+
After installation goto the settings page 'Staging' and do your adjustments there.
|
120 |
+
|
121 |
+
|
122 |
+
== Frequently Asked Questions ==
|
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.
|
130 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress.
|
131 |
+
3. Start Plugins->Staging
|
132 |
+
|
133 |
+
== Screenshots ==
|
134 |
+
|
135 |
+
1. Step 1. Create new WordPress staging site
|
136 |
+
2. Step 2. Scanning your website for files and database tables
|
137 |
+
3. Step 3. Wordpress Staging site creation in progress
|
138 |
+
4. Finish!
|
139 |
+
|
140 |
+
== Changelog ==
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
= 2.0.6 =
|
145 |
+
* Fix: Cancel Cloning button not working
|
146 |
+
* Fix: Limit max execution time to a maximum of 30sec to prevent high memory consumption and script timeouts
|
147 |
+
|
148 |
+
|
149 |
+
= 2.0.5 =
|
150 |
+
* New: Major version - Complete rewrite of the code base
|
151 |
+
* New: Batch processing allows to clone even huge sites without any timeouts
|
152 |
+
* New: Preparation for WP QUADS PRO with ability to copy file changes back to live site
|
153 |
+
* New: Bypass (broken) third party plugins during wp staging related ajax requests to prevent processing errors. Use a mu plugin for this.
|
154 |
+
|
155 |
+
= 1.1.6 =
|
156 |
+
* New: Add download link to WP Staging Beta Version 2.0.1
|
157 |
+
|
158 |
+
= 1.1.5 =
|
159 |
+
* Fix: Admin notice is throwing a false positive write permission error
|
160 |
+
* New: Move log folder to wp-content/uploads/wp-staging/logs
|
161 |
+
* New: Tested up to WP 4.7.3
|
162 |
+
|
163 |
+
= 1.1.4 =
|
164 |
+
* Fix: Fatal error Unsupported operand types
|
165 |
+
|
166 |
+
= 1.1.3 =
|
167 |
+
* New: Tested up to wp 4.7.2
|
168 |
+
* Fix: Arrows in drop down for folder selection are distorted
|
169 |
+
* Tweak: Show working log as default to make debugging easier
|
170 |
+
|
171 |
+
= 1.1.2 =
|
172 |
+
* Fix: Settings are not deleted when plugin is removed
|
173 |
+
* Fix: Staging site is available for non administrators
|
174 |
+
|
175 |
+
= 1.1.1 =
|
176 |
+
* Fix: Change rating url
|
177 |
+
|
178 |
+
= 1.1.0 =
|
179 |
+
* New: Tested up to WP 4.6
|
180 |
+
* New: Create a poll and ask what feature is most required
|
181 |
+
|
182 |
+
= 1.0.9 =
|
183 |
+
* Fix: Undefined WPSTG() warning
|
184 |
+
* Fix: Change compatibility version to wp 4.5.3
|
185 |
+
|
186 |
+
= 1.0.8 =
|
187 |
+
* Tested up to WP 4.5.2
|
188 |
+
|
189 |
+
= 1.0.7 =
|
190 |
+
* Fix: Activation hook is not fired and staging site is not working properly
|
191 |
+
* Performance: Increase default query copy limit to 1000
|
192 |
+
|
193 |
+
= 1.0.6 =
|
194 |
+
* Fix: Uninstalling plugin throwing error
|
195 |
+
* Fix: Error permission admin notice although permission issues are correct
|
196 |
+
|
197 |
+
|
198 |
+
= 1.0.5 =
|
199 |
+
* New: Tested up to WP 4.5
|
200 |
+
* Fix: Download system log not working
|
201 |
+
* Fix: Click on Optimizer "Select all | none | invert" links leads to jumping
|
202 |
+
* Tweak: Make clear that unselecting a checkbox will exlude table or file from copy process
|
203 |
+
* Tweak: Remove unnecessary text
|
204 |
+
* Tweak: Change beta notice in dashboard. WP Staging is stable
|
205 |
+
* Tweak: Change twitter handle to @wpstg
|
206 |
+
|
207 |
+
= 1.0.3 =
|
208 |
+
* Fix: Missing const MASHFS_VERSION
|
209 |
+
* Fix: Remove error "table XY has been created, BUT inserting rows failed."
|
210 |
+
* Fix: Not tested up to 4.4.2 message shown although it's tested up to WP 4.4.2
|
211 |
+
* New: Disable either free or pro version and does not allow to have both version enabled at the same time
|
212 |
+
|
213 |
+
= 1.0.2 =
|
214 |
+
* Tweak: Change setting description of uninstall option
|
215 |
+
* Tweak: Lower tags in readme.txt
|
216 |
+
|
217 |
+
= 1.0.1 =
|
218 |
+
* New: Orange colored admin bar on staging site for better visualization and comparision between production live site and staging site
|
219 |
+
* Tweak: Remove contact link on multisite notification
|
220 |
+
|
221 |
+
= 1.0.0 =
|
222 |
+
* Fix: Do not follow symlinks during file copy process
|
223 |
+
* Fix: css error
|
224 |
+
* Fix: Show "not-compatible" notice only when blog version is higher than plugin tested version.
|
225 |
+
* Fix: undefined var $size
|
226 |
+
* Fix: Check if $path is null before writing to remaining_files.json
|
227 |
+
* Fix: $db_helper undefined message
|
228 |
+
* Fix: Skip non utf8 encoded files during copying process
|
229 |
+
|
230 |
+
Complete changelog: [https://wp-staging.com/changelog.txt](https://wp-staging.com/changelog.txt)
|
231 |
+
|
232 |
+
== Upgrade Notice ==
|
233 |
+
|
234 |
+
= 2.0.2 =
|
235 |
+
2.0.2 * New: Batch processing allows to clone even huge sites without any timeouts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uninstall.php
CHANGED
@@ -1,39 +1,89 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
*
|
9 |
-
*
|
10 |
-
* @
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Backend;
|
4 |
+
|
5 |
+
use WPStaging\Backend\Optimizer\Optimizer;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Uninstall WP-Staging
|
9 |
+
*
|
10 |
+
* @package WPSTG
|
11 |
+
* @subpackage Uninstall
|
12 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
13 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
14 |
+
* @since 0.9.0
|
15 |
+
*/
|
16 |
+
// No direct access
|
17 |
+
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" );
|
51 |
+
delete_option( "wpstg_version" );
|
52 |
+
delete_option( "wpstg_installDate" );
|
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();
|
wp-staging.php
CHANGED
@@ -1,56 +1,80 @@
|
|
1 |
-
<?php
|
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.
|
10 |
-
* Text Domain: wpstg
|
11 |
-
* Domain Path: /languages/
|
12 |
-
|
13 |
-
*
|
14 |
-
* WP-Staging is free software: you can redistribute it and/or modify
|
15 |
-
* it under the terms of the GNU General Public License as published by
|
16 |
-
* the Free Software Foundation, either version 2 of the License, or
|
17 |
-
* any later version.
|
18 |
-
*
|
19 |
-
* WP-Staging is distributed in the hope that it will be useful,
|
20 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 |
-
* GNU General Public License for more details.
|
23 |
-
*
|
24 |
-
* You should have received a copy of the GNU General Public License
|
25 |
-
* along with Staging. If not, see <http://www.gnu.org/licenses/>.
|
26 |
-
*
|
27 |
-
* @package WPSTG
|
28 |
-
* @category Core
|
29 |
-
* @author René Hermenau, Ilgıt Yıldırım
|
30 |
-
*/
|
31 |
-
|
32 |
-
// No Direct Access
|
33 |
-
if (!defined("WPINC"))
|
34 |
-
{
|
35 |
-
die;
|
36 |
-
}
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
//
|
43 |
-
if (
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
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.6
|
10 |
+
* Text Domain: wpstg
|
11 |
+
* Domain Path: /languages/
|
12 |
+
|
13 |
+
*
|
14 |
+
* WP-Staging is free software: you can redistribute it and/or modify
|
15 |
+
* it under the terms of the GNU General Public License as published by
|
16 |
+
* the Free Software Foundation, either version 2 of the License, or
|
17 |
+
* any later version.
|
18 |
+
*
|
19 |
+
* WP-Staging is distributed in the hope that it will be useful,
|
20 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 |
+
* GNU General Public License for more details.
|
23 |
+
*
|
24 |
+
* You should have received a copy of the GNU General Public License
|
25 |
+
* along with Staging. If not, see <http://www.gnu.org/licenses/>.
|
26 |
+
*
|
27 |
+
* @package WPSTG
|
28 |
+
* @category Core
|
29 |
+
* @author René Hermenau, Ilgıt Yıldırım
|
30 |
+
*/
|
31 |
+
|
32 |
+
// No Direct Access
|
33 |
+
if (!defined("WPINC"))
|
34 |
+
{
|
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) {
|
73 |
+
return $wp_filter;
|
74 |
+
});
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Inititalize WPStaging
|
79 |
+
*/
|
80 |
+
$wpStaging->run();
|