Version Description
- 2015-12-29 =
- Fixed: Backup names will use the time zone selected in general settings.
- Added: basic backup/restore logs.
- Added: An option to exclude files based on size (files larger than 25MB will be excluded by default)
- Added: An option to ignore the wordpress table prefix during backup/restore.
- Added: An option to check the mysql connection during restore.
- Added: A search and replace tool into the plugin dashboard.
- Changed: A .htaccess file will be placed in the temporary directories to prevent external access to the files.
- Changed: Files are no longer copied to a temporary location during backup.
- Changed: Database import is done before the rest of the files are extracted.
- Changed: siteurl option is updated during the database import.
- Changed: search and replace will not run when the URLs are similar.
- Changed: Increased the default values for memory_limit and max_execution_time from 512MB/300 to 1024MB/600.
- Removed: The use of wordpress' unzip_file (ziparchive will be used when available with pclzip as fallback)
Download this release
Release Info
Developer | wpacademy |
Plugin | WP Clone by WP Academy |
Version | 2.2.1 |
Comparing to | |
See all releases |
Code changes from version 2.2 to 2.2.1
- lib/css/style.css +19 -1
- lib/functions.php +590 -190
- lib/js/backupmanager.js +58 -6
- lib/view.php +57 -11
- readme.txt +35 -17
- wpclone.php +42 -4
lib/css/style.css
CHANGED
@@ -52,10 +52,12 @@
|
|
52 |
display: none;
|
53 |
}
|
54 |
|
|
|
|
|
|
|
55 |
div.info {
|
56 |
padding: 15px;
|
57 |
margin: 30px 0;
|
58 |
-
max-width: 60%;
|
59 |
background: #e1e1ea;
|
60 |
border-radius: 5px;
|
61 |
-moz-box-shadow: 5px 5px 15px #aaa;
|
@@ -98,6 +100,22 @@ table.restore-backup-options td, table.restore-backup-options th {
|
|
98 |
background: #fff0b3;
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
a.copy-button {
|
102 |
}
|
103 |
|
52 |
display: none;
|
53 |
}
|
54 |
|
55 |
+
.width-60 {
|
56 |
+
max-width: 60%;
|
57 |
+
}
|
58 |
div.info {
|
59 |
padding: 15px;
|
60 |
margin: 30px 0;
|
|
|
61 |
background: #e1e1ea;
|
62 |
border-radius: 5px;
|
63 |
-moz-box-shadow: 5px 5px 15px #aaa;
|
100 |
background: #fff0b3;
|
101 |
}
|
102 |
|
103 |
+
a#close-thickbox {
|
104 |
+
position: absolute;
|
105 |
+
top: 0;
|
106 |
+
right: 0;
|
107 |
+
font-weight: bold;
|
108 |
+
}
|
109 |
+
|
110 |
+
div#search-n-replace {
|
111 |
+
display: none;
|
112 |
+
position: relative;
|
113 |
+
}
|
114 |
+
|
115 |
+
div#search-n-replace-info{
|
116 |
+
min-height: 20px;
|
117 |
+
}
|
118 |
+
|
119 |
a.copy-button {
|
120 |
}
|
121 |
|
lib/functions.php
CHANGED
@@ -23,7 +23,18 @@ function wpa_db_backup_wpdb($destination)
|
|
23 |
$return = '';
|
24 |
|
25 |
// Get all of the tables
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
// Cycle through each provided table
|
28 |
foreach ($tables as $table) {
|
29 |
|
@@ -69,46 +80,50 @@ function wpa_db_backup_wpdb($destination)
|
|
69 |
/**
|
70 |
* @link http://davidwalsh.name/backup-mysql-database-php
|
71 |
*/
|
72 |
-
function wpa_db_backup_direct($destination
|
73 |
{
|
74 |
|
75 |
global $wpdb;
|
76 |
-
$
|
|
|
77 |
if ( false === $link ) {
|
78 |
wpa_backup_error('db', mysql_error() );
|
79 |
}
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
if($
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
{
|
92 |
-
$tables[] = $row[0];
|
93 |
-
}
|
94 |
}
|
95 |
-
|
96 |
-
{
|
97 |
-
|
|
|
|
|
|
|
|
|
98 |
}
|
|
|
|
|
99 |
$return = '';
|
100 |
-
|
101 |
foreach($tables as $table)
|
102 |
{
|
103 |
|
104 |
-
$result = mysql_query('SELECT * FROM '
|
105 |
if ( false === $result ) {
|
106 |
wpa_backup_error('db', mysql_error() );
|
107 |
}
|
108 |
$num_fields = mysql_num_fields($result);
|
109 |
|
110 |
$return.= 'DROP TABLE IF EXISTS '.$table.';';
|
111 |
-
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '
|
112 |
$return.= "\n\n".$row2[1].";\n\n";
|
113 |
|
114 |
for ($i = 0; $i < $num_fields; $i++)
|
@@ -141,9 +156,10 @@ function wpa_insert_data($name, $size)
|
|
141 |
global $current_user;
|
142 |
$backup = array(
|
143 |
$time => array(
|
144 |
-
'name'
|
145 |
-
'
|
146 |
-
'
|
|
|
147 |
)
|
148 |
);
|
149 |
|
@@ -162,30 +178,65 @@ function wpa_insert_data($name, $size)
|
|
162 |
function CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb = false )
|
163 |
{
|
164 |
$folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
|
165 |
-
$
|
166 |
-
$zipFileName
|
167 |
-
$exclude
|
168 |
-
$dbonly
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
wpa_backup_error ( 'file', sprintf( __( 'Unable to create the temporary backup directory,please make sure that PHP has permission to write into the <code>%s</code> directory.' ), WPCLONE_DIR_BACKUP ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
-
if( false === $dbonly )
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
wpa_save_prefix($folderToBeZipped);
|
177 |
/* error handler is called from within the db backup functions */
|
178 |
if ( $use_wpdb ) {
|
|
|
179 |
wpa_db_backup_wpdb( $folderToBeZipped );
|
180 |
} else {
|
|
|
181 |
wpa_db_backup_direct( $folderToBeZipped );
|
182 |
}
|
|
|
183 |
|
184 |
/* error haldler is called from within the wpa_zip function */
|
|
|
185 |
wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
|
186 |
-
|
187 |
wpa_delete_dir( $folderToBeZipped );
|
188 |
-
|
|
|
|
|
|
|
|
|
|
|
189 |
}
|
190 |
|
191 |
function DeleteWPBackupZip($nm)
|
@@ -195,7 +246,12 @@ function DeleteWPBackupZip($nm)
|
|
195 |
if( empty( $backups ) || ! isset( $backups[$nm] ) ) {
|
196 |
return array(
|
197 |
'status' => 'failed',
|
198 |
-
'msg' => 'Something is not quite right here,
|
|
|
|
|
|
|
|
|
|
|
199 |
}
|
200 |
|
201 |
if ( file_exists( WPCLONE_DIR_BACKUP . $backups[$nm]['name'] ) ) {
|
@@ -243,48 +299,31 @@ function bytesToSize($bytes, $precision = 2)
|
|
243 |
}
|
244 |
}
|
245 |
|
246 |
-
function
|
247 |
-
|
248 |
-
|
249 |
-
$
|
250 |
-
$
|
251 |
-
$
|
252 |
-
$urlEndPos = strpos($fileContent, '"', $urlStartPos);
|
253 |
-
$backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
|
254 |
return $backupSiteUrl;
|
|
|
255 |
}
|
256 |
|
257 |
-
function
|
258 |
-
{
|
259 |
-
global $wp_filesystem;
|
260 |
-
$dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
|
261 |
-
/* we don't want to nuke the curret database if if something went wrong with the above operation */
|
262 |
-
if ( false === $dbFileContent ) {
|
263 |
-
wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
|
264 |
-
}
|
265 |
|
|
|
266 |
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
}
|
272 |
|
273 |
-
mysql_select_db( DB_NAME, $
|
274 |
-
mysql_set_charset(DB_CHARSET, $
|
275 |
|
276 |
-
|
277 |
-
foreach ($res AS $query) {
|
278 |
-
mysql_query($query, $conn);
|
279 |
-
}
|
280 |
-
mysql_close($conn);
|
281 |
-
$backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
|
282 |
-
$currentSiteUrl = site_url();
|
283 |
-
$backupSiteUrl = untrailingslashit($backupSiteUrl);
|
284 |
-
$currentSiteUrl = untrailingslashit($currentSiteUrl);
|
285 |
-
$report = wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
|
286 |
|
287 |
-
return array( 'url' => $currentSiteUrl, 'report' => $report );
|
288 |
}
|
289 |
|
290 |
/**
|
@@ -292,114 +331,142 @@ function processConfigAndDatabaseFile($databaseFileInZip)
|
|
292 |
* @param type $replace URL of the current site.
|
293 |
* @return type total time it took for the operation.
|
294 |
*/
|
295 |
-
function wpa_safe_replace_wrapper ( $search, $replace ) {
|
296 |
if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
|
297 |
require_once 'icit_srdb_replacer.php';
|
298 |
}
|
299 |
-
|
300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
$all_tables = array();
|
302 |
-
@mysql_select_db( DB_NAME, $connection );
|
303 |
-
mysql_set_charset( DB_CHARSET, $connection );
|
304 |
-
$all_tables_mysql = @mysql_query( 'SHOW TABLES LIKE "' . $wpdb->prefix . '%"', $connection );
|
305 |
|
306 |
-
if (
|
307 |
-
|
|
|
|
|
308 |
} else {
|
309 |
-
|
310 |
-
|
311 |
-
}
|
312 |
}
|
313 |
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
$report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
|
|
|
|
|
315 |
return $report;
|
316 |
}
|
317 |
|
318 |
-
|
319 |
-
function processRestoringBackup($url, $zipmode) {
|
320 |
-
wpa_cleanup( true );
|
321 |
-
if (!is_string($url) || '' == $url) {
|
322 |
-
wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
|
323 |
-
}
|
324 |
|
325 |
global $wp_filesystem;
|
326 |
$temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
|
327 |
-
$
|
328 |
-
if ( is_wp_error($temp_dir_err) ) {
|
329 |
-
wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
|
330 |
-
}
|
331 |
-
$pathParts = pathinfo($url);
|
332 |
-
$zipFilename = wpa_fetch_file($url);
|
333 |
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
|
338 |
-
$unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
|
339 |
-
}
|
340 |
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
}
|
345 |
-
/* check the table prefixes */
|
346 |
-
$old_db_prefix = $unzippedFolderPath . '/prefix.txt';
|
347 |
-
$prefix = wpa_check_prefix($old_db_prefix);
|
348 |
-
if ($prefix) {
|
349 |
-
wpa_replace_prefix( $prefix );
|
350 |
-
}
|
351 |
-
$wp_filesystem->delete( $old_db_prefix );
|
352 |
-
/* import db */
|
353 |
-
$databaseFile = $unzippedFolderPath . '/database.sql';
|
354 |
-
$currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
|
355 |
-
/* */
|
356 |
-
$wp_filesystem->delete( $databaseFile );
|
357 |
|
358 |
-
|
359 |
|
|
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
}
|
367 |
|
368 |
-
|
|
|
369 |
|
370 |
-
|
371 |
|
372 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
|
374 |
-
|
375 |
-
/* copy pasta (more or less) from serialized search and replace script by interconnectit */
|
376 |
-
$time = array_sum( explode( ' ', $report[ 'end' ] ) ) - array_sum( explode( ' ', $report[ 'start' ] ) );
|
377 |
-
printf( '<div class="info"><p>Search and replace scanned <strong>%d</strong> tables with a total of <strong>%d</strong> rows, ' , $report['tables'], $report['rows'] );
|
378 |
-
printf( '<strong>%d</strong> cells were changed and <strong>%d</strong> db updates were performed. it took <strong>%f</strong> seconds.</p></div>', $report['change'], $report['updates'], $time );
|
379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
|
381 |
-
if ( ! empty( $report['errors'] ) && is_array( $report['errors'] ) ) {
|
382 |
-
echo '<div class="error">';
|
383 |
-
echo '<h3>The following errors were encountered during the search and replace process.</h3>';
|
384 |
-
foreach( $report['errors'] as $error )
|
385 |
-
echo '<p>' . $error . '</p>';
|
386 |
-
echo '</div>';
|
387 |
-
}
|
388 |
|
389 |
-
|
390 |
|
391 |
-
|
|
|
|
|
|
|
|
|
392 |
|
393 |
-
|
|
|
|
|
394 |
|
395 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
}
|
397 |
|
|
|
|
|
398 |
}
|
399 |
|
400 |
function wpa_save_prefix($path) {
|
401 |
global $wpdb;
|
402 |
-
$prefix = $wpdb->prefix;
|
403 |
$file = $path . '/prefix.txt';
|
404 |
if ( is_dir($path) && is_writable($path) ) {
|
405 |
file_put_contents($file, $prefix);
|
@@ -434,32 +501,36 @@ function wpa_check_prefix($file) {
|
|
434 |
* @return as false in the event of failure.
|
435 |
*/
|
436 |
function wpa_unzip($zipfile, $path, $zipmode = false){
|
437 |
-
|
|
|
|
|
|
|
438 |
|
439 |
if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
|
440 |
$previous_encoding = mb_internal_encoding();
|
441 |
mb_internal_encoding('ISO-8859-1');
|
442 |
}
|
443 |
|
444 |
-
define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
|
445 |
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
446 |
$z = new PclZip($zipfile);
|
447 |
-
|
|
|
448 |
|
449 |
-
|
|
|
|
|
|
|
450 |
|
451 |
-
if ( $files
|
452 |
wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
|
453 |
}
|
454 |
-
|
455 |
-
}
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
wpa_backup_error( 'unzip', $z->get_error_message(), true );
|
460 |
-
}
|
461 |
-
return true;
|
462 |
}
|
|
|
463 |
}
|
464 |
/**
|
465 |
* @since 2.0.6
|
@@ -469,21 +540,37 @@ function wpa_unzip($zipfile, $path, $zipmode = false){
|
|
469 |
*/
|
470 |
function wpa_zip($zip_name, $folder, $zipmode = false){
|
471 |
if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
|
|
|
472 |
define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
|
473 |
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
|
474 |
$z = new PclZip($zip_name);
|
475 |
-
$v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
|
476 |
if ($v_list == 0) {
|
477 |
wpa_backup_error( 'pclzip', $z->errorInfo(true) );
|
478 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
} else {
|
|
|
480 |
$z = new ZipArchive();
|
481 |
if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
|
482 |
-
wpa_backup_error( 'zip', $z );
|
483 |
}
|
484 |
wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
|
|
|
|
|
|
|
485 |
$z->close();
|
|
|
486 |
}
|
|
|
|
|
487 |
}
|
488 |
|
489 |
function wpa_ziparc($zip, $dir, $base) {
|
@@ -503,11 +590,16 @@ function wpa_ziparc($zip, $dir, $base) {
|
|
503 |
* @since 2.0.6
|
504 |
*/
|
505 |
function wpa_bump_limits(){
|
506 |
-
$
|
507 |
-
$
|
508 |
-
|
509 |
-
|
|
|
|
|
|
|
|
|
510 |
}
|
|
|
511 |
/**
|
512 |
* @since 2.0.6
|
513 |
*/
|
@@ -527,7 +619,7 @@ function wpa_wpfs_init(){
|
|
527 |
}
|
528 |
|
529 |
$form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
|
530 |
-
$extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
|
531 |
$type = '';
|
532 |
if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
|
533 |
return true;
|
@@ -574,25 +666,36 @@ function wpa_copy($source, $target) {
|
|
574 |
/**
|
575 |
* @since 2.0.6
|
576 |
*/
|
577 |
-
function wpa_replace_prefix($
|
|
|
578 |
$wpconfig = wpa_wpconfig_path();
|
579 |
global $wp_filesystem;
|
580 |
|
581 |
if ( ! $wp_filesystem->is_writable($wpconfig) ) {
|
582 |
if( false === $wp_filesystem->chmod( $wpconfig ) )
|
583 |
wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
584 |
}
|
585 |
|
586 |
-
$
|
587 |
-
$
|
588 |
-
|
589 |
-
$fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
|
590 |
-
$wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
|
591 |
}
|
592 |
/**
|
593 |
* @since 2.0.6
|
594 |
*/
|
595 |
function wpa_create_backup (){
|
|
|
596 |
if( true === is_multisite() )
|
597 |
die( 'wpclone does not work on multisite installs.' );
|
598 |
if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
|
@@ -601,13 +704,18 @@ function wpa_create_backup (){
|
|
601 |
wpa_cleanup();
|
602 |
$use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
|
603 |
$backupName = wpa_backup_name();
|
|
|
|
|
|
|
604 |
|
605 |
$zipmode = isset($_POST['zipmode']) ? true : false;
|
606 |
list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
|
607 |
|
608 |
wpa_insert_data($zipFileName, $zipSize);
|
609 |
-
$backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
|
610 |
$zipSize = bytesToSize($zipSize);
|
|
|
|
|
611 |
echo <<<EOF
|
612 |
|
613 |
<h1>Backup Successful!</h1>
|
@@ -622,6 +730,8 @@ Here is your backup file : <br />
|
|
622 |
|
623 |
(Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
|
624 |
EOF;
|
|
|
|
|
625 |
}
|
626 |
/**
|
627 |
* @since 2.0.6
|
@@ -639,23 +749,23 @@ function wpa_remove_backup(){
|
|
639 |
*/
|
640 |
function wpa_wpconfig_path () {
|
641 |
|
642 |
-
|
643 |
|
644 |
-
|
645 |
-
|
646 |
|
647 |
-
|
648 |
-
|
649 |
|
650 |
-
|
651 |
-
|
652 |
|
653 |
-
|
654 |
-
|
655 |
|
656 |
-
|
657 |
|
658 |
-
|
659 |
|
660 |
}
|
661 |
|
@@ -663,17 +773,22 @@ function wpa_fetch_file($path){
|
|
663 |
$z = pathinfo($path);
|
664 |
global $wp_filesystem;
|
665 |
if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
|
|
|
666 |
return WPCLONE_DIR_BACKUP . $z['basename'];
|
667 |
}
|
668 |
else {
|
|
|
669 |
$url = download_url($path, 750);
|
670 |
-
if ( is_wp_error($url) )
|
|
|
|
|
|
|
671 |
return $url;
|
672 |
}
|
673 |
}
|
674 |
|
675 |
function wpa_backup_name() {
|
676 |
-
$backup_name = 'wpclone_backup_' .
|
677 |
$backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
|
678 |
$rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
|
679 |
$backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
|
@@ -683,11 +798,12 @@ function wpa_backup_name() {
|
|
683 |
function wpa_backup_error($error, $data, $restore = false) {
|
684 |
|
685 |
$temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
|
|
|
686 |
|
687 |
if( !file_exists( $temp_dir ) ) {
|
688 |
unset($temp_dir);
|
689 |
}
|
690 |
-
|
691 |
switch ( $error ) :
|
692 |
/* during backup */
|
693 |
case 'file' :
|
@@ -713,7 +829,7 @@ function wpa_backup_error($error, $data, $restore = false) {
|
|
713 |
$error = __( 'while cloning the database' );
|
714 |
break;
|
715 |
case 'unzip' :
|
716 |
-
$error = __( 'while extracting the zip file using
|
717 |
break;
|
718 |
case 'pclunzip' :
|
719 |
$error = __( 'while extracting the zip file using the PclZip library' );
|
@@ -733,7 +849,7 @@ function wpa_backup_error($error, $data, $restore = false) {
|
|
733 |
printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
|
734 |
echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
|
735 |
if( isset( $temp_dir ) ) {
|
736 |
-
printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $
|
737 |
echo '</div>';
|
738 |
if( $restore ) {
|
739 |
global $wp_filesystem;
|
@@ -813,7 +929,8 @@ function wpa_excluded_dirs() {
|
|
813 |
$ex = trim( $ex );
|
814 |
if( '' !== $ex ) {
|
815 |
$ex = trim( $ex, "/\\" );
|
816 |
-
|
|
|
817 |
}
|
818 |
}
|
819 |
}
|
@@ -828,7 +945,7 @@ function wpa_wpc_dir_size( $path ) {
|
|
828 |
|
829 |
foreach( $i as $file => $info ) {
|
830 |
|
831 |
-
if(
|
832 |
$size += $info->getSize();
|
833 |
$files++;
|
834 |
|
@@ -836,7 +953,16 @@ function wpa_wpc_dir_size( $path ) {
|
|
836 |
|
837 |
}
|
838 |
|
839 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
840 |
|
841 |
}
|
842 |
|
@@ -845,7 +971,7 @@ function wpa_wpc_db_size() {
|
|
845 |
global $wpdb;
|
846 |
$sql = 'SELECT sum(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = "' . DB_NAME . '"';
|
847 |
$size = $wpdb->get_var( $sql );
|
848 |
-
return
|
849 |
|
850 |
}
|
851 |
|
@@ -906,11 +1032,285 @@ function wpa_wpc_scan_dir() {
|
|
906 |
function wpa_wpc_filter_list( $a, $b ) {
|
907 |
|
908 |
$return = array();
|
909 |
-
foreach( $a as $v )
|
910 |
-
|
|
|
|
|
|
|
|
|
911 |
return array_keys( $return );
|
912 |
|
913 |
}
|
914 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
915 |
|
916 |
/* end of file */
|
23 |
$return = '';
|
24 |
|
25 |
// Get all of the tables
|
26 |
+
if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
|
27 |
+
wpa_wpc_log( 'ignore prefix enabled, backing up all the tables' );
|
28 |
+
$tables = $wpdb->get_col('SHOW TABLES');
|
29 |
+
|
30 |
+
} else {
|
31 |
+
wpa_wpc_log( sprintf( 'backing up tables with "%s" prefix', $wpdb->prefix ) );
|
32 |
+
$tables = $wpdb->get_col('SHOW TABLES LIKE "' . $wpdb->prefix . '%"');
|
33 |
+
|
34 |
+
}
|
35 |
+
|
36 |
+
wpa_wpc_log( sprintf( 'number of tables to backup - %d', count( $tables ) ) );
|
37 |
+
|
38 |
// Cycle through each provided table
|
39 |
foreach ($tables as $table) {
|
40 |
|
80 |
/**
|
81 |
* @link http://davidwalsh.name/backup-mysql-database-php
|
82 |
*/
|
83 |
+
function wpa_db_backup_direct($destination)
|
84 |
{
|
85 |
|
86 |
global $wpdb;
|
87 |
+
$prefix = $wpdb->prefix;
|
88 |
+
$link = wpa_wpc_mysql_connect();
|
89 |
if ( false === $link ) {
|
90 |
wpa_backup_error('db', mysql_error() );
|
91 |
}
|
92 |
+
|
93 |
+
$tables = array();
|
94 |
+
|
95 |
+
if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
|
96 |
+
wpa_wpc_log( 'ignore prefix enabled, backing up all the tables' );
|
97 |
+
$result = mysql_query('SHOW TABLES');
|
98 |
+
|
99 |
+
} else {
|
100 |
+
wpa_wpc_log( sprintf( 'backing up tables with "%s" prefix', $prefix ) );
|
101 |
+
$result = mysql_query('SHOW TABLES LIKE "' . $prefix . '%"');
|
102 |
+
|
|
|
|
|
|
|
103 |
}
|
104 |
+
|
105 |
+
if ( false === $result ) {
|
106 |
+
wpa_backup_error('db', mysql_error() );
|
107 |
+
}
|
108 |
+
|
109 |
+
while( $row = mysql_fetch_row( $result ) ) {
|
110 |
+
$tables[] = $row[0];
|
111 |
}
|
112 |
+
|
113 |
+
wpa_wpc_log( sprintf( 'number of tables to backup - %d', count( $tables ) ) );
|
114 |
$return = '';
|
115 |
+
|
116 |
foreach($tables as $table)
|
117 |
{
|
118 |
|
119 |
+
$result = mysql_query( 'SELECT * FROM ' . $table, $link );
|
120 |
if ( false === $result ) {
|
121 |
wpa_backup_error('db', mysql_error() );
|
122 |
}
|
123 |
$num_fields = mysql_num_fields($result);
|
124 |
|
125 |
$return.= 'DROP TABLE IF EXISTS '.$table.';';
|
126 |
+
$row2 = mysql_fetch_row( mysql_query( 'SHOW CREATE TABLE ' . $table, $link ) );
|
127 |
$return.= "\n\n".$row2[1].";\n\n";
|
128 |
|
129 |
for ($i = 0; $i < $num_fields; $i++)
|
156 |
global $current_user;
|
157 |
$backup = array(
|
158 |
$time => array(
|
159 |
+
'name' => $name . '.zip',
|
160 |
+
'log' => $name . '.log',
|
161 |
+
'creator' => $current_user->user_login,
|
162 |
+
'size' => $size
|
163 |
)
|
164 |
);
|
165 |
|
178 |
function CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb = false )
|
179 |
{
|
180 |
$folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
|
181 |
+
$htaccess = "<Files>\r\n\tOrder allow,deny\r\n\tDeny from all\r\n\tSatisfy all\r\n</Files>";
|
182 |
+
$zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
|
183 |
+
$exclude = wpa_excluded_dirs();
|
184 |
+
$dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
|
185 |
+
$skip = 25 * 1024 * 1024;
|
186 |
+
|
187 |
+
if( isset( $_POST['skipfiles'] ) && '' !== $_POST['skipfiles'] ) {
|
188 |
+
|
189 |
+
if( 0 === $_POST['skipfiles'] ) {
|
190 |
+
$skip = false;
|
191 |
|
192 |
+
} else {
|
193 |
+
$skip = $_POST['skipfiles'] * 1024 * 1024;
|
194 |
+
|
195 |
+
}
|
196 |
+
|
197 |
+
}
|
198 |
+
|
199 |
+
if( false === mkdir( $folderToBeZipped ) ) {
|
200 |
wpa_backup_error ( 'file', sprintf( __( 'Unable to create the temporary backup directory,please make sure that PHP has permission to write into the <code>%s</code> directory.' ), WPCLONE_DIR_BACKUP ) );
|
201 |
+
}
|
202 |
+
|
203 |
+
file_put_contents( $folderToBeZipped . '/.htaccess', $htaccess );
|
204 |
+
|
205 |
+
if( $dbonly ) {
|
206 |
+
wpa_wpc_log ( 'database only backup, no files will be copied' );
|
207 |
+
}
|
208 |
|
209 |
+
if( false === $dbonly ) {
|
210 |
+
if( $skip ) {
|
211 |
+
wpa_wpc_log( sprintf( 'files larger than %s will be excluded from the backup', bytesToSize( $skip ) ) );
|
212 |
+
}
|
213 |
+
wpa_wpc_log( 'generating file list' );
|
214 |
+
file_put_contents( $folderToBeZipped . '/file.list', serialize( wpa_wpc_get_filelist( WPCLONE_WP_CONTENT, $exclude, $skip ) ) );
|
215 |
+
wpa_wpc_log( 'finished generating file list' );
|
216 |
+
}
|
217 |
|
218 |
wpa_save_prefix($folderToBeZipped);
|
219 |
/* error handler is called from within the db backup functions */
|
220 |
if ( $use_wpdb ) {
|
221 |
+
wpa_wpc_log ( 'database backup started [wpdb]' );
|
222 |
wpa_db_backup_wpdb( $folderToBeZipped );
|
223 |
} else {
|
224 |
+
wpa_wpc_log ( 'database backup started' );
|
225 |
wpa_db_backup_direct( $folderToBeZipped );
|
226 |
}
|
227 |
+
wpa_wpc_log ( 'database backup finished' );
|
228 |
|
229 |
/* error haldler is called from within the wpa_zip function */
|
230 |
+
|
231 |
wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
|
232 |
+
|
233 |
wpa_delete_dir( $folderToBeZipped );
|
234 |
+
|
235 |
+
if( ! file_exists( $zipFileName ) ) {
|
236 |
+
wpa_backup_error( 'backup', 'possibly out of free disk space' );
|
237 |
+
}
|
238 |
+
$zipSize = filesize($zipFileName);
|
239 |
+
return array($backupName, $zipSize);
|
240 |
}
|
241 |
|
242 |
function DeleteWPBackupZip($nm)
|
246 |
if( empty( $backups ) || ! isset( $backups[$nm] ) ) {
|
247 |
return array(
|
248 |
'status' => 'failed',
|
249 |
+
'msg' => 'Something is not quite right here, refresh the backup list and try again later.' );
|
250 |
+
}
|
251 |
+
|
252 |
+
if( isset( $backups[$nm]['log'] ) && file_exists( WPCLONE_DIR_BACKUP . $backups[$nm]['log'] ) ) {
|
253 |
+
@unlink( WPCLONE_DIR_BACKUP . $backups[$nm]['log'] );
|
254 |
+
|
255 |
}
|
256 |
|
257 |
if ( file_exists( WPCLONE_DIR_BACKUP . $backups[$nm]['name'] ) ) {
|
299 |
}
|
300 |
}
|
301 |
|
302 |
+
function wpa_wpc_get_url( $db ) {
|
303 |
+
|
304 |
+
$pos = strpos( $db, 'siteurl' ) + 8;
|
305 |
+
$urlStartPos = strpos( $db, '"', $pos ) + 1;
|
306 |
+
$urlEndPos = strpos( $db, '"', $urlStartPos );
|
307 |
+
$backupSiteUrl = substr( $db, $urlStartPos, $urlEndPos - $urlStartPos );
|
|
|
|
|
308 |
return $backupSiteUrl;
|
309 |
+
|
310 |
}
|
311 |
|
312 |
+
function wpa_wpc_mysql_connect() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
+
$link = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
|
315 |
|
316 |
+
if ( false === $link ) {
|
317 |
+
mysql_close( $link );
|
318 |
+
sleep(2);
|
319 |
+
$link = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD, true );
|
320 |
}
|
321 |
|
322 |
+
mysql_select_db( DB_NAME, $link );
|
323 |
+
mysql_set_charset( DB_CHARSET, $link );
|
324 |
|
325 |
+
return $link;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
|
|
|
327 |
}
|
328 |
|
329 |
/**
|
331 |
* @param type $replace URL of the current site.
|
332 |
* @return type total time it took for the operation.
|
333 |
*/
|
334 |
+
function wpa_safe_replace_wrapper ( $search, $replace, $prefix ) {
|
335 |
if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
|
336 |
require_once 'icit_srdb_replacer.php';
|
337 |
}
|
338 |
+
|
339 |
+
wpa_wpc_log( 'search and replace started' );
|
340 |
+
|
341 |
+
$connection = wpa_wpc_mysql_connect();
|
342 |
+
|
343 |
+
|
344 |
+
if ( false === $connection ) {
|
345 |
+
|
346 |
+
wpa_wpc_log( 'mysql connection failure @ safe replace wrapper - error : "' . mysql_error( $connection ) . '" retrying..' );
|
347 |
+
|
348 |
+
mysql_close( $connection );
|
349 |
+
sleep(1);
|
350 |
+
$connection = wpa_wpc_mysql_connect();
|
351 |
+
|
352 |
+
}
|
353 |
+
|
354 |
$all_tables = array();
|
|
|
|
|
|
|
355 |
|
356 |
+
if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
|
357 |
+
wpa_wpc_log( 'ignore table prefix enabled, search and replace will scan all the tables in the database' );
|
358 |
+
$all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
|
359 |
+
|
360 |
} else {
|
361 |
+
$all_tables_mysql = @mysql_query( 'SHOW TABLES LIKE "' . $prefix . '%"', $connection );
|
362 |
+
|
|
|
363 |
}
|
364 |
|
365 |
+
while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
|
366 |
+
$all_tables[] = $table[ 0 ];
|
367 |
+
}
|
368 |
+
|
369 |
+
wpa_wpc_log( sprintf( 'there are %d tables to scan', count( $all_tables ) ) );
|
370 |
+
|
371 |
$report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
|
372 |
+
mysql_close( $connection );
|
373 |
+
wpa_wpc_log( 'search and replace finished' );
|
374 |
return $report;
|
375 |
}
|
376 |
|
377 |
+
function wpa_wpc_temp_dir() {
|
|
|
|
|
|
|
|
|
|
|
378 |
|
379 |
global $wp_filesystem;
|
380 |
$temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
|
381 |
+
$err = $wp_filesystem->mkdir( $temp_dir );
|
|
|
|
|
|
|
|
|
|
|
382 |
|
383 |
+
if ( is_wp_error( $err ) ) {
|
384 |
+
wpa_backup_error('dirrest', $err->get_error_message(), true );
|
385 |
+
}
|
|
|
|
|
|
|
386 |
|
387 |
+
$content = "<Files>\r\n\tOrder allow,deny\r\n\tDeny from all\r\n\tSatisfy all\r\n</Files>";
|
388 |
+
$file = trailingslashit( $temp_dir ) . '.htaccess';
|
389 |
+
$wp_filesystem->put_contents( $file, $content, 0644 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
|
391 |
+
return $temp_dir;
|
392 |
|
393 |
+
}
|
394 |
|
395 |
+
function processRestoringBackup($url, $zipmode) {
|
396 |
+
wpa_cleanup( true );
|
397 |
+
if (!is_string($url) || '' == $url) {
|
398 |
+
wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
|
399 |
+
}
|
|
|
400 |
|
401 |
+
global $wp_filesystem;
|
402 |
+
$GLOBALS['wpclone']['logfile'] = 'wpclone_restore_' . current_time( 'dS_M_Y_h-iA', false ) . '_' . wp_generate_password( 10, false ) . '.log';
|
403 |
|
404 |
+
wpa_wpc_log_start( 'restore' );
|
405 |
|
406 |
+
if( $zipmode ) {
|
407 |
+
define( 'PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP );
|
408 |
+
|
409 |
+
}
|
410 |
+
|
411 |
+
$temp_dir = wpa_wpc_temp_dir();
|
412 |
+
$site_url = site_url();
|
413 |
+
$permalink_url = admin_url( 'options-permalink.php' );
|
414 |
+
$zipfile = wpa_fetch_file($url);
|
415 |
+
$report = wpa_wpc_process_db( $zipfile, $zipmode );
|
416 |
+
$unzipped_folder = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
|
417 |
+
|
418 |
+
|
419 |
+
wpa_unzip( $zipfile, $temp_dir, $zipmode );
|
420 |
+
wpa_wpc_log( 'copying files..' );
|
421 |
+
wpa_copy( $unzipped_folder . '/wp-content', WPCLONE_WP_CONTENT );
|
422 |
+
|
423 |
+
wpa_wpc_log( 'deleting temp directory..' );
|
424 |
+
$wp_filesystem->delete( $temp_dir, true );
|
425 |
+
/* remove the zip file only if it was downloaded from an external location. */
|
426 |
+
$wptmp = explode( '.', $zipfile );
|
427 |
+
if ( in_array( 'tmp', $wptmp ) ) {
|
428 |
+
wpa_wpc_log( 'deleting downloaded zip file..' );
|
429 |
+
$wp_filesystem->delete( $zipfile );
|
430 |
+
}
|
431 |
|
432 |
+
wpa_wpc_log( 'restore finished' );
|
|
|
|
|
|
|
|
|
433 |
|
434 |
+
echo '<div class="width-60"><h1>Restore Successful!</h1>';
|
435 |
+
printf( 'Visit your restored site [ <a href="%s" target=blank>here</a> ]<br><br>', $site_url );
|
436 |
+
printf( '<strong>You may need to re-save your permalink structure <a href="%s" target=blank>Here</a></strong>', $permalink_url );
|
437 |
+
printf( '</br><a href="%s">log</a>', convertPathIntoUrl( WPCLONE_DIR_BACKUP . $GLOBALS['wpclone']['logfile'] ) );
|
438 |
+
unset( $GLOBALS['wpclone'] );
|
439 |
+
echo wpa_wpc_search_n_replace_report( $report );
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
|
442 |
+
}
|
443 |
|
444 |
+
function wpa_wpc_search_n_replace_report( $report ) {
|
445 |
+
|
446 |
+
if( is_string( $report ) ) {
|
447 |
+
return sprintf( '<div class="info"><p>%s</p></div>', $report );
|
448 |
+
}
|
449 |
|
450 |
+
$time = array_sum( explode( ' ', $report[ 'end' ] ) ) - array_sum( explode( ' ', $report[ 'start' ] ) );
|
451 |
+
$return = sprintf( '<div class="info"><p>Search and replace scanned <strong>%d</strong> tables with a total of <strong>%d</strong> rows. ' , $report['tables'], $report['rows'] );
|
452 |
+
$return .= sprintf( '<strong>%d</strong> cells were changed and <strong>%d</strong> db updates were performed in <strong>%f</strong> seconds.</p></div>', $report['change'], $report['updates'], $time );
|
453 |
|
454 |
+
if ( ! empty( $report['errors'] ) && is_array( $report['errors'] ) ) {
|
455 |
+
$return .= '<div>';
|
456 |
+
$return .= '<h4>search and replace returned the following errors.</h4>';
|
457 |
+
foreach( $report['errors'] as $error ) {
|
458 |
+
$return .= '<p class="error">' . $error . '</p>';
|
459 |
+
}
|
460 |
+
$return .= '</div>';
|
461 |
}
|
462 |
|
463 |
+
return $return;
|
464 |
+
|
465 |
}
|
466 |
|
467 |
function wpa_save_prefix($path) {
|
468 |
global $wpdb;
|
469 |
+
$prefix = $wpdb->prefix;
|
470 |
$file = $path . '/prefix.txt';
|
471 |
if ( is_dir($path) && is_writable($path) ) {
|
472 |
file_put_contents($file, $prefix);
|
501 |
* @return as false in the event of failure.
|
502 |
*/
|
503 |
function wpa_unzip($zipfile, $path, $zipmode = false){
|
504 |
+
|
505 |
+
if ( $zipmode || ( ! in_array('ZipArchive', get_declared_classes() ) || ! class_exists( 'ZipArchive' ) ) ) {
|
506 |
+
|
507 |
+
wpa_wpc_log( 'extracting archive using pclzip' );
|
508 |
|
509 |
if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
|
510 |
$previous_encoding = mb_internal_encoding();
|
511 |
mb_internal_encoding('ISO-8859-1');
|
512 |
}
|
513 |
|
|
|
514 |
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
515 |
$z = new PclZip($zipfile);
|
516 |
+
|
517 |
+
$files = $z->extract( PCLZIP_OPT_PATH, $path );
|
518 |
|
519 |
+
if ( isset( $previous_encoding ) ) {
|
520 |
+
mb_internal_encoding( $previous_encoding );
|
521 |
+
|
522 |
+
}
|
523 |
|
524 |
+
if ( $files === 0 ) {
|
525 |
wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
|
526 |
}
|
527 |
+
|
528 |
+
} else {
|
529 |
+
wpa_wpc_log( 'extracting archive using ziparchive' );
|
530 |
+
wpa_wpc_unzip( $zipfile, $path );
|
531 |
+
|
|
|
|
|
|
|
532 |
}
|
533 |
+
|
534 |
}
|
535 |
/**
|
536 |
* @since 2.0.6
|
540 |
*/
|
541 |
function wpa_zip($zip_name, $folder, $zipmode = false){
|
542 |
if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
|
543 |
+
wpa_wpc_log( 'archiving files using pclzip' );
|
544 |
define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
|
545 |
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
|
546 |
$z = new PclZip($zip_name);
|
547 |
+
$v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP );
|
548 |
if ($v_list == 0) {
|
549 |
wpa_backup_error( 'pclzip', $z->errorInfo(true) );
|
550 |
}
|
551 |
+
$file_list = wpa_wpc_zip( $z, $zipmode );
|
552 |
+
|
553 |
+
if( $file_list ) {
|
554 |
+
$z->add( $file_list, PCLZIP_OPT_REMOVE_PATH, WPCLONE_ROOT, PCLZIP_OPT_ADD_PATH, 'wpclone_backup' );
|
555 |
+
}
|
556 |
+
|
557 |
+
$z->delete( PCLZIP_OPT_BY_NAME, 'wpclone_backup/file.list' );
|
558 |
+
|
559 |
} else {
|
560 |
+
wpa_wpc_log( 'archiving files using ziparchive' );
|
561 |
$z = new ZipArchive();
|
562 |
if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
|
563 |
+
wpa_backup_error( 'zip', $z->getStatusString() );
|
564 |
}
|
565 |
wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
|
566 |
+
|
567 |
+
wpa_wpc_zip( $z, $zipmode );
|
568 |
+
$z->deleteName( 'wpclone_backup/file.list' );
|
569 |
$z->close();
|
570 |
+
|
571 |
}
|
572 |
+
|
573 |
+
|
574 |
}
|
575 |
|
576 |
function wpa_ziparc($zip, $dir, $base) {
|
590 |
* @since 2.0.6
|
591 |
*/
|
592 |
function wpa_bump_limits(){
|
593 |
+
$GLOBALS['wpclone'] = array();
|
594 |
+
$GLOBALS['wpclone']['time'] = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 600; /* 10 minutes */
|
595 |
+
$GLOBALS['wpclone']['mem'] = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '1024M';
|
596 |
+
|
597 |
+
@ini_set('memory_limit', $GLOBALS['wpclone']['mem']);
|
598 |
+
@ini_set('max_execution_time', $GLOBALS['wpclone']['time']);
|
599 |
+
@ini_set('mysql.connect_timeout', $GLOBALS['wpclone']['time']);
|
600 |
+
@ini_set('default_socket_timeout', $GLOBALS['wpclone']['time']);
|
601 |
}
|
602 |
+
|
603 |
/**
|
604 |
* @since 2.0.6
|
605 |
*/
|
619 |
}
|
620 |
|
621 |
$form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
|
622 |
+
$extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'ignore_prefix', 'wipedb', 'mysql_check', 'restoreBackup', 'createBackup' );
|
623 |
$type = '';
|
624 |
if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
|
625 |
return true;
|
666 |
/**
|
667 |
* @since 2.0.6
|
668 |
*/
|
669 |
+
function wpa_replace_prefix( $current, $new ){
|
670 |
+
|
671 |
$wpconfig = wpa_wpconfig_path();
|
672 |
global $wp_filesystem;
|
673 |
|
674 |
if ( ! $wp_filesystem->is_writable($wpconfig) ) {
|
675 |
if( false === $wp_filesystem->chmod( $wpconfig ) )
|
676 |
wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
|
677 |
+
|
678 |
+
}
|
679 |
+
|
680 |
+
$content = file( $wpconfig );
|
681 |
+
|
682 |
+
foreach( $content as $key => $value ) {
|
683 |
+
|
684 |
+
if( false !== strpos( $value, '$table_prefix' ) ) {
|
685 |
+
$content[$key] = str_replace( $current, $new, $value );
|
686 |
+
}
|
687 |
+
|
688 |
}
|
689 |
|
690 |
+
$content = implode( $content );
|
691 |
+
$wp_filesystem->put_contents( $wpconfig, $content, 0600 );
|
692 |
+
|
|
|
|
|
693 |
}
|
694 |
/**
|
695 |
* @since 2.0.6
|
696 |
*/
|
697 |
function wpa_create_backup (){
|
698 |
+
|
699 |
if( true === is_multisite() )
|
700 |
die( 'wpclone does not work on multisite installs.' );
|
701 |
if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
|
704 |
wpa_cleanup();
|
705 |
$use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
|
706 |
$backupName = wpa_backup_name();
|
707 |
+
$GLOBALS['wpclone']['logfile'] = $backupName . '.log';
|
708 |
+
|
709 |
+
wpa_wpc_log_start( 'backup' );
|
710 |
|
711 |
$zipmode = isset($_POST['zipmode']) ? true : false;
|
712 |
list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
|
713 |
|
714 |
wpa_insert_data($zipFileName, $zipSize);
|
715 |
+
$backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName . '.zip');
|
716 |
$zipSize = bytesToSize($zipSize);
|
717 |
+
wpa_wpc_log( 'backup finished');
|
718 |
+
|
719 |
echo <<<EOF
|
720 |
|
721 |
<h1>Backup Successful!</h1>
|
730 |
|
731 |
(Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
|
732 |
EOF;
|
733 |
+
printf( '</br><a href="%s">log</a>', convertPathIntoUrl( WPCLONE_DIR_BACKUP . $GLOBALS['wpclone']['logfile'] ) );
|
734 |
+
unset( $GLOBALS['wpclone'] );
|
735 |
}
|
736 |
/**
|
737 |
* @since 2.0.6
|
749 |
*/
|
750 |
function wpa_wpconfig_path () {
|
751 |
|
752 |
+
if ( file_exists( ABSPATH . 'wp-config.php') ) {
|
753 |
|
754 |
+
/** The config file resides in ABSPATH */
|
755 |
+
return ABSPATH . 'wp-config.php';
|
756 |
|
757 |
+
}
|
758 |
+
elseif ( file_exists( dirname(ABSPATH) . '/wp-config.php' ) && ! file_exists( dirname(ABSPATH) . '/wp-settings.php' ) ) {
|
759 |
|
760 |
+
/** The config file resides one level above ABSPATH but is not part of another install */
|
761 |
+
return dirname(ABSPATH) . '/wp-config.php';
|
762 |
|
763 |
+
}
|
764 |
+
else {
|
765 |
|
766 |
+
return false;
|
767 |
|
768 |
+
}
|
769 |
|
770 |
}
|
771 |
|
773 |
$z = pathinfo($path);
|
774 |
global $wp_filesystem;
|
775 |
if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
|
776 |
+
wpa_wpc_log( 'file exists in the backup folder, filesize - ' . bytesToSize( filesize( WPCLONE_DIR_BACKUP . $z['basename'] ) ) );
|
777 |
return WPCLONE_DIR_BACKUP . $z['basename'];
|
778 |
}
|
779 |
else {
|
780 |
+
wpa_wpc_log( 'file download started' );
|
781 |
$url = download_url($path, 750);
|
782 |
+
if ( is_wp_error($url) ) {
|
783 |
+
wpa_backup_error( 'url', $url->get_error_message(), true );
|
784 |
+
}
|
785 |
+
wpa_wpc_log( 'download finished, filesize - ' . bytesToSize( filesize( $url ) ) );
|
786 |
return $url;
|
787 |
}
|
788 |
}
|
789 |
|
790 |
function wpa_backup_name() {
|
791 |
+
$backup_name = 'wpclone_backup_' . current_time( 'dS_M_Y_h-iA', false ) . '_' . get_option( 'blogname' );
|
792 |
$backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
|
793 |
$rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
|
794 |
$backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
|
798 |
function wpa_backup_error($error, $data, $restore = false) {
|
799 |
|
800 |
$temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
|
801 |
+
$disp_dir = str_replace( WPCLONE_ROOT, '**SITE-ROOT**/', wpCloneSafePathMode( $temp_dir ) );
|
802 |
|
803 |
if( !file_exists( $temp_dir ) ) {
|
804 |
unset($temp_dir);
|
805 |
}
|
806 |
+
|
807 |
switch ( $error ) :
|
808 |
/* during backup */
|
809 |
case 'file' :
|
829 |
$error = __( 'while cloning the database' );
|
830 |
break;
|
831 |
case 'unzip' :
|
832 |
+
$error = __( 'while extracting the zip file using php ziparchive' );
|
833 |
break;
|
834 |
case 'pclunzip' :
|
835 |
$error = __( 'while extracting the zip file using the PclZip library' );
|
849 |
printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
|
850 |
echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
|
851 |
if( isset( $temp_dir ) ) {
|
852 |
+
printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $disp_dir );
|
853 |
echo '</div>';
|
854 |
if( $restore ) {
|
855 |
global $wp_filesystem;
|
929 |
$ex = trim( $ex );
|
930 |
if( '' !== $ex ) {
|
931 |
$ex = trim( $ex, "/\\" );
|
932 |
+
wpa_wpc_log( sprintf( 'files inside "**SITE_ROOT**/wp-content/%s/" will not be included in the backup', $ex ) );
|
933 |
+
$exclude[] = wpCloneSafePathMode( trailingslashit( WPCLONE_WP_CONTENT ) . $ex ) ;
|
934 |
}
|
935 |
}
|
936 |
}
|
945 |
|
946 |
foreach( $i as $file => $info ) {
|
947 |
|
948 |
+
if( false === strpos( wpCloneSafePathMode( $file ), WPCLONE_DIR_BACKUP ) ) {
|
949 |
$size += $info->getSize();
|
950 |
$files++;
|
951 |
|
953 |
|
954 |
}
|
955 |
|
956 |
+
$ret = array(
|
957 |
+
'dbsize' => wpa_wpc_db_size(),
|
958 |
+
'size' => bytesToSize( $size ),
|
959 |
+
'files' => $files,
|
960 |
+
'time' => time()
|
961 |
+
);
|
962 |
+
|
963 |
+
update_option( 'wpclone_directory_scan', $ret );
|
964 |
+
unset( $ret['time'] );
|
965 |
+
return $ret;
|
966 |
|
967 |
}
|
968 |
|
971 |
global $wpdb;
|
972 |
$sql = 'SELECT sum(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = "' . DB_NAME . '"';
|
973 |
$size = $wpdb->get_var( $sql );
|
974 |
+
return bytesToSize( $size );
|
975 |
|
976 |
}
|
977 |
|
1032 |
function wpa_wpc_filter_list( $a, $b ) {
|
1033 |
|
1034 |
$return = array();
|
1035 |
+
foreach( $a as $v ) {
|
1036 |
+
$return[$v] = '';
|
1037 |
+
}
|
1038 |
+
foreach( $b as $v ) {
|
1039 |
+
unset( $return[$v] );
|
1040 |
+
}
|
1041 |
return array_keys( $return );
|
1042 |
|
1043 |
}
|
1044 |
|
1045 |
+
function wpa_wpc_log( $msg ) {
|
1046 |
+
|
1047 |
+
if( ! isset( $GLOBALS['wpclone']['logfile'] ) ) {
|
1048 |
+
return;
|
1049 |
+
}
|
1050 |
+
$file = WPCLONE_DIR_BACKUP . $GLOBALS['wpclone']['logfile'];
|
1051 |
+
$time = date( 'l, d-M-Y H:i:s', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
|
1052 |
+
$msg = $time . ' - ' . $msg . "\r\n";
|
1053 |
+
file_put_contents( $file, $msg, FILE_APPEND );
|
1054 |
+
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
function wpa_wpc_log_start( $action ) {
|
1058 |
+
|
1059 |
+
global $wp_version;
|
1060 |
+
global $wpdb;
|
1061 |
+
|
1062 |
+
wpa_wpc_log( sprintf( '%s started', $action ) );
|
1063 |
+
wpa_wpc_log( 'wp version : ' . $wp_version );
|
1064 |
+
wpa_wpc_log( 'php version : ' . phpversion() );
|
1065 |
+
wpa_wpc_log( 'mysql version : ' . $wpdb->db_version() );
|
1066 |
+
wpa_wpc_log( 'memory limit : ' . ini_get( 'memory_limit' ) );
|
1067 |
+
wpa_wpc_log( 'execution time : ' . ini_get( 'max_execution_time' ) );
|
1068 |
+
wpa_wpc_log( 'mysql timeout : ' . ini_get( 'mysql.connect_timeout' ) );
|
1069 |
+
wpa_wpc_log( 'socket timeout : ' . ini_get( 'default_socket_timeout' ) );
|
1070 |
+
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
function wpa_wpc_strpos_array( $array, $haystack ) {
|
1074 |
+
|
1075 |
+
foreach( $array as $needle ) {
|
1076 |
+
if( false !== strpos( $haystack, $needle ) ) {
|
1077 |
+
return true;
|
1078 |
+
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
function wpa_wpc_get_filelist( $path, $exclude, $skip = false ) {
|
1086 |
+
|
1087 |
+
$i = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::UNIX_PATHS | FilesystemIterator::SKIP_DOTS ) );
|
1088 |
+
$skipped = 0;
|
1089 |
+
$size = 0;
|
1090 |
+
$files = 0;
|
1091 |
+
$list = array();
|
1092 |
+
|
1093 |
+
foreach( $i as $file => $info ) {
|
1094 |
+
|
1095 |
+
$file = wpCloneSafePathMode( $file );
|
1096 |
+
|
1097 |
+
if( false !== strpos( $file, WPCLONE_DIR_BACKUP ) ) {
|
1098 |
+
continue;
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
if( false !== strpos( $file, WPCLONE_DIR_PLUGIN ) ) {
|
1102 |
+
continue;
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
if( ! empty( $exclude ) && wpa_wpc_strpos_array( $exclude, $file ) ) {
|
1106 |
+
$skipped++;
|
1107 |
+
wpa_wpc_log( sprintf( 'file is inside an excluded directory, and it will not be included in the backup - "%s"',
|
1108 |
+
str_replace( WPCLONE_ROOT, '**SITE-ROOT**/', $file ) ) );
|
1109 |
+
continue;
|
1110 |
+
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
if( $skip && $info->getSize() > $skip ) {
|
1114 |
+
$skipped++;
|
1115 |
+
wpa_wpc_log( sprintf( 'file skipped, file is larger than %s - "%s" %s',
|
1116 |
+
bytesToSize( $skip ), str_replace( WPCLONE_ROOT, '**SITE-ROOT**/', $file ), bytesToSize( $info->getSize() ) ) );
|
1117 |
+
continue;
|
1118 |
+
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
if( $info->isFile() ) {
|
1122 |
+
$list[] = $file;
|
1123 |
+
$files++;
|
1124 |
+
$size += $info->getSize();
|
1125 |
+
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
}
|
1129 |
+
|
1130 |
+
if( $skipped > 0 ) {
|
1131 |
+
wpa_wpc_log( sprintf( '%d files were excluded from the backup', $skipped ) );
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
wpa_wpc_log( sprintf( 'number of files to include in the archive is %d, and their uncompressed size is %s',
|
1135 |
+
$files, bytesToSize( $size ) ) );
|
1136 |
+
|
1137 |
+
return $list;
|
1138 |
+
|
1139 |
+
}
|
1140 |
+
|
1141 |
+
|
1142 |
+
function wpa_wpc_zip( $zh, $zipmode ) {
|
1143 |
+
|
1144 |
+
$file = WPCLONE_DIR_BACKUP . 'wpclone_backup/file.list';
|
1145 |
+
|
1146 |
+
if( is_readable( $file ) ) {
|
1147 |
+
$filelist = unserialize( file_get_contents( $file ) );
|
1148 |
+
|
1149 |
+
} else {
|
1150 |
+
return false;
|
1151 |
+
|
1152 |
+
}
|
1153 |
+
|
1154 |
+
if( $zipmode ) {
|
1155 |
+
return $filelist;
|
1156 |
+
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
foreach( $filelist as $file ) {
|
1160 |
+
$zh->addFile( $file, str_replace( WPCLONE_ROOT, 'wpclone_backup/', $file ) );
|
1161 |
+
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
$zh->deleteName( 'wpclone_backup/file.list' );
|
1165 |
+
|
1166 |
+
}
|
1167 |
+
|
1168 |
+
function wpa_wpc_unzip( $zipfile, $temp_dir ) {
|
1169 |
+
|
1170 |
+
$z = new ZipArchive();
|
1171 |
+
|
1172 |
+
if( true === $z->open( $zipfile ) ) {
|
1173 |
+
$z->extractTo( $temp_dir );
|
1174 |
+
|
1175 |
+
} else {
|
1176 |
+
wpa_wpc_log( sprintf( 'failed to open the zip file : %s', $z->getStatusString() ) );
|
1177 |
+
wpa_backup_error( 'unzip', $z->getStatusString(), true );
|
1178 |
+
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
function wpa_wpc_get_db( $zipfile, $zipmode ) {
|
1184 |
+
|
1185 |
+
$ret = array();
|
1186 |
+
if( $zipmode || ( ! in_array( 'ZipArchive', get_declared_classes() ) || ! class_exists( 'ZipArchive' ) ) ) {
|
1187 |
+
|
1188 |
+
wpa_wpc_log( 'extracting database using pclzip' );
|
1189 |
+
|
1190 |
+
if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
|
1191 |
+
$previous_encoding = mb_internal_encoding();
|
1192 |
+
mb_internal_encoding('ISO-8859-1');
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
1196 |
+
$z = new PclZip($zipfile);
|
1197 |
+
$database = $z->extract( PCLZIP_OPT_BY_NAME, 'wpclone_backup/database.sql', PCLZIP_OPT_EXTRACT_AS_STRING );
|
1198 |
+
$prefix = $z->extract( PCLZIP_OPT_BY_NAME, 'wpclone_backup/prefix.txt', PCLZIP_OPT_EXTRACT_AS_STRING );
|
1199 |
+
|
1200 |
+
if ( isset( $previous_encoding ) ) {
|
1201 |
+
mb_internal_encoding($previous_encoding);
|
1202 |
+
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
if( 'ok' === $database[0]['status'] && 'ok' === $prefix[0]['status'] ) {
|
1206 |
+
$ret['database'] = $database[0]['content'];
|
1207 |
+
$ret['prefix'] = $prefix[0]['content'];
|
1208 |
+
|
1209 |
+
} else {
|
1210 |
+
wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
|
1211 |
+
|
1212 |
+
}
|
1213 |
+
|
1214 |
+
return $ret;
|
1215 |
+
|
1216 |
+
} else {
|
1217 |
+
|
1218 |
+
$z = new ZipArchive();
|
1219 |
+
|
1220 |
+
if( true === $z->open( $zipfile ) ) {
|
1221 |
+
|
1222 |
+
wpa_wpc_log( 'extracting database using ziparchive' );
|
1223 |
+
$ret['database'] = $z->getFromName( 'wpclone_backup/database.sql' );
|
1224 |
+
$ret['prefix'] = $z->getFromName( 'wpclone_backup/prefix.txt' );
|
1225 |
+
if( false === $ret['database'] || false === $ret['prefix'] ) {
|
1226 |
+
wpa_backup_error( 'unzip', $z->getStatusString(), true );
|
1227 |
+
|
1228 |
+
}
|
1229 |
+
|
1230 |
+
$z->close();
|
1231 |
+
return $ret;
|
1232 |
+
|
1233 |
+
} else {
|
1234 |
+
wpa_backup_error( 'unzip', $z->getStatusString(), true );
|
1235 |
+
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
}
|
1239 |
+
|
1240 |
+
}
|
1241 |
+
|
1242 |
+
function wpa_wpc_process_db( $zipfile, $zipmode = false ) {
|
1243 |
+
|
1244 |
+
$files = wpa_wpc_get_db( $zipfile, $zipmode );
|
1245 |
+
|
1246 |
+
$prefix = wpa_wpc_get_prefix( $files['prefix'] );
|
1247 |
+
$old_url = untrailingslashit( wpa_wpc_get_url( $files['database'] ) );
|
1248 |
+
$cur_url = untrailingslashit( site_url() );
|
1249 |
+
$found = false;
|
1250 |
+
$db = explode( ";\n", $files['database'] );
|
1251 |
+
$link = wpa_wpc_mysql_connect();
|
1252 |
+
|
1253 |
+
wpa_wpc_log( 'database import started' );
|
1254 |
+
foreach( $db as $query ) {
|
1255 |
+
|
1256 |
+
if( ! $found && false !== strpos( $query, '"siteurl",' ) ) {
|
1257 |
+
$query = str_replace( $old_url, $cur_url, $query, $count );
|
1258 |
+
wpa_wpc_log( sprintf( 'updating mysql query with current site\'s url - new query : "%s"', ltrim( $query ) ) );
|
1259 |
+
if( $count > 0 ) {
|
1260 |
+
$found = true;
|
1261 |
+
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
if( isset( $_POST['mysql_check'] ) && 'true' === $_POST['mysql_check'] ) {
|
1267 |
+
if( ! mysql_ping( $link ) ) {
|
1268 |
+
mysql_close( $link );
|
1269 |
+
$link = wpa_wpc_mysql_connect();
|
1270 |
+
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
$status = mysql_query( $query, $link );
|
1276 |
+
|
1277 |
+
if( false === $status ) {
|
1278 |
+
wpa_wpc_log( sprintf( 'mysql query failed. error : %d %s - query : "%s"', mysql_errno(), mysql_error(), ltrim( $query ) ) );
|
1279 |
+
|
1280 |
+
}
|
1281 |
+
|
1282 |
+
}
|
1283 |
+
wpa_wpc_log( 'database import finished' );
|
1284 |
+
|
1285 |
+
if( $cur_url === $old_url ) {
|
1286 |
+
wpa_wpc_log( 'URLs are similar, skipping search and replace' );
|
1287 |
+
$report = 'Search and replace did not run because the URLs are similar';
|
1288 |
+
|
1289 |
+
} else {
|
1290 |
+
$report = wpa_safe_replace_wrapper( $old_url, $cur_url, $prefix );
|
1291 |
+
|
1292 |
+
}
|
1293 |
+
|
1294 |
+
return $report;
|
1295 |
+
|
1296 |
+
|
1297 |
+
}
|
1298 |
+
|
1299 |
+
function wpa_wpc_get_prefix( $prev_prefix ) {
|
1300 |
+
|
1301 |
+
global $wpdb;
|
1302 |
+
$cur_prefix = $wpdb->prefix;
|
1303 |
+
|
1304 |
+
if ( $cur_prefix !== $prev_prefix ) {
|
1305 |
+
wpa_wpc_log( sprintf( 'changing prefix from "%s" to "%s"', $cur_prefix, $prev_prefix ) );
|
1306 |
+
wpa_replace_prefix( $cur_prefix, $prev_prefix );
|
1307 |
+
$cur_prefix = $prev_prefix;
|
1308 |
+
|
1309 |
+
}
|
1310 |
+
|
1311 |
+
return $cur_prefix;
|
1312 |
+
|
1313 |
+
}
|
1314 |
+
|
1315 |
|
1316 |
/* end of file */
|
lib/js/backupmanager.js
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
|
2 |
jQuery(function($) {
|
3 |
|
4 |
initialize();
|
@@ -15,6 +14,22 @@ jQuery(function($) {
|
|
15 |
|
16 |
function bindActions() {
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
$("input[id='fullBackup']").click(function() {
|
19 |
|
20 |
$("#RestoreOptions").hide("fast");
|
@@ -58,12 +73,12 @@ jQuery(function($) {
|
|
58 |
|
59 |
$("input[name$='backupUrl']").click(function() {
|
60 |
prepareBackUrlOption();
|
61 |
-
|
62 |
});
|
63 |
|
64 |
$("input[name$='restore_from_url']").focus(function() {
|
65 |
prepareBackUrlOption();
|
66 |
-
|
67 |
});
|
68 |
|
69 |
$("input#submit").click(function() {
|
@@ -118,7 +133,7 @@ jQuery(function($) {
|
|
118 |
$("#backupChoices").show("fast");
|
119 |
$("input#submit").val("Create Backup").removeClass("btn-warning").addClass("btn-primary");
|
120 |
$("input[id='fullBackup']").attr('checked',
|
121 |
-
|
122 |
}
|
123 |
|
124 |
function getSize() {
|
@@ -132,11 +147,15 @@ jQuery(function($) {
|
|
132 |
},
|
133 |
success: function(data){
|
134 |
data = $.parseJSON(data);
|
135 |
-
|
|
|
|
|
|
|
|
|
136 |
},
|
137 |
error: function(e){
|
138 |
$("span#filesize").html( "Unable to calculate size." );
|
139 |
-
}
|
140 |
});
|
141 |
|
142 |
}
|
@@ -227,4 +246,37 @@ jQuery(function($) {
|
|
227 |
|
228 |
}
|
229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
});
|
|
|
1 |
jQuery(function($) {
|
2 |
|
3 |
initialize();
|
14 |
|
15 |
function bindActions() {
|
16 |
|
17 |
+
$("a#close-thickbox").click(function(e) {
|
18 |
+
e.preventDefault();
|
19 |
+
tb_remove();
|
20 |
+
$("div#search-n-replace-info").html('');
|
21 |
+
$("input[name='searchfor'], input[name='replacewith']").val('');
|
22 |
+
$("input[name='ignoreprefix']").attr('checked', false);
|
23 |
+
});
|
24 |
+
|
25 |
+
$("input[name='search-n-replace-submit']").click(function(e) {
|
26 |
+
e.preventDefault();
|
27 |
+
if( $(this).data("working") ) return;
|
28 |
+
$("#search-n-replace-info").html('').css( 'background', 'url(' + wpclone.spinner + ') no-repeat center' )
|
29 |
+
$(this).data("working", true);
|
30 |
+
search_and_replace();
|
31 |
+
});
|
32 |
+
|
33 |
$("input[id='fullBackup']").click(function() {
|
34 |
|
35 |
$("#RestoreOptions").hide("fast");
|
73 |
|
74 |
$("input[name$='backupUrl']").click(function() {
|
75 |
prepareBackUrlOption();
|
76 |
+
$("input#submit").removeClass("btn-primary").addClass("btn-warning");
|
77 |
});
|
78 |
|
79 |
$("input[name$='restore_from_url']").focus(function() {
|
80 |
prepareBackUrlOption();
|
81 |
+
$("input#submit").removeClass("btn-primary").addClass("btn-warning");
|
82 |
});
|
83 |
|
84 |
$("input#submit").click(function() {
|
133 |
$("#backupChoices").show("fast");
|
134 |
$("input#submit").val("Create Backup").removeClass("btn-warning").addClass("btn-primary");
|
135 |
$("input[id='fullBackup']").attr('checked',
|
136 |
+
$("input[name$='createBackup']").is(':checked') && !$("input[id$='customBackup']").is(':checked'));
|
137 |
}
|
138 |
|
139 |
function getSize() {
|
147 |
},
|
148 |
success: function(data){
|
149 |
data = $.parseJSON(data);
|
150 |
+
var cache = '';
|
151 |
+
if( 'undefined' !== typeof data.time ) {
|
152 |
+
cache = '</br>(calculated ' + data.time + ' minute[s] ago.)';
|
153 |
+
}
|
154 |
+
$("span#filesize").html( "Number of files in wp-content directory - <code>" + data.files + "</code>, and their total size - <code>" + data.size + "</code> (files larger than 25MB will be excluded from the backup, you can change it from advanced settings) </br>Database size is <code>" + data.dbsize + "</code>." + cache );
|
155 |
},
|
156 |
error: function(e){
|
157 |
$("span#filesize").html( "Unable to calculate size." );
|
158 |
+
}
|
159 |
});
|
160 |
|
161 |
}
|
246 |
|
247 |
}
|
248 |
|
249 |
+
function search_and_replace() {
|
250 |
+
|
251 |
+
var prefix = '';
|
252 |
+
|
253 |
+
if( $("input[name='ignoreprefix']").prop("checked") ) {
|
254 |
+
prefix = 'true';
|
255 |
+
}
|
256 |
+
|
257 |
+
$.ajax({
|
258 |
+
url: ajaxurl,
|
259 |
+
type: 'post',
|
260 |
+
data: {
|
261 |
+
action : 'wpclone-search-n-replace',
|
262 |
+
search : $("input[name='searchfor']").val(),
|
263 |
+
replace: $("input[name='replacewith']").val(),
|
264 |
+
ignore_prefix : prefix,
|
265 |
+
nonce : wpclone.nonce
|
266 |
+
},
|
267 |
+
success: function(data) {
|
268 |
+
$("div#search-n-replace-info").css('background', '').append(data);
|
269 |
+
},
|
270 |
+
error: function(e){
|
271 |
+
console.log(e);
|
272 |
+
},
|
273 |
+
complete: function(){
|
274 |
+
$("input[name='search-n-replace-submit']").removeData("working");
|
275 |
+
}
|
276 |
+
|
277 |
+
});
|
278 |
+
|
279 |
+
}
|
280 |
+
|
281 |
+
|
282 |
});
|
lib/view.php
CHANGED
@@ -41,6 +41,18 @@ if (wpa_wpfs_init()) return;
|
|
41 |
if( false === get_option( 'wpclone_backups' ) ) wpa_wpc_import_db();
|
42 |
$backups = get_option( 'wpclone_backups' );
|
43 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
<div id="wrapper">
|
45 |
<div id="MainView">
|
46 |
|
@@ -60,26 +72,43 @@ $backups = get_option( 'wpclone_backups' );
|
|
60 |
<form id="backupForm" name="backupForm" action="#" method="post">
|
61 |
<?php
|
62 |
if ( isset($_GET['mode']) && 'advanced' == $_GET['mode'] ) { ?>
|
63 |
-
<div class="info">
|
64 |
<table>
|
65 |
<tr align="left"><th colspan=""><label for="zipmode">Alternate zip method</label></th><td colspan="2"><input type="checkbox" name="zipmode" value="alt" /></td></tr>
|
66 |
<tr align="left"><th><label for="use_wpdb">Use wpdb to backup the database</label></th><td colspan="2"><input type="checkbox" name="use_wpdb" value="true" /></td></tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
<tr><td colspan="4"><h3>Overriding the Maximum memory and Execution time</h3></td></tr>
|
68 |
<tr><td colspan="4"><p>You can use these two fields to override the maximum memory and execution time on most hosts.</br>
|
69 |
-
For example, if you want to increase the RAM to
|
70 |
-
And if you want to increase the execution time to
|
71 |
-
Default values will be used if you leave them blank. The default value for RAM is
|
72 |
<tr align="left"><th><label for="maxmem">Maximum memory limit</label></th><td colspan="2"><input type="text" name="maxmem" /></td></tr>
|
73 |
<tr align="left"><th><label for="maxexec">Script execution time</label></th><td><input type="text" name="maxexec" /></td></tr>
|
74 |
<tr><td colspan="4"><h3>Exclude directories from backup, and backup database only</h3></td></tr>
|
75 |
<tr><td colspan="4"><p>Depending on your web host, WP Clone may not work for large sites.
|
76 |
You may, however, exclude all of your 'wp-content' directory from the backup (use "Backup database only" option below), or exclude specific directories.
|
77 |
-
You would then copy these files over to the new site via FTP before restoring the backup with WP Clone.</p
|
|
|
|
|
78 |
<tr align="left"><th><label for="dbonly">Backup database only</label></th><td colspan="2"><input type="checkbox" name="dbonly" value="true" /></td></tr>
|
|
|
79 |
<tr align="left"><th><label for="exclude">Excluded directories</label></th><td><textarea cols="70" rows="5" name="exclude" ></textarea></td></tr>
|
80 |
<tr><th></th><td colspan="5"><p>Enter one per line, i.e. <code>uploads/backups</code>,use the forward slash <code>/</code> as the directory separator. Directories start at 'wp-content' level.</br>
|
81 |
</br>For example, BackWPup saves its backups into <code>/wp-content/uploads/backwpup-abc123-backups/</code> (the middle part, 'abc123' in this case, is random characters).
|
82 |
-
If you wanted to exclude that directory, you have to enter <code>uploads/backwpup-abc123-backups</code> into the above field.</p></td></tr>
|
83 |
</table>
|
84 |
</div>
|
85 |
<?php
|
@@ -111,9 +140,16 @@ $backups = get_option( 'wpclone_backups' );
|
|
111 |
<a href="<?php echo $filename ?>" class="zclip"> (<?php echo bytesToSize($backup['size']);?>) <?php echo $backup['name'] ?></a>
|
112 |
<input type="hidden" name="backup_name" value="<?php echo $filename ?>" />
|
113 |
</td>
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
<td><a class="copy-button" href="#" data-clipboard-text="<?php echo $filename ?>" >Copy URL</a></td>
|
116 |
<td><a href="<?php echo $url; ?>" class="delete" data-fileid="<?php echo $key; ?>">Delete</a></td>
|
|
|
117 |
</tr>
|
118 |
|
119 |
<?php endforeach ?>
|
@@ -141,7 +177,9 @@ $backups = get_option( 'wpclone_backups' );
|
|
141 |
</div>
|
142 |
|
143 |
<input id="submit" name="submit" class="btn-primary btn" type="submit" value="Create Backup"/>
|
144 |
-
|
|
|
|
|
145 |
</form>
|
146 |
<?php
|
147 |
if(!isset($_GET['mode'])){
|
@@ -158,6 +196,8 @@ $backups = get_option( 'wpclone_backups' );
|
|
158 |
echo "<p><a href='#' id='uninstall' class='button' style='margin-top:10px'>Delete backups and remove database entries</a>"
|
159 |
. "</br>WP Clone does not remove backups when you deactivate the plugin. Use the above button if you want to remove all the backups.</p>";
|
160 |
|
|
|
|
|
161 |
|
162 |
?>
|
163 |
</div>
|
@@ -196,18 +236,24 @@ $backups = get_option( 'wpclone_backups' );
|
|
196 |
|
197 |
function wpa_wpc_sysinfo(){
|
198 |
global $wpdb;
|
199 |
-
echo '<div class="info">';
|
200 |
echo '<h3>System Info:</h3><p>';
|
201 |
-
echo 'Memory limit: ' . ini_get('memory_limit')
|
|
|
|
|
|
|
|
|
|
|
202 |
echo 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds</br>';
|
203 |
echo 'PHP version : ' . phpversion() . '</br>';
|
204 |
echo 'MySQL version : ' . $wpdb->db_version() . '</br>';
|
205 |
if (ini_get('safe_mode')) { echo '<span style="color:#f11">PHP is running in safemode!</span></br>'; }
|
|
|
206 |
if ( ! file_exists( WPCLONE_DIR_BACKUP ) ) {
|
207 |
echo 'Backup path :<span style="color:#660000">Backup directory not found. '
|
208 |
. 'Unless there is a permissions or ownership issue, refreshing the backup list should create the directory.</span></br>';
|
209 |
} else {
|
210 |
-
echo 'Backup
|
211 |
}
|
212 |
echo 'Files : <span id="filesize"><img src="' . esc_url( admin_url( 'images/spinner.gif' ) ) . '"></span></br>';
|
213 |
if ( file_exists( WPCLONE_DIR_BACKUP ) && !is_writable(WPCLONE_DIR_BACKUP)) { echo '<span style="color:#f11">Backup directory is not writable, please change its permissions.</span></br>'; }
|
41 |
if( false === get_option( 'wpclone_backups' ) ) wpa_wpc_import_db();
|
42 |
$backups = get_option( 'wpclone_backups' );
|
43 |
?>
|
44 |
+
<div id="search-n-replace">
|
45 |
+
<a href="#" id="close-thickbox" class="button">X</a>
|
46 |
+
<form name="searchnreplace" action="#" method="post">
|
47 |
+
<table class="searchnreplace">
|
48 |
+
<tr><th><label for="searchfor">Search for</label></th><td colspan="5"><input type="text" name="searchfor" /></td></tr>
|
49 |
+
<tr><th><label for="replacewith">Replace with</label></th><td colspan="5"><input type="text" name="replacewith" /></td></tr>
|
50 |
+
<tr><th><label for="ignoreprefix">Ignore table prefix</label></th><td colspan="2"><input type="checkbox" name="ignoreprefix" value="true" /></td></tr>
|
51 |
+
</table>
|
52 |
+
<input type="submit" class="button" name="search-n-replace-submit" value="Run">
|
53 |
+
</form>
|
54 |
+
<div id="search-n-replace-info"></div>
|
55 |
+
</div>
|
56 |
<div id="wrapper">
|
57 |
<div id="MainView">
|
58 |
|
72 |
<form id="backupForm" name="backupForm" action="#" method="post">
|
73 |
<?php
|
74 |
if ( isset($_GET['mode']) && 'advanced' == $_GET['mode'] ) { ?>
|
75 |
+
<div class="info width-60">
|
76 |
<table>
|
77 |
<tr align="left"><th colspan=""><label for="zipmode">Alternate zip method</label></th><td colspan="2"><input type="checkbox" name="zipmode" value="alt" /></td></tr>
|
78 |
<tr align="left"><th><label for="use_wpdb">Use wpdb to backup the database</label></th><td colspan="2"><input type="checkbox" name="use_wpdb" value="true" /></td></tr>
|
79 |
+
<tr align="left"><th><label for="ignore_prefix">Ignore table prefix</label></th><td colspan="2"><input type="checkbox" name="ignore_prefix" value="true" /></td></tr>
|
80 |
+
<tr>
|
81 |
+
<td colspan="4">
|
82 |
+
<p>If enabled during a backup, all the tables in the database will be included in the backup.</br>
|
83 |
+
If enabled during a restore, search and replace will alter all the tables in the database.</br>
|
84 |
+
By default, only the tables that share the wordpress table prefix are included/altered during a backup/restore.</p>
|
85 |
+
</td>
|
86 |
+
</tr>
|
87 |
+
<tr align="left"><th><label for="mysql_check">Refresh MySQL connection during Restore</label></th><td colspan="2"><input type="checkbox" name="mysql_check" value="true" /></td></tr>
|
88 |
+
<tr>
|
89 |
+
<td colspan="4">
|
90 |
+
<p>This will check the MySQL connection inside the main loop before each database query during restore. Enable this if the restored site is incomplete.</p>
|
91 |
+
</td>
|
92 |
+
</tr>
|
93 |
<tr><td colspan="4"><h3>Overriding the Maximum memory and Execution time</h3></td></tr>
|
94 |
<tr><td colspan="4"><p>You can use these two fields to override the maximum memory and execution time on most hosts.</br>
|
95 |
+
For example, if you want to increase the RAM to 2GB, enter <code>2048</code> into the Maximum memory limit field.</br>
|
96 |
+
And if you want to increase the execution time to 15 minutes, enter <code>900</code> into the Script execution time field.</br>
|
97 |
+
Default values will be used if you leave them blank. The default value for RAM is 1024MB and the default value for execution time is 600 seconds (ten minutes).</p></td></tr>
|
98 |
<tr align="left"><th><label for="maxmem">Maximum memory limit</label></th><td colspan="2"><input type="text" name="maxmem" /></td></tr>
|
99 |
<tr align="left"><th><label for="maxexec">Script execution time</label></th><td><input type="text" name="maxexec" /></td></tr>
|
100 |
<tr><td colspan="4"><h3>Exclude directories from backup, and backup database only</h3></td></tr>
|
101 |
<tr><td colspan="4"><p>Depending on your web host, WP Clone may not work for large sites.
|
102 |
You may, however, exclude all of your 'wp-content' directory from the backup (use "Backup database only" option below), or exclude specific directories.
|
103 |
+
You would then copy these files over to the new site via FTP before restoring the backup with WP Clone.</p>
|
104 |
+
<p>You could also skip files that are larger than the value entered into the below field. For example, enter <code>100</code> if you want to skip files larger than 100MB.
|
105 |
+
The default value of 25MB will be used If you leave it blank. Enter <code>0</code> if you want to disable it.</p></td></tr>
|
106 |
<tr align="left"><th><label for="dbonly">Backup database only</label></th><td colspan="2"><input type="checkbox" name="dbonly" value="true" /></td></tr>
|
107 |
+
<tr align="left"><th><label for="skipfiles">Skip files larger than</label></th><td><input type="text" name="skipfiles" /> <strong>MB</strong></td></tr>
|
108 |
<tr align="left"><th><label for="exclude">Excluded directories</label></th><td><textarea cols="70" rows="5" name="exclude" ></textarea></td></tr>
|
109 |
<tr><th></th><td colspan="5"><p>Enter one per line, i.e. <code>uploads/backups</code>,use the forward slash <code>/</code> as the directory separator. Directories start at 'wp-content' level.</br>
|
110 |
</br>For example, BackWPup saves its backups into <code>/wp-content/uploads/backwpup-abc123-backups/</code> (the middle part, 'abc123' in this case, is random characters).
|
111 |
+
If you wanted to exclude that directory, you have to enter <code>uploads/backwpup-abc123-backups</code> into the above field.</p></td></tr>
|
112 |
</table>
|
113 |
</div>
|
114 |
<?php
|
140 |
<a href="<?php echo $filename ?>" class="zclip"> (<?php echo bytesToSize($backup['size']);?>) <?php echo $backup['name'] ?></a>
|
141 |
<input type="hidden" name="backup_name" value="<?php echo $filename ?>" />
|
142 |
</td>
|
143 |
+
<?php
|
144 |
+
if( isset( $backup['log'] ) ){
|
145 |
+
printf( '<td><a href="%s">log</a></td>', convertPathIntoUrl(WPCLONE_DIR_BACKUP . $backup['log'] ) );
|
146 |
+
} else {
|
147 |
+
echo '<td>—</td>';
|
148 |
+
}
|
149 |
+
?>
|
150 |
<td><a class="copy-button" href="#" data-clipboard-text="<?php echo $filename ?>" >Copy URL</a></td>
|
151 |
<td><a href="<?php echo $url; ?>" class="delete" data-fileid="<?php echo $key; ?>">Delete</a></td>
|
152 |
+
|
153 |
</tr>
|
154 |
|
155 |
<?php endforeach ?>
|
177 |
</div>
|
178 |
|
179 |
<input id="submit" name="submit" class="btn-primary btn" type="submit" value="Create Backup"/>
|
180 |
+
|
181 |
+
|
182 |
+
<?php wp_nonce_field('wpclone-submit')?>
|
183 |
</form>
|
184 |
<?php
|
185 |
if(!isset($_GET['mode'])){
|
196 |
echo "<p><a href='#' id='uninstall' class='button' style='margin-top:10px'>Delete backups and remove database entries</a>"
|
197 |
. "</br>WP Clone does not remove backups when you deactivate the plugin. Use the above button if you want to remove all the backups.</p>";
|
198 |
|
199 |
+
echo '<p><a href="#TB_inline?height=200&width=600&inlineId=search-n-replace&modal=true" class="thickbox">Search and Replace</a></p>';
|
200 |
+
|
201 |
|
202 |
?>
|
203 |
</div>
|
236 |
|
237 |
function wpa_wpc_sysinfo(){
|
238 |
global $wpdb;
|
239 |
+
echo '<div class="info width-60">';
|
240 |
echo '<h3>System Info:</h3><p>';
|
241 |
+
echo 'Memory limit: ' . ini_get('memory_limit');
|
242 |
+
if( false === ini_set( 'memory_limit', '257M' ) ) {
|
243 |
+
echo ' <span style="color:#660000">memory limit cannot be increased</span></br>';
|
244 |
+
} else {
|
245 |
+
echo '</br>';
|
246 |
+
}
|
247 |
echo 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds</br>';
|
248 |
echo 'PHP version : ' . phpversion() . '</br>';
|
249 |
echo 'MySQL version : ' . $wpdb->db_version() . '</br>';
|
250 |
if (ini_get('safe_mode')) { echo '<span style="color:#f11">PHP is running in safemode!</span></br>'; }
|
251 |
+
printf( 'Root directory : <code>%s</code></br>', WPCLONE_ROOT );
|
252 |
if ( ! file_exists( WPCLONE_DIR_BACKUP ) ) {
|
253 |
echo 'Backup path :<span style="color:#660000">Backup directory not found. '
|
254 |
. 'Unless there is a permissions or ownership issue, refreshing the backup list should create the directory.</span></br>';
|
255 |
} else {
|
256 |
+
echo 'Backup directory : <code>' . WPCLONE_DIR_BACKUP . '</code></br>';
|
257 |
}
|
258 |
echo 'Files : <span id="filesize"><img src="' . esc_url( admin_url( 'images/spinner.gif' ) ) . '"></span></br>';
|
259 |
if ( file_exists( WPCLONE_DIR_BACKUP ) && !is_writable(WPCLONE_DIR_BACKUP)) { echo '<span style="color:#f11">Backup directory is not writable, please change its permissions.</span></br>'; }
|
readme.txt
CHANGED
@@ -5,8 +5,8 @@ Tags: wp academy, wpacademy, move wordpress, copy wordpress, clone wordpress, in
|
|
5 |
Author URI: http://wpacademy.com
|
6 |
Plugin URI: http://wpacademy.com/software
|
7 |
Requires at least: 3.0
|
8 |
-
Tested up to: 4.
|
9 |
-
Stable tag: 2.2
|
10 |
License: GPLv2 or later
|
11 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
|
@@ -24,28 +24,30 @@ WP Clone is a superior solution to even commercial WordPress cloning plugins for
|
|
24 |
* It uses the WordPress internal zip archive function, which makes it compatible with virtually 100% of hosts that support WordPress (no special PHP libraries are required)
|
25 |
|
26 |
<blockquote>
|
27 |
-
= Update
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
= Update April 2015 =
|
32 |
-
WP Clone fails to restore in about 10-20% of installations. This appears to be related to the hosting platform rather than the WordPress version. We are attempting to isolate this problem and determine the types of installations that fail in order to update the plugin. Under no circumstances should the source (origin) site ever be damaged or destroyed.
|
33 |
-
Feel free to leave a negative review and details of your failure on the support forum, but please be polite as we do not receive any remuneration for writing and supporting this plugin. We will investigate as we can. As a reminder also to never overwrite an installation for which you do not have a backup -- in normal usage this plugin would be used only to overwrite a new (or blank) WordPress installation. Thanks -- WP Academy Support
|
34 |
</blockquote>
|
35 |
|
36 |
= Help Video =
|
37 |
[youtube http://www.youtube.com/watch?v=xN5Ffhyn4Ao]
|
38 |
|
39 |
-
=
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
-
|
43 |
-
No WordPress backup plugin will work reliably on all hosts. If you have any problems, try doing a "Database Only" backup (use "Advanced Options"), transfer the wp-content directory over with FTP, and then restore new site. You should also deactivate and delete any page caching plugins (i.e. W3 Total Cache) before backup.
|
44 |
-
If you still have an issue, please post to the WordPress.org support forum where we support this plugin for free, and we'll respond on a "best-effort" basis. You can also try the Duplicator plugin http://wordpress.org/plugins/duplicator/ or All-in-One WP Migration https://wordpress.org/plugins/all-in-one-wp-migration/, both of which work pretty good, but are not as fast as WP Clone to migrate sites; or use the manual method described here http://members.wpacademy.com/ww3.htm?moving-wordpress.htm
|
45 |
|
46 |
-
=
|
47 |
-
|
48 |
-
Donation page.
|
49 |
|
50 |
= Additional documentation =
|
51 |
Additional documentation, including supported hosts, at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
|
@@ -54,6 +56,7 @@ Additional documentation, including supported hosts, at the [WP Clone FAQ Page](
|
|
54 |
WP Clone uses functions from the "Safe Search and Replace on Database with Serialized Data" script first written by David Coveney of Interconnect IT Ltd (UK) http://www.davidcoveney.com or http://www.interconnectit.com and
|
55 |
released under the WTFPL http://sam.zoy.org/wtfpl/. Partial script with full changelog is placed inside 'lib/files' directory.
|
56 |
|
|
|
57 |
|
58 |
== Installation ==
|
59 |
|
@@ -66,6 +69,21 @@ released under the WTFPL http://sam.zoy.org/wtfpl/. Partial script with full cha
|
|
66 |
Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
|
67 |
|
68 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
= 2.2 - 2015-11-16 =
|
70 |
* Fixed: Missing backups that some users encountered after upgrading to 2.1.9
|
71 |
* Added: An option to refresh the backup list.
|
5 |
Author URI: http://wpacademy.com
|
6 |
Plugin URI: http://wpacademy.com/software
|
7 |
Requires at least: 3.0
|
8 |
+
Tested up to: 4.4
|
9 |
+
Stable tag: 2.2.1
|
10 |
License: GPLv2 or later
|
11 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
|
24 |
* It uses the WordPress internal zip archive function, which makes it compatible with virtually 100% of hosts that support WordPress (no special PHP libraries are required)
|
25 |
|
26 |
<blockquote>
|
27 |
+
= Update December 2015 =
|
28 |
+
Prior to the latest update, WP Clone was failing in 10-20% of installations (particularly larger installations), as reflected in the negative reviews.
|
29 |
+
Since the latest update, we have successfully restored 2GB sites, but we cannot guarantee the reliability on all installations.
|
30 |
+
<strong>Please carefully read the section below NO SUPPORT AND DISCLAIMER before you attempt to use this plugin.</strong>
|
|
|
|
|
|
|
31 |
</blockquote>
|
32 |
|
33 |
= Help Video =
|
34 |
[youtube http://www.youtube.com/watch?v=xN5Ffhyn4Ao]
|
35 |
|
36 |
+
= NO SUPPORT AND DISCLAIMER =
|
37 |
+
As mentioned above, WP Clone fails in 10-20% of installations. As such it is NOT intended as a regular backup method, its strength consists in migrating WordPress installations. The failures appear to be related to the multiplicity of WordPress hosting platforms and the size of the installation rather than the WordPress version (so please don't feedback "WP Clone does not work for my version of WordPress", this is most probably false). Do however, leave negative reviews and open a discussion on the support forum if you get a failure, providing as much detail as possible, including your hosting system and the size of your site. We will likely not be able to respond, but the information will be useful in helping to isolate the problems with the different hosting systems. Thank you.
|
38 |
+
|
39 |
+
= Recommendations for using (or not) WP Clone =
|
40 |
+
* NEVER overwrite an installation for which you do not have an alternate backup source (i.e. a cPanel backup). Normally you would restore onto a fresh WP installation on another host or on a subdomain. If the restore fails your destination site might become unusable, so be prepared to enter cPanel and then destroy / recreate the new installation if necessary.
|
41 |
+
* There is never an issue in damaging the source installation. So backup sites at your pleasure. If your backup succeeds it is probable that your restore will also succeed. But don't take any chances.
|
42 |
+
* Large sites (>2GB) might take as long as an hour to backup. Sites of 250 MB or less should take no more than a minute or two, depending on your server.
|
43 |
+
* We recommend you deactivate and delete page caching, security and maybe redirection plugins and re-install them on the new site, if necessary. In general, delete all unnecessary plugins and data from your site before you backup. You can also use the "Exclude directories" option if you have large media files, which you can then copy back to the new site with FTP.
|
44 |
+
* An alternate method that should work in 99% of installations is to do a "Database Only" backup (use "Advanced Settings"), transfer the wp-content directory over with FTP, and then restore new site.
|
45 |
+
* Note also that WP Clone should NOT be used on WP Engine or any hosting system with proprietary operating system. Instead, use their built-in tools.
|
46 |
|
47 |
+
You can also try the [Duplicator plugin](https://wordpress.org/plugins/duplicator/) or [All-in-One WP Migration](https://wordpress.org/plugins/all-in-one-wp-migration/), both of which work pretty good, but are not as fast as WP Clone to migrate sites; or use the manual method described here http://wpencyclopedia.com/enc/index.htm?moving-wordpress.htm
|
|
|
|
|
48 |
|
49 |
+
= Donations =
|
50 |
+
Although we are not able to provide support to every installation, we have spent countless hours improving the plugin and responding to user feedback. We believe that WP Clone is far and away the easiest WordPress restoration plugin and intend to continue to develop it. If you are able to support our efforts, use the Donations Page.
|
|
|
51 |
|
52 |
= Additional documentation =
|
53 |
Additional documentation, including supported hosts, at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
|
56 |
WP Clone uses functions from the "Safe Search and Replace on Database with Serialized Data" script first written by David Coveney of Interconnect IT Ltd (UK) http://www.davidcoveney.com or http://www.interconnectit.com and
|
57 |
released under the WTFPL http://sam.zoy.org/wtfpl/. Partial script with full changelog is placed inside 'lib/files' directory.
|
58 |
|
59 |
+
If you are able to help out with plugin development or wish to contribute insights into improving the product, we would also appreciate that very much. Write to marc@wpacademy.com.
|
60 |
|
61 |
== Installation ==
|
62 |
|
69 |
Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
|
70 |
|
71 |
== Changelog ==
|
72 |
+
= 2.2.1 - 2015-12-29 =
|
73 |
+
* Fixed: Backup names will use the time zone selected in general settings.
|
74 |
+
* Added: basic backup/restore logs.
|
75 |
+
* Added: An option to exclude files based on size (files larger than 25MB will be excluded by default)
|
76 |
+
* Added: An option to ignore the wordpress table prefix during backup/restore.
|
77 |
+
* Added: An option to check the mysql connection during restore.
|
78 |
+
* Added: A search and replace tool into the plugin dashboard.
|
79 |
+
* Changed: A .htaccess file will be placed in the temporary directories to prevent external access to the files.
|
80 |
+
* Changed: Files are no longer copied to a temporary location during backup.
|
81 |
+
* Changed: Database import is done before the rest of the files are extracted.
|
82 |
+
* Changed: siteurl option is updated during the database import.
|
83 |
+
* Changed: search and replace will not run when the URLs are similar.
|
84 |
+
* Changed: Increased the default values for memory_limit and max_execution_time from 512MB/300 to 1024MB/600.
|
85 |
+
* Removed: The use of wordpress' unzip_file (ziparchive will be used when available with pclzip as fallback)
|
86 |
+
|
87 |
= 2.2 - 2015-11-16 =
|
88 |
* Fixed: Missing backups that some users encountered after upgrading to 2.1.9
|
89 |
* Added: An option to refresh the backup list.
|
wpclone.php
CHANGED
@@ -4,7 +4,7 @@ Plugin name: WP Clone by WP Academy
|
|
4 |
Plugin URI: http://wpacademy.com/software/
|
5 |
Description: Move or copy a WordPress site to another server or to another domain name, move to/from local server hosting, and backup sites.
|
6 |
Author: WP Academy
|
7 |
-
Version: 2.2
|
8 |
Author URI: http://wpacademy.com/
|
9 |
*/
|
10 |
|
@@ -32,6 +32,7 @@ add_action( 'wp_ajax_wpclone-ajax-size', 'wpa_wpc_ajax_size' );
|
|
32 |
add_action( 'wp_ajax_wpclone-ajax-dir', 'wpa_wpc_ajax_dir' );
|
33 |
add_action( 'wp_ajax_wpclone-ajax-delete', 'wpa_wpc_ajax_delete' );
|
34 |
add_action( 'wp_ajax_wpclone-ajax-uninstall', 'wpa_wpc_ajax_uninstall' );
|
|
|
35 |
|
36 |
function wpclone_plugin_menu() {
|
37 |
add_menu_page (
|
@@ -46,8 +47,17 @@ function wpclone_plugin_menu() {
|
|
46 |
function wpa_wpc_ajax_size() {
|
47 |
|
48 |
check_ajax_referer( 'wpclone-ajax-submit', 'nonce' );
|
49 |
-
|
50 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
echo json_encode( $size );
|
52 |
wp_die();
|
53 |
|
@@ -80,13 +90,40 @@ function wpa_wpc_ajax_delete() {
|
|
80 |
function wpa_wpc_ajax_uninstall() {
|
81 |
|
82 |
check_ajax_referer( 'wpclone-ajax-submit', 'nonce' );
|
83 |
-
if( file_exists( WPCLONE_DIR_BACKUP ) )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
delete_option( 'wpclone_backups' );
|
85 |
wpa_wpc_remove_table();
|
86 |
wp_die();
|
87 |
|
88 |
}
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
function wpclone_plugin_options() {
|
91 |
include_once 'lib/view.php';
|
92 |
}
|
@@ -100,6 +137,7 @@ function wpa_enqueue_scripts(){
|
|
100 |
wp_enqueue_script('wpclone');
|
101 |
wp_enqueue_style('wpclone');
|
102 |
wp_deregister_script('heartbeat');
|
|
|
103 |
}
|
104 |
if( isset($_GET['page']) && 'wp-clone' == $_GET['page'] ) add_action('admin_enqueue_scripts', 'wpa_enqueue_scripts');
|
105 |
|
4 |
Plugin URI: http://wpacademy.com/software/
|
5 |
Description: Move or copy a WordPress site to another server or to another domain name, move to/from local server hosting, and backup sites.
|
6 |
Author: WP Academy
|
7 |
+
Version: 2.2.1
|
8 |
Author URI: http://wpacademy.com/
|
9 |
*/
|
10 |
|
32 |
add_action( 'wp_ajax_wpclone-ajax-dir', 'wpa_wpc_ajax_dir' );
|
33 |
add_action( 'wp_ajax_wpclone-ajax-delete', 'wpa_wpc_ajax_delete' );
|
34 |
add_action( 'wp_ajax_wpclone-ajax-uninstall', 'wpa_wpc_ajax_uninstall' );
|
35 |
+
add_action( 'wp_ajax_wpclone-search-n-replace', 'wpa_wpc_ajax_search_n_replace' );
|
36 |
|
37 |
function wpclone_plugin_menu() {
|
38 |
add_menu_page (
|
47 |
function wpa_wpc_ajax_size() {
|
48 |
|
49 |
check_ajax_referer( 'wpclone-ajax-submit', 'nonce' );
|
50 |
+
|
51 |
+
$cached = get_option( 'wpclone_directory_scan' );
|
52 |
+
$interval = 600; /* 10 minutes */
|
53 |
+
|
54 |
+
if( false !== $cached && time() - $cached['time'] < $interval ) {
|
55 |
+
$size = $cached;
|
56 |
+
$size['time'] = date( 'i', time() - $size['time'] );
|
57 |
+
} else {
|
58 |
+
$size = wpa_wpc_dir_size( WP_CONTENT_DIR );
|
59 |
+
}
|
60 |
+
|
61 |
echo json_encode( $size );
|
62 |
wp_die();
|
63 |
|
90 |
function wpa_wpc_ajax_uninstall() {
|
91 |
|
92 |
check_ajax_referer( 'wpclone-ajax-submit', 'nonce' );
|
93 |
+
if( file_exists( WPCLONE_DIR_BACKUP ) ) {
|
94 |
+
wpa_delete_dir( WPCLONE_DIR_BACKUP );
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
if( file_exists( WPCLONE_WP_CONTENT . 'wpclone-temp' ) ) {
|
99 |
+
wpa_delete_dir( WPCLONE_WP_CONTENT . 'wpclone-temp' );
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
delete_option( 'wpclone_backups' );
|
104 |
wpa_wpc_remove_table();
|
105 |
wp_die();
|
106 |
|
107 |
}
|
108 |
|
109 |
+
function wpa_wpc_ajax_search_n_replace() {
|
110 |
+
check_ajax_referer( 'wpclone-ajax-submit', 'nonce' );
|
111 |
+
global $wpdb;
|
112 |
+
$search = isset( $_POST['search'] ) ? $_POST['search'] : '';
|
113 |
+
$replace = isset( $_POST['replace'] ) ? $_POST['replace'] : '';
|
114 |
+
|
115 |
+
if( empty( $search ) || empty( $replace ) ) {
|
116 |
+
echo '<p class="error">Search and Replace values cannot be empty.</p>';
|
117 |
+
wp_die();
|
118 |
+
}
|
119 |
+
|
120 |
+
wpa_bump_limits();
|
121 |
+
$report = wpa_safe_replace_wrapper( $search, $replace, $wpdb->prefix );
|
122 |
+
echo wpa_wpc_search_n_replace_report( $report );
|
123 |
+
|
124 |
+
wp_die();
|
125 |
+
}
|
126 |
+
|
127 |
function wpclone_plugin_options() {
|
128 |
include_once 'lib/view.php';
|
129 |
}
|
137 |
wp_enqueue_script('wpclone');
|
138 |
wp_enqueue_style('wpclone');
|
139 |
wp_deregister_script('heartbeat');
|
140 |
+
add_thickbox();
|
141 |
}
|
142 |
if( isset($_GET['page']) && 'wp-clone' == $_GET['page'] ) add_action('admin_enqueue_scripts', 'wpa_enqueue_scripts');
|
143 |
|