WP Clone by WP Academy - Version 2.2.3

Version Description

  • 2016-11-29 =
  • Added: PHP7 support
  • Added: a multisite check during restore.
  • Fixed: failed backups due to unreadable files.
Download this release

Release Info

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

Code changes from version 2.2.2 to 2.2.3

Files changed (5) hide show
  1. lib/class.wpc-wpdb.php +145 -0
  2. lib/functions.php +77 -72
  3. lib/icit_srdb_replacer.php +14 -14
  4. readme.txt +7 -2
  5. wpclone.php +13 -2
lib/class.wpc-wpdb.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author Andy Camm
4
+ */
5
+
6
+ // Subclass wpdb to ensure compatibility with WordPress and to use
7
+ // the appropriate MySQL module (uses MySQLi on PHP >= 5.5)
8
+ // and provide access to the additional raw MySQL/MySQLi module calls
9
+ // that we are using
10
+ class wpc_wpdb extends wpdb
11
+ {
12
+
13
+ // This is copied from the base class as its use_mysqli member is private
14
+ protected $use_mysqli = false;
15
+
16
+ public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
17
+ parent::__construct($dbuser, $dbpassword, $dbname, $dbhost);
18
+
19
+ // This is copied from the base class as its use_mysqli member is private
20
+ // Use ext/mysqli if it exists and:
21
+ // - WP_USE_EXT_MYSQL is defined as false, or
22
+ // - We are a development version of WordPress, or
23
+ // - We are running PHP 5.5 or greater, or
24
+ // - ext/mysql is not loaded.
25
+ //
26
+ if ( function_exists( 'mysqli_connect' ) ) {
27
+ if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
28
+ $this->use_mysqli = ! WP_USE_EXT_MYSQL;
29
+ } elseif ( version_compare( phpversion(), '5.5', '>=' ) || ! function_exists( 'mysql_connect' ) ) {
30
+ $this->use_mysqli = true;
31
+ } elseif ( false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
32
+ $this->use_mysqli = true;
33
+ }
34
+ }
35
+ }
36
+
37
+ public function get_dbh()
38
+ {
39
+ return $this->dbh;
40
+ }
41
+
42
+ public function query($querystring)
43
+ {
44
+ if ($this->use_mysqli)
45
+ {
46
+ return $this->get_dbh()->query($querystring);
47
+ }
48
+ else
49
+ {
50
+ return mysql_query($querystring, $this->get_dbh());
51
+ }
52
+ }
53
+
54
+ public function ping()
55
+ {
56
+ if ($this->use_mysqli)
57
+ {
58
+ return $this->get_dbh()->ping();
59
+ }
60
+ else
61
+ {
62
+ return mysql_ping($this->get_dbh());
63
+ }
64
+ }
65
+
66
+
67
+ public function close()
68
+ {
69
+ if ($this->use_mysqli)
70
+ {
71
+ $this->get_dbh()->close();
72
+ }
73
+ else{
74
+ return mysql_close($this->get_dbh());
75
+ }
76
+ }
77
+
78
+ public function error()
79
+ {
80
+ if ($this->use_mysqli)
81
+ {
82
+ return $this->get_dbh()->error;
83
+ }
84
+ else
85
+ {
86
+ return mysql_error($this->get_dbh());
87
+ }
88
+ }
89
+
90
+ public function errno()
91
+ {
92
+ if ($this->use_mysqli)
93
+ {
94
+ return $this->get_dbh()->errno;
95
+ }
96
+ else
97
+ {
98
+ return mysql_errno($this->get_dbh());
99
+ }
100
+ }
101
+
102
+
103
+ public function real_escape_string($str)
104
+ {
105
+ return $this->_escape($str);
106
+ }
107
+
108
+ public function num_fields( $result)
109
+ {
110
+ if ($this->use_mysqli)
111
+ {
112
+ return $result->field_count;
113
+ }
114
+ else
115
+ {
116
+ return mysql_num_fields($result);
117
+ }
118
+ }
119
+
120
+ public function fetch_array($result)
121
+ {
122
+ if ($this->use_mysqli)
123
+ {
124
+ return $result->fetch_array();
125
+
126
+ }
127
+ else {
128
+ return mysql_fetch_array($result);
129
+ }
130
+ }
131
+
132
+ // Fetch a row from a query result
133
+ public function fetch_row( $result)
134
+ {
135
+ if ($this->use_mysqli)
136
+ {
137
+ return $result->fetch_row();
138
+ }
139
+ else
140
+ {
141
+ return mysql_fetch_row($result);
142
+ }
143
+ }
144
+
145
+ }
lib/functions.php CHANGED
@@ -40,9 +40,15 @@ function wpa_db_backup_wpdb($destination)
40
 
41
  // First part of the output � remove the table
42
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
43
- $numberOfFields = count($result[0]);
44
  $numberOfItems = count($result);
45
-
 
 
 
 
 
 
 
46
  // Second part of the output � create table
47
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
48
  $return.= 'DROP TABLE IF EXISTS '.$table.';';
@@ -55,7 +61,11 @@ function wpa_db_backup_wpdb($destination)
55
  $query = "INSERT INTO {$table} VALUES(";
56
 
57
  for ($j = 0; $j < $numberOfFields; $j++) {
58
- $query .= (empty($row[$j])) ? '"", ' : '"' . mysql_real_escape_string($row[$j]) . '", ';
 
 
 
 
59
  }
60
 
61
  $return .= substr($query, 0, -2) . ");\n";
@@ -85,28 +95,27 @@ function wpa_db_backup_direct($destination)
85
 
86
  global $wpdb;
87
  $prefix = $wpdb->prefix;
88
- $link = wpa_wpc_mysql_connect();
89
- if ( false === $link ) {
90
- wpa_backup_error('db', mysql_error() );
91
  }
92
 
93
  $tables = array();
94
 
95
  if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
96
  wpa_wpc_log( 'ignore prefix enabled, backing up all the tables' );
97
- $result = mysql_query('SHOW TABLES');
98
 
99
  } else {
100
  wpa_wpc_log( sprintf( 'backing up tables with "%s" prefix', $prefix ) );
101
- $result = mysql_query('SHOW TABLES LIKE "' . $prefix . '%"');
102
-
103
  }
104
 
105
  if ( false === $result ) {
106
- wpa_backup_error('db', mysql_error() );
107
  }
108
 
109
- while( $row = mysql_fetch_row( $result ) ) {
110
  $tables[] = $row[0];
111
  }
112
 
@@ -115,32 +124,31 @@ function wpa_db_backup_direct($destination)
115
 
116
  foreach($tables as $table)
117
  {
 
 
 
 
 
118
 
119
- $result = mysql_query( 'SELECT * FROM ' . $table, $link );
120
- if ( false === $result ) {
121
- wpa_backup_error('db', mysql_error() );
122
- }
123
- $num_fields = mysql_num_fields($result);
124
-
125
- $return.= 'DROP TABLE IF EXISTS '.$table.';';
126
- $row2 = mysql_fetch_row( mysql_query( 'SHOW CREATE TABLE ' . $table, $link ) );
127
- $return.= "\n\n".$row2[1].";\n\n";
128
 
129
- for ($i = 0; $i < $num_fields; $i++)
 
 
130
  {
131
- while($row = mysql_fetch_row($result))
132
- {
133
- $return.= 'INSERT INTO '.$table.' VALUES(';
134
- for($j=0; $j<$num_fields; $j++)
135
- {
136
- $row[$j] = mysql_real_escape_string( $row[$j] );
137
- if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
138
- if ($j<($num_fields-1)) { $return.= ','; }
139
- }
140
- $return.= ");\n";
141
- }
142
  }
143
- $return.="\n\n\n";
 
144
 
145
  }
146
  //save file
@@ -226,7 +234,7 @@ function CreateWPFullBackupZip($backupName, $zipmode, $use_wpdb = false )
226
  }
227
  wpa_wpc_log ( 'database backup finished' );
228
 
229
- /* error haldler is called from within the wpa_zip function */
230
 
231
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
232
 
@@ -309,21 +317,12 @@ function wpa_wpc_get_url( $db ) {
309
 
310
  }
311
 
312
- function wpa_wpc_mysql_connect() {
313
-
314
- $link = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD );
315
-
316
- if ( false === $link ) {
317
- mysql_close( $link );
318
- sleep(2);
319
- $link = mysql_connect( DB_HOST, DB_USER, DB_PASSWORD, true );
320
- }
321
-
322
- mysql_select_db( DB_NAME, $link );
323
- mysql_set_charset( DB_CHARSET, $link );
324
-
325
- return $link;
326
 
 
 
 
 
 
327
  }
328
 
329
  /**
@@ -338,38 +337,36 @@ function wpa_safe_replace_wrapper ( $search, $replace, $prefix ) {
338
 
339
  wpa_wpc_log( 'search and replace started' );
340
 
341
- $connection = wpa_wpc_mysql_connect();
342
-
343
-
344
- if ( false === $connection ) {
345
 
346
- wpa_wpc_log( 'mysql connection failure @ safe replace wrapper - error : "' . mysql_error( $connection ) . '" retrying..' );
347
 
348
- mysql_close( $connection );
349
  sleep(1);
350
- $connection = wpa_wpc_mysql_connect();
351
-
352
  }
353
 
354
  $all_tables = array();
355
 
356
  if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
357
  wpa_wpc_log( 'ignore table prefix enabled, search and replace will scan all the tables in the database' );
358
- $all_tables_mysql = @mysql_query( 'SHOW TABLES', $connection );
359
 
360
  } else {
361
- $all_tables_mysql = @mysql_query( 'SHOW TABLES LIKE "' . $prefix . '%"', $connection );
362
-
363
  }
364
 
365
- while ( $table = mysql_fetch_array( $all_tables_mysql ) ) {
366
  $all_tables[] = $table[ 0 ];
367
  }
368
 
369
  wpa_wpc_log( sprintf( 'there are %d tables to scan', count( $all_tables ) ) );
370
 
371
- $report = icit_srdb_replacer( $connection, $search, $replace, $all_tables );
372
- mysql_close( $connection );
373
  wpa_wpc_log( 'search and replace finished' );
374
  return $report;
375
  }
@@ -393,6 +390,9 @@ function wpa_wpc_temp_dir() {
393
  }
394
 
395
  function processRestoringBackup($url, $zipmode) {
 
 
 
396
  wpa_cleanup( true );
397
  if (!is_string($url) || '' == $url) {
398
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
@@ -1103,6 +1103,14 @@ function wpa_wpc_get_filelist( $path, $exclude, $skip = false ) {
1103
  continue;
1104
  }
1105
 
 
 
 
 
 
 
 
 
1106
  if( ! empty( $exclude ) && wpa_wpc_strpos_array( $exclude, $file ) ) {
1107
  $skipped++;
1108
  wpa_wpc_log( sprintf( 'file is inside an excluded directory, and it will not be included in the backup - "%s"',
@@ -1249,7 +1257,7 @@ function wpa_wpc_process_db( $zipfile, $zipmode = false ) {
1249
  $cur_url = untrailingslashit( site_url() );
1250
  $found = false;
1251
  $db = explode( ";\n", $files['database'] );
1252
- $link = wpa_wpc_mysql_connect();
1253
 
1254
  wpa_wpc_log( 'database import started' );
1255
  foreach( $db as $query ) {
@@ -1265,19 +1273,16 @@ function wpa_wpc_process_db( $zipfile, $zipmode = false ) {
1265
  }
1266
 
1267
  if( isset( $_POST['mysql_check'] ) && 'true' === $_POST['mysql_check'] ) {
1268
- if( ! mysql_ping( $link ) ) {
1269
- mysql_close( $link );
1270
- $link = wpa_wpc_mysql_connect();
1271
-
1272
  }
1273
-
1274
  }
1275
 
1276
- $status = mysql_query( $query, $link );
1277
-
1278
  if( false === $status ) {
1279
- wpa_wpc_log( sprintf( 'mysql query failed. error : %d %s - query : "%s"', mysql_errno(), mysql_error(), ltrim( $query ) ) );
1280
-
1281
  }
1282
 
1283
  }
40
 
41
  // First part of the output � remove the table
42
  $result = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_N);
 
43
  $numberOfItems = count($result);
44
+ if ($numberOfItems == 0) {
45
+ // Empty table - don't attempt to use $result[0] as it doesn't exist
46
+ $numberOfFields = 0;
47
+ }
48
+ else {
49
+ $numberOfFields = count($result[0]);
50
+ }
51
+
52
  // Second part of the output � create table
53
  $row2 = $wpdb->get_row("SHOW CREATE TABLE {$table}", ARRAY_N);
54
  $return.= 'DROP TABLE IF EXISTS '.$table.';';
61
  $query = "INSERT INTO {$table} VALUES(";
62
 
63
  for ($j = 0; $j < $numberOfFields; $j++) {
64
+ // Change to 'isset()' instead of 'empty()' as 'empty()' returns true for the
65
+ // string "0" - but we may need to explicitly set value to 0 for fields where this
66
+ // is not the default. This makes the output of this method identical to the
67
+ // wpa_db_backup_direct() method
68
+ $query .= (!isset($row[$j])) ? '"", ' : '"' . esc_sql($row[$j]) . '", ';
69
  }
70
 
71
  $return .= substr($query, 0, -2) . ");\n";
95
 
96
  global $wpdb;
97
  $prefix = $wpdb->prefix;
98
+ $wpcdb = wpa_wpc_mysql_connect();
99
+ if ( false === $wpcdb->get_dbh() ) {
100
+ wpa_backup_error('db', $wpcdb->error() );
101
  }
102
 
103
  $tables = array();
104
 
105
  if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
106
  wpa_wpc_log( 'ignore prefix enabled, backing up all the tables' );
107
+ $result = $wpcbd->query('SHOW TABLES');
108
 
109
  } else {
110
  wpa_wpc_log( sprintf( 'backing up tables with "%s" prefix', $prefix ) );
111
+ $result = $wpcdb->query('SHOW TABLES LIKE "' . $prefix . '%"');
 
112
  }
113
 
114
  if ( false === $result ) {
115
+ wpa_backup_error('db', $wpcdb->error() );
116
  }
117
 
118
+ while( $row = $wpcdb->fetch_row( $result ) ) {
119
  $tables[] = $row[0];
120
  }
121
 
124
 
125
  foreach($tables as $table)
126
  {
127
+ $result = $wpcdb->query( 'SELECT * FROM ' . $table );
128
+ if ( false === $result ) {
129
+ wpa_backup_error('db', $wpcdb->error() );
130
+ }
131
+ $num_fields = $wpcdb->num_fields($result);
132
 
133
+ $return.= 'DROP TABLE IF EXISTS '.$table.';';
134
+ $row2 = $wpcdb->fetch_row( $wpcdb->query( 'SHOW CREATE TABLE ' . $table ) );
135
+ $return.= "\n\n".$row2[1].";\n\n";
 
 
 
 
 
 
136
 
137
+ for ($i = 0; $i < $num_fields; $i++)
138
+ {
139
+ while($row = $wpcdb->fetch_row($result))
140
  {
141
+ $return.= 'INSERT INTO '.$table.' VALUES(';
142
+ for($j=0; $j<$num_fields; $j++)
143
+ {
144
+ $row[$j] = $wpcdb->real_escape_string( $row[$j] );
145
+ if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
146
+ if ($j<($num_fields-1)) { $return.= ', '; } // Add extra space to match wpdb backup method
147
+ }
148
+ $return.= ");\n";
 
 
 
149
  }
150
+ }
151
+ $return.="\n";
152
 
153
  }
154
  //save file
234
  }
235
  wpa_wpc_log ( 'database backup finished' );
236
 
237
+ /* error handler is called from within the wpa_zip function */
238
 
239
  wpa_zip($zipFileName, $folderToBeZipped, $zipmode);
240
 
317
 
318
  }
319
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
+ function wpa_wpc_mysql_connect() {
322
+ // Use subclass of wpdb to ensure compatibility with WordPress database and use the appropriate MySQL module
323
+ // and provide the extra functions we need
324
+ $db = new wpc_wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
325
+ return $db;
326
  }
327
 
328
  /**
337
 
338
  wpa_wpc_log( 'search and replace started' );
339
 
340
+ $wpcdb = wpa_wpc_mysql_connect();
341
+
342
+ if ( false === $wpcdb->get_dbh() ) {
 
343
 
344
+ wpa_wpc_log( 'mysql connection failure @ safe replace wrapper - error : "' . $wpdbc->error() . '" retrying..' );
345
 
346
+ $wpcdb->close();
347
  sleep(1);
348
+ // Try to create a new connection
349
+ $wpcdb = wpa_wpc_mysql_connect();
350
  }
351
 
352
  $all_tables = array();
353
 
354
  if( isset( $_POST['ignore_prefix'] ) && 'true' === $_POST['ignore_prefix'] ) {
355
  wpa_wpc_log( 'ignore table prefix enabled, search and replace will scan all the tables in the database' );
356
+ $all_tables_mysql = @$wpcdb->query( 'SHOW TABLES' );
357
 
358
  } else {
359
+ $all_tables_mysql = @$wpcdb->query( 'SHOW TABLES LIKE "' . $prefix . '%"' );
 
360
  }
361
 
362
+ while ( $table = $wpcdb->fetch_array( $all_tables_mysql ) ) {
363
  $all_tables[] = $table[ 0 ];
364
  }
365
 
366
  wpa_wpc_log( sprintf( 'there are %d tables to scan', count( $all_tables ) ) );
367
 
368
+ $report = icit_srdb_replacer( $wpcdb, $search, $replace, $all_tables );
369
+ $wpcdb->close( );
370
  wpa_wpc_log( 'search and replace finished' );
371
  return $report;
372
  }
390
  }
391
 
392
  function processRestoringBackup($url, $zipmode) {
393
+ if( true === is_multisite() )
394
+ die( 'wpclone does not work on multisite installs.' );
395
+
396
  wpa_cleanup( true );
397
  if (!is_string($url) || '' == $url) {
398
  wpa_backup_error( 'restore', sprintf( __( 'The provided URL "<code>%s</code>" is either not valid or empty' ), $url ), true );
1103
  continue;
1104
  }
1105
 
1106
+ if( ! $info->isReadable() ) {
1107
+ $skipped++;
1108
+ wpa_wpc_log( sprintf( 'file skipped, file is not readable - "%s"',
1109
+ str_replace( WPCLONE_ROOT, '**SITE-ROOT**/', $file ) ) );
1110
+ continue;
1111
+
1112
+ }
1113
+
1114
  if( ! empty( $exclude ) && wpa_wpc_strpos_array( $exclude, $file ) ) {
1115
  $skipped++;
1116
  wpa_wpc_log( sprintf( 'file is inside an excluded directory, and it will not be included in the backup - "%s"',
1257
  $cur_url = untrailingslashit( site_url() );
1258
  $found = false;
1259
  $db = explode( ";\n", $files['database'] );
1260
+ $wpcdb = wpa_wpc_mysql_connect();
1261
 
1262
  wpa_wpc_log( 'database import started' );
1263
  foreach( $db as $query ) {
1273
  }
1274
 
1275
  if( isset( $_POST['mysql_check'] ) && 'true' === $_POST['mysql_check'] ) {
1276
+ if( ! $wpcdb->ping() ) {
1277
+ $wpcdb->close();
1278
+ $wpcdb = wpa_wpc_mysql_connect();
 
1279
  }
 
1280
  }
1281
 
1282
+ $status = $wpcdb->query( $query );
1283
+
1284
  if( false === $status ) {
1285
+ wpa_wpc_log( sprintf( 'mysql query failed. error : %d %s - query : "%s"', $wpcdb->errno(), $wpcdb->error(), ltrim( $query ) ) );
 
1286
  }
1287
 
1288
  }
lib/icit_srdb_replacer.php CHANGED
@@ -51,16 +51,16 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria
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,
@@ -77,13 +77,13 @@ function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables =
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;
@@ -97,12 +97,12 @@ function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables =
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++;
@@ -123,19 +123,19 @@ function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables =
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
 
51
  * We split large tables into 50,000 row blocks when dealing with them to save
52
  * on memmory consumption.
53
  *
54
+ * @param wpc_wpdb $wpcdb The db wrapper 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( $wpcdb, $search = '', $replace = '', $tables = array( ) ) {
62
  global $guid, $exclude_cols;
63
+
64
  $report = array( 'tables' => 0,
65
  'rows' => 0,
66
  'change' => 0,
77
  $columns = array( );
78
 
79
  // Get a list of columns in this table
80
+ $fields = $wpcdb->query( 'DESCRIBE ' . $table );
81
+ while( $column = $wpcdb->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 = $wpcdb->query( 'SELECT COUNT(*) FROM ' . $table );
86
+ $rows_result = $wpcdb->fetch_array( $row_count );
87
  $row_count = $rows_result[ 0 ];
88
  if ( $row_count == 0 )
89
  continue;
97
  $start = $page * $page_size;
98
  $end = $start + $page_size;
99
  // Grab the content of the table
100
+ $data = $wpcdb->query( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ) );
101
 
102
  if ( ! $data )
103
+ $report[ 'errors' ][] = $wpcdb->error();
104
 
105
+ while ( $row = $wpcdb->fetch_array( $data ) ) {
106
 
107
  $report[ 'rows' ]++; // Increment the row counter
108
  $current_row++;
123
  // Something was changed
124
  if ( $edited_data != $data_to_fix ) {
125
  $report[ 'change' ]++;
126
+ $update_sql[] = $column . ' = "' . $wpcdb->real_escape_string( $edited_data ) . '"';
127
  $upd = true;
128
  }
129
 
130
  if ( $primary_key )
131
+ $where_sql[] = $column . ' = "' . $wpcdb->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 = $wpcdb->query( $sql );
137
  if ( ! $result )
138
+ $report[ 'errors' ][] = $wpcdb->error( );
139
  else
140
  $report[ 'updates' ]++;
141
 
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.4
9
- Stable tag: 2.2.2
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -69,6 +69,11 @@ If you are able to help out with plugin development or wish to contribute insigh
69
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
70
 
71
  == Changelog ==
 
 
 
 
 
72
  = 2.2.2 - 2015-12-30 =
73
  * Fixed: A bug introduced in 2.2.1 which caused the file archiver to use the wrong zip library on installations where ziparchive is disabled.
74
 
5
  Author URI: http://wpacademy.com
6
  Plugin URI: http://wpacademy.com/software
7
  Requires at least: 3.0
8
+ Tested up to: 4.6
9
+ Stable tag: 2.2.3
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
69
  Review FAQ's and Help Video at the [WP Clone FAQ Page](http://members.wpacademy.com/wpclone-faq "WP Clone FAQ")
70
 
71
  == Changelog ==
72
+ = 2.2.3 - 2016-11-29 =
73
+ * Added: PHP7 support
74
+ * Added: a multisite check during restore.
75
+ * Fixed: failed backups due to unreadable files.
76
+
77
  = 2.2.2 - 2015-12-30 =
78
  * Fixed: A bug introduced in 2.2.1 which caused the file archiver to use the wrong zip library on installations where ziparchive is disabled.
79
 
wpclone.php CHANGED
@@ -4,11 +4,12 @@ Plugin name: WP Clone by WP Academy
4
  Plugin URI: http://wpacademy.com/software/
5
  Description: Move or copy a WordPress site to another server or to another domain name, move to/from local server hosting, and backup sites.
6
  Author: WP Academy
7
- Version: 2.2.2
8
  Author URI: http://wpacademy.com/
9
  */
10
 
11
  include_once 'lib/functions.php';
 
12
 
13
  $upload_dir = wp_upload_dir();
14
 
@@ -222,4 +223,14 @@ function wpa_wpc_msnotice() {
222
  }
223
 
224
  if ( is_multisite() )
225
- add_action( 'admin_notices', 'wpa_wpc_msnotice');
 
 
 
 
 
 
 
 
 
 
4
  Plugin URI: http://wpacademy.com/software/
5
  Description: Move or copy a WordPress site to another server or to another domain name, move to/from local server hosting, and backup sites.
6
  Author: WP Academy
7
+ Version: 2.2.3
8
  Author URI: http://wpacademy.com/
9
  */
10
 
11
  include_once 'lib/functions.php';
12
+ include_once 'lib/class.wpc-wpdb.php';
13
 
14
  $upload_dir = wp_upload_dir();
15
 
223
  }
224
 
225
  if ( is_multisite() )
226
+ add_action( 'admin_notices', 'wpa_wpc_msnotice');
227
+
228
+ function wpa_wpc_phpnotice() {
229
+ echo '<div class="error">';
230
+ echo '<h4>WP Clone Notice.</h4>';
231
+ printf( '<p>WP Clone is not compatible with PHP %s, please upgrade to PHP 5.3 or newer.</p></div>', phpversion() );
232
+ }
233
+
234
+ if( version_compare( phpversion(), '5.3', '<' ) ){
235
+ add_action( 'admin_notices', 'wpa_wpc_phpnotice');
236
+ }