WP Clone by WP Academy - Version 2.1.6

Version Description

  • 2013-07-07 =
  • Added: An option to exclude specific directories during backup.
  • Added: An option to only backup the database.
  • Added: An admin notice for multisite users.
  • Changed: File operations during backup are now handled directly instead of using the WP filesystem abstraction class.
Download this release

Release Info

Developer wpacademy
Plugin Icon 128x128 WP Clone by WP Academy
Version 2.1.6
Comparing to
See all releases

Code changes from version 2.1.5 to 2.1.6

Files changed (5) hide show
  1. lib/css/style.css +1 -1
  2. lib/functions.php +1 -1
  3. lib/view.php +33 -27
  4. readme.txt +15 -2
  5. wpclone.php +11 -2
lib/css/style.css CHANGED
@@ -51,7 +51,7 @@
51
  div.info {
52
  padding: 15px;
53
  margin: 30px 0;
54
- width: 530px;
55
  background: #fea;
56
  border-radius: 5px;
57
  -moz-box-shadow: 5px 5px 15px #aaa;
51
  div.info {
52
  padding: 15px;
53
  margin: 30px 0;
54
+ width: 600px;
55
  background: #fea;
56
  border-radius: 5px;
57
  -moz-box-shadow: 5px 5px 15px #aaa;
lib/functions.php CHANGED
@@ -1 +1 @@
1
- <?php
2
  return str_replace("\\", "/", $path);
3
  return rtrim(str_replace("//", "/", wpCloneSafePathMode($path)), '/') . '/';
4
  return str_replace(rtrim(WPCLONE_ROOT, "/\\"), site_url(), $path);
5
  return str_replace(site_url(), rtrim(WPCLONE_ROOT, "/\\"), $url);
6
  global $wpdb;
7
  $WPCLONE_DB_ICONV_IN = "UTF-8";
8
  $WPCLONE_DB_ICONV_OUT = "ISO-8859-1//TRANSLIT";
9
  $return = '';
10
  // Get all of the tables
11
  $tables = $wpdb->get_col('SHOW TABLES');
12
  // Cycle through each provided table
13
  foreach ($tables as $table) {
14
  // First part of the output � remove the table
15
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
16
  $numberOfFields = count($result[0]);
17
  $numberOfItems = count($result);
18
  // Second part of the output � create table
19
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
20
  $return .= "\n\n" . $row2[1] . ";\n\n";
21
  // Third part of the output � insert values into new table
22
  for ($currentRowNumber = 0; $currentRowNumber < $numberOfItems; $currentRowNumber++) {
23
  $row = $result[$currentRowNumber];
24
  $query = "INSERT INTO {$table} VALUES(";
25
  for ($j = 0; $j < $numberOfFields; $j++) {
26
  $row[$j] = iconv($WPCLONE_DB_ICONV_IN, $WPCLONE_DB_ICONV_OUT, $row[$j]);
27
  $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
28
  }
29
  $return .= substr($query, 0, -2) . ");\n";
30
  }
31
  $return .= "\n";
32
  }
33
  // Generate the filename for the sql file
34
  $File_open = fopen($destination . '/database.sql', 'w+');
35
  // Save the sql file
36
  fwrite($File_open, $return);
37
  //file close
38
  fclose($File_open);
39
  $wpdb->flush();
40
  * @link http://davidwalsh.name/backup-mysql-database-php
41
  */
42
  if ( false === $link ) {
43
  wpa_backup_error('db', mysql_error() );
44
  }
45
  if ( false === $result ) {
46
  wpa_backup_error('db', mysql_error() );
47
  }
48
 
49
  if ( false === $result ) {
50
  wpa_backup_error('db', mysql_error() );
51
  }
52
 
53
  global $wpdb;
54
  global $current_user;
55
  $wpdb->insert($wpdb->prefix . "wpclone", array(
56
  'backup_name' => $name,
57
  'data_time' => current_time('mysql', get_option('gmt_offset')),
58
  'creator' => $current_user->user_login,
59
  'backup_size' => $size)
60
  );
61
  $wpdb->flush();
62
  $folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
63
  $destinationPath = $folderToBeZipped . '/' . basename(WPCLONE_WP_CONTENT);
64
  $zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
65
  global $wp_filesystem;
66
 
67
  /* create the backup directory and call the cleanup function if it failed to do so */
68
  $dir = $wp_filesystem->mkdir( $folderToBeZipped );
69
  if( is_wp_error($dir) ) {
70
  wpa_backup_error ( 'file', $dir->get_error_message() . $folderToBeZipped );
71
  }
72
  /* copy wp-content directory into the newly created backup directory. call the cleanup function if it fails.
73
  * (wpa_copy doesn't return anything at the moment)*/
74
  $files = wpa_copy(WPCLONE_WP_CONTENT, $destinationPath);
75
  if( is_wp_error($files) ) {
76
  wpa_backup_error ( 'file', $files->get_error_message() );
77
  }
78
  wpa_save_prefix($folderToBeZipped);
79
  /* error handler is called from within the db backup functions */
80
  if ( $use_wpdb ) {
81
  wpa_db_backup_wpdb( $folderToBeZipped );
82
  } else {
83
  wpa_db_backup_direct( $folderToBeZipped );
84
  }
85
 
86
  /* error haldler is called from within the wpa_zip function */
87
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
88
  $zipSize = filesize($zipFileName);
89
  $wp_filesystem->delete( $folderToBeZipped, true );
90
  return array($backupName . '.zip', $zipSize);
91
  global $wpdb;
92
  $wp_backup = "{$wpdb->prefix}wpclone";
93
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
94
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
95
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
96
  return $deleteRow;
97
  $kilobyte = 1024;
98
  $megabyte = $kilobyte * 1024;
99
  $gigabyte = $megabyte * 1024;
100
  $terabyte = $gigabyte * 1024;
101
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
102
  return $bytes . ' B';
103
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
104
  return round($bytes / $kilobyte, $precision) . ' KB';
105
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
106
  return round($bytes / $megabyte, $precision) . ' MB';
107
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
108
  return round($bytes / $gigabyte, $precision) . ' GB';
109
  } elseif ($bytes >= $terabyte) {
110
  return round($bytes / $terabyte, $precision) . ' TB';
111
  } else {
112
  return $bytes . ' B';
113
  }
114
  $fileContent = file_get_contents($databaseFile, true);
115
  $pos = strpos($fileContent, 'siteurl') + 8;
116
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
117
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
118
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
119
  return $backupSiteUrl;
120
 
121
  $dbFileContent = file_get_contents($databaseFileInZip);
122
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
123
  if ( false === $dbFileContent ) {
124
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
125
  }
126
 
127
 
128
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
129
  /* and we cannot nuke the db if the connection failed now can we */
130
  if ( false === $conn ) {
131
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
132
  }
133
 
134
  mysql_select_db( DB_NAME, $conn);
135
 
136
  $query = mysql_query("SHOW TABLES", $conn);
137
  /* point of no return,if it fails after this you're royally boned ;) */
138
  while (($fetch = mysql_fetch_array($query))) {
139
  mysql_query("Drop table `{$fetch[0]}`");
140
  }
141
  flush();
142
 
143
  $res = explode(";\n", $dbFileContent);
144
  foreach ($res AS $query) {
145
  mysql_query($query, $conn);
146
  }
147
  mysql_close($conn);
148
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
149
  $currentSiteUrl = site_url();
150
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
151
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
152
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
153
 
154
  return $currentSiteUrl;
155
  * @param type $search URL of the previous site.
156
  * @param type $replace URL of the current site.
157
  * @return type total time it took for the operation.
158
  */
159
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
160
  require_once 'icit_srdb_replacer.php';
161
  }
162
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
163
  $all_tables = array( );
164
  @mysql_select_db( DB_NAME, $connection );
165
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
166
  if ( ! $all_tables_mysql ) {
167
  wpa_backup_error( 'dbrest', mysql_error(), true );
168
  } else {
169
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
170
  $all_tables[] = $table[ 0 ];
171
  }
172
  }
173
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
174
  return $report;
175
  wpa_cleanup( true );
176
  if (!is_string($url) || '' == $url) {
177
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
178
  }
179
 
180
  global $wp_filesystem;
181
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
182
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
183
  if ( is_wp_error($temp_dir_err) ) {
184
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
185
  }
186
  $pathParts = pathinfo($url);
187
  $zipFilename = wpa_fetch_file($url);
188
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
189
  if ($result) {
190
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
191
  if ( !file_exists( $unzippedFolderPath ) ) {
192
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
193
  }
194
 
195
  /* if we're here then the file extraction worked,but let's make doubly sure */
196
  if( !is_dir( $unzippedFolderPath ) ) {
197
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
198
  }
199
  /* check the table prefixes */
200
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
201
  $prefix = wpa_check_prefix($old_db_prefix);
202
  if ($prefix) {
203
  wpa_replace_prefix( $prefix );
204
  }
205
  /* import db */
206
  $databaseFile = $unzippedFolderPath . '/database.sql';
207
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
208
  /* */
209
  wpa_copy( $unzippedFolderPath, WPCLONE_ROOT );
210
 
211
  $wp_filesystem->delete( $temp_dir, true );
212
  /* remove the zip file only if it was downloaded from an external location. */
213
  $wptmp = explode('.', $zipFilename);
214
  if ( in_array( 'tmp', $wptmp ) ) {
215
  $wp_filesystem->delete( $zipFilename );
216
  }
217
  echo "<h1>Restore Successful!</h1>";
218
  echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
219
  echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
220
  } else {
221
  echo "<h1>Restore unsuccessful!!!</h1>";
222
  echo "Please try again.";
223
  }
224
  global $wpdb;
225
  $prefix = $wpdb->prefix;
226
  $file = $path . '/prefix.txt';
227
  if ( is_dir($path) && is_writable($path) ) {
228
  file_put_contents($file, $prefix);
229
  }
230
  * Checks to see whether the destination site's table prefix matches that of the origin site.old prefix is returned in case of a mismatch.
231
  *
232
  * @param type $file path to the prefix.txt file.
233
  * @return type bool string
234
  */
235
  global $wpdb;
236
  $prefix = $wpdb->prefix;
237
  if (file_exists($file) && is_readable($file)) {
238
  $old_prefix = file_get_contents($file);
239
  if ( $prefix !== $old_prefix ) {
240
  return $old_prefix;
241
  }
242
  else {
243
  return false;
244
  }
245
  }
246
  return false;
247
  * @since 2.0.6
248
  *
249
  * @param type $zipfile path to the zip file that needs to be extracted.
250
  * @param type $path the place to where the file needs to be extracted.
251
  * @return as false in the event of failure.
252
  */
253
  if ( $zipmode ) {
254
  if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
255
  $previous_encoding = mb_internal_encoding();
256
  mb_internal_encoding('ISO-8859-1');
257
  }
258
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
259
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
260
  $z = new PclZip($zipfile);
261
  $files = $z->extract(PCLZIP_OPT_PATH, $path);
262
  if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
263
  if ( $files == 0 ) {
264
  wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
265
  }
266
  return true;
267
  }
268
  else {
269
  $z= unzip_file($zipfile, $path);
270
  if (is_wp_error($z)) {
271
  wpa_backup_error( 'unzip', $z->get_error_message(), true );
272
  }
273
  return true;
274
  }
275
  * @since 2.0.6
276
  *
277
  * @param type $name name of the zip file.
278
  * @param type $file_list an array of files that needs to be archived.
279
  */
280
  if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
281
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
282
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
283
  $z = new PclZip($zip_name);
284
  $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
285
  if ($v_list == 0) {
286
  wpa_backup_error( 'pclzip', $z->errorInfo(true) );
287
  }
288
  } else {
289
  $z = new ZipArchive();
290
  if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
291
  wpa_backup_error( 'zip', $z );
292
  }
293
  wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
294
  $z->close();
295
  }
296
  $new_folder = str_replace($base, '', $dir);
297
  $zip->addEmptyDir($new_folder);
298
  foreach( glob( $dir . '/*' ) as $file ){
299
  if( is_dir($file) ) {
300
  wpa_ziparc($zip, $file, $base);
301
  } else {
302
  $new_file = str_replace( $base, '', $file );
303
  $zip->addFile($file, $new_file);
304
  }
305
  }
306
  * just a simple function to increase PHP limits.
307
  * @since 2.0.6
308
  */
309
  $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 900;
310
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
311
  @ini_set('memory_limit', $mem);
312
  @ini_set('max_execution_time', $time); //900 seconds = 15 minutes
313
  * @since 2.0.6
314
  */
315
  if (!empty($_REQUEST['del'])) {
316
  wpa_remove_backup();
317
  return true;
318
  }
319
  if (empty($_POST)) return false;
320
  check_admin_referer('wpclone-submit');
321
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
322
  $extra_fields = array('restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup');
323
  $type = '';
324
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
325
  return true;
326
  }
327
  if (!WP_Filesystem($creds)) {
328
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
329
  return true;
330
  }
331
  wpa_bump_limits();
332
 
333
  if (isset($_POST['createBackup'])) {
334
  wpa_create_backup();
335
  return true;
336
  }
337
 
338
  $zipmode = isset($_POST['zipmode']) ? true : false;
339
  $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
340
  processRestoringBackup($url, $zipmode);
341
  return true;
342
  * @since 2.0.6
343
  */
344
  global $wp_filesystem;
345
  if (is_readable($source)) {
346
  if (is_dir($source)) {
347
  if (!strstr(wpCloneSafePathMode($source), rtrim(WPCLONE_DIR_BACKUP, "/\\"))) {
348
  if (!file_exists($target)) {
349
  $wp_filesystem->mkdir($target);
350
  }
351
  $d = dir($source);
352
  while (FALSE !== ($entry = $d->read())) {
353
  if ($entry == '.' || $entry == '..') {
354
  continue;
355
  }
356
  $Entry = "{$source}/{$entry}";
357
  if (is_dir($Entry)) {
358
  wpa_copy($Entry, $target . '/' . $entry);
359
  } else {
360
  $wp_filesystem->copy($Entry, $target . '/' . $entry, true, FS_CHMOD_FILE);
361
  }
362
  }
363
  $d->close();
364
  }
365
  }
366
  else {
367
  $wp_filesystem->copy($source, $target, true);
368
  }
369
  }
370
  * @since 2.0.6
371
  */
372
  $wpconfig = wpa_wpconfig_path();
373
  if ( ! is_writable($wpconfig) ) {
374
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable." ), $wpconfig ), true );
375
  }
376
 
377
  global $wp_filesystem;
378
  $fileContent = file_get_contents($wpconfig);
379
  $pos = strpos($fileContent, '$table_prefix');
380
  $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
381
  $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
382
  $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
383
  * @since 2.0.6
384
  */
385
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
386
  wpa_create_directory();
387
  }
388
  wpa_cleanup();
389
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
390
  $backupName = wpa_backup_name();
391
  $zipmode = isset($_POST['zipmode']) ? true : false;
392
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
393
  wpa_insert_data($zipFileName, $zipSize);
394
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
395
  $zipSize = bytesToSize($zipSize);
396
  echo <<<EOF
397
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
398
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
399
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
400
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
401
  * @since 2.0.6
402
  */
403
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
404
  echo <<<EOT
405
  <h1>Deleted Successful!</h1> <br />
406
  {$deleteRow->backup_name} <br />
407
  File deleted from backup folder and database...
408
  * @since 2.1.2
409
  * copypasta from wp-load.php
410
  * @return the path to wp-config.php
411
  */
412
  $z = pathinfo($path);
413
  if (file_exists(WPCLONE_DIR_BACKUP . $z['basename'])) {
414
  return WPCLONE_DIR_BACKUP . $z['basename'];
415
  }
416
  else {
417
  $url = download_url($path, 750);
418
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
419
  return $url;
420
  }
421
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
422
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
423
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
424
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
425
  return $backup_name;
426
 
427
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
428
 
429
  if( !file_exists( $temp_dir ) ) {
430
  unset($temp_dir);
431
  }
432
  switch ( $error ) :
433
  /* during backup */
434
  case 'file' :
435
  $error = __( 'while copying files into the temp directory' );
436
  break;
437
  case 'db' :
438
  $error = __( 'during the database backup' );
439
  break;
440
  case 'zip' :
441
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
442
  break;
443
  case 'pclzip' :
444
  $error = __( 'while creating the zip file using the PclZip library' );
445
  break;
446
  /* during restore */
447
  case 'dirrest' :
448
  $error = __( 'while creating the temp directory' );
449
  break;
450
  case 'filerest' :
451
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
452
  break;
453
  case 'dbrest' :
454
  $error = __( 'while cloning the database' );
455
  break;
456
  case 'unzip' :
457
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
458
  break;
459
  case 'pclunzip' :
460
  $error = __( 'while extracting the zip file using the PclZip library' );
461
  break;
462
  case 'url' :
463
  $error = __( 'while downloading the zip file' );
464
  break;
465
  case 'wpconfig' :
466
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
467
  break;
468
  /* and a catch all for the things that aren't covered above */
469
  default :
470
  $error = sprintf( __( 'during the %s process' ), $error );
471
  endswitch;
472
 
473
  echo '<div class="wpclone_notice updated">';
474
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
475
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
476
  if( isset( $temp_dir ) ) {
477
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
478
  echo '</div>';
479
  global $wp_filesystem;
480
  $wp_filesystem->delete($temp_dir, true);
481
  } else {
482
  echo '</div>';
483
  }
484
  die;
485
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
486
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
487
  global $wp_filesystem;
488
  $wp_filesystem->delete($backup_dir, true);
489
  }
 
490
  return str_replace("\\", "/", $path);
491
  return rtrim(str_replace("//", "/", wpCloneSafePathMode($path)), '/') . '/';
492
  return str_replace(rtrim(WPCLONE_ROOT, "/\\"), site_url(), $path);
493
  return str_replace(site_url(), rtrim(WPCLONE_ROOT, "/\\"), $url);
494
  global $wpdb;
495
  $WPCLONE_DB_ICONV_IN = "UTF-8";
496
  $WPCLONE_DB_ICONV_OUT = "ISO-8859-1//TRANSLIT";
497
  $return = '';
498
  // Get all of the tables
499
  $tables = $wpdb->get_col('SHOW TABLES');
500
  // Cycle through each provided table
501
  foreach ($tables as $table) {
502
  // First part of the output � remove the table
503
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
504
  $numberOfFields = count($result[0]);
505
  $numberOfItems = count($result);
506
  // Second part of the output � create table
507
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
508
  $return .= "\n\n" . $row2[1] . ";\n\n";
509
  // Third part of the output � insert values into new table
510
  for ($currentRowNumber = 0; $currentRowNumber < $numberOfItems; $currentRowNumber++) {
511
  $row = $result[$currentRowNumber];
512
  $query = "INSERT INTO {$table} VALUES(";
513
  for ($j = 0; $j < $numberOfFields; $j++) {
514
  $row[$j] = iconv($WPCLONE_DB_ICONV_IN, $WPCLONE_DB_ICONV_OUT, $row[$j]);
515
  $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
516
  }
517
  $return .= substr($query, 0, -2) . ");\n";
518
  }
519
  $return .= "\n";
520
  }
521
  // Generate the filename for the sql file
522
  $File_open = fopen($destination . '/database.sql', 'w+');
523
  // Save the sql file
524
  fwrite($File_open, $return);
525
  //file close
526
  fclose($File_open);
527
  $wpdb->flush();
528
  * @link http://davidwalsh.name/backup-mysql-database-php
529
  */
530
  if ( false === $link ) {
531
  wpa_backup_error('db', mysql_error() );
532
  }
533
  if ( false === $result ) {
534
  wpa_backup_error('db', mysql_error() );
535
  }
536
 
537
  if ( false === $result ) {
538
  wpa_backup_error('db', mysql_error() );
539
  }
540
 
541
  global $wpdb;
542
  global $current_user;
543
  $wpdb->insert($wpdb->prefix . "wpclone", array(
544
  'backup_name' => $name,
545
  'data_time' => current_time('mysql', get_option('gmt_offset')),
546
  'creator' => $current_user->user_login,
547
  'backup_size' => $size)
548
  );
549
  $wpdb->flush();
550
  $folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
551
  $destinationPath = $folderToBeZipped . '/' . basename(WPCLONE_WP_CONTENT);
552
  $zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
553
  $exclude = wpa_excluded_dirs();
554
  $dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
555
 
556
  if( false === mkdir( $folderToBeZipped ) )
557
  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 ) );
558
 
559
  if( false === $dbonly )
560
  wpa_copy_dir( untrailingslashit( WPCLONE_WP_CONTENT ), $destinationPath, $exclude);
561
 
562
  wpa_save_prefix($folderToBeZipped);
563
  /* error handler is called from within the db backup functions */
564
  if ( $use_wpdb ) {
565
  wpa_db_backup_wpdb( $folderToBeZipped );
566
  } else {
567
  wpa_db_backup_direct( $folderToBeZipped );
568
  }
569
 
570
  /* error haldler is called from within the wpa_zip function */
571
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
572
  $zipSize = filesize($zipFileName);
573
  wpa_delete_dir( $folderToBeZipped );
574
  return array($backupName . '.zip', $zipSize);
575
  global $wpdb;
576
  $wp_backup = "{$wpdb->prefix}wpclone";
577
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
578
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
579
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
580
  return $deleteRow;
581
  $kilobyte = 1024;
582
  $megabyte = $kilobyte * 1024;
583
  $gigabyte = $megabyte * 1024;
584
  $terabyte = $gigabyte * 1024;
585
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
586
  return $bytes . ' B';
587
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
588
  return round($bytes / $kilobyte, $precision) . ' KB';
589
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
590
  return round($bytes / $megabyte, $precision) . ' MB';
591
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
592
  return round($bytes / $gigabyte, $precision) . ' GB';
593
  } elseif ($bytes >= $terabyte) {
594
  return round($bytes / $terabyte, $precision) . ' TB';
595
  } else {
596
  return $bytes . ' B';
597
  }
598
  global $wp_filesystem;
599
  $fileContent = $wp_filesystem->get_contents($databaseFile);
600
  $pos = strpos($fileContent, 'siteurl') + 8;
601
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
602
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
603
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
604
  return $backupSiteUrl;
605
  global $wp_filesystem;
606
  $dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
607
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
608
  if ( false === $dbFileContent ) {
609
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
610
  }
611
 
612
 
613
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
614
  /* and we cannot nuke the db if the connection failed now can we */
615
  if ( false === $conn ) {
616
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
617
  }
618
 
619
  mysql_select_db( DB_NAME, $conn);
620
 
621
  $query = mysql_query("SHOW TABLES", $conn);
622
  /* point of no return,if it fails after this you're royally boned ;) */
623
  while (($fetch = mysql_fetch_array($query))) {
624
  mysql_query("Drop table `{$fetch[0]}`");
625
  }
626
  flush();
627
 
628
  $res = explode(";\n", $dbFileContent);
629
  foreach ($res AS $query) {
630
  mysql_query($query, $conn);
631
  }
632
  mysql_close($conn);
633
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
634
  $currentSiteUrl = site_url();
635
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
636
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
637
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
638
 
639
  return $currentSiteUrl;
640
  * @param type $search URL of the previous site.
641
  * @param type $replace URL of the current site.
642
  * @return type total time it took for the operation.
643
  */
644
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
645
  require_once 'icit_srdb_replacer.php';
646
  }
647
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
648
  $all_tables = array( );
649
  @mysql_select_db( DB_NAME, $connection );
650
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
651
  if ( ! $all_tables_mysql ) {
652
  wpa_backup_error( 'dbrest', mysql_error(), true );
653
  } else {
654
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
655
  $all_tables[] = $table[ 0 ];
656
  }
657
  }
658
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
659
  return $report;
660
  wpa_cleanup( true );
661
  if (!is_string($url) || '' == $url) {
662
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
663
  }
664
 
665
  global $wp_filesystem;
666
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
667
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
668
  if ( is_wp_error($temp_dir_err) ) {
669
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
670
  }
671
  $pathParts = pathinfo($url);
672
  $zipFilename = wpa_fetch_file($url);
673
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
674
  if ($result) {
675
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
676
  if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
677
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
678
  }
679
 
680
  /* if we're here then the file extraction worked,but let's make doubly sure */
681
  if( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
682
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
683
  }
684
  /* check the table prefixes */
685
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
686
  $prefix = wpa_check_prefix($old_db_prefix);
687
  if ($prefix) {
688
  wpa_replace_prefix( $prefix );
689
  }
690
  $wp_filesystem->delete( $old_db_prefix );
691
  /* import db */
692
  $databaseFile = $unzippedFolderPath . '/database.sql';
693
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
694
  /* */
695
  $wp_filesystem->delete( $databaseFile );
696
  wpa_copy( $unzippedFolderPath . '/wp-content', WPCLONE_WP_CONTENT );
697
 
698
  $wp_filesystem->delete( $temp_dir, true );
699
  /* remove the zip file only if it was downloaded from an external location. */
700
  $wptmp = explode('.', $zipFilename);
701
  if ( in_array( 'tmp', $wptmp ) ) {
702
  $wp_filesystem->delete( $zipFilename );
703
  }
704
  echo "<h1>Restore Successful!</h1>";
705
  echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
706
  echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
707
  } else {
708
  echo "<h1>Restore unsuccessful!!!</h1>";
709
  echo "Please try again.";
710
  }
711
  global $wpdb;
712
  $prefix = $wpdb->prefix;
713
  $file = $path . '/prefix.txt';
714
  if ( is_dir($path) && is_writable($path) ) {
715
  file_put_contents($file, $prefix);
716
  }
717
  * Checks to see whether the destination site's table prefix matches that of the origin site.old prefix is returned in case of a mismatch.
718
  *
719
  * @param type $file path to the prefix.txt file.
720
  * @return type bool string
721
  */
722
  global $wpdb;
723
  $prefix = $wpdb->prefix;
724
  if (file_exists($file) && is_readable($file)) {
725
  $old_prefix = file_get_contents($file);
726
  if ( $prefix !== $old_prefix ) {
727
  return $old_prefix;
728
  }
729
  else {
730
  return false;
731
  }
732
  }
733
  return false;
734
  * @since 2.0.6
735
  *
736
  * @param type $zipfile path to the zip file that needs to be extracted.
737
  * @param type $path the place to where the file needs to be extracted.
738
  * @return as false in the event of failure.
739
  */
740
  if ( $zipmode ) {
741
  if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
742
  $previous_encoding = mb_internal_encoding();
743
  mb_internal_encoding('ISO-8859-1');
744
  }
745
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
746
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
747
  $z = new PclZip($zipfile);
748
  $files = $z->extract(PCLZIP_OPT_PATH, $path);
749
  if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
750
  if ( $files == 0 ) {
751
  wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
752
  }
753
  return true;
754
  }
755
  else {
756
  $z= unzip_file($zipfile, $path);
757
  if (is_wp_error($z)) {
758
  wpa_backup_error( 'unzip', $z->get_error_message(), true );
759
  }
760
  return true;
761
  }
762
  * @since 2.0.6
763
  *
764
  * @param type $name name of the zip file.
765
  * @param type $file_list an array of files that needs to be archived.
766
  */
767
  if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
768
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
769
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
770
  $z = new PclZip($zip_name);
771
  $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
772
  if ($v_list == 0) {
773
  wpa_backup_error( 'pclzip', $z->errorInfo(true) );
774
  }
775
  } else {
776
  $z = new ZipArchive();
777
  if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
778
  wpa_backup_error( 'zip', $z );
779
  }
780
  wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
781
  $z->close();
782
  }
783
  $new_folder = str_replace($base, '', $dir);
784
  $zip->addEmptyDir($new_folder);
785
  foreach( glob( $dir . '/*' ) as $file ){
786
  if( is_dir($file) ) {
787
  wpa_ziparc($zip, $file, $base);
788
  } else {
789
  $new_file = str_replace( $base, '', $file );
790
  $zip->addFile($file, $new_file);
791
  }
792
  }
793
  * just a simple function to increase PHP limits.
794
  * @since 2.0.6
795
  */
796
  $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 300; /*300 seconds = 5 minutes*/
797
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
798
  @ini_set('memory_limit', $mem);
799
  @ini_set('max_execution_time', $time);
800
  * @since 2.0.6
801
  */
802
  if (!empty($_REQUEST['del'])) {
803
  wpa_remove_backup();
804
  return true;
805
  }
806
  if (empty($_POST)) return false;
807
  check_admin_referer('wpclone-submit');
808
 
809
  wpa_bump_limits();
810
 
811
  if (isset($_POST['createBackup'])) {
812
  wpa_create_backup();
813
  return true;
814
  }
815
 
816
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
817
  $extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
818
  $type = '';
819
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
820
  return true;
821
  }
822
  if (!WP_Filesystem($creds)) {
823
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
824
  return true;
825
  }
826
 
827
  $zipmode = isset($_POST['zipmode']) ? true : false;
828
  $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
829
  processRestoringBackup($url, $zipmode);
830
  return true;
831
  * @since 2.0.6
832
  */
833
  global $wp_filesystem;
834
  if (is_readable($source)) {
835
  if (is_dir($source)) {
836
  if (!file_exists($target)) {
837
  $wp_filesystem->mkdir($target);
838
  }
839
  $d = dir($source);
840
  while (FALSE !== ($entry = $d->read())) {
841
  if ($entry == '.' || $entry == '..') {
842
  continue;
843
  }
844
  $Entry = "{$source}/{$entry}";
845
  if (is_dir($Entry)) {
846
  wpa_copy($Entry, $target . '/' . $entry);
847
  } else {
848
  $wp_filesystem->copy($Entry, $target . '/' . $entry, true, FS_CHMOD_FILE);
849
  }
850
  }
851
  $d->close();
852
  }
853
  else {
854
  $wp_filesystem->copy($source, $target, true);
855
  }
856
  }
857
  * @since 2.0.6
858
  */
859
  $wpconfig = wpa_wpconfig_path();
860
  global $wp_filesystem;
861
 
862
  if ( ! $wp_filesystem->is_writable($wpconfig) ) {
863
  if( false === $wp_filesystem->chmod( $wpconfig ) )
864
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
865
  }
866
 
867
  $fileContent = $wp_filesystem->get_contents($wpconfig);
868
  $pos = strpos($fileContent, '$table_prefix');
869
  $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
870
  $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
871
  $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
872
  * @since 2.0.6
873
  */
874
  if( true === is_multisite() )
875
  die( 'wpclone does not work on multisite installs.' );
876
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
877
  wpa_create_directory();
878
  }
879
  wpa_cleanup();
880
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
881
  $backupName = wpa_backup_name();
882
  $zipmode = isset($_POST['zipmode']) ? true : false;
883
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
884
  wpa_insert_data($zipFileName, $zipSize);
885
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
886
  $zipSize = bytesToSize($zipSize);
887
  echo <<<EOF
888
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
889
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
890
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
891
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
892
  * @since 2.0.6
893
  */
894
  check_admin_referer('wpclone-submit');
895
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
896
  echo <<<EOT
897
  <h1>Deleted Successful!</h1> <br />
898
  {$deleteRow->backup_name} <br />
899
  File deleted from backup folder and database...
900
  * @since 2.1.2
901
  * copypasta from wp-load.php
902
  * @return the path to wp-config.php
903
  */
904
  $z = pathinfo($path);
905
  global $wp_filesystem;
906
  if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
907
  return WPCLONE_DIR_BACKUP . $z['basename'];
908
  }
909
  else {
910
  $url = download_url($path, 750);
911
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
912
  return $url;
913
  }
914
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
915
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
916
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
917
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
918
  return $backup_name;
919
 
920
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
921
 
922
  if( !file_exists( $temp_dir ) ) {
923
  unset($temp_dir);
924
  }
925
  switch ( $error ) :
926
  /* during backup */
927
  case 'file' :
928
  $error = __( 'while copying files into the temp directory' );
929
  break;
930
  case 'db' :
931
  $error = __( 'during the database backup' );
932
  break;
933
  case 'zip' :
934
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
935
  break;
936
  case 'pclzip' :
937
  $error = __( 'while creating the zip file using the PclZip library' );
938
  break;
939
  /* during restore */
940
  case 'dirrest' :
941
  $error = __( 'while creating the temp directory' );
942
  break;
943
  case 'filerest' :
944
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
945
  break;
946
  case 'dbrest' :
947
  $error = __( 'while cloning the database' );
948
  break;
949
  case 'unzip' :
950
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
951
  break;
952
  case 'pclunzip' :
953
  $error = __( 'while extracting the zip file using the PclZip library' );
954
  break;
955
  case 'url' :
956
  $error = __( 'while downloading the zip file' );
957
  break;
958
  case 'wpconfig' :
959
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
960
  break;
961
  /* and a catch all for the things that aren't covered above */
962
  default :
963
  $error = sprintf( __( 'during the %s process' ), $error );
964
  endswitch;
965
 
966
  echo '<div class="wpclone_notice updated">';
967
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
968
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
969
  if( isset( $temp_dir ) ) {
970
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
971
  echo '</div>';
972
  if( $restore ) {
973
  global $wp_filesystem;
974
  $wp_filesystem->delete($temp_dir, true);
975
  } else {
976
  wpa_delete_dir( $temp_dir );
977
  }
978
  } else {
979
  echo '</div>';
980
  }
981
  die;
982
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
983
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
984
  if( $restore ) {
985
  global $wp_filesystem;
986
  $wp_filesystem->delete($backup_dir, true);
987
  } else {
988
  wpa_delete_dir( $backup_dir );
989
  }
990
  }
991
  * recursively copies a directory from one place to another. excludes 'uploads/wp-clone' by default.
992
  * @since 2.1.6
993
  * @param string $from
994
  * @param string $to
995
  * @param array $exclude an array of directory paths to exclude.
996
  */
997
  if( false === stripos( wpCloneSafePathMode( $from ), rtrim( wpCloneSafePathMode( WPCLONE_DIR_BACKUP ), "/\\" ) ) ) {
998
  if( !file_exists( $to ) )
999
  @mkdir ( $to );
1000
  $files = array_diff( scandir( $from ), array( '.', '..' ) );
1001
  foreach( $files as $file ) {
1002
  if( in_array( $from . '/' . $file, $exclude ) ) {
1003
  continue;
1004
  } else {
1005
  if( is_dir( $from . '/' . $file ) ) {
1006
  wpa_copy_dir( $from . '/' . $file, $to . '/' . $file, $exclude );
1007
  } else {
1008
  @copy( $from . '/' . $file, $to . '/' . $file );
1009
  }
1010
  }
1011
  }
1012
  unset( $files );
1013
  }
1014
  * recursively deletes all the files in the given directory.
1015
  * @since 2.1.6
1016
  * @param string $dir path to the directory that needs to be deleted.
1017
  */
1018
  if( !empty( $dir ) ) {
1019
  $dir = trailingslashit( $dir );
1020
  $files = array_diff( scandir( $dir ), array( '.', '..' ) );
1021
  foreach ( $files as $file ) {
1022
  if( is_dir( $dir . $file ) ) {
1023
  wpa_delete_dir( $dir . $file );
1024
  } else {
1025
  @unlink( $dir . $file );
1026
  }
1027
  }
1028
  @rmdir($dir);
1029
  }
1030
  * @since 2.1.6
1031
  */
1032
  $exclude = array();
1033
  if( isset( $_POST['exclude'] ) && '' != $_POST['exclude'] ) {
1034
  foreach( explode( "\n", $_POST['exclude'] ) as $ex ) {
1035
  $ex = trim( $ex );
1036
  if( '' !== $ex ) {
1037
  $ex = trim( $ex, "/\\" );
1038
  $exclude[] = trailingslashit( WPCLONE_WP_CONTENT ) . str_replace( '\\', '/', $ex ) ;
1039
  }
1040
  }
1041
  }
1042
  return $exclude;
 
1
  return str_replace("\\", "/", $path);
2
  return rtrim(str_replace("//", "/", wpCloneSafePathMode($path)), '/') . '/';
3
  return str_replace(rtrim(WPCLONE_ROOT, "/\\"), site_url(), $path);
4
  return str_replace(site_url(), rtrim(WPCLONE_ROOT, "/\\"), $url);
5
  global $wpdb;
6
  $WPCLONE_DB_ICONV_IN = "UTF-8";
7
  $WPCLONE_DB_ICONV_OUT = "ISO-8859-1//TRANSLIT";
8
  $return = '';
9
  // Get all of the tables
10
  $tables = $wpdb->get_col('SHOW TABLES');
11
  // Cycle through each provided table
12
  foreach ($tables as $table) {
13
  // First part of the output � remove the table
14
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
15
  $numberOfFields = count($result[0]);
16
  $numberOfItems = count($result);
17
  // Second part of the output � create table
18
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
19
  $return .= "\n\n" . $row2[1] . ";\n\n";
20
  // Third part of the output � insert values into new table
21
  for ($currentRowNumber = 0; $currentRowNumber < $numberOfItems; $currentRowNumber++) {
22
  $row = $result[$currentRowNumber];
23
  $query = "INSERT INTO {$table} VALUES(";
24
  for ($j = 0; $j < $numberOfFields; $j++) {
25
  $row[$j] = iconv($WPCLONE_DB_ICONV_IN, $WPCLONE_DB_ICONV_OUT, $row[$j]);
26
  $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
27
  }
28
  $return .= substr($query, 0, -2) . ");\n";
29
  }
30
  $return .= "\n";
31
  }
32
  // Generate the filename for the sql file
33
  $File_open = fopen($destination . '/database.sql', 'w+');
34
  // Save the sql file
35
  fwrite($File_open, $return);
36
  //file close
37
  fclose($File_open);
38
  $wpdb->flush();
39
  * @link http://davidwalsh.name/backup-mysql-database-php
40
  */
41
  if ( false === $link ) {
42
  wpa_backup_error('db', mysql_error() );
43
  }
44
  if ( false === $result ) {
45
  wpa_backup_error('db', mysql_error() );
46
  }
47
 
48
  if ( false === $result ) {
49
  wpa_backup_error('db', mysql_error() );
50
  }
51
 
52
  global $wpdb;
53
  global $current_user;
54
  $wpdb->insert($wpdb->prefix . "wpclone", array(
55
  'backup_name' => $name,
56
  'data_time' => current_time('mysql', get_option('gmt_offset')),
57
  'creator' => $current_user->user_login,
58
  'backup_size' => $size)
59
  );
60
  $wpdb->flush();
61
  $folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
62
  $destinationPath = $folderToBeZipped . '/' . basename(WPCLONE_WP_CONTENT);
63
  $zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
64
  global $wp_filesystem;
65
 
66
  /* create the backup directory and call the cleanup function if it failed to do so */
67
  $dir = $wp_filesystem->mkdir( $folderToBeZipped );
68
  if( is_wp_error($dir) ) {
69
  wpa_backup_error ( 'file', $dir->get_error_message() . $folderToBeZipped );
70
  }
71
  /* copy wp-content directory into the newly created backup directory. call the cleanup function if it fails.
72
  * (wpa_copy doesn't return anything at the moment)*/
73
  $files = wpa_copy(WPCLONE_WP_CONTENT, $destinationPath);
74
  if( is_wp_error($files) ) {
75
  wpa_backup_error ( 'file', $files->get_error_message() );
76
  }
77
  wpa_save_prefix($folderToBeZipped);
78
  /* error handler is called from within the db backup functions */
79
  if ( $use_wpdb ) {
80
  wpa_db_backup_wpdb( $folderToBeZipped );
81
  } else {
82
  wpa_db_backup_direct( $folderToBeZipped );
83
  }
84
 
85
  /* error haldler is called from within the wpa_zip function */
86
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
87
  $zipSize = filesize($zipFileName);
88
  $wp_filesystem->delete( $folderToBeZipped, true );
89
  return array($backupName . '.zip', $zipSize);
90
  global $wpdb;
91
  $wp_backup = "{$wpdb->prefix}wpclone";
92
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
93
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
94
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
95
  return $deleteRow;
96
  $kilobyte = 1024;
97
  $megabyte = $kilobyte * 1024;
98
  $gigabyte = $megabyte * 1024;
99
  $terabyte = $gigabyte * 1024;
100
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
101
  return $bytes . ' B';
102
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
103
  return round($bytes / $kilobyte, $precision) . ' KB';
104
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
105
  return round($bytes / $megabyte, $precision) . ' MB';
106
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
107
  return round($bytes / $gigabyte, $precision) . ' GB';
108
  } elseif ($bytes >= $terabyte) {
109
  return round($bytes / $terabyte, $precision) . ' TB';
110
  } else {
111
  return $bytes . ' B';
112
  }
113
  $fileContent = file_get_contents($databaseFile, true);
114
  $pos = strpos($fileContent, 'siteurl') + 8;
115
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
116
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
117
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
118
  return $backupSiteUrl;
119
 
120
  $dbFileContent = file_get_contents($databaseFileInZip);
121
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
122
  if ( false === $dbFileContent ) {
123
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
124
  }
125
 
126
 
127
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
128
  /* and we cannot nuke the db if the connection failed now can we */
129
  if ( false === $conn ) {
130
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
131
  }
132
 
133
  mysql_select_db( DB_NAME, $conn);
134
 
135
  $query = mysql_query("SHOW TABLES", $conn);
136
  /* point of no return,if it fails after this you're royally boned ;) */
137
  while (($fetch = mysql_fetch_array($query))) {
138
  mysql_query("Drop table `{$fetch[0]}`");
139
  }
140
  flush();
141
 
142
  $res = explode(";\n", $dbFileContent);
143
  foreach ($res AS $query) {
144
  mysql_query($query, $conn);
145
  }
146
  mysql_close($conn);
147
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
148
  $currentSiteUrl = site_url();
149
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
150
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
151
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
152
 
153
  return $currentSiteUrl;
154
  * @param type $search URL of the previous site.
155
  * @param type $replace URL of the current site.
156
  * @return type total time it took for the operation.
157
  */
158
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
159
  require_once 'icit_srdb_replacer.php';
160
  }
161
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
162
  $all_tables = array( );
163
  @mysql_select_db( DB_NAME, $connection );
164
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
165
  if ( ! $all_tables_mysql ) {
166
  wpa_backup_error( 'dbrest', mysql_error(), true );
167
  } else {
168
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
169
  $all_tables[] = $table[ 0 ];
170
  }
171
  }
172
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
173
  return $report;
174
  wpa_cleanup( true );
175
  if (!is_string($url) || '' == $url) {
176
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
177
  }
178
 
179
  global $wp_filesystem;
180
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
181
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
182
  if ( is_wp_error($temp_dir_err) ) {
183
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
184
  }
185
  $pathParts = pathinfo($url);
186
  $zipFilename = wpa_fetch_file($url);
187
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
188
  if ($result) {
189
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
190
  if ( !file_exists( $unzippedFolderPath ) ) {
191
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
192
  }
193
 
194
  /* if we're here then the file extraction worked,but let's make doubly sure */
195
  if( !is_dir( $unzippedFolderPath ) ) {
196
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
197
  }
198
  /* check the table prefixes */
199
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
200
  $prefix = wpa_check_prefix($old_db_prefix);
201
  if ($prefix) {
202
  wpa_replace_prefix( $prefix );
203
  }
204
  /* import db */
205
  $databaseFile = $unzippedFolderPath . '/database.sql';
206
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
207
  /* */
208
  wpa_copy( $unzippedFolderPath, WPCLONE_ROOT );
209
 
210
  $wp_filesystem->delete( $temp_dir, true );
211
  /* remove the zip file only if it was downloaded from an external location. */
212
  $wptmp = explode('.', $zipFilename);
213
  if ( in_array( 'tmp', $wptmp ) ) {
214
  $wp_filesystem->delete( $zipFilename );
215
  }
216
  echo "<h1>Restore Successful!</h1>";
217
  echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
218
  echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
219
  } else {
220
  echo "<h1>Restore unsuccessful!!!</h1>";
221
  echo "Please try again.";
222
  }
223
  global $wpdb;
224
  $prefix = $wpdb->prefix;
225
  $file = $path . '/prefix.txt';
226
  if ( is_dir($path) && is_writable($path) ) {
227
  file_put_contents($file, $prefix);
228
  }
229
  * Checks to see whether the destination site's table prefix matches that of the origin site.old prefix is returned in case of a mismatch.
230
  *
231
  * @param type $file path to the prefix.txt file.
232
  * @return type bool string
233
  */
234
  global $wpdb;
235
  $prefix = $wpdb->prefix;
236
  if (file_exists($file) && is_readable($file)) {
237
  $old_prefix = file_get_contents($file);
238
  if ( $prefix !== $old_prefix ) {
239
  return $old_prefix;
240
  }
241
  else {
242
  return false;
243
  }
244
  }
245
  return false;
246
  * @since 2.0.6
247
  *
248
  * @param type $zipfile path to the zip file that needs to be extracted.
249
  * @param type $path the place to where the file needs to be extracted.
250
  * @return as false in the event of failure.
251
  */
252
  if ( $zipmode ) {
253
  if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
254
  $previous_encoding = mb_internal_encoding();
255
  mb_internal_encoding('ISO-8859-1');
256
  }
257
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
258
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
259
  $z = new PclZip($zipfile);
260
  $files = $z->extract(PCLZIP_OPT_PATH, $path);
261
  if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
262
  if ( $files == 0 ) {
263
  wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
264
  }
265
  return true;
266
  }
267
  else {
268
  $z= unzip_file($zipfile, $path);
269
  if (is_wp_error($z)) {
270
  wpa_backup_error( 'unzip', $z->get_error_message(), true );
271
  }
272
  return true;
273
  }
274
  * @since 2.0.6
275
  *
276
  * @param type $name name of the zip file.
277
  * @param type $file_list an array of files that needs to be archived.
278
  */
279
  if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
280
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
281
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
282
  $z = new PclZip($zip_name);
283
  $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
284
  if ($v_list == 0) {
285
  wpa_backup_error( 'pclzip', $z->errorInfo(true) );
286
  }
287
  } else {
288
  $z = new ZipArchive();
289
  if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
290
  wpa_backup_error( 'zip', $z );
291
  }
292
  wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
293
  $z->close();
294
  }
295
  $new_folder = str_replace($base, '', $dir);
296
  $zip->addEmptyDir($new_folder);
297
  foreach( glob( $dir . '/*' ) as $file ){
298
  if( is_dir($file) ) {
299
  wpa_ziparc($zip, $file, $base);
300
  } else {
301
  $new_file = str_replace( $base, '', $file );
302
  $zip->addFile($file, $new_file);
303
  }
304
  }
305
  * just a simple function to increase PHP limits.
306
  * @since 2.0.6
307
  */
308
  $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 900;
309
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
310
  @ini_set('memory_limit', $mem);
311
  @ini_set('max_execution_time', $time); //900 seconds = 15 minutes
312
  * @since 2.0.6
313
  */
314
  if (!empty($_REQUEST['del'])) {
315
  wpa_remove_backup();
316
  return true;
317
  }
318
  if (empty($_POST)) return false;
319
  check_admin_referer('wpclone-submit');
320
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
321
  $extra_fields = array('restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup');
322
  $type = '';
323
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
324
  return true;
325
  }
326
  if (!WP_Filesystem($creds)) {
327
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
328
  return true;
329
  }
330
  wpa_bump_limits();
331
 
332
  if (isset($_POST['createBackup'])) {
333
  wpa_create_backup();
334
  return true;
335
  }
336
 
337
  $zipmode = isset($_POST['zipmode']) ? true : false;
338
  $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
339
  processRestoringBackup($url, $zipmode);
340
  return true;
341
  * @since 2.0.6
342
  */
343
  global $wp_filesystem;
344
  if (is_readable($source)) {
345
  if (is_dir($source)) {
346
  if (!strstr(wpCloneSafePathMode($source), rtrim(WPCLONE_DIR_BACKUP, "/\\"))) {
347
  if (!file_exists($target)) {
348
  $wp_filesystem->mkdir($target);
349
  }
350
  $d = dir($source);
351
  while (FALSE !== ($entry = $d->read())) {
352
  if ($entry == '.' || $entry == '..') {
353
  continue;
354
  }
355
  $Entry = "{$source}/{$entry}";
356
  if (is_dir($Entry)) {
357
  wpa_copy($Entry, $target . '/' . $entry);
358
  } else {
359
  $wp_filesystem->copy($Entry, $target . '/' . $entry, true, FS_CHMOD_FILE);
360
  }
361
  }
362
  $d->close();
363
  }
364
  }
365
  else {
366
  $wp_filesystem->copy($source, $target, true);
367
  }
368
  }
369
  * @since 2.0.6
370
  */
371
  $wpconfig = wpa_wpconfig_path();
372
  if ( ! is_writable($wpconfig) ) {
373
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable." ), $wpconfig ), true );
374
  }
375
 
376
  global $wp_filesystem;
377
  $fileContent = file_get_contents($wpconfig);
378
  $pos = strpos($fileContent, '$table_prefix');
379
  $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
380
  $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
381
  $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
382
  * @since 2.0.6
383
  */
384
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
385
  wpa_create_directory();
386
  }
387
  wpa_cleanup();
388
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
389
  $backupName = wpa_backup_name();
390
  $zipmode = isset($_POST['zipmode']) ? true : false;
391
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
392
  wpa_insert_data($zipFileName, $zipSize);
393
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
394
  $zipSize = bytesToSize($zipSize);
395
  echo <<<EOF
396
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
397
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
398
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
399
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
400
  * @since 2.0.6
401
  */
402
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
403
  echo <<<EOT
404
  <h1>Deleted Successful!</h1> <br />
405
  {$deleteRow->backup_name} <br />
406
  File deleted from backup folder and database...
407
  * @since 2.1.2
408
  * copypasta from wp-load.php
409
  * @return the path to wp-config.php
410
  */
411
  $z = pathinfo($path);
412
  if (file_exists(WPCLONE_DIR_BACKUP . $z['basename'])) {
413
  return WPCLONE_DIR_BACKUP . $z['basename'];
414
  }
415
  else {
416
  $url = download_url($path, 750);
417
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
418
  return $url;
419
  }
420
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
421
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
422
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
423
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
424
  return $backup_name;
425
 
426
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
427
 
428
  if( !file_exists( $temp_dir ) ) {
429
  unset($temp_dir);
430
  }
431
  switch ( $error ) :
432
  /* during backup */
433
  case 'file' :
434
  $error = __( 'while copying files into the temp directory' );
435
  break;
436
  case 'db' :
437
  $error = __( 'during the database backup' );
438
  break;
439
  case 'zip' :
440
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
441
  break;
442
  case 'pclzip' :
443
  $error = __( 'while creating the zip file using the PclZip library' );
444
  break;
445
  /* during restore */
446
  case 'dirrest' :
447
  $error = __( 'while creating the temp directory' );
448
  break;
449
  case 'filerest' :
450
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
451
  break;
452
  case 'dbrest' :
453
  $error = __( 'while cloning the database' );
454
  break;
455
  case 'unzip' :
456
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
457
  break;
458
  case 'pclunzip' :
459
  $error = __( 'while extracting the zip file using the PclZip library' );
460
  break;
461
  case 'url' :
462
  $error = __( 'while downloading the zip file' );
463
  break;
464
  case 'wpconfig' :
465
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
466
  break;
467
  /* and a catch all for the things that aren't covered above */
468
  default :
469
  $error = sprintf( __( 'during the %s process' ), $error );
470
  endswitch;
471
 
472
  echo '<div class="wpclone_notice updated">';
473
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
474
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
475
  if( isset( $temp_dir ) ) {
476
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
477
  echo '</div>';
478
  global $wp_filesystem;
479
  $wp_filesystem->delete($temp_dir, true);
480
  } else {
481
  echo '</div>';
482
  }
483
  die;
484
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
485
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
486
  global $wp_filesystem;
487
  $wp_filesystem->delete($backup_dir, true);
488
  }
489
+ <?php
490
  return str_replace("\\", "/", $path);
491
  return rtrim(str_replace("//", "/", wpCloneSafePathMode($path)), '/') . '/';
492
  return str_replace(rtrim(WPCLONE_ROOT, "/\\"), site_url(), $path);
493
  return str_replace(site_url(), rtrim(WPCLONE_ROOT, "/\\"), $url);
494
  global $wpdb;
495
  $WPCLONE_DB_ICONV_IN = "UTF-8";
496
  $WPCLONE_DB_ICONV_OUT = "ISO-8859-1//TRANSLIT";
497
  $return = '';
498
  // Get all of the tables
499
  $tables = $wpdb->get_col('SHOW TABLES');
500
  // Cycle through each provided table
501
  foreach ($tables as $table) {
502
  // First part of the output � remove the table
503
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
504
  $numberOfFields = count($result[0]);
505
  $numberOfItems = count($result);
506
  // Second part of the output � create table
507
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
508
  $return .= "\n\n" . $row2[1] . ";\n\n";
509
  // Third part of the output � insert values into new table
510
  for ($currentRowNumber = 0; $currentRowNumber < $numberOfItems; $currentRowNumber++) {
511
  $row = $result[$currentRowNumber];
512
  $query = "INSERT INTO {$table} VALUES(";
513
  for ($j = 0; $j < $numberOfFields; $j++) {
514
  $row[$j] = iconv($WPCLONE_DB_ICONV_IN, $WPCLONE_DB_ICONV_OUT, $row[$j]);
515
  $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
516
  }
517
  $return .= substr($query, 0, -2) . ");\n";
518
  }
519
  $return .= "\n";
520
  }
521
  // Generate the filename for the sql file
522
  $File_open = fopen($destination . '/database.sql', 'w+');
523
  // Save the sql file
524
  fwrite($File_open, $return);
525
  //file close
526
  fclose($File_open);
527
  $wpdb->flush();
528
  * @link http://davidwalsh.name/backup-mysql-database-php
529
  */
530
  if ( false === $link ) {
531
  wpa_backup_error('db', mysql_error() );
532
  }
533
  if ( false === $result ) {
534
  wpa_backup_error('db', mysql_error() );
535
  }
536
 
537
  if ( false === $result ) {
538
  wpa_backup_error('db', mysql_error() );
539
  }
540
 
541
  global $wpdb;
542
  global $current_user;
543
  $wpdb->insert($wpdb->prefix . "wpclone", array(
544
  'backup_name' => $name,
545
  'data_time' => current_time('mysql', get_option('gmt_offset')),
546
  'creator' => $current_user->user_login,
547
  'backup_size' => $size)
548
  );
549
  $wpdb->flush();
550
  $folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
551
  $destinationPath = $folderToBeZipped . '/' . basename(WPCLONE_WP_CONTENT);
552
  $zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
553
  $exclude = wpa_excluded_dirs();
554
  $dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
555
 
556
  if( false === mkdir( $folderToBeZipped ) )
557
  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 ) );
558
 
559
  if( false === $dbonly )
560
  wpa_copy_dir( untrailingslashit( WPCLONE_WP_CONTENT ), $destinationPath, $exclude);
561
 
562
  wpa_save_prefix($folderToBeZipped);
563
  /* error handler is called from within the db backup functions */
564
  if ( $use_wpdb ) {
565
  wpa_db_backup_wpdb( $folderToBeZipped );
566
  } else {
567
  wpa_db_backup_direct( $folderToBeZipped );
568
  }
569
 
570
  /* error haldler is called from within the wpa_zip function */
571
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
572
  $zipSize = filesize($zipFileName);
573
  wpa_delete_dir( $folderToBeZipped );
574
  return array($backupName . '.zip', $zipSize);
575
  global $wpdb;
576
  $wp_backup = "{$wpdb->prefix}wpclone";
577
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
578
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
579
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
580
  return $deleteRow;
581
  $kilobyte = 1024;
582
  $megabyte = $kilobyte * 1024;
583
  $gigabyte = $megabyte * 1024;
584
  $terabyte = $gigabyte * 1024;
585
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
586
  return $bytes . ' B';
587
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
588
  return round($bytes / $kilobyte, $precision) . ' KB';
589
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
590
  return round($bytes / $megabyte, $precision) . ' MB';
591
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
592
  return round($bytes / $gigabyte, $precision) . ' GB';
593
  } elseif ($bytes >= $terabyte) {
594
  return round($bytes / $terabyte, $precision) . ' TB';
595
  } else {
596
  return $bytes . ' B';
597
  }
598
  global $wp_filesystem;
599
  $fileContent = $wp_filesystem->get_contents($databaseFile);
600
  $pos = strpos($fileContent, 'siteurl') + 8;
601
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
602
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
603
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
604
  return $backupSiteUrl;
605
  global $wp_filesystem;
606
  $dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
607
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
608
  if ( false === $dbFileContent ) {
609
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
610
  }
611
 
612
 
613
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
614
  /* and we cannot nuke the db if the connection failed now can we */
615
  if ( false === $conn ) {
616
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
617
  }
618
 
619
  mysql_select_db( DB_NAME, $conn);
620
 
621
  $query = mysql_query("SHOW TABLES", $conn);
622
  /* point of no return,if it fails after this you're royally boned ;) */
623
  while (($fetch = mysql_fetch_array($query))) {
624
  mysql_query("Drop table `{$fetch[0]}`");
625
  }
626
  flush();
627
 
628
  $res = explode(";\n", $dbFileContent);
629
  foreach ($res AS $query) {
630
  mysql_query($query, $conn);
631
  }
632
  mysql_close($conn);
633
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
634
  $currentSiteUrl = site_url();
635
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
636
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
637
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
638
 
639
  return $currentSiteUrl;
640
  * @param type $search URL of the previous site.
641
  * @param type $replace URL of the current site.
642
  * @return type total time it took for the operation.
643
  */
644
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
645
  require_once 'icit_srdb_replacer.php';
646
  }
647
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
648
  $all_tables = array( );
649
  @mysql_select_db( DB_NAME, $connection );
650
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
651
  if ( ! $all_tables_mysql ) {
652
  wpa_backup_error( 'dbrest', mysql_error(), true );
653
  } else {
654
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
655
  $all_tables[] = $table[ 0 ];
656
  }
657
  }
658
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
659
  return $report;
660
  wpa_cleanup( true );
661
  if (!is_string($url) || '' == $url) {
662
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
663
  }
664
 
665
  global $wp_filesystem;
666
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
667
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
668
  if ( is_wp_error($temp_dir_err) ) {
669
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
670
  }
671
  $pathParts = pathinfo($url);
672
  $zipFilename = wpa_fetch_file($url);
673
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
674
  if ($result) {
675
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
676
  if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
677
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
678
  }
679
 
680
  /* if we're here then the file extraction worked,but let's make doubly sure */
681
  if( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
682
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
683
  }
684
  /* check the table prefixes */
685
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
686
  $prefix = wpa_check_prefix($old_db_prefix);
687
  if ($prefix) {
688
  wpa_replace_prefix( $prefix );
689
  }
690
  $wp_filesystem->delete( $old_db_prefix );
691
  /* import db */
692
  $databaseFile = $unzippedFolderPath . '/database.sql';
693
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
694
  /* */
695
  $wp_filesystem->delete( $databaseFile );
696
  wpa_copy( $unzippedFolderPath . '/wp-content', WPCLONE_WP_CONTENT );
697
 
698
  $wp_filesystem->delete( $temp_dir, true );
699
  /* remove the zip file only if it was downloaded from an external location. */
700
  $wptmp = explode('.', $zipFilename);
701
  if ( in_array( 'tmp', $wptmp ) ) {
702
  $wp_filesystem->delete( $zipFilename );
703
  }
704
  echo "<h1>Restore Successful!</h1>";
705
  echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
706
  echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
707
  } else {
708
  echo "<h1>Restore unsuccessful!!!</h1>";
709
  echo "Please try again.";
710
  }
711
  global $wpdb;
712
  $prefix = $wpdb->prefix;
713
  $file = $path . '/prefix.txt';
714
  if ( is_dir($path) && is_writable($path) ) {
715
  file_put_contents($file, $prefix);
716
  }
717
  * Checks to see whether the destination site's table prefix matches that of the origin site.old prefix is returned in case of a mismatch.
718
  *
719
  * @param type $file path to the prefix.txt file.
720
  * @return type bool string
721
  */
722
  global $wpdb;
723
  $prefix = $wpdb->prefix;
724
  if (file_exists($file) && is_readable($file)) {
725
  $old_prefix = file_get_contents($file);
726
  if ( $prefix !== $old_prefix ) {
727
  return $old_prefix;
728
  }
729
  else {
730
  return false;
731
  }
732
  }
733
  return false;
734
  * @since 2.0.6
735
  *
736
  * @param type $zipfile path to the zip file that needs to be extracted.
737
  * @param type $path the place to where the file needs to be extracted.
738
  * @return as false in the event of failure.
739
  */
740
  if ( $zipmode ) {
741
  if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
742
  $previous_encoding = mb_internal_encoding();
743
  mb_internal_encoding('ISO-8859-1');
744
  }
745
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
746
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
747
  $z = new PclZip($zipfile);
748
  $files = $z->extract(PCLZIP_OPT_PATH, $path);
749
  if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
750
  if ( $files == 0 ) {
751
  wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
752
  }
753
  return true;
754
  }
755
  else {
756
  $z= unzip_file($zipfile, $path);
757
  if (is_wp_error($z)) {
758
  wpa_backup_error( 'unzip', $z->get_error_message(), true );
759
  }
760
  return true;
761
  }
762
  * @since 2.0.6
763
  *
764
  * @param type $name name of the zip file.
765
  * @param type $file_list an array of files that needs to be archived.
766
  */
767
  if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
768
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
769
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
770
  $z = new PclZip($zip_name);
771
  $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
772
  if ($v_list == 0) {
773
  wpa_backup_error( 'pclzip', $z->errorInfo(true) );
774
  }
775
  } else {
776
  $z = new ZipArchive();
777
  if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
778
  wpa_backup_error( 'zip', $z );
779
  }
780
  wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
781
  $z->close();
782
  }
783
  $new_folder = str_replace($base, '', $dir);
784
  $zip->addEmptyDir($new_folder);
785
  foreach( glob( $dir . '/*' ) as $file ){
786
  if( is_dir($file) ) {
787
  wpa_ziparc($zip, $file, $base);
788
  } else {
789
  $new_file = str_replace( $base, '', $file );
790
  $zip->addFile($file, $new_file);
791
  }
792
  }
793
  * just a simple function to increase PHP limits.
794
  * @since 2.0.6
795
  */
796
  $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 300; /*300 seconds = 5 minutes*/
797
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
798
  @ini_set('memory_limit', $mem);
799
  @ini_set('max_execution_time', $time);
800
  * @since 2.0.6
801
  */
802
  if (!empty($_REQUEST['del'])) {
803
  wpa_remove_backup();
804
  return true;
805
  }
806
  if (empty($_POST)) return false;
807
  check_admin_referer('wpclone-submit');
808
 
809
  wpa_bump_limits();
810
 
811
  if (isset($_POST['createBackup'])) {
812
  wpa_create_backup();
813
  return true;
814
  }
815
 
816
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
817
  $extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
818
  $type = '';
819
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
820
  return true;
821
  }
822
  if (!WP_Filesystem($creds)) {
823
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
824
  return true;
825
  }
826
 
827
  $zipmode = isset($_POST['zipmode']) ? true : false;
828
  $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
829
  processRestoringBackup($url, $zipmode);
830
  return true;
831
  * @since 2.0.6
832
  */
833
  global $wp_filesystem;
834
  if (is_readable($source)) {
835
  if (is_dir($source)) {
836
  if (!file_exists($target)) {
837
  $wp_filesystem->mkdir($target);
838
  }
839
  $d = dir($source);
840
  while (FALSE !== ($entry = $d->read())) {
841
  if ($entry == '.' || $entry == '..') {
842
  continue;
843
  }
844
  $Entry = "{$source}/{$entry}";
845
  if (is_dir($Entry)) {
846
  wpa_copy($Entry, $target . '/' . $entry);
847
  } else {
848
  $wp_filesystem->copy($Entry, $target . '/' . $entry, true, FS_CHMOD_FILE);
849
  }
850
  }
851
  $d->close();
852
  }
853
  else {
854
  $wp_filesystem->copy($source, $target, true);
855
  }
856
  }
857
  * @since 2.0.6
858
  */
859
  $wpconfig = wpa_wpconfig_path();
860
  global $wp_filesystem;
861
 
862
  if ( ! $wp_filesystem->is_writable($wpconfig) ) {
863
  if( false === $wp_filesystem->chmod( $wpconfig ) )
864
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
865
  }
866
 
867
  $fileContent = $wp_filesystem->get_contents($wpconfig);
868
  $pos = strpos($fileContent, '$table_prefix');
869
  $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
870
  $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
871
  $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
872
  * @since 2.0.6
873
  */
874
  if( true === is_multisite() )
875
  die( 'wpclone does not work on multisite installs.' );
876
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
877
  wpa_create_directory();
878
  }
879
  wpa_cleanup();
880
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
881
  $backupName = wpa_backup_name();
882
  $zipmode = isset($_POST['zipmode']) ? true : false;
883
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
884
  wpa_insert_data($zipFileName, $zipSize);
885
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
886
  $zipSize = bytesToSize($zipSize);
887
  echo <<<EOF
888
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
889
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
890
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
891
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
892
  * @since 2.0.6
893
  */
894
  check_admin_referer('wpclone-submit');
895
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
896
  echo <<<EOT
897
  <h1>Deleted Successful!</h1> <br />
898
  {$deleteRow->backup_name} <br />
899
  File deleted from backup folder and database...
900
  * @since 2.1.2
901
  * copypasta from wp-load.php
902
  * @return the path to wp-config.php
903
  */
904
  $z = pathinfo($path);
905
  global $wp_filesystem;
906
  if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
907
  return WPCLONE_DIR_BACKUP . $z['basename'];
908
  }
909
  else {
910
  $url = download_url($path, 750);
911
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
912
  return $url;
913
  }
914
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
915
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
916
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
917
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
918
  return $backup_name;
919
 
920
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
921
 
922
  if( !file_exists( $temp_dir ) ) {
923
  unset($temp_dir);
924
  }
925
  switch ( $error ) :
926
  /* during backup */
927
  case 'file' :
928
  $error = __( 'while copying files into the temp directory' );
929
  break;
930
  case 'db' :
931
  $error = __( 'during the database backup' );
932
  break;
933
  case 'zip' :
934
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
935
  break;
936
  case 'pclzip' :
937
  $error = __( 'while creating the zip file using the PclZip library' );
938
  break;
939
  /* during restore */
940
  case 'dirrest' :
941
  $error = __( 'while creating the temp directory' );
942
  break;
943
  case 'filerest' :
944
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
945
  break;
946
  case 'dbrest' :
947
  $error = __( 'while cloning the database' );
948
  break;
949
  case 'unzip' :
950
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
951
  break;
952
  case 'pclunzip' :
953
  $error = __( 'while extracting the zip file using the PclZip library' );
954
  break;
955
  case 'url' :
956
  $error = __( 'while downloading the zip file' );
957
  break;
958
  case 'wpconfig' :
959
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
960
  break;
961
  /* and a catch all for the things that aren't covered above */
962
  default :
963
  $error = sprintf( __( 'during the %s process' ), $error );
964
  endswitch;
965
 
966
  echo '<div class="wpclone_notice updated">';
967
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
968
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
969
  if( isset( $temp_dir ) ) {
970
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
971
  echo '</div>';
972
  if( $restore ) {
973
  global $wp_filesystem;
974
  $wp_filesystem->delete($temp_dir, true);
975
  } else {
976
  wpa_delete_dir( $temp_dir );
977
  }
978
  } else {
979
  echo '</div>';
980
  }
981
  die;
982
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
983
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
984
  if( $restore ) {
985
  global $wp_filesystem;
986
  $wp_filesystem->delete($backup_dir, true);
987
  } else {
988
  wpa_delete_dir( $backup_dir );
989
  }
990
  }
991
  * recursively copies a directory from one place to another. excludes 'uploads/wp-clone' by default.
992
  * @since 2.1.6
993
  * @param string $from
994
  * @param string $to
995
  * @param array $exclude an array of directory paths to exclude.
996
  */
997
  if( false === stripos( wpCloneSafePathMode( $from ), rtrim( wpCloneSafePathMode( WPCLONE_DIR_BACKUP ), "/\\" ) ) ) {
998
  if( !file_exists( $to ) )
999
  @mkdir ( $to );
1000
  $files = array_diff( scandir( $from ), array( '.', '..' ) );
1001
  foreach( $files as $file ) {
1002
  if( in_array( $from . '/' . $file, $exclude ) ) {
1003
  continue;
1004
  } else {
1005
  if( is_dir( $from . '/' . $file ) ) {
1006
  wpa_copy_dir( $from . '/' . $file, $to . '/' . $file, $exclude );
1007
  } else {
1008
  @copy( $from . '/' . $file, $to . '/' . $file );
1009
  }
1010
  }
1011
  }
1012
  unset( $files );
1013
  }
1014
  * recursively deletes all the files in the given directory.
1015
  * @since 2.1.6
1016
  * @param string $dir path to the directory that needs to be deleted.
1017
  */
1018
  if( !empty( $dir ) ) {
1019
  $dir = trailingslashit( $dir );
1020
  $files = array_diff( scandir( $dir ), array( '.', '..' ) );
1021
  foreach ( $files as $file ) {
1022
  if( is_dir( $dir . $file ) ) {
1023
  wpa_delete_dir( $dir . $file );
1024
  } else {
1025
  @unlink( $dir . $file );
1026
  }
1027
  }
1028
  @rmdir($dir);
1029
  }
1030
  * @since 2.1.6
1031
  */
1032
  $exclude = array();
1033
  if( isset( $_POST['exclude'] ) && '' != $_POST['exclude'] ) {
1034
  foreach( explode( "\n", $_POST['exclude'] ) as $ex ) {
1035
  $ex = trim( $ex );
1036
  if( '' !== $ex ) {
1037
  $ex = trim( $ex, "/\\" );
1038
  $exclude[] = trailingslashit( WPCLONE_WP_CONTENT ) . str_replace( '\\', '/', $ex ) ;
1039
  }
1040
  }
1041
  }
1042
  return $exclude;
lib/view.php CHANGED
@@ -57,17 +57,22 @@ $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id D
57
 
58
  <p>&nbsp;</p>
59
 
60
- <p>Please note that you will not see an alert box after clicking on the "Copy URL" link if you're using Firefox version 18 or 19.</p>
61
-
62
  <form id="backupForm" name="backupForm" action="#" method="post">
63
  <?php
64
  if ( isset($_GET['mode']) && 'advanced' == $_GET['mode'] ) { ?>
65
  <div class="info">
66
  <table>
67
- <tr align="left"><th><label for="zipmode">Alternate zip method</label></th><td colspan="2"><input type="checkbox" name="zipmode" value="alt" /></td></tr>
68
  <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>
69
  <tr align="left"><th><label for="maxmem">Maximum memory limit</label></th><td colspan="2"><input type="text" name="maxmem" /></td></tr>
70
  <tr align="left"><th><label for="maxexec">Script execution time</label></th><td><input type="text" name="maxexec" /></td></tr>
 
 
 
 
 
 
 
71
  </table>
72
  </div>
73
  <?php
@@ -127,6 +132,12 @@ $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id D
127
  <input id="submit" name="submit" class="btn-primary btn" type="submit" value="Create Backup"/>
128
  <?php wp_nonce_field('wpclone-submit')?>
129
  </form>
 
 
 
 
 
 
130
  </div>
131
  <div id="sidebar">
132
 
@@ -141,10 +152,10 @@ $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id D
141
  <ul>
142
  <h2>WP Academy News</h2>
143
  <h3>WPAcademy.com</h3>
144
- <?php wpa_fetch_feed ('http://members.wpacademy.com/feed', 3); ?>
145
  <h3>Twitter @WPAcademy</h3>
146
  <?php /* wpa_fetch_feed ('http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=wpacademy', 5); */ ?>
147
- <a class="twitter-timeline" data-tweet-limit="5" height="400" href="https://twitter.com/WPAcademy" data-widget-id="342116561412304898">Tweets by @WPAcademy</a>
148
  <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
149
 
150
  </ul>
@@ -181,28 +192,23 @@ $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id D
181
  echo '</div>';
182
  }
183
 
184
- if(!isset($_GET['mode'])){
185
- $link = admin_url( 'admin.php?page=wp-clone&mode=advanced' );
186
- echo "<p style='padding:5px;'><a href='{$link}' style='margin-top:10px'>Advanced Settings</a></p>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
-
189
- function wpa_fetch_feed ($feed, $limit) {
190
- include_once(ABSPATH . WPINC . '/feed.php');
191
- $rss = fetch_feed($feed);
192
- if (!is_wp_error( $rss ) ) :
193
- $maxitems = $rss->get_item_quantity($limit);
194
- $rss_items = $rss->get_items(0, $maxitems);
195
- endif;
196
- if ( isset($maxitems) && $maxitems == 0 ) echo '<li>No items.</li>';
197
- else
198
- // Loop through each feed item and display each item as a hyperlink.
199
- foreach ( $rss_items as $item ) : ?>
200
- <li>
201
- <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
202
- title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
203
- <?php echo esc_html( $item->get_title() ); ?></a>
204
- </li>
205
- <?php endforeach;
206
- }
207
 
208
  /** it all ends here folks. */
57
 
58
  <p>&nbsp;</p>
59
 
 
 
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 align="left"><th><label for="maxmem">Maximum memory limit</label></th><td colspan="2"><input type="text" name="maxmem" /></td></tr>
68
  <tr align="left"><th><label for="maxexec">Script execution time</label></th><td><input type="text" name="maxexec" /></td></tr>
69
+ <tr><td colspan="4"><h3>Exclude directories from backup, and backup database only</h3></td></tr>
70
+ <tr><td colspan="4"><p>Depending on your web host, WP Clone may not work for large sites.
71
+ You may, however, exclude all of your 'wp-content' directory from the backup (use "Backup database only" option below), or exclude specific directories.
72
+ You would then copy these files over to the new site via FTP before restoring the backup with WP Clone.</p></td></tr>
73
+ <tr align="left"><th><label for="dbonly">Backup database only</label></th><td colspan="2"><input type="checkbox" name="dbonly" value="true" /></td></tr>
74
+ <tr align="left"><th><label for="exclude">Excluded directories</label></th><td><textarea cols="70" rows="5" name="exclude" ></textarea></td></tr>
75
+ <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.</p></td></tr>
76
  </table>
77
  </div>
78
  <?php
132
  <input id="submit" name="submit" class="btn-primary btn" type="submit" value="Create Backup"/>
133
  <?php wp_nonce_field('wpclone-submit')?>
134
  </form>
135
+ <?php
136
+ if(!isset($_GET['mode'])){
137
+ $link = admin_url( 'admin.php?page=wp-clone&mode=advanced' );
138
+ echo "<p style='padding:5px;'><a href='{$link}' style='margin-top:10px'>Advanced Settings</a></p>";
139
+ }
140
+ ?>
141
  </div>
142
  <div id="sidebar">
143
 
152
  <ul>
153
  <h2>WP Academy News</h2>
154
  <h3>WPAcademy.com</h3>
155
+ <?php wpa_fetch_feed ('http://members.wpacademy.com/category/news/feed', 3); ?>
156
  <h3>Twitter @WPAcademy</h3>
157
  <?php /* wpa_fetch_feed ('http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=wpacademy', 5); */ ?>
158
+ <a class="twitter-timeline" height="400" href="https://twitter.com/WPAcademy" data-widget-id="342116561412304898">Tweets by @WPAcademy</a>
159
  <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
160
 
161
  </ul>
192
  echo '</div>';
193
  }
194
 
195
+ function wpa_fetch_feed ($feed, $limit) {
196
+ include_once(ABSPATH . WPINC . '/feed.php');
197
+ $rss = fetch_feed($feed);
198
+ if (!is_wp_error( $rss ) ) :
199
+ $maxitems = $rss->get_item_quantity($limit);
200
+ $rss_items = $rss->get_items(0, $maxitems);
201
+ endif;
202
+ if ( isset($maxitems) && $maxitems == 0 ) echo '<li>No items.</li>';
203
+ else
204
+ // Loop through each feed item and display each item as a hyperlink.
205
+ foreach ( $rss_items as $item ) : ?>
206
+ <li>
207
+ <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
208
+ title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
209
+ <?php echo esc_html( $item->get_title() ); ?></a>
210
+ </li>
211
+ <?php endforeach;
212
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
  /** it all ends here folks. */
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: 3.5.1
9
- Stable tag: 2.1.5
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -26,6 +26,13 @@ WP Clone is a superior solution to even commercial WordPress cloning plugins for
26
  = Help Video =
27
  [youtube http://www.youtube.com/watch?v=xN5Ffhyn4Ao]
28
 
 
 
 
 
 
 
 
29
  = Please donate to support plugin development & ongoing support =
30
  WP Clone is provided free of charge to the community and supported through the plugin forums on WordPress.org. Please help defray our development expenses and help with support costs through the [Donations Page](http://wpacademy.com/software "Donations page")
31
  Donation page.
@@ -49,6 +56,12 @@ released under the WTFPL http://sam.zoy.org/wtfpl/. Partial script with full cha
49
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
50
 
51
  == Changelog ==
 
 
 
 
 
 
52
  = 2.1.5 - 2013-06-05 =
53
  * Changed: UI Twitter feed from rss to the official twitter widget.
54
  * Changed: UI Sidebar link attributes.
5
  Author URI: http://wpacademy.com
6
  Plugin URI: http://wpacademy.com/software
7
  Requires at least: 3.0
8
+ Tested up to: 3.8
9
+ Stable tag: 2.1.6
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
26
  = Help Video =
27
  [youtube http://www.youtube.com/watch?v=xN5Ffhyn4Ao]
28
 
29
+ = New features (July 2013): Exclude directories and Database-only backup =
30
+ We have implemented exclude-directories on the backup, and also database-only backup! By transferring the contents of 'wp-content' directory with FTP from your old site to new site, you should now be able to migrate sites of any size.
31
+
32
+ = Support and Disclaimer =
33
+ 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.
34
+ 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/ which works pretty good, but is 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
35
+
36
  = Please donate to support plugin development & ongoing support =
37
  WP Clone is provided free of charge to the community and supported through the plugin forums on WordPress.org. Please help defray our development expenses and help with support costs through the [Donations Page](http://wpacademy.com/software "Donations page")
38
  Donation page.
56
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
57
 
58
  == Changelog ==
59
+ = 2.1.6 - 2013-07-07 =
60
+ * Added: An option to exclude specific directories during backup.
61
+ * Added: An option to only backup the database.
62
+ * Added: An admin notice for multisite users.
63
+ * Changed: File operations during backup are now handled directly instead of using the WP filesystem abstraction class.
64
+
65
  = 2.1.5 - 2013-06-05 =
66
  * Changed: UI Twitter feed from rss to the official twitter widget.
67
  * Changed: UI Sidebar link attributes.
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.1.5
8
  Author URI: http://wpacademy.com/
9
  */
10
 
@@ -18,7 +18,7 @@ define('WPCLONE_BACKUP_FOLDER', 'wp-clone');
18
  define('WPCLONE_DIR_UPLOADS', str_replace('\\', '/', $upload_dir['basedir']));
19
  define('WPCLONE_DIR_PLUGIN', str_replace('\\', '/', plugin_dir_path(__FILE__)));
20
  define('WPCLONE_URL_PLUGIN', plugin_dir_url(__FILE__));
21
- define('WPCLONE_DIR_BACKUP', WPCLONE_DIR_UPLOADS . '/' .WPCLONE_BACKUP_FOLDER . '/');
22
  define('WPCLONE_INSTALLER_PATH', WPCLONE_DIR_PLUGIN);
23
  define('WPCLONE_WP_CONTENT' , str_replace('\\', '/', WP_CONTENT_DIR));
24
 
@@ -108,3 +108,12 @@ function wpa_install_database() {
108
  dbDelta($sql);
109
  }
110
  }
 
 
 
 
 
 
 
 
 
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.1.6
8
  Author URI: http://wpacademy.com/
9
  */
10
 
18
  define('WPCLONE_DIR_UPLOADS', str_replace('\\', '/', $upload_dir['basedir']));
19
  define('WPCLONE_DIR_PLUGIN', str_replace('\\', '/', plugin_dir_path(__FILE__)));
20
  define('WPCLONE_URL_PLUGIN', plugin_dir_url(__FILE__));
21
+ define('WPCLONE_DIR_BACKUP', WPCLONE_DIR_UPLOADS . '/' . WPCLONE_BACKUP_FOLDER . '/');
22
  define('WPCLONE_INSTALLER_PATH', WPCLONE_DIR_PLUGIN);
23
  define('WPCLONE_WP_CONTENT' , str_replace('\\', '/', WP_CONTENT_DIR));
24
 
108
  dbDelta($sql);
109
  }
110
  }
111
+
112
+ function wpa_wpc_msnotice() {
113
+ echo '<div class="error">';
114
+ echo '<h4>WP Clone Notice.</h4>';
115
+ echo '<p>WP Clone is not compatible with multisite installations.</p></div>';
116
+ }
117
+
118
+ if ( is_multisite() )
119
+ add_action( 'admin_notices', 'wpa_wpc_msnotice');