WP Clone by WP Academy - Version 2.1.9

Version Description

  • 2015-11-10 =
  • Disabled heartbeat on wpclone's admin page.
  • DB_CHARSET in wp-config.php is used during direct database transactions.
Download this release

Release Info

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

Code changes from version 2.1.8 to 2.1.9

Files changed (5) hide show
  1. lib/functions.php +783 -1
  2. lib/icit_srdb_replacer.php +154 -154
  3. lib/view.php +214 -214
  4. readme.txt +5 -2
  5. wpclone.php +2 -1
lib/functions.php CHANGED
@@ -1 +1,783 @@
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
  $exclude = wpa_excluded_dirs();
66
  $dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
67
 
68
  if( false === mkdir( $folderToBeZipped ) )
69
  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 ) );
70
 
71
  if( false === $dbonly )
72
  wpa_copy_dir( untrailingslashit( WPCLONE_WP_CONTENT ), $destinationPath, $exclude);
73
 
74
  wpa_save_prefix($folderToBeZipped);
75
  /* error handler is called from within the db backup functions */
76
  if ( $use_wpdb ) {
77
  wpa_db_backup_wpdb( $folderToBeZipped );
78
  } else {
79
  wpa_db_backup_direct( $folderToBeZipped );
80
  }
81
 
82
  /* error haldler is called from within the wpa_zip function */
83
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
84
  $zipSize = filesize($zipFileName);
85
  wpa_delete_dir( $folderToBeZipped );
86
  return array($backupName . '.zip', $zipSize);
87
  global $wpdb;
88
  $wp_backup = "{$wpdb->prefix}wpclone";
89
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
90
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
91
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
92
  return $deleteRow;
93
  $kilobyte = 1024;
94
  $megabyte = $kilobyte * 1024;
95
  $gigabyte = $megabyte * 1024;
96
  $terabyte = $gigabyte * 1024;
97
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
98
  return $bytes . ' B';
99
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
100
  return round($bytes / $kilobyte, $precision) . ' KB';
101
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
102
  return round($bytes / $megabyte, $precision) . ' MB';
103
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
104
  return round($bytes / $gigabyte, $precision) . ' GB';
105
  } elseif ($bytes >= $terabyte) {
106
  return round($bytes / $terabyte, $precision) . ' TB';
107
  } else {
108
  return $bytes . ' B';
109
  }
110
  global $wp_filesystem;
111
  $fileContent = $wp_filesystem->get_contents($databaseFile);
112
  $pos = strpos($fileContent, 'siteurl') + 8;
113
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
114
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
115
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
116
  return $backupSiteUrl;
117
  global $wp_filesystem;
118
  $dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
119
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
120
  if ( false === $dbFileContent ) {
121
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
122
  }
123
 
124
 
125
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
126
  /* and we cannot nuke the db if the connection failed now can we */
127
  if ( false === $conn ) {
128
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
129
  }
130
 
131
  mysql_select_db( DB_NAME, $conn);
132
 
133
  $query = mysql_query("SHOW TABLES", $conn);
134
  /* point of no return,if it fails after this you're royally boned ;) */
135
  while (($fetch = mysql_fetch_array($query))) {
136
  mysql_query("Drop table `{$fetch[0]}`");
137
  }
138
  flush();
139
 
140
  $res = explode(";\n", $dbFileContent);
141
  foreach ($res AS $query) {
142
  mysql_query($query, $conn);
143
  }
144
  mysql_close($conn);
145
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
146
  $currentSiteUrl = site_url();
147
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
148
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
149
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
150
 
151
  return $currentSiteUrl;
152
  * @param type $search URL of the previous site.
153
  * @param type $replace URL of the current site.
154
  * @return type total time it took for the operation.
155
  */
156
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
157
  require_once 'icit_srdb_replacer.php';
158
  }
159
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
160
  $all_tables = array( );
161
  @mysql_select_db( DB_NAME, $connection );
162
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
163
  if ( ! $all_tables_mysql ) {
164
  wpa_backup_error( 'dbrest', mysql_error(), true );
165
  } else {
166
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
167
  $all_tables[] = $table[ 0 ];
168
  }
169
  }
170
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
171
  return $report;
172
  wpa_cleanup( true );
173
  if (!is_string($url) || '' == $url) {
174
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
175
  }
176
 
177
  global $wp_filesystem;
178
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
179
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
180
  if ( is_wp_error($temp_dir_err) ) {
181
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
182
  }
183
  $pathParts = pathinfo($url);
184
  $zipFilename = wpa_fetch_file($url);
185
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
186
  if ($result) {
187
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
188
  if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
189
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
190
  }
191
 
192
  /* if we're here then the file extraction worked,but let's make doubly sure */
193
  if( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
194
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
195
  }
196
  /* check the table prefixes */
197
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
198
  $prefix = wpa_check_prefix($old_db_prefix);
199
  if ($prefix) {
200
  wpa_replace_prefix( $prefix );
201
  }
202
  $wp_filesystem->delete( $old_db_prefix );
203
  /* import db */
204
  $databaseFile = $unzippedFolderPath . '/database.sql';
205
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
206
  /* */
207
  $wp_filesystem->delete( $databaseFile );
208
  wpa_copy( $unzippedFolderPath . '/wp-content', WPCLONE_WP_CONTENT );
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'] : 300; /*300 seconds = 5 minutes*/
309
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
310
  @ini_set('memory_limit', $mem);
311
  @ini_set('max_execution_time', $time);
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
 
321
  wpa_bump_limits();
322
 
323
  if (isset($_POST['createBackup'])) {
324
  wpa_create_backup();
325
  return true;
326
  }
327
 
328
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
329
  $extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
330
  $type = '';
331
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
332
  return true;
333
  }
334
  if (!WP_Filesystem($creds)) {
335
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
336
  return true;
337
  }
338
 
339
  $zipmode = isset($_POST['zipmode']) ? true : false;
340
  $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
341
  processRestoringBackup($url, $zipmode);
342
  return true;
343
  * @since 2.0.6
344
  */
345
  global $wp_filesystem;
346
  if (is_readable($source)) {
347
  if (is_dir($source)) {
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
  else {
366
  $wp_filesystem->copy($source, $target, true);
367
  }
368
  }
369
  * @since 2.0.6
370
  */
371
  $wpconfig = wpa_wpconfig_path();
372
  global $wp_filesystem;
373
 
374
  if ( ! $wp_filesystem->is_writable($wpconfig) ) {
375
  if( false === $wp_filesystem->chmod( $wpconfig ) )
376
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
377
  }
378
 
379
  $fileContent = $wp_filesystem->get_contents($wpconfig);
380
  $pos = strpos($fileContent, '$table_prefix');
381
  $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
382
  $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
383
  $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
384
  * @since 2.0.6
385
  */
386
  if( true === is_multisite() )
387
  die( 'wpclone does not work on multisite installs.' );
388
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
389
  wpa_create_directory();
390
  }
391
  wpa_cleanup();
392
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
393
  $backupName = wpa_backup_name();
394
  $zipmode = isset($_POST['zipmode']) ? true : false;
395
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
396
  wpa_insert_data($zipFileName, $zipSize);
397
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
398
  $zipSize = bytesToSize($zipSize);
399
  echo <<<EOF
400
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
401
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
402
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
403
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
404
  * @since 2.0.6
405
  */
406
  check_admin_referer('wpclone-submit');
407
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
408
  echo <<<EOT
409
  <h1>Deleted Successful!</h1> <br />
410
  {$deleteRow->backup_name} <br />
411
  File deleted from backup folder and database...
412
  * @since 2.1.2
413
  * copypasta from wp-load.php
414
  * @return the path to wp-config.php
415
  */
416
  $z = pathinfo($path);
417
  global $wp_filesystem;
418
  if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
419
  return WPCLONE_DIR_BACKUP . $z['basename'];
420
  }
421
  else {
422
  $url = download_url($path, 750);
423
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
424
  return $url;
425
  }
426
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
427
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
428
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
429
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
430
  return $backup_name;
431
 
432
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
433
 
434
  if( !file_exists( $temp_dir ) ) {
435
  unset($temp_dir);
436
  }
437
  switch ( $error ) :
438
  /* during backup */
439
  case 'file' :
440
  $error = __( 'while copying files into the temp directory' );
441
  break;
442
  case 'db' :
443
  $error = __( 'during the database backup' );
444
  break;
445
  case 'zip' :
446
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
447
  break;
448
  case 'pclzip' :
449
  $error = __( 'while creating the zip file using the PclZip library' );
450
  break;
451
  /* during restore */
452
  case 'dirrest' :
453
  $error = __( 'while creating the temp directory' );
454
  break;
455
  case 'filerest' :
456
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
457
  break;
458
  case 'dbrest' :
459
  $error = __( 'while cloning the database' );
460
  break;
461
  case 'unzip' :
462
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
463
  break;
464
  case 'pclunzip' :
465
  $error = __( 'while extracting the zip file using the PclZip library' );
466
  break;
467
  case 'url' :
468
  $error = __( 'while downloading the zip file' );
469
  break;
470
  case 'wpconfig' :
471
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
472
  break;
473
  /* and a catch all for the things that aren't covered above */
474
  default :
475
  $error = sprintf( __( 'during the %s process' ), $error );
476
  endswitch;
477
 
478
  echo '<div class="wpclone_notice updated">';
479
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
480
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
481
  if( isset( $temp_dir ) ) {
482
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
483
  echo '</div>';
484
  if( $restore ) {
485
  global $wp_filesystem;
486
  $wp_filesystem->delete($temp_dir, true);
487
  } else {
488
  wpa_delete_dir( $temp_dir );
489
  }
490
  } else {
491
  echo '</div>';
492
  }
493
  die;
494
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
495
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
496
  if( $restore ) {
497
  global $wp_filesystem;
498
  $wp_filesystem->delete($backup_dir, true);
499
  } else {
500
  wpa_delete_dir( $backup_dir );
501
  }
502
  }
503
  * recursively copies a directory from one place to another. excludes 'uploads/wp-clone' by default.
504
  * @since 2.1.6
505
  * @param string $from
506
  * @param string $to
507
  * @param array $exclude an array of directory paths to exclude.
508
  */
509
  if( false === stripos( wpCloneSafePathMode( $from ), rtrim( wpCloneSafePathMode( WPCLONE_DIR_BACKUP ), "/\\" ) ) ) {
510
  if( !file_exists( $to ) )
511
  @mkdir ( $to );
512
  $files = array_diff( scandir( $from ), array( '.', '..' ) );
513
  foreach( $files as $file ) {
514
  if( in_array( $from . '/' . $file, $exclude ) ) {
515
  continue;
516
  } else {
517
  if( is_dir( $from . '/' . $file ) ) {
518
  wpa_copy_dir( $from . '/' . $file, $to . '/' . $file, $exclude );
519
  } else {
520
  @copy( $from . '/' . $file, $to . '/' . $file );
521
  }
522
  }
523
  }
524
  unset( $files );
525
  }
526
  * recursively deletes all the files in the given directory.
527
  * @since 2.1.6
528
  * @param string $dir path to the directory that needs to be deleted.
529
  */
530
  if( !empty( $dir ) ) {
531
  $dir = trailingslashit( $dir );
532
  $files = array_diff( scandir( $dir ), array( '.', '..' ) );
533
  foreach ( $files as $file ) {
534
  if( is_dir( $dir . $file ) ) {
535
  wpa_delete_dir( $dir . $file );
536
  } else {
537
  @unlink( $dir . $file );
538
  }
539
  }
540
  @rmdir($dir);
541
  }
542
  * @since 2.1.6
543
  */
544
  $exclude = array();
545
  if( isset( $_POST['exclude'] ) && '' != $_POST['exclude'] ) {
546
  foreach( explode( "\n", $_POST['exclude'] ) as $ex ) {
547
  $ex = trim( $ex );
548
  if( '' !== $ex ) {
549
  $ex = trim( $ex, "/\\" );
550
  $exclude[] = trailingslashit( WPCLONE_WP_CONTENT ) . str_replace( '\\', '/', $ex ) ;
551
  }
552
  }
553
  }
554
  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
  $exclude = wpa_excluded_dirs();
65
  $dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
66
 
67
  if( false === mkdir( $folderToBeZipped ) )
68
  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 ) );
69
 
70
  if( false === $dbonly )
71
  wpa_copy_dir( untrailingslashit( WPCLONE_WP_CONTENT ), $destinationPath, $exclude);
72
 
73
  wpa_save_prefix($folderToBeZipped);
74
  /* error handler is called from within the db backup functions */
75
  if ( $use_wpdb ) {
76
  wpa_db_backup_wpdb( $folderToBeZipped );
77
  } else {
78
  wpa_db_backup_direct( $folderToBeZipped );
79
  }
80
 
81
  /* error haldler is called from within the wpa_zip function */
82
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
83
  $zipSize = filesize($zipFileName);
84
  wpa_delete_dir( $folderToBeZipped );
85
  return array($backupName . '.zip', $zipSize);
86
  global $wpdb;
87
  $wp_backup = "{$wpdb->prefix}wpclone";
88
  $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
89
  $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
90
  if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
91
  return $deleteRow;
92
  $kilobyte = 1024;
93
  $megabyte = $kilobyte * 1024;
94
  $gigabyte = $megabyte * 1024;
95
  $terabyte = $gigabyte * 1024;
96
  if (($bytes >= 0) && ($bytes < $kilobyte)) {
97
  return $bytes . ' B';
98
  } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
99
  return round($bytes / $kilobyte, $precision) . ' KB';
100
  } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
101
  return round($bytes / $megabyte, $precision) . ' MB';
102
  } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
103
  return round($bytes / $gigabyte, $precision) . ' GB';
104
  } elseif ($bytes >= $terabyte) {
105
  return round($bytes / $terabyte, $precision) . ' TB';
106
  } else {
107
  return $bytes . ' B';
108
  }
109
  global $wp_filesystem;
110
  $fileContent = $wp_filesystem->get_contents($databaseFile);
111
  $pos = strpos($fileContent, 'siteurl') + 8;
112
  $urlStartPos = strpos($fileContent, '"', $pos) + 1;
113
  $urlEndPos = strpos($fileContent, '"', $urlStartPos);
114
  $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
115
  return $backupSiteUrl;
116
  global $wp_filesystem;
117
  $dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
118
  /* we don't want to nuke the curret database if if something went wrong with the above operation */
119
  if ( false === $dbFileContent ) {
120
  wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
121
  }
122
 
123
 
124
  $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
125
  /* and we cannot nuke the db if the connection failed now can we */
126
  if ( false === $conn ) {
127
  wpa_backup_error('dbrest', __( 'database connection failed' ), true );
128
  }
129
 
130
  mysql_select_db( DB_NAME, $conn);
131
 
132
  $query = mysql_query("SHOW TABLES", $conn);
133
  /* point of no return,if it fails after this you're royally boned ;) */
134
  while (($fetch = mysql_fetch_array($query))) {
135
  mysql_query("Drop table `{$fetch[0]}`");
136
  }
137
  flush();
138
 
139
  $res = explode(";\n", $dbFileContent);
140
  foreach ($res AS $query) {
141
  mysql_query($query, $conn);
142
  }
143
  mysql_close($conn);
144
  $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
145
  $currentSiteUrl = site_url();
146
  $backupSiteUrl = untrailingslashit($backupSiteUrl);
147
  $currentSiteUrl = untrailingslashit($currentSiteUrl);
148
  wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
149
 
150
  return $currentSiteUrl;
151
  * @param type $search URL of the previous site.
152
  * @param type $replace URL of the current site.
153
  * @return type total time it took for the operation.
154
  */
155
  if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
156
  require_once 'icit_srdb_replacer.php';
157
  }
158
  $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
159
  $all_tables = array( );
160
  @mysql_select_db( DB_NAME, $connection );
161
  $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
162
  if ( ! $all_tables_mysql ) {
163
  wpa_backup_error( 'dbrest', mysql_error(), true );
164
  } else {
165
  while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
166
  $all_tables[] = $table[ 0 ];
167
  }
168
  }
169
  $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
170
  return $report;
171
  wpa_cleanup( true );
172
  if (!is_string($url) || '' == $url) {
173
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
174
  }
175
 
176
  global $wp_filesystem;
177
  $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
178
  $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
179
  if ( is_wp_error($temp_dir_err) ) {
180
  wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
181
  }
182
  $pathParts = pathinfo($url);
183
  $zipFilename = wpa_fetch_file($url);
184
  $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
185
  if ($result) {
186
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
187
  if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
188
  $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
189
  }
190
 
191
  /* if we're here then the file extraction worked,but let's make doubly sure */
192
  if( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
193
  wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
194
  }
195
  /* check the table prefixes */
196
  $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
197
  $prefix = wpa_check_prefix($old_db_prefix);
198
  if ($prefix) {
199
  wpa_replace_prefix( $prefix );
200
  }
201
  $wp_filesystem->delete( $old_db_prefix );
202
  /* import db */
203
  $databaseFile = $unzippedFolderPath . '/database.sql';
204
  $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
205
  /* */
206
  $wp_filesystem->delete( $databaseFile );
207
  wpa_copy( $unzippedFolderPath . '/wp-content', WPCLONE_WP_CONTENT );
208
 
209
  $wp_filesystem->delete( $temp_dir, true );
210
  /* remove the zip file only if it was downloaded from an external location. */
211
  $wptmp = explode('.', $zipFilename);
212
  if ( in_array( 'tmp', $wptmp ) ) {
213
  $wp_filesystem->delete( $zipFilename );
214
  }
215
  echo "<h1>Restore Successful!</h1>";
216
  echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
217
  echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
218
  } else {
219
  echo "<h1>Restore unsuccessful!!!</h1>";
220
  echo "Please try again.";
221
  }
222
  global $wpdb;
223
  $prefix = $wpdb->prefix;
224
  $file = $path . '/prefix.txt';
225
  if ( is_dir($path) && is_writable($path) ) {
226
  file_put_contents($file, $prefix);
227
  }
228
  * 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.
229
  *
230
  * @param type $file path to the prefix.txt file.
231
  * @return type bool string
232
  */
233
  global $wpdb;
234
  $prefix = $wpdb->prefix;
235
  if (file_exists($file) && is_readable($file)) {
236
  $old_prefix = file_get_contents($file);
237
  if ( $prefix !== $old_prefix ) {
238
  return $old_prefix;
239
  }
240
  else {
241
  return false;
242
  }
243
  }
244
  return false;
245
  * @since 2.0.6
246
  *
247
  * @param type $zipfile path to the zip file that needs to be extracted.
248
  * @param type $path the place to where the file needs to be extracted.
249
  * @return as false in the event of failure.
250
  */
251
  if ( $zipmode ) {
252
  if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
253
  $previous_encoding = mb_internal_encoding();
254
  mb_internal_encoding('ISO-8859-1');
255
  }
256
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
257
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
258
  $z = new PclZip($zipfile);
259
  $files = $z->extract(PCLZIP_OPT_PATH, $path);
260
  if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
261
  if ( $files == 0 ) {
262
  wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
263
  }
264
  return true;
265
  }
266
  else {
267
  $z= unzip_file($zipfile, $path);
268
  if (is_wp_error($z)) {
269
  wpa_backup_error( 'unzip', $z->get_error_message(), true );
270
  }
271
  return true;
272
  }
273
  * @since 2.0.6
274
  *
275
  * @param type $name name of the zip file.
276
  * @param type $file_list an array of files that needs to be archived.
277
  */
278
  if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
279
  define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
280
  require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
281
  $z = new PclZip($zip_name);
282
  $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
283
  if ($v_list == 0) {
284
  wpa_backup_error( 'pclzip', $z->errorInfo(true) );
285
  }
286
  } else {
287
  $z = new ZipArchive();
288
  if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
289
  wpa_backup_error( 'zip', $z );
290
  }
291
  wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
292
  $z->close();
293
  }
294
  $new_folder = str_replace($base, '', $dir);
295
  $zip->addEmptyDir($new_folder);
296
  foreach( glob( $dir . '/*' ) as $file ){
297
  if( is_dir($file) ) {
298
  wpa_ziparc($zip, $file, $base);
299
  } else {
300
  $new_file = str_replace( $base, '', $file );
301
  $zip->addFile($file, $new_file);
302
  }
303
  }
304
  * just a simple function to increase PHP limits.
305
  * @since 2.0.6
306
  */
307
  $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 300; /*300 seconds = 5 minutes*/
308
  $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
309
  @ini_set('memory_limit', $mem);
310
  @ini_set('max_execution_time', $time);
311
  * @since 2.0.6
312
  */
313
  if (!empty($_REQUEST['del'])) {
314
  wpa_remove_backup();
315
  return true;
316
  }
317
  if (empty($_POST)) return false;
318
  check_admin_referer('wpclone-submit');
319
 
320
  wpa_bump_limits();
321
 
322
  if (isset($_POST['createBackup'])) {
323
  wpa_create_backup();
324
  return true;
325
  }
326
 
327
  $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
328
  $extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
329
  $type = '';
330
  if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
331
  return true;
332
  }
333
  if (!WP_Filesystem($creds)) {
334
  request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
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 (!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
  else {
365
  $wp_filesystem->copy($source, $target, true);
366
  }
367
  }
368
  * @since 2.0.6
369
  */
370
  $wpconfig = wpa_wpconfig_path();
371
  global $wp_filesystem;
372
 
373
  if ( ! $wp_filesystem->is_writable($wpconfig) ) {
374
  if( false === $wp_filesystem->chmod( $wpconfig ) )
375
  wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
376
  }
377
 
378
  $fileContent = $wp_filesystem->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( true === is_multisite() )
386
  die( 'wpclone does not work on multisite installs.' );
387
  if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
388
  wpa_create_directory();
389
  }
390
  wpa_cleanup();
391
  $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
392
  $backupName = wpa_backup_name();
393
  $zipmode = isset($_POST['zipmode']) ? true : false;
394
  list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
395
  wpa_insert_data($zipFileName, $zipSize);
396
  $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
397
  $zipSize = bytesToSize($zipSize);
398
  echo <<<EOF
399
  <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
400
  <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
401
  <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
402
  (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
403
  * @since 2.0.6
404
  */
405
  check_admin_referer('wpclone-submit');
406
  $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
407
  echo <<<EOT
408
  <h1>Deleted Successful!</h1> <br />
409
  {$deleteRow->backup_name} <br />
410
  File deleted from backup folder and database...
411
  * @since 2.1.2
412
  * copypasta from wp-load.php
413
  * @return the path to wp-config.php
414
  */
415
  $z = pathinfo($path);
416
  global $wp_filesystem;
417
  if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
418
  return WPCLONE_DIR_BACKUP . $z['basename'];
419
  }
420
  else {
421
  $url = download_url($path, 750);
422
  if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
423
  return $url;
424
  }
425
  $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
426
  $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
427
  $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
428
  $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
429
  return $backup_name;
430
 
431
  $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
432
 
433
  if( !file_exists( $temp_dir ) ) {
434
  unset($temp_dir);
435
  }
436
  switch ( $error ) :
437
  /* during backup */
438
  case 'file' :
439
  $error = __( 'while copying files into the temp directory' );
440
  break;
441
  case 'db' :
442
  $error = __( 'during the database backup' );
443
  break;
444
  case 'zip' :
445
  $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
446
  break;
447
  case 'pclzip' :
448
  $error = __( 'while creating the zip file using the PclZip library' );
449
  break;
450
  /* during restore */
451
  case 'dirrest' :
452
  $error = __( 'while creating the temp directory' );
453
  break;
454
  case 'filerest' :
455
  $error = __( 'while copying files from the temp directory into the wp-content directory' );
456
  break;
457
  case 'dbrest' :
458
  $error = __( 'while cloning the database' );
459
  break;
460
  case 'unzip' :
461
  $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
462
  break;
463
  case 'pclunzip' :
464
  $error = __( 'while extracting the zip file using the PclZip library' );
465
  break;
466
  case 'url' :
467
  $error = __( 'while downloading the zip file' );
468
  break;
469
  case 'wpconfig' :
470
  $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
471
  break;
472
  /* and a catch all for the things that aren't covered above */
473
  default :
474
  $error = sprintf( __( 'during the %s process' ), $error );
475
  endswitch;
476
 
477
  echo '<div class="wpclone_notice updated">';
478
  printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
479
  echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
480
  if( isset( $temp_dir ) ) {
481
  printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
482
  echo '</div>';
483
  if( $restore ) {
484
  global $wp_filesystem;
485
  $wp_filesystem->delete($temp_dir, true);
486
  } else {
487
  wpa_delete_dir( $temp_dir );
488
  }
489
  } else {
490
  echo '</div>';
491
  }
492
  die;
493
  $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
494
  if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
495
  if( $restore ) {
496
  global $wp_filesystem;
497
  $wp_filesystem->delete($backup_dir, true);
498
  } else {
499
  wpa_delete_dir( $backup_dir );
500
  }
501
  }
502
  * recursively copies a directory from one place to another. excludes 'uploads/wp-clone' by default.
503
  * @since 2.1.6
504
  * @param string $from
505
  * @param string $to
506
  * @param array $exclude an array of directory paths to exclude.
507
  */
508
  if( false === stripos( wpCloneSafePathMode( $from ), rtrim( wpCloneSafePathMode( WPCLONE_DIR_BACKUP ), "/\\" ) ) ) {
509
  if( !file_exists( $to ) )
510
  @mkdir ( $to );
511
  $files = array_diff( scandir( $from ), array( '.', '..' ) );
512
  foreach( $files as $file ) {
513
  if( in_array( $from . '/' . $file, $exclude ) ) {
514
  continue;
515
  } else {
516
  if( is_dir( $from . '/' . $file ) ) {
517
  wpa_copy_dir( $from . '/' . $file, $to . '/' . $file, $exclude );
518
  } else {
519
  @copy( $from . '/' . $file, $to . '/' . $file );
520
  }
521
  }
522
  }
523
  unset( $files );
524
  }
525
  * recursively deletes all the files in the given directory.
526
  * @since 2.1.6
527
  * @param string $dir path to the directory that needs to be deleted.
528
  */
529
  if( !empty( $dir ) ) {
530
  $dir = trailingslashit( $dir );
531
  $files = array_diff( scandir( $dir ), array( '.', '..' ) );
532
  foreach ( $files as $file ) {
533
  if( is_dir( $dir . $file ) ) {
534
  wpa_delete_dir( $dir . $file );
535
  } else {
536
  @unlink( $dir . $file );
537
  }
538
  }
539
  @rmdir($dir);
540
  }
541
  * @since 2.1.6
542
  */
543
  $exclude = array();
544
  if( isset( $_POST['exclude'] ) && '' != $_POST['exclude'] ) {
545
  foreach( explode( "\n", $_POST['exclude'] ) as $ex ) {
546
  $ex = trim( $ex );
547
  if( '' !== $ex ) {
548
  $ex = trim( $ex, "/\\" );
549
  $exclude[] = trailingslashit( WPCLONE_WP_CONTENT ) . str_replace( '\\', '/', $ex ) ;
550
  }
551
  }
552
  }
553
  return $exclude;
554
+ <?php
555
+
556
+ function wpCloneSafePathMode($path) {
557
+ return str_replace("\\", "/", $path);
558
+ }
559
+
560
+ function wpCloneDirectory($path) {
561
+ return rtrim(str_replace("//", "/", wpCloneSafePathMode($path)), '/') . '/';
562
+ }
563
+
564
+ function convertPathIntoUrl($path) {
565
+ return str_replace(rtrim(WPCLONE_ROOT, "/\\"), site_url(), $path);
566
+ }
567
+
568
+ function convertUrlIntoPath($url) {
569
+ return str_replace(site_url(), rtrim(WPCLONE_ROOT, "/\\"), $url);
570
+ }
571
+
572
+ function wpa_db_backup_wpdb($destination)
573
+ {
574
+ global $wpdb;
575
+ $WPCLONE_DB_ICONV_IN = "UTF-8";
576
+ $WPCLONE_DB_ICONV_OUT = "ISO-8859-1//TRANSLIT";
577
+
578
+ $return = '';
579
+
580
+ // Get all of the tables
581
+ $tables = $wpdb->get_col('SHOW TABLES');
582
+ // Cycle through each provided table
583
+ foreach ($tables as $table) {
584
+
585
+ // First part of the output � remove the table
586
+ $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
587
+ $numberOfFields = count($result[0]);
588
+ $numberOfItems = count($result);
589
+
590
+ // Second part of the output � create table
591
+ $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
592
+ $return .= "\n\n" . $row2[1] . ";\n\n";
593
+
594
+ // Third part of the output � insert values into new table
595
+ for ($currentRowNumber = 0; $currentRowNumber < $numberOfItems; $currentRowNumber++) {
596
+
597
+ $row = $result[$currentRowNumber];
598
+ $query = "INSERT INTO {$table} VALUES(";
599
+
600
+ for ($j = 0; $j < $numberOfFields; $j++) {
601
+ $row[$j] = iconv($WPCLONE_DB_ICONV_IN, $WPCLONE_DB_ICONV_OUT, $row[$j]);
602
+ $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
603
+ }
604
+
605
+ $return .= substr($query, 0, -2) . ");\n";
606
+
607
+ }
608
+
609
+ $return .= "\n";
610
+ }
611
+
612
+ // Generate the filename for the sql file
613
+ $File_open = fopen($destination . '/database.sql', 'w+');
614
+
615
+ // Save the sql file
616
+ fwrite($File_open, $return);
617
+
618
+ //file close
619
+ fclose($File_open);
620
+
621
+ $wpdb->flush();
622
+ }
623
+
624
+ /**
625
+ * @link http://davidwalsh.name/backup-mysql-database-php
626
+ */
627
+ function wpa_db_backup_direct($destination,$tables = '*')
628
+ {
629
+
630
+ $link = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
631
+ if ( false === $link ) {
632
+ wpa_backup_error('db', mysql_error() );
633
+ }
634
+ mysql_select_db( DB_NAME, $link );
635
+ mysql_set_charset(DB_CHARSET, $link);
636
+ //get all of the tables
637
+ if($tables == '*')
638
+ {
639
+ $tables = array();
640
+ $result = mysql_query('SHOW TABLES');
641
+ if ( false === $result ) {
642
+ wpa_backup_error('db', mysql_error() );
643
+ }
644
+ while($row = mysql_fetch_row($result))
645
+ {
646
+ $tables[] = $row[0];
647
+ }
648
+ }
649
+ else
650
+ {
651
+ $tables = is_array($tables) ? $tables : explode(',',$tables);
652
+ }
653
+ $return = '';
654
+ //cycle through
655
+ foreach($tables as $table)
656
+ {
657
+
658
+ $result = mysql_query('SELECT * FROM '.$table);
659
+ if ( false === $result ) {
660
+ wpa_backup_error('db', mysql_error() );
661
+ }
662
+ $num_fields = mysql_num_fields($result);
663
+
664
+ $return.= 'DROP TABLE '.$table.';';
665
+ $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
666
+ $return.= "\n\n".$row2[1].";\n\n";
667
+
668
+ for ($i = 0; $i < $num_fields; $i++)
669
+ {
670
+ while($row = mysql_fetch_row($result))
671
+ {
672
+ $return.= 'INSERT INTO '.$table.' VALUES(';
673
+ for($j=0; $j<$num_fields; $j++)
674
+ {
675
+ $row[$j] = mysql_real_escape_string( $row[$j] );
676
+ if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
677
+ if ($j<($num_fields-1)) { $return.= ','; }
678
+ }
679
+ $return.= ");\n";
680
+ }
681
+ }
682
+ $return.="\n\n\n";
683
+
684
+ }
685
+ mysql_close($link);
686
+ //save file
687
+ $handle = fopen($destination . '/database.sql','w+');
688
+ fwrite($handle,$return);
689
+ fclose($handle);
690
+ }
691
+
692
+ function wpa_insert_data($name, $size)
693
+ {
694
+ global $wpdb;
695
+ global $current_user;
696
+ $wpdb->insert($wpdb->prefix . "wpclone", array(
697
+ 'backup_name' => $name,
698
+ 'data_time' => current_time('mysql', get_option('gmt_offset')),
699
+ 'creator' => $current_user->user_login,
700
+ 'backup_size' => $size)
701
+ );
702
+
703
+ $wpdb->flush();
704
+ }
705
+
706
+ function CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb = false )
707
+ {
708
+ $folderToBeZipped = WPCLONE_DIR_BACKUP . 'wpclone_backup';
709
+ $destinationPath = $folderToBeZipped . '/' . basename(WPCLONE_WP_CONTENT);
710
+ $zipFileName = WPCLONE_DIR_BACKUP . $backupName . '.zip';
711
+ $exclude = wpa_excluded_dirs();
712
+ $dbonly = isset( $_POST['dbonly'] ) && 'true' == $_POST['dbonly'] ? true : false;
713
+
714
+ if( false === mkdir( $folderToBeZipped ) )
715
+ 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 ) );
716
+
717
+ if( false === $dbonly )
718
+ wpa_copy_dir( untrailingslashit( WPCLONE_WP_CONTENT ), $destinationPath, $exclude);
719
+
720
+ wpa_save_prefix($folderToBeZipped);
721
+ /* error handler is called from within the db backup functions */
722
+ if ( $use_wpdb ) {
723
+ wpa_db_backup_wpdb( $folderToBeZipped );
724
+ } else {
725
+ wpa_db_backup_direct( $folderToBeZipped );
726
+ }
727
+
728
+ /* error haldler is called from within the wpa_zip function */
729
+ wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
730
+ $zipSize = filesize($zipFileName);
731
+ wpa_delete_dir( $folderToBeZipped );
732
+ return array($backupName . '.zip', $zipSize);
733
+ }
734
+
735
+ function DeleteWPBackupZip($nm)
736
+ {
737
+ global $wpdb;
738
+ $wp_backup = "{$wpdb->prefix}wpclone";
739
+ $deleteRow = $wpdb->get_row("SELECT * FROM {$wp_backup} WHERE id = '{$nm}'");
740
+
741
+ $wpdb->query("DELETE FROM {$wp_backup} WHERE id = '{$nm}' ");
742
+ if (file_exists(WPCLONE_DIR_BACKUP . $deleteRow->backup_name)) unlink(WPCLONE_DIR_BACKUP . $deleteRow->backup_name) or die ('unable to delete backup file.');
743
+ return $deleteRow;
744
+ }
745
+
746
+ function bytesToSize($bytes, $precision = 2)
747
+ {
748
+ $kilobyte = 1024;
749
+ $megabyte = $kilobyte * 1024;
750
+ $gigabyte = $megabyte * 1024;
751
+ $terabyte = $gigabyte * 1024;
752
+ if (($bytes >= 0) && ($bytes < $kilobyte)) {
753
+ return $bytes . ' B';
754
+ } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
755
+ return round($bytes / $kilobyte, $precision) . ' KB';
756
+ } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
757
+ return round($bytes / $megabyte, $precision) . ' MB';
758
+ } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
759
+ return round($bytes / $gigabyte, $precision) . ' GB';
760
+ } elseif ($bytes >= $terabyte) {
761
+ return round($bytes / $terabyte, $precision) . ' TB';
762
+ } else {
763
+ return $bytes . ' B';
764
+ }
765
+ }
766
+
767
+ function replaceSiteUrlFromDatabaseFile($databaseFile)
768
+ {
769
+ global $wp_filesystem;
770
+ $fileContent = $wp_filesystem->get_contents($databaseFile);
771
+ $pos = strpos($fileContent, 'siteurl') + 8;
772
+ $urlStartPos = strpos($fileContent, '"', $pos) + 1;
773
+ $urlEndPos = strpos($fileContent, '"', $urlStartPos);
774
+ $backupSiteUrl = substr($fileContent, $urlStartPos, $urlEndPos - $urlStartPos);
775
+ return $backupSiteUrl;
776
+ }
777
+
778
+ function processConfigAndDatabaseFile($databaseFileInZip)
779
+ {
780
+ global $wp_filesystem;
781
+ $dbFileContent = $wp_filesystem->get_contents($databaseFileInZip);
782
+ /* we don't want to nuke the curret database if if something went wrong with the above operation */
783
+ if ( false === $dbFileContent ) {
784
+ wpa_backup_error( 'dbrest', sprintf ( __( 'Cannot read <code>%s</code>' ), $databaseFileInZip ) , true );
785
+ }
786
+
787
+
788
+ $conn = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
789
+ /* and we cannot nuke the db if the connection failed now can we */
790
+ if ( false === $conn ) {
791
+ wpa_backup_error('dbrest', __( 'database connection failed' ), true );
792
+ }
793
+
794
+ mysql_select_db( DB_NAME, $conn);
795
+ mysql_set_charset(DB_CHARSET, $conn);
796
+ $query = mysql_query("SHOW TABLES", $conn);
797
+ /* point of no return,if it fails after this you're royally boned ;) */
798
+ while (($fetch = mysql_fetch_array($query))) {
799
+ mysql_query("Drop table `{$fetch[0]}`");
800
+ }
801
+ flush();
802
+
803
+ $res = explode(";\n", $dbFileContent);
804
+ foreach ($res AS $query) {
805
+ mysql_query($query, $conn);
806
+ }
807
+ mysql_close($conn);
808
+ $backupSiteUrl = replaceSiteUrlFromDatabaseFile($databaseFileInZip); /* don't let the name fool you,it just returns the old site's url */
809
+ $currentSiteUrl = site_url();
810
+ $backupSiteUrl = untrailingslashit($backupSiteUrl);
811
+ $currentSiteUrl = untrailingslashit($currentSiteUrl);
812
+ wpa_safe_replace_wrapper ( $backupSiteUrl, $currentSiteUrl );
813
+
814
+ return $currentSiteUrl;
815
+ }
816
+
817
+ /**
818
+ * @param type $search URL of the previous site.
819
+ * @param type $replace URL of the current site.
820
+ * @return type total time it took for the operation.
821
+ */
822
+ function wpa_safe_replace_wrapper ( $search, $replace ) {
823
+ if ( !function_exists( 'icit_srdb_replacer' ) && !function_exists( 'recursive_unserialize_replace' ) ) {
824
+ require_once 'icit_srdb_replacer.php';
825
+ }
826
+ $connection = @mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
827
+ $all_tables = array( );
828
+ @mysql_select_db( DB_NAME, $connection );
829
+ $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
830
+
831
+ if ( ! $all_tables_mysql ) {
832
+ wpa_backup_error( 'dbrest', mysql_error(), true );
833
+ } else {
834
+ while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
835
+ $all_tables[] = $table[ 0 ];
836
+ }
837
+ }
838
+
839
+ $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
840
+ return $report;
841
+ }
842
+
843
+
844
+ function processRestoringBackup($url, $zipmode) {
845
+ wpa_cleanup( true );
846
+ if (!is_string($url) || '' == $url) {
847
+ wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
848
+ }
849
+
850
+ global $wp_filesystem;
851
+ $temp_dir = trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp';
852
+ $temp_dir_err = $wp_filesystem->mkdir( $temp_dir );
853
+ if ( is_wp_error($temp_dir_err) ) {
854
+ wpa_backup_error('dirrest', $temp_dir_err->get_error_message(), true );
855
+ }
856
+ $pathParts = pathinfo($url);
857
+ $zipFilename = wpa_fetch_file($url);
858
+
859
+ $result = wpa_unzip($zipFilename, $temp_dir, $zipmode);
860
+ if ($result) {
861
+ $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . 'wpclone_backup' );
862
+ if ( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
863
+ $unzippedFolderPath = wpCloneSafePathMode( trailingslashit( $temp_dir ) . $pathParts['filename'] );
864
+ }
865
+
866
+ /* if we're here then the file extraction worked,but let's make doubly sure */
867
+ if( ! $wp_filesystem->is_dir( $unzippedFolderPath ) ) {
868
+ wpa_backup_error( 'restore', sprintf( __( 'Cannot find <code>%s<code>' ), $unzippedFolderPath ), true );
869
+ }
870
+ /* check the table prefixes */
871
+ $old_db_prefix = $unzippedFolderPath . '/prefix.txt';
872
+ $prefix = wpa_check_prefix($old_db_prefix);
873
+ if ($prefix) {
874
+ wpa_replace_prefix( $prefix );
875
+ }
876
+ $wp_filesystem->delete( $old_db_prefix );
877
+ /* import db */
878
+ $databaseFile = $unzippedFolderPath . '/database.sql';
879
+ $currentSiteUrl = processConfigAndDatabaseFile($databaseFile);
880
+ /* */
881
+ $wp_filesystem->delete( $databaseFile );
882
+
883
+ wpa_copy( $unzippedFolderPath . '/wp-content', WPCLONE_WP_CONTENT );
884
+
885
+
886
+ $wp_filesystem->delete( $temp_dir, true );
887
+ /* remove the zip file only if it was downloaded from an external location. */
888
+ $wptmp = explode('.', $zipFilename);
889
+ if ( in_array( 'tmp', $wptmp ) ) {
890
+ $wp_filesystem->delete( $zipFilename );
891
+ }
892
+
893
+ echo "<h1>Restore Successful!</h1>";
894
+
895
+ echo "Visit your restored site [ <a href='{$currentSiteUrl}' target=blank>here</a> ]<br><br>";
896
+
897
+ echo "<strong>You may need to re-save your permalink structure <a href='{$currentSiteUrl}/wp-admin/options-permalink.php' target=blank>Here</a></strong>";
898
+
899
+ } else {
900
+
901
+ echo "<h1>Restore unsuccessful!!!</h1>";
902
+
903
+ echo "Please try again.";
904
+ }
905
+
906
+ }
907
+
908
+ function wpa_save_prefix($path) {
909
+ global $wpdb;
910
+ $prefix = $wpdb->prefix;
911
+ $file = $path . '/prefix.txt';
912
+ if ( is_dir($path) && is_writable($path) ) {
913
+ file_put_contents($file, $prefix);
914
+ }
915
+ }
916
+ /**
917
+ * 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.
918
+ *
919
+ * @param type $file path to the prefix.txt file.
920
+ * @return type bool string
921
+ */
922
+ function wpa_check_prefix($file) {
923
+ global $wpdb;
924
+ $prefix = $wpdb->prefix;
925
+ if (file_exists($file) && is_readable($file)) {
926
+ $old_prefix = file_get_contents($file);
927
+ if ( $prefix !== $old_prefix ) {
928
+ return $old_prefix;
929
+ }
930
+ else {
931
+ return false;
932
+ }
933
+ }
934
+ return false;
935
+ }
936
+
937
+ /**
938
+ * @since 2.0.6
939
+ *
940
+ * @param type $zipfile path to the zip file that needs to be extracted.
941
+ * @param type $path the place to where the file needs to be extracted.
942
+ * @return as false in the event of failure.
943
+ */
944
+ function wpa_unzip($zipfile, $path, $zipmode = false){
945
+ if ( $zipmode ) {
946
+
947
+ if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
948
+ $previous_encoding = mb_internal_encoding();
949
+ mb_internal_encoding('ISO-8859-1');
950
+ }
951
+
952
+ define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
953
+ require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
954
+ $z = new PclZip($zipfile);
955
+ $files = $z->extract(PCLZIP_OPT_PATH, $path);
956
+
957
+ if ( isset($previous_encoding) ) mb_internal_encoding($previous_encoding);
958
+
959
+ if ( $files == 0 ) {
960
+ wpa_backup_error( 'pclunzip', $z->errorInfo(true), true );
961
+ }
962
+ return true;
963
+ }
964
+ else {
965
+ $z= unzip_file($zipfile, $path);
966
+ if (is_wp_error($z)) {
967
+ wpa_backup_error( 'unzip', $z->get_error_message(), true );
968
+ }
969
+ return true;
970
+ }
971
+ }
972
+ /**
973
+ * @since 2.0.6
974
+ *
975
+ * @param type $name name of the zip file.
976
+ * @param type $file_list an array of files that needs to be archived.
977
+ */
978
+ function wpa_zip($zip_name, $folder, $zipmode = false){
979
+ if ( $zipmode || (!in_array('ZipArchive', get_declared_classes()) || !class_exists('ZipArchive')) ) {
980
+ define('PCLZIP_TEMPORARY_DIR', WPCLONE_DIR_BACKUP);
981
+ require_once ( ABSPATH . 'wp-admin/includes/class-pclzip.php');
982
+ $z = new PclZip($zip_name);
983
+ $v_list = $z->create($folder, PCLZIP_OPT_REMOVE_PATH, WPCLONE_DIR_BACKUP);
984
+ if ($v_list == 0) {
985
+ wpa_backup_error( 'pclzip', $z->errorInfo(true) );
986
+ }
987
+ } else {
988
+ $z = new ZipArchive();
989
+ if ( true !== $z->open( $zip_name, ZIPARCHIVE::CREATE ) ) {
990
+ wpa_backup_error( 'zip', $z );
991
+ }
992
+ wpa_ziparc($z, $folder, WPCLONE_DIR_BACKUP);
993
+ $z->close();
994
+ }
995
+ }
996
+
997
+ function wpa_ziparc($zip, $dir, $base) {
998
+ $new_folder = str_replace($base, '', $dir);
999
+ $zip->addEmptyDir($new_folder);
1000
+ foreach( glob( $dir . '/*' ) as $file ){
1001
+ if( is_dir($file) ) {
1002
+ wpa_ziparc($zip, $file, $base);
1003
+ } else {
1004
+ $new_file = str_replace( $base, '', $file );
1005
+ $zip->addFile($file, $new_file);
1006
+ }
1007
+ }
1008
+ }
1009
+ /**
1010
+ * just a simple function to increase PHP limits.
1011
+ * @since 2.0.6
1012
+ */
1013
+ function wpa_bump_limits(){
1014
+ $time = isset( $_POST['maxexec'] ) && '' != $_POST['maxexec'] ? $_POST['maxexec'] : 300; /*300 seconds = 5 minutes*/
1015
+ $mem = isset ( $_POST['maxmem'] ) && '' != $_POST['maxmem'] ? $_POST['maxmem'] . 'M' : '512M';
1016
+ @ini_set('memory_limit', $mem);
1017
+ @ini_set('max_execution_time', $time);
1018
+ }
1019
+ /**
1020
+ * @since 2.0.6
1021
+ */
1022
+ function wpa_wpfs_init(){
1023
+ if (!empty($_REQUEST['del'])) {
1024
+ wpa_remove_backup();
1025
+ return true;
1026
+ }
1027
+ if (empty($_POST)) return false;
1028
+ check_admin_referer('wpclone-submit');
1029
+
1030
+ wpa_bump_limits();
1031
+
1032
+ if (isset($_POST['createBackup'])) {
1033
+ wpa_create_backup();
1034
+ return true;
1035
+ }
1036
+
1037
+ $form_post = wp_nonce_url('admin.php?page=wp-clone', 'wpclone-submit');
1038
+ $extra_fields = array( 'restore_from_url', 'maxmem', 'maxexec', 'zipmode', 'restoreBackup', 'createBackup' );
1039
+ $type = '';
1040
+ if ( false === ($creds = request_filesystem_credentials($form_post, $type, false, false, $extra_fields)) ){
1041
+ return true;
1042
+ }
1043
+ if (!WP_Filesystem($creds)) {
1044
+ request_filesystem_credentials($form_post, $type, true, false, $extra_fields);
1045
+ return true;
1046
+ }
1047
+
1048
+ $zipmode = isset($_POST['zipmode']) ? true : false;
1049
+ $url = isset($_POST['restoreBackup']) ? $_POST['restoreBackup'] : $_POST['restore_from_url'];
1050
+ processRestoringBackup($url, $zipmode);
1051
+ return true;
1052
+ }
1053
+ /**
1054
+ * @since 2.0.6
1055
+ */
1056
+ function wpa_copy($source, $target) {
1057
+ global $wp_filesystem;
1058
+ if (is_readable($source)) {
1059
+ if (is_dir($source)) {
1060
+ if (!file_exists($target)) {
1061
+ $wp_filesystem->mkdir($target);
1062
+ }
1063
+ $d = dir($source);
1064
+ while (FALSE !== ($entry = $d->read())) {
1065
+ if ($entry == '.' || $entry == '..') {
1066
+ continue;
1067
+ }
1068
+ $Entry = "{$source}/{$entry}";
1069
+ if (is_dir($Entry)) {
1070
+ wpa_copy($Entry, $target . '/' . $entry);
1071
+ } else {
1072
+ $wp_filesystem->copy($Entry, $target . '/' . $entry, true, FS_CHMOD_FILE);
1073
+ }
1074
+ }
1075
+ $d->close();
1076
+ }
1077
+ else {
1078
+ $wp_filesystem->copy($source, $target, true);
1079
+ }
1080
+ }
1081
+ }
1082
+ /**
1083
+ * @since 2.0.6
1084
+ */
1085
+ function wpa_replace_prefix($newPrefix){
1086
+ $wpconfig = wpa_wpconfig_path();
1087
+ global $wp_filesystem;
1088
+
1089
+ if ( ! $wp_filesystem->is_writable($wpconfig) ) {
1090
+ if( false === $wp_filesystem->chmod( $wpconfig ) )
1091
+ wpa_backup_error('wpconfig', sprintf( __( "<code>%s</code> is not writable and wpclone was unable to change the file permissions." ), $wpconfig ), true );
1092
+ }
1093
+
1094
+ $fileContent = $wp_filesystem->get_contents($wpconfig);
1095
+ $pos = strpos($fileContent, '$table_prefix');
1096
+ $str = substr($fileContent, $pos, strpos($fileContent, PHP_EOL, $pos) - $pos);
1097
+ $fileContent = str_replace($str, '$table_prefix = "' . $newPrefix . '";', $fileContent);
1098
+ $wp_filesystem->put_contents($wpconfig, $fileContent, 0600);
1099
+ }
1100
+ /**
1101
+ * @since 2.0.6
1102
+ */
1103
+ function wpa_create_backup (){
1104
+ if( true === is_multisite() )
1105
+ die( 'wpclone does not work on multisite installs.' );
1106
+ if ( !file_exists(WPCLONE_DIR_BACKUP) ) {
1107
+ wpa_create_directory();
1108
+ }
1109
+ wpa_cleanup();
1110
+ $use_wpdb = isset( $_POST['use_wpdb'] ) && 'true' == $_POST['use_wpdb'] ? true : false;
1111
+ $backupName = wpa_backup_name();
1112
+
1113
+ $zipmode = isset($_POST['zipmode']) ? true : false;
1114
+ list($zipFileName, $zipSize) = CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb);
1115
+
1116
+ wpa_insert_data($zipFileName, $zipSize);
1117
+ $backZipPath = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $zipFileName);
1118
+ $zipSize = bytesToSize($zipSize);
1119
+ echo <<<EOF
1120
+
1121
+ <h1>Backup Successful!</h1>
1122
+
1123
+ <br />
1124
+
1125
+ Here is your backup file : <br />
1126
+
1127
+ <a href='{$backZipPath}'><span>{$backZipPath}</span></a> ( {$zipSize} ) &nbsp;&nbsp;|&nbsp;&nbsp;
1128
+ <input type='hidden' name='backupUrl' class='backupUrl' value="{$backZipPath}" />
1129
+ <a class='copy-button' href='#' data-clipboard-text='{$backZipPath}'>Copy URL</a> &nbsp;<br /><br />
1130
+
1131
+ (Copy that link and paste it into the "Restore URL" of your new WordPress installation to clone this site)
1132
+ EOF;
1133
+ }
1134
+ /**
1135
+ * @since 2.0.6
1136
+ */
1137
+ function wpa_remove_backup(){
1138
+ check_admin_referer('wpclone-submit');
1139
+ $deleteRow = DeleteWPBackupZip($_REQUEST['del']);
1140
+ echo <<<EOT
1141
+ <h1>Deleted Successful!</h1> <br />
1142
+
1143
+ {$deleteRow->backup_name} <br />
1144
+
1145
+ File deleted from backup folder and database...
1146
+ EOT;
1147
+ }
1148
+ /**
1149
+ * @since 2.1.2
1150
+ * copypasta from wp-load.php
1151
+ * @return the path to wp-config.php
1152
+ */
1153
+ function wpa_wpconfig_path () {
1154
+
1155
+ if ( file_exists( ABSPATH . 'wp-config.php') ) {
1156
+
1157
+ /** The config file resides in ABSPATH */
1158
+ return ABSPATH . 'wp-config.php';
1159
+
1160
+ }
1161
+ elseif ( file_exists( dirname(ABSPATH) . '/wp-config.php' ) && ! file_exists( dirname(ABSPATH) . '/wp-settings.php' ) ) {
1162
+
1163
+ /** The config file resides one level above ABSPATH but is not part of another install */
1164
+ return dirname(ABSPATH) . '/wp-config.php';
1165
+
1166
+ }
1167
+ else {
1168
+
1169
+ return false;
1170
+
1171
+ }
1172
+
1173
+ }
1174
+
1175
+ function wpa_fetch_file($path){
1176
+ $z = pathinfo($path);
1177
+ global $wp_filesystem;
1178
+ if ( $wp_filesystem->is_file(WPCLONE_DIR_BACKUP . $z['basename']) ) {
1179
+ return WPCLONE_DIR_BACKUP . $z['basename'];
1180
+ }
1181
+ else {
1182
+ $url = download_url($path, 750);
1183
+ if ( is_wp_error($url) ) wpa_backup_error( 'url', $url->get_error_message(), true );
1184
+ return $url;
1185
+ }
1186
+ }
1187
+
1188
+ function wpa_backup_name() {
1189
+ $backup_name = 'wpclone_backup_' . date( 'dS_M_Y_h-iA' ) . '_' . get_option( 'blogname' );
1190
+ $backup_name = substr( str_replace( ' ', '', $backup_name ), 0, 40 );
1191
+ $rand_str = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ), 0, 10 );
1192
+ $backup_name = sanitize_file_name( $backup_name ) . '_' . $rand_str;
1193
+ return $backup_name;
1194
+ }
1195
+
1196
+ function wpa_backup_error($error, $data, $restore = false) {
1197
+
1198
+ $temp_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
1199
+
1200
+ if( !file_exists( $temp_dir ) ) {
1201
+ unset($temp_dir);
1202
+ }
1203
+
1204
+ switch ( $error ) :
1205
+ /* during backup */
1206
+ case 'file' :
1207
+ $error = __( 'while copying files into the temp directory' );
1208
+ break;
1209
+ case 'db' :
1210
+ $error = __( 'during the database backup' );
1211
+ break;
1212
+ case 'zip' :
1213
+ $error = __( 'while creating the zip file using PHP\'s ZipArchive library' );
1214
+ break;
1215
+ case 'pclzip' :
1216
+ $error = __( 'while creating the zip file using the PclZip library' );
1217
+ break;
1218
+ /* during restore */
1219
+ case 'dirrest' :
1220
+ $error = __( 'while creating the temp directory' );
1221
+ break;
1222
+ case 'filerest' :
1223
+ $error = __( 'while copying files from the temp directory into the wp-content directory' );
1224
+ break;
1225
+ case 'dbrest' :
1226
+ $error = __( 'while cloning the database' );
1227
+ break;
1228
+ case 'unzip' :
1229
+ $error = __( 'while extracting the zip file using WP\'s zip file extractor' );
1230
+ break;
1231
+ case 'pclunzip' :
1232
+ $error = __( 'while extracting the zip file using the PclZip library' );
1233
+ break;
1234
+ case 'url' :
1235
+ $error = __( 'while downloading the zip file' );
1236
+ break;
1237
+ case 'wpconfig' :
1238
+ $error = __( 'while trying to modify the table prefix in the wp-config.php file' );
1239
+ break;
1240
+ /* and a catch all for the things that aren't covered above */
1241
+ default :
1242
+ $error = sprintf( __( 'during the %s process' ), $error );
1243
+ endswitch;
1244
+
1245
+ echo '<div class="wpclone_notice updated">';
1246
+ printf( __( 'The plugin encountered an error %s,the following error message was returned:</br>' ), $error );
1247
+ echo '<div class="error">' . __( 'Error Message : ' ) . $data . '</div></br>';
1248
+ if( isset( $temp_dir ) ) {
1249
+ printf( __( 'Temporary files created in <code>%s</code> will be deleted.' ), $temp_dir );
1250
+ echo '</div>';
1251
+ if( $restore ) {
1252
+ global $wp_filesystem;
1253
+ $wp_filesystem->delete($temp_dir, true);
1254
+ } else {
1255
+ wpa_delete_dir( $temp_dir );
1256
+ }
1257
+ } else {
1258
+ echo '</div>';
1259
+ }
1260
+ die;
1261
+ }
1262
+
1263
+ function wpa_cleanup( $restore = false ) {
1264
+ $backup_dir = $restore ? trailingslashit( WPCLONE_WP_CONTENT ) . 'wpclone-temp' : trailingslashit( WPCLONE_DIR_BACKUP ) . 'wpclone_backup';
1265
+ if ( file_exists( $backup_dir ) && is_dir( $backup_dir ) ) {
1266
+ if( $restore ) {
1267
+ global $wp_filesystem;
1268
+ $wp_filesystem->delete($backup_dir, true);
1269
+ } else {
1270
+ wpa_delete_dir( $backup_dir );
1271
+ }
1272
+ }
1273
+ }
1274
+ /**
1275
+ * recursively copies a directory from one place to another. excludes 'uploads/wp-clone' by default.
1276
+ * @since 2.1.6
1277
+ * @param string $from
1278
+ * @param string $to
1279
+ * @param array $exclude an array of directory paths to exclude.
1280
+ */
1281
+ function wpa_copy_dir( $from, $to, $exclude ) {
1282
+ if( false === stripos( wpCloneSafePathMode( $from ), rtrim( wpCloneSafePathMode( WPCLONE_DIR_BACKUP ), "/\\" ) ) ) {
1283
+ if( !file_exists( $to ) )
1284
+ @mkdir ( $to );
1285
+ $files = array_diff( scandir( $from ), array( '.', '..' ) );
1286
+ foreach( $files as $file ) {
1287
+ if( in_array( $from . '/' . $file, $exclude ) ) {
1288
+ continue;
1289
+ } else {
1290
+ if( is_dir( $from . '/' . $file ) ) {
1291
+ wpa_copy_dir( $from . '/' . $file, $to . '/' . $file, $exclude );
1292
+ } else {
1293
+ @copy( $from . '/' . $file, $to . '/' . $file );
1294
+ }
1295
+ }
1296
+ }
1297
+ unset( $files );
1298
+ }
1299
+ }
1300
+ /**
1301
+ * recursively deletes all the files in the given directory.
1302
+ * @since 2.1.6
1303
+ * @param string $dir path to the directory that needs to be deleted.
1304
+ */
1305
+ function wpa_delete_dir( $dir ) {
1306
+ if( !empty( $dir ) ) {
1307
+ $dir = trailingslashit( $dir );
1308
+ $files = array_diff( scandir( $dir ), array( '.', '..' ) );
1309
+ foreach ( $files as $file ) {
1310
+ if( is_dir( $dir . $file ) ) {
1311
+ wpa_delete_dir( $dir . $file );
1312
+ } else {
1313
+ @unlink( $dir . $file );
1314
+ }
1315
+ }
1316
+ @rmdir($dir);
1317
+ }
1318
+ }
1319
+ /**
1320
+ * @since 2.1.6
1321
+ */
1322
+ function wpa_excluded_dirs() {
1323
+ $exclude = array();
1324
+ if( isset( $_POST['exclude'] ) && '' != $_POST['exclude'] ) {
1325
+ foreach( explode( "\n", $_POST['exclude'] ) as $ex ) {
1326
+ $ex = trim( $ex );
1327
+ if( '' !== $ex ) {
1328
+ $ex = trim( $ex, "/\\" );
1329
+ $exclude[] = trailingslashit( WPCLONE_WP_CONTENT ) . str_replace( '\\', '/', $ex ) ;
1330
+ }
1331
+ }
1332
+ }
1333
+ return $exclude;
1334
+ }
1335
+
1336
+ /* end of file */
lib/icit_srdb_replacer.php CHANGED
@@ -1,154 +1,154 @@
1
- <?php
2
- /**
3
- * Take a serialised array and unserialise it replacing elements as needed and
4
- * unserialising any subordinate arrays and performing the replace on those too.
5
- *
6
- * @param string $from String we're looking to replace.
7
- * @param string $to What we want it to be replaced with
8
- * @param array $data Used to pass any subordinate arrays back to in.
9
- * @param bool $serialised Does the array passed via $data need serialising.
10
- *
11
- * @return array The original array with all elements replaced as needed.
12
- */
13
- function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) {
14
-
15
- // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
16
- try {
17
-
18
- if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
19
- $data = recursive_unserialize_replace( $from, $to, $unserialized, true );
20
- }
21
-
22
- elseif ( is_array( $data ) ) {
23
- $_tmp = array( );
24
- foreach ( $data as $key => $value ) {
25
- $_tmp[ $key ] = recursive_unserialize_replace( $from, $to, $value, false );
26
- }
27
-
28
- $data = $_tmp;
29
- unset( $_tmp );
30
- }
31
-
32
- else {
33
- if ( is_string( $data ) )
34
- $data = str_replace( $from, $to, $data );
35
- }
36
-
37
- if ( $serialised )
38
- return serialize( $data );
39
-
40
- } catch( Exception $error ) {
41
-
42
- }
43
-
44
- return $data;
45
- }
46
-
47
- /**
48
- * The main loop triggered in step 5. Up here to keep it out of the way of the
49
- * HTML. This walks every table in the db that was selected in step 3 and then
50
- * walks every row and column replacing all occurences of a string with another.
51
- * We split large tables into 50,000 row blocks when dealing with them to save
52
- * on memmory consumption.
53
- *
54
- * @param mysql $connection The db connection object
55
- * @param string $search What we want to replace
56
- * @param string $replace What we want to replace it with.
57
- * @param array $tables The tables we want to look at.
58
- *
59
- * @return array Collection of information gathered during the run.
60
- */
61
- function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables = array( ) ) {
62
- global $guid, $exclude_cols;
63
-
64
- $report = array( 'tables' => 0,
65
- 'rows' => 0,
66
- 'change' => 0,
67
- 'updates' => 0,
68
- 'start' => microtime( ),
69
- 'end' => microtime( ),
70
- 'errors' => array( ),
71
- );
72
-
73
- if ( is_array( $tables ) && ! empty( $tables ) ) {
74
- foreach( $tables as $table ) {
75
- $report[ 'tables' ]++;
76
-
77
- $columns = array( );
78
-
79
- // Get a list of columns in this table
80
- $fields = mysql_query( 'DESCRIBE ' . $table, $connection );
81
- while( $column = mysql_fetch_array( $fields ) )
82
- $columns[ $column[ 'Field' ] ] = $column[ 'Key' ] == 'PRI' ? true : false;
83
-
84
- // Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley
85
- $row_count = mysql_query( 'SELECT COUNT(*) FROM ' . $table, $connection );
86
- $rows_result = mysql_fetch_array( $row_count );
87
- $row_count = $rows_result[ 0 ];
88
- if ( $row_count == 0 )
89
- continue;
90
-
91
- $page_size = 50000;
92
- $pages = ceil( $row_count / $page_size );
93
-
94
- for( $page = 0; $page < $pages; $page++ ) {
95
-
96
- $current_row = 0;
97
- $start = $page * $page_size;
98
- $end = $start + $page_size;
99
- // Grab the content of the table
100
- $data = mysql_query( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ), $connection );
101
-
102
- if ( ! $data )
103
- $report[ 'errors' ][] = mysql_error( );
104
-
105
- while ( $row = mysql_fetch_array( $data ) ) {
106
-
107
- $report[ 'rows' ]++; // Increment the row counter
108
- $current_row++;
109
-
110
- $update_sql = array( );
111
- $where_sql = array( );
112
- $upd = false;
113
-
114
- foreach( $columns as $column => $primary_key ) {
115
- if ( $guid == 1 && in_array( $column, $exclude_cols ) )
116
- continue;
117
-
118
- $edited_data = $data_to_fix = $row[ $column ];
119
-
120
- // Run a search replace on the data that'll respect the serialisation.
121
- $edited_data = recursive_unserialize_replace( $search, $replace, $data_to_fix );
122
-
123
- // Something was changed
124
- if ( $edited_data != $data_to_fix ) {
125
- $report[ 'change' ]++;
126
- $update_sql[] = $column . ' = "' . mysql_real_escape_string( $edited_data ) . '"';
127
- $upd = true;
128
- }
129
-
130
- if ( $primary_key )
131
- $where_sql[] = $column . ' = "' . mysql_real_escape_string( $data_to_fix ) . '"';
132
- }
133
-
134
- if ( $upd && ! empty( $where_sql ) ) {
135
- $sql = 'UPDATE ' . $table . ' SET ' . implode( ', ', $update_sql ) . ' WHERE ' . implode( ' AND ', array_filter( $where_sql ) );
136
- $result = mysql_query( $sql, $connection );
137
- if ( ! $result )
138
- $report[ 'errors' ][] = mysql_error( );
139
- else
140
- $report[ 'updates' ]++;
141
-
142
- } elseif ( $upd ) {
143
- $report[ 'errors' ][] = sprintf( '"%s" has no primary key, manual change needed on row %s.', $table, $current_row );
144
- }
145
-
146
- }
147
- }
148
- }
149
-
150
- }
151
- $report[ 'end' ] = microtime( );
152
-
153
- return $report;
154
- }
1
+ <?php
2
+ /**
3
+ * Take a serialised array and unserialise it replacing elements as needed and
4
+ * unserialising any subordinate arrays and performing the replace on those too.
5
+ *
6
+ * @param string $from String we're looking to replace.
7
+ * @param string $to What we want it to be replaced with
8
+ * @param array $data Used to pass any subordinate arrays back to in.
9
+ * @param bool $serialised Does the array passed via $data need serialising.
10
+ *
11
+ * @return array The original array with all elements replaced as needed.
12
+ */
13
+ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) {
14
+
15
+ // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
16
+ try {
17
+
18
+ if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
19
+ $data = recursive_unserialize_replace( $from, $to, $unserialized, true );
20
+ }
21
+
22
+ elseif ( is_array( $data ) ) {
23
+ $_tmp = array( );
24
+ foreach ( $data as $key => $value ) {
25
+ $_tmp[ $key ] = recursive_unserialize_replace( $from, $to, $value, false );
26
+ }
27
+
28
+ $data = $_tmp;
29
+ unset( $_tmp );
30
+ }
31
+
32
+ else {
33
+ if ( is_string( $data ) )
34
+ $data = str_replace( $from, $to, $data );
35
+ }
36
+
37
+ if ( $serialised )
38
+ return serialize( $data );
39
+
40
+ } catch( Exception $error ) {
41
+
42
+ }
43
+
44
+ return $data;
45
+ }
46
+
47
+ /**
48
+ * The main loop triggered in step 5. Up here to keep it out of the way of the
49
+ * HTML. This walks every table in the db that was selected in step 3 and then
50
+ * walks every row and column replacing all occurences of a string with another.
51
+ * We split large tables into 50,000 row blocks when dealing with them to save
52
+ * on memmory consumption.
53
+ *
54
+ * @param mysql $connection The db connection object
55
+ * @param string $search What we want to replace
56
+ * @param string $replace What we want to replace it with.
57
+ * @param array $tables The tables we want to look at.
58
+ *
59
+ * @return array Collection of information gathered during the run.
60
+ */
61
+ function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables = array( ) ) {
62
+ global $guid, $exclude_cols;
63
+
64
+ $report = array( 'tables' => 0,
65
+ 'rows' => 0,
66
+ 'change' => 0,
67
+ 'updates' => 0,
68
+ 'start' => microtime( ),
69
+ 'end' => microtime( ),
70
+ 'errors' => array( ),
71
+ );
72
+
73
+ if ( is_array( $tables ) && ! empty( $tables ) ) {
74
+ foreach( $tables as $table ) {
75
+ $report[ 'tables' ]++;
76
+
77
+ $columns = array( );
78
+
79
+ // Get a list of columns in this table
80
+ $fields = mysql_query( 'DESCRIBE ' . $table, $connection );
81
+ while( $column = mysql_fetch_array( $fields ) )
82
+ $columns[ $column[ 'Field' ] ] = $column[ 'Key' ] == 'PRI' ? true : false;
83
+
84
+ // Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley
85
+ $row_count = mysql_query( 'SELECT COUNT(*) FROM ' . $table, $connection );
86
+ $rows_result = mysql_fetch_array( $row_count );
87
+ $row_count = $rows_result[ 0 ];
88
+ if ( $row_count == 0 )
89
+ continue;
90
+
91
+ $page_size = 50000;
92
+ $pages = ceil( $row_count / $page_size );
93
+
94
+ for( $page = 0; $page < $pages; $page++ ) {
95
+
96
+ $current_row = 0;
97
+ $start = $page * $page_size;
98
+ $end = $start + $page_size;
99
+ // Grab the content of the table
100
+ $data = mysql_query( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ), $connection );
101
+
102
+ if ( ! $data )
103
+ $report[ 'errors' ][] = mysql_error( );
104
+
105
+ while ( $row = mysql_fetch_array( $data ) ) {
106
+
107
+ $report[ 'rows' ]++; // Increment the row counter
108
+ $current_row++;
109
+
110
+ $update_sql = array( );
111
+ $where_sql = array( );
112
+ $upd = false;
113
+
114
+ foreach( $columns as $column => $primary_key ) {
115
+ if ( $guid == 1 && in_array( $column, $exclude_cols ) )
116
+ continue;
117
+
118
+ $edited_data = $data_to_fix = $row[ $column ];
119
+
120
+ // Run a search replace on the data that'll respect the serialisation.
121
+ $edited_data = recursive_unserialize_replace( $search, $replace, $data_to_fix );
122
+
123
+ // Something was changed
124
+ if ( $edited_data != $data_to_fix ) {
125
+ $report[ 'change' ]++;
126
+ $update_sql[] = $column . ' = "' . mysql_real_escape_string( $edited_data ) . '"';
127
+ $upd = true;
128
+ }
129
+
130
+ if ( $primary_key )
131
+ $where_sql[] = $column . ' = "' . mysql_real_escape_string( $data_to_fix ) . '"';
132
+ }
133
+
134
+ if ( $upd && ! empty( $where_sql ) ) {
135
+ $sql = 'UPDATE ' . $table . ' SET ' . implode( ', ', $update_sql ) . ' WHERE ' . implode( ' AND ', array_filter( $where_sql ) );
136
+ $result = mysql_query( $sql, $connection );
137
+ if ( ! $result )
138
+ $report[ 'errors' ][] = mysql_error( );
139
+ else
140
+ $report[ 'updates' ]++;
141
+
142
+ } elseif ( $upd ) {
143
+ $report[ 'errors' ][] = sprintf( '"%s" has no primary key, manual change needed on row %s.', $table, $current_row );
144
+ }
145
+
146
+ }
147
+ }
148
+ }
149
+
150
+ }
151
+ $report[ 'end' ] = microtime( );
152
+
153
+ return $report;
154
+ }
lib/view.php CHANGED
@@ -1,215 +1,215 @@
1
- <script type="text/javascript">
2
- jQuery ( function($) {
3
-
4
- ZeroClipboard.setDefaults( { moviePath: '<?php echo WPCLONE_URL_PLUGIN ?>lib/js/ZeroClipboard.swf' } );
5
-
6
- /**workaround for firefox versions 18 and 19.
7
- https://bugzilla.mozilla.org/show_bug.cgi?id=829557
8
- https://github.com/jonrohan/ZeroClipboard/issues/73
9
- */
10
- var enableZC = true;
11
- var is_firefox18 = navigator.userAgent.toLowerCase().indexOf('firefox/18') > -1;
12
- var is_firefox19 = navigator.userAgent.toLowerCase().indexOf('firefox/19') > -1;
13
- if (is_firefox18 || is_firefox19) enableZC = false;
14
-
15
- if ( $( ".restore-backup-options" ).length ) {
16
- $( ".restore-backup-options" ).each( function() {
17
- var clip = new ZeroClipboard( $( "a.copy-button",this ) );
18
- /** FF 18/19 users won't see an alert box. */
19
- if (enableZC) {
20
- clip.on( 'complete', function (client, args) {
21
- alert( "Copied to clipboard:\n" + args.text );
22
- });
23
- }
24
- });
25
- } else {
26
- var clip = new ZeroClipboard( $( "a.copy-button" ) );
27
- /** FF 18/19 users won't see an alert box. */
28
- if (enableZC) {
29
- clip.on( 'complete', function (client, args) {
30
- alert( "Copied to clipboard:\n" + args.text );
31
- });
32
- }
33
- }
34
- });
35
-
36
- </script>
37
-
38
- <?php
39
- if (wpa_wpfs_init()) return;
40
- global $wpdb;
41
- $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id DESC", ARRAY_A);
42
-
43
- ?>
44
- <div id="wrapper">
45
- <div id="MainView">
46
-
47
- <h2>Welcome to WP Clone by WP Academy</h2>
48
-
49
- <p>You can use this tool to create a backup of this site and (optionally) restore it to another server, or another WordPress installation on the same server.</p>
50
-
51
- <p><strong>Here is how it works:</strong> the "Backup" function will give you a URL that you can then copy and paste
52
- into the "Restore" dialog of a new WordPress site, which will clone the original site to the new site. You must
53
- install the plugin on the new site and then run the WP Clone > Restore function.</p>
54
-
55
- <p><strong>Choose your selection below:</strong> either create a backup of this site, or choose which backup you
56
- would like to restore.</p>
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
79
- }
80
- ?>
81
- <strong>Create Backup</strong>
82
- <input id="createBackup" name="createBackup" type="radio" value="fullBackup" checked="checked"/><br/><br/>
83
-
84
- <?php if (count($result) > 0) : ?>
85
-
86
- <div class="try">
87
-
88
- <?php foreach ($result AS $row) :
89
-
90
- $filename = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $row['backup_name']);
91
- $url = wp_nonce_url( get_bloginfo('wpurl') . '/wp-admin/options-general.php?page=wp-clone&del=' . $row['id'], 'wpclone-submit');
92
- ?>
93
- <div class="restore-backup-options">
94
- <strong>Restore backup </strong>
95
-
96
- <input class="restoreBackup" name="restoreBackup" type="radio"
97
- value="<?php echo $filename ?>" />&nbsp;
98
-
99
- <a href="<?php echo $filename ?>" class="zclip">
100
- (&nbsp;<?php echo bytesToSize($row['backup_size']);?>&nbsp;)&nbsp; <?php echo $row['backup_name'] ?>
101
- </a>&nbsp;|&nbsp;
102
-
103
- <input type="hidden" name="backup_name" value="<?php echo $filename ?>" />
104
-
105
- <a class="copy-button" href="#" data-clipboard-text="<?php echo $filename ?>" >Copy URL</a> &nbsp;|&nbsp;
106
- <a href="<?php echo $url; ?>">Delete</a>
107
- </div>
108
-
109
- <?php endforeach ?>
110
-
111
- </div>
112
-
113
- <?php endif ?>
114
-
115
- <strong>Restore from URL:</strong><input id="backupUrl" name="backupUrl" type="radio" value="backupUrl"/>
116
-
117
- <input type="text" name="restore_from_url" class="Url" value="" size="80px"/><br/><br/>
118
-
119
- <div class="RestoreOptions" id="RestoreOptions">
120
-
121
- <input type="checkbox" name="approve" id="approve" /> I AGREE (Required for "Restore" function):<br/>
122
-
123
- 1. You have nothing of value in your current site <strong>[<?php echo site_url() ?>]</strong><br/>
124
-
125
- 2. Your current site at <strong>[<?php echo site_url() ?>]</strong> may become unusable in case of failure,
126
- and you will need to re-install WordPress<br/>
127
-
128
- 3. Your WordPress database <strong>[<?php echo DB_NAME; ?>]</strong> will be overwritten from the database in the backup file. <br/>
129
-
130
- </div>
131
-
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
-
144
- <ul>
145
- <h2>WP Academy Resources</h2>
146
- <iframe src="//player.vimeo.com/video/98912458?title=0&amp;byline=0&amp;portrait=0" width="300" height="225" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
147
- <li><a href="http://wpencyclopedia.com" target="_blank" title="WP Encyclopedia">WordPress Business Encyclopedia</a></li>
148
- <li><a href="http://www.wpacademy.com/wordpress-training" target="_blank" title="WP Live">WP Live</a></li>
149
- <li><a href="http://wpacademy.com/websites" target="_blank" title="WP Academy Websites">Websites</a></li>
150
- <li><a href="http://www.wpacademy.com/hosting" target="_blank" title="Managed WordPress Hosting">Managed WordPress Hosting</a></li>
151
- </ul>
152
-
153
- <ul>
154
- <h2>WP Academy News</h2>
155
- <h3>WPAcademy.com</h3>
156
- <?php wpa_fetch_feed ('http://members.wpacademy.com/category/news/feed', 3); ?>
157
- <h3>Twitter @WPAcademy</h3>
158
- <?php /* wpa_fetch_feed ('http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=wpacademy', 5); */ ?>
159
- <a class="twitter-timeline" height="400" href="https://twitter.com/WPAcademy" data-widget-id="342116561412304898">Tweets by @WPAcademy</a>
160
- <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>
161
-
162
- </ul>
163
-
164
- <ul>
165
- <h2>Help & Support</h2>
166
- <li><a href="http://members.wpacademy.com/wpclone-faq" target="_blank" title="WP Clone FAQ">Visit the WP Clone FAQ Page</a></li>
167
- <li><a href="http://wordpress.org/support/plugin/wp-clone-by-wp-academy" target="_blank" title="Support Forum">Support forum at WordPress.org</a></li>
168
- </ul>
169
-
170
- </div>
171
- </div> <!--wrapper-->
172
- <p style="clear: both;" ></p>
173
- <?php
174
- if ( isset($_GET['mode']) && 'advanced' == $_GET['mode'] ) {
175
- global $wpdb;
176
- echo '<div class="info">';
177
- echo '<h3>System Info:</h3>';
178
- echo 'Memory limit: ' . ini_get('memory_limit') . '</br>';
179
- echo 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds</br>';
180
- echo 'PHP version : ' . phpversion() . '</br>';
181
- echo 'MySQL version : ' . $wpdb->db_version() . '</br>';
182
- if (ini_get('safe_mode')) { echo '<span style="color:#f11">PHP is running in safemode!</span></br>'; }
183
- echo '<h4>Directory list:</h4>';
184
- echo 'Uploads path : <pre>' . WPCLONE_DIR_UPLOADS . '</pre></br>';
185
- echo 'Plugin path : <pre>' . WPCLONE_DIR_PLUGIN . '</pre></br>';
186
- echo 'Plugin URL : <pre>' . WPCLONE_URL_PLUGIN . '</pre></br>';
187
- echo 'Backup path : <pre>' . WPCLONE_DIR_BACKUP . '</pre></br>';
188
- echo 'wp-content path : <pre>' . WPCLONE_WP_CONTENT . '</pre></br>';
189
- echo 'Site Root : <pre>' . WPCLONE_ROOT . '</pre></br>';
190
- echo 'ABSPATH : <pre>' . ABSPATH . '</pre></br>';
191
- if (!is_writable(WPCLONE_DIR_BACKUP)) { echo '<span style="color:#f11">Cannot write to the backup directory!</span></br>'; }
192
- if (!is_writable(WPCLONE_WP_CONTENT)) { echo '<span style="color:#f11">Cannot write to the root directory!</span></br>'; }
193
- echo '</div>';
194
- }
195
-
196
- function wpa_fetch_feed ($feed, $limit) {
197
- include_once(ABSPATH . WPINC . '/feed.php');
198
- $rss = fetch_feed($feed);
199
- if (!is_wp_error( $rss ) ) :
200
- $maxitems = $rss->get_item_quantity($limit);
201
- $rss_items = $rss->get_items(0, $maxitems);
202
- endif;
203
- if ( isset($maxitems) && $maxitems == 0 ) echo '<li>No items.</li>';
204
- else
205
- // Loop through each feed item and display each item as a hyperlink.
206
- foreach ( $rss_items as $item ) : ?>
207
- <li>
208
- <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
209
- title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
210
- <?php echo esc_html( $item->get_title() ); ?></a>
211
- </li>
212
- <?php endforeach;
213
- }
214
-
215
  /** it all ends here folks. */
1
+ <script type="text/javascript">
2
+ jQuery ( function($) {
3
+
4
+ ZeroClipboard.setDefaults( { moviePath: '<?php echo WPCLONE_URL_PLUGIN ?>lib/js/ZeroClipboard.swf' } );
5
+
6
+ /**workaround for firefox versions 18 and 19.
7
+ https://bugzilla.mozilla.org/show_bug.cgi?id=829557
8
+ https://github.com/jonrohan/ZeroClipboard/issues/73
9
+ */
10
+ var enableZC = true;
11
+ var is_firefox18 = navigator.userAgent.toLowerCase().indexOf('firefox/18') > -1;
12
+ var is_firefox19 = navigator.userAgent.toLowerCase().indexOf('firefox/19') > -1;
13
+ if (is_firefox18 || is_firefox19) enableZC = false;
14
+
15
+ if ( $( ".restore-backup-options" ).length ) {
16
+ $( ".restore-backup-options" ).each( function() {
17
+ var clip = new ZeroClipboard( $( "a.copy-button",this ) );
18
+ /** FF 18/19 users won't see an alert box. */
19
+ if (enableZC) {
20
+ clip.on( 'complete', function (client, args) {
21
+ alert( "Copied to clipboard:\n" + args.text );
22
+ });
23
+ }
24
+ });
25
+ } else {
26
+ var clip = new ZeroClipboard( $( "a.copy-button" ) );
27
+ /** FF 18/19 users won't see an alert box. */
28
+ if (enableZC) {
29
+ clip.on( 'complete', function (client, args) {
30
+ alert( "Copied to clipboard:\n" + args.text );
31
+ });
32
+ }
33
+ }
34
+ });
35
+
36
+ </script>
37
+
38
+ <?php
39
+ if (wpa_wpfs_init()) return;
40
+ global $wpdb;
41
+ $result = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wpclone ORDER BY id DESC", ARRAY_A);
42
+
43
+ ?>
44
+ <div id="wrapper">
45
+ <div id="MainView">
46
+
47
+ <h2>Welcome to WP Clone by WP Academy</h2>
48
+
49
+ <p>You can use this tool to create a backup of this site and (optionally) restore it to another server, or another WordPress installation on the same server.</p>
50
+
51
+ <p><strong>Here is how it works:</strong> the "Backup" function will give you a URL that you can then copy and paste
52
+ into the "Restore" dialog of a new WordPress site, which will clone the original site to the new site. You must
53
+ install the plugin on the new site and then run the WP Clone > Restore function.</p>
54
+
55
+ <p><strong>Choose your selection below:</strong> either create a backup of this site, or choose which backup you
56
+ would like to restore.</p>
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
79
+ }
80
+ ?>
81
+ <strong>Create Backup</strong>
82
+ <input id="createBackup" name="createBackup" type="radio" value="fullBackup" checked="checked"/><br/><br/>
83
+
84
+ <?php if (count($result) > 0) : ?>
85
+
86
+ <div class="try">
87
+
88
+ <?php foreach ($result AS $row) :
89
+
90
+ $filename = convertPathIntoUrl(WPCLONE_DIR_BACKUP . $row['backup_name']);
91
+ $url = wp_nonce_url( get_bloginfo('wpurl') . '/wp-admin/options-general.php?page=wp-clone&del=' . $row['id'], 'wpclone-submit');
92
+ ?>
93
+ <div class="restore-backup-options">
94
+ <strong>Restore backup </strong>
95
+
96
+ <input class="restoreBackup" name="restoreBackup" type="radio"
97
+ value="<?php echo $filename ?>" />&nbsp;
98
+
99
+ <a href="<?php echo $filename ?>" class="zclip">
100
+ (&nbsp;<?php echo bytesToSize($row['backup_size']);?>&nbsp;)&nbsp; <?php echo $row['backup_name'] ?>
101
+ </a>&nbsp;|&nbsp;
102
+
103
+ <input type="hidden" name="backup_name" value="<?php echo $filename ?>" />
104
+
105
+ <a class="copy-button" href="#" data-clipboard-text="<?php echo $filename ?>" >Copy URL</a> &nbsp;|&nbsp;
106
+ <a href="<?php echo $url; ?>">Delete</a>
107
+ </div>
108
+
109
+ <?php endforeach ?>
110
+
111
+ </div>
112
+
113
+ <?php endif ?>
114
+
115
+ <strong>Restore from URL:</strong><input id="backupUrl" name="backupUrl" type="radio" value="backupUrl"/>
116
+
117
+ <input type="text" name="restore_from_url" class="Url" value="" size="80px"/><br/><br/>
118
+
119
+ <div class="RestoreOptions" id="RestoreOptions">
120
+
121
+ <input type="checkbox" name="approve" id="approve" /> I AGREE (Required for "Restore" function):<br/>
122
+
123
+ 1. You have nothing of value in your current site <strong>[<?php echo site_url() ?>]</strong><br/>
124
+
125
+ 2. Your current site at <strong>[<?php echo site_url() ?>]</strong> may become unusable in case of failure,
126
+ and you will need to re-install WordPress<br/>
127
+
128
+ 3. Your WordPress database <strong>[<?php echo DB_NAME; ?>]</strong> will be overwritten from the database in the backup file. <br/>
129
+
130
+ </div>
131
+
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
+
144
+ <ul>
145
+ <h2>WP Academy Resources</h2>
146
+ <iframe src="//player.vimeo.com/video/98912458?title=0&amp;byline=0&amp;portrait=0" width="300" height="225" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
147
+ <li><a href="http://wpencyclopedia.com" target="_blank" title="WP Encyclopedia">WordPress Business Encyclopedia</a></li>
148
+ <li><a href="http://www.wpacademy.com/wordpress-training" target="_blank" title="WP Live">WP Live</a></li>
149
+ <li><a href="http://wpacademy.com/websites" target="_blank" title="WP Academy Websites">Websites</a></li>
150
+ <li><a href="http://www.wpacademy.com/hosting" target="_blank" title="Managed WordPress Hosting">Managed WordPress Hosting</a></li>
151
+ </ul>
152
+
153
+ <ul>
154
+ <h2>WP Academy News</h2>
155
+ <h3>WPAcademy.com</h3>
156
+ <?php wpa_fetch_feed ('http://members.wpacademy.com/category/news/feed', 3); ?>
157
+ <h3>Twitter @WPAcademy</h3>
158
+ <?php /* wpa_fetch_feed ('http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=wpacademy', 5); */ ?>
159
+ <a class="twitter-timeline" height="400" href="https://twitter.com/WPAcademy" data-widget-id="342116561412304898">Tweets by @WPAcademy</a>
160
+ <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>
161
+
162
+ </ul>
163
+
164
+ <ul>
165
+ <h2>Help & Support</h2>
166
+ <li><a href="http://members.wpacademy.com/wpclone-faq" target="_blank" title="WP Clone FAQ">Visit the WP Clone FAQ Page</a></li>
167
+ <li><a href="http://wordpress.org/support/plugin/wp-clone-by-wp-academy" target="_blank" title="Support Forum">Support forum at WordPress.org</a></li>
168
+ </ul>
169
+
170
+ </div>
171
+ </div> <!--wrapper-->
172
+ <p style="clear: both;" ></p>
173
+ <?php
174
+ if ( isset($_GET['mode']) && 'advanced' == $_GET['mode'] ) {
175
+ global $wpdb;
176
+ echo '<div class="info">';
177
+ echo '<h3>System Info:</h3>';
178
+ echo 'Memory limit: ' . ini_get('memory_limit') . '</br>';
179
+ echo 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds</br>';
180
+ echo 'PHP version : ' . phpversion() . '</br>';
181
+ echo 'MySQL version : ' . $wpdb->db_version() . '</br>';
182
+ if (ini_get('safe_mode')) { echo '<span style="color:#f11">PHP is running in safemode!</span></br>'; }
183
+ echo '<h4>Directory list:</h4>';
184
+ echo 'Uploads path : <pre>' . WPCLONE_DIR_UPLOADS . '</pre></br>';
185
+ echo 'Plugin path : <pre>' . WPCLONE_DIR_PLUGIN . '</pre></br>';
186
+ echo 'Plugin URL : <pre>' . WPCLONE_URL_PLUGIN . '</pre></br>';
187
+ echo 'Backup path : <pre>' . WPCLONE_DIR_BACKUP . '</pre></br>';
188
+ echo 'wp-content path : <pre>' . WPCLONE_WP_CONTENT . '</pre></br>';
189
+ echo 'Site Root : <pre>' . WPCLONE_ROOT . '</pre></br>';
190
+ echo 'ABSPATH : <pre>' . ABSPATH . '</pre></br>';
191
+ if (!is_writable(WPCLONE_DIR_BACKUP)) { echo '<span style="color:#f11">Cannot write to the backup directory!</span></br>'; }
192
+ if (!is_writable(WPCLONE_WP_CONTENT)) { echo '<span style="color:#f11">Cannot write to the root directory!</span></br>'; }
193
+ echo '</div>';
194
+ }
195
+
196
+ function wpa_fetch_feed ($feed, $limit) {
197
+ include_once(ABSPATH . WPINC . '/feed.php');
198
+ $rss = fetch_feed($feed);
199
+ if (!is_wp_error( $rss ) ) :
200
+ $maxitems = $rss->get_item_quantity($limit);
201
+ $rss_items = $rss->get_items(0, $maxitems);
202
+ endif;
203
+ if ( isset($maxitems) && $maxitems == 0 ) echo '<li>No items.</li>';
204
+ else
205
+ // Loop through each feed item and display each item as a hyperlink.
206
+ foreach ( $rss_items as $item ) : ?>
207
+ <li>
208
+ <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
209
+ title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
210
+ <?php echo esc_html( $item->get_title() ); ?></a>
211
+ </li>
212
+ <?php endforeach;
213
+ }
214
+
215
  /** 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: 4.2
9
- Stable tag: 2.1.8
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -66,6 +66,9 @@ released under the WTFPL http://sam.zoy.org/wtfpl/. Partial script with full cha
66
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
67
 
68
  == Changelog ==
 
 
 
69
  = 2.1.8 - 2014-09-18 =
70
  * Updated: Readme description.
71
  = 2.1.7 - 2014-07-30 =
5
  Author URI: http://wpacademy.com
6
  Plugin URI: http://wpacademy.com/software
7
  Requires at least: 3.0
8
+ Tested up to: 4.3
9
+ Stable tag: 2.1.9
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
66
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
67
 
68
  == Changelog ==
69
+ = 2.1.9 - 2015-11-10 =
70
+ * Disabled heartbeat on wpclone's admin page.
71
+ * DB_CHARSET in wp-config.php is used during direct database transactions.
72
  = 2.1.8 - 2014-09-18 =
73
  * Updated: Readme description.
74
  = 2.1.7 - 2014-07-30 =
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.8
8
  Author URI: http://wpacademy.com/
9
  */
10
 
@@ -50,6 +50,7 @@ function wpa_enqueue_scripts(){
50
  wp_enqueue_script('jquery-zclip');
51
  wp_enqueue_script('wpclone');
52
  wp_enqueue_style('wpclone');
 
53
  }
54
  if( isset($_GET['page']) && 'wp-clone' == $_GET['page'] ) add_action('admin_enqueue_scripts', 'wpa_enqueue_scripts');
55
 
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.9
8
  Author URI: http://wpacademy.com/
9
  */
10
 
50
  wp_enqueue_script('jquery-zclip');
51
  wp_enqueue_script('wpclone');
52
  wp_enqueue_style('wpclone');
53
+ wp_deregister_script('heartbeat');
54
  }
55
  if( isset($_GET['page']) && 'wp-clone' == $_GET['page'] ) add_action('admin_enqueue_scripts', 'wpa_enqueue_scripts');
56