WP Migrate DB - Version 0.4

Version Description

Runs export over 4x faster and adds some nice new features often requested. Upgrade recommended.

Download this release

Release Info

Developer bradt
Plugin Icon 128x128 WP Migrate DB
Version 0.4
Comparing to
See all releases

Code changes from version 0.3 to 0.4

Files changed (5) hide show
  1. installer.php +240 -0
  2. readme.txt +17 -4
  3. script.js +27 -0
  4. styles.css +38 -0
  5. wp-migrate-db.php +172 -61
installer.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ WP App Store Installer for Product Integration
4
+ http://wpappstore.com/
5
+ Version: 0.2
6
+
7
+ The following code is intended for developers to include
8
+ in their themes/plugins to help distribute the WP App Store plugin.
9
+
10
+ License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
11
+ */
12
+
13
+ if ( !class_exists( 'WP_App_Store_Installer' ) ) :
14
+
15
+ class WP_App_Store_Installer {
16
+ public $api_url = 'https://wpappstore.com/api/client';
17
+ public $cdn_url = 'http://cdn.wpappstore.com';
18
+
19
+ public $slug = 'wp-app-store';
20
+
21
+ public $run_installer = null;
22
+
23
+ public $affiliate_id = '2421';
24
+
25
+ public $output = array(
26
+ 'head' => '',
27
+ 'body' => ''
28
+ );
29
+
30
+ function __construct() {
31
+ // Stop if the user doesn't have access to install themes
32
+ if ( !current_user_can( 'install_plugins' ) ) {
33
+ return;
34
+ }
35
+
36
+ // Stop if user has chosen to hide this already
37
+ $user = wp_get_current_user();
38
+ if ( get_user_meta( $user->ID, 'wpas_installer_hide' ) ) {
39
+ return;
40
+ }
41
+
42
+ if ( defined( 'WPAS_API_URL' ) ) {
43
+ $this->api_url = WPAS_API_URL;
44
+ }
45
+
46
+ add_action( 'admin_init', array( $this, 'handle_request' ) );
47
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
48
+
49
+ // Plugin upgrade hooks
50
+ add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 );
51
+ }
52
+
53
+ function get_menu() {
54
+ $menu = get_site_transient( 'wpas_menu' );
55
+ if ( $menu ) return $menu;
56
+
57
+ // Let's refresh the menu
58
+ $url = $this->cdn_url . '/client/menu.json';
59
+ $data = wp_remote_get( $url );
60
+
61
+ if ( !is_wp_error( $data ) && 200 == $data['response']['code'] ) {
62
+ $menu = json_decode( $data['body'], true );
63
+ }
64
+
65
+ // Try retrieve a backup from the last refresh time
66
+ if ( !$menu ) {
67
+ $menu = get_site_transient( 'wpas_menu_backup' );
68
+ }
69
+
70
+ // Not even a backup? Yikes, let's use the hardcoded menu
71
+ if ( !$menu ) {
72
+ $menu = array(
73
+ 'slug' => 'wp-app-store',
74
+ 'title' => 'WP App Store',
75
+ 'subtitle' => 'Home',
76
+ 'position' => 999,
77
+ 'submenu' => array(
78
+ 'wp-app-store-themes' => 'Themes',
79
+ 'wp-app-store-plugins' => 'Plugins'
80
+ )
81
+ );
82
+ }
83
+
84
+ set_site_transient( 'wpas_menu', $menu, 60*60*24 );
85
+ set_site_transient( 'wpas_menu_backup', $menu );
86
+
87
+ return $menu;
88
+ }
89
+
90
+ function admin_menu() {
91
+ // Stop if the WP App Store plugin is already installed and activated
92
+ if ( class_exists( 'WP_App_Store' ) ) {
93
+ return;
94
+ }
95
+
96
+ // Stop if the WP App Store plugin is already installed, but not activated
97
+ $plugins = array_keys( get_plugins() );
98
+ foreach ( $plugins as $plugin ) {
99
+ if ( strpos( $plugin, 'wp-app-store.php' ) !== false ) {
100
+ return;
101
+ }
102
+ }
103
+
104
+ $menu = $this->get_menu();
105
+
106
+ add_menu_page( $menu['title'], $menu['title'], 'install_themes', $this->slug, array( $this, 'render_page' ), null, $menu['position'] );
107
+
108
+ add_action( 'admin_print_styles', array( $this, 'enqueue_styles' ) );
109
+ add_action( 'admin_head', array( $this, 'admin_head' ) );
110
+ }
111
+
112
+ function enqueue_styles() {
113
+ wp_enqueue_style( $this->slug . '-global', $this->cdn_url . '/asset/css/client-global.css' );
114
+ }
115
+
116
+ function get_install_url() {
117
+ return 'update.php?action=install-plugin&plugin=wp-app-store&_wpnonce=' . urlencode( wp_create_nonce( 'install-plugin_wp-app-store' ) );
118
+ }
119
+
120
+ function current_url() {
121
+ $ssl = ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == 'on' ) ? 's' : '';
122
+ $port = ( $_SERVER['SERVER_PORT'] != '80' ) ? ':' . $_SERVER['SERVER_PORT'] : '';
123
+ return sprintf( 'http%s://%s%s%s', $ssl, $_SERVER['SERVER_NAME'], $port, $_SERVER['REQUEST_URI'] );
124
+ }
125
+
126
+ function handle_request() {
127
+ if ( !isset( $_GET['page'] ) || !preg_match( '@^' . $this->slug . '@', $_GET['page'] ) ) {
128
+ return;
129
+ }
130
+
131
+ if ( isset( $_GET['wpas-hide'] ) ) {
132
+ $user = wp_get_current_user();
133
+ update_user_meta( $user->ID, 'wpas_installer_hide', '1' );
134
+ wp_redirect( 'index.php' );
135
+ exit;
136
+ }
137
+
138
+ $url = $this->api_url . '/installer-splash/?wpas-install-url=' . urlencode( $this->get_install_url() );
139
+
140
+ $args = array(
141
+ 'sslverify' => false,
142
+ 'timeout' => 30,
143
+ 'headers' => array(
144
+ 'Referer' => $this->current_url(),
145
+ 'User-Agent' => 'PHP/' . PHP_VERSION . ' WordPress/' . get_bloginfo( 'version' )
146
+ )
147
+ );
148
+
149
+ $remote = wp_remote_get( $url, $args );
150
+
151
+ //print_r($remote);
152
+
153
+ if ( is_wp_error( $remote ) || 200 != $remote['response']['code'] || !( $data = json_decode( $remote['body'], true ) ) ) {
154
+ $this->output['body'] .= $this->get_communication_error();
155
+ }
156
+
157
+ $this->output['body'] .= $data['body'];
158
+
159
+ $this->output['head'] .= "
160
+ <script>
161
+ WPAPPSTORE = {};
162
+ WPAPPSTORE.INSTALL_URL = '" . addslashes( $this->get_install_url() ) . "';
163
+ </script>
164
+ ";
165
+
166
+ if ( isset( $data['head'] ) ) {
167
+ $this->output['head'] .= $data['head'];
168
+ }
169
+ }
170
+
171
+ function get_communication_error() {
172
+ ob_start();
173
+ ?>
174
+ <div class="wrap">
175
+ <h2>Communication Error</h2>
176
+ <p><?php _e( 'Sorry, we could not reach the WP App Store to setup the auto installer. Please try again later.' ); ?></p>
177
+ <p><?php _e( 'In the meantime, you can check out the WP App Store at <a href="http://wpappstore.com/">http://wpappstore.com/</a>.' ); ?></p>
178
+ </div>
179
+ <?php
180
+ return ob_get_clean();
181
+ }
182
+
183
+ function admin_head() {
184
+ if ( !isset( $this->output['head'] ) ) return;
185
+ echo $this->output['head'];
186
+ }
187
+
188
+ function render_page() {
189
+ echo $this->output['body'];
190
+ }
191
+
192
+ function get_client_upgrade_data() {
193
+ $info = get_site_transient( 'wpas_client_upgrade' );
194
+ if ( $info ) return $info;
195
+
196
+ $url = $this->cdn_url . '/client/upgrade.json';
197
+ $data = wp_remote_get( $url, array( 'timeout' => 30 ) );
198
+
199
+ if ( !is_wp_error( $data ) && 200 == $data['response']['code'] ) {
200
+ if ( $info = json_decode( $data['body'], true ) ) {
201
+ set_site_transient( 'wpas_client_upgrade', $info, 60*60*24 );
202
+ return $info;
203
+ }
204
+ }
205
+
206
+ return false;
207
+ }
208
+
209
+ function plugins_api( $api, $action, $args ) {
210
+ if (
211
+ 'plugin_information' != $action || false !== $api
212
+ || !isset( $args->slug ) || 'wp-app-store' != $args->slug
213
+ ) return $api;
214
+
215
+ $upgrade = $this->get_client_upgrade_data();
216
+ $menu = $this->get_menu();
217
+
218
+ if ( !$upgrade ) return $api;
219
+
220
+ // Add affiliate ID to WP settings if it's not already set by another
221
+ // theme or plugin
222
+ if ( $this->affiliate_id && !get_site_transient( 'wpas_affiliate_id' ) ) {
223
+ set_site_transient( 'wpas_affiliate_id', $this->affiliate_id );
224
+ }
225
+
226
+ $api = new stdClass();
227
+ $api->name = $menu['title'];
228
+ $api->version = $upgrade['version'];
229
+ $api->download_link = $upgrade['download_url'];
230
+ return $api;
231
+ }
232
+ }
233
+
234
+ function wp_app_store_installer_init() {
235
+ new WP_App_Store_Installer();
236
+ }
237
+
238
+ add_action( 'init', 'wp_app_store_installer_init' );
239
+
240
+ endif;
readme.txt CHANGED
@@ -3,8 +3,9 @@ Contributors: bradt
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  Tags: database, migrate, backup, mysql
5
  Requires at least: 2.0.3
6
- Tested up to: 3.3
7
- Stable tag: 0.3
 
8
 
9
  Exports your database, does a find and replace on URLs and file paths, then allows you to save it to your computer.
10
 
@@ -28,6 +29,16 @@ Example: <code>s:5:"hello"</code> becomes <code>s:11:"hello world"</code>
28
 
29
  == Changelog ==
30
 
 
 
 
 
 
 
 
 
 
 
31
  = 0.3 - 2011-12-16 =
32
  * Bug fix: [Null formatting error](http://plugins.trac.wordpress.org/ticket/1430)
33
  * Bug fix: [Deprecated capability](http://plugins.trac.wordpress.org/ticket/1431)
@@ -48,6 +59,8 @@ Example: <code>s:5:"hello"</code> becomes <code>s:11:"hello world"</code>
48
 
49
  == Upgrade Notice ==
50
 
51
- = 0.2.2 =
 
52
 
53
- This version fixes a bug that breaks the WordPress core export feature. It is highly recommended that everyone upgrade.
 
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
4
  Tags: database, migrate, backup, mysql
5
  Requires at least: 2.0.3
6
+ Tested up to: 3.4.1
7
+ Stable tag: 0.4
8
+ License: GPLv2
9
 
10
  Exports your database, does a find and replace on URLs and file paths, then allows you to save it to your computer.
11
 
29
 
30
  == Changelog ==
31
 
32
+ = 0.4 - 2012-08-07 =
33
+ * New: More than 4x faster than version 0.3 due to find & replace improvements
34
+ * New: Option to turn off replacing GUIDs
35
+ * New: Option to exclude spam comments and post revisions from the export
36
+ * New: Option to save file with gzip compression
37
+ * New: Added date and time to file names
38
+ * New: Display path to SQL file on the server
39
+ * New: WP App Store installer integration
40
+ * Bug fix: Notices and warnings displayed when WP_DEBUG is on
41
+
42
  = 0.3 - 2011-12-16 =
43
  * Bug fix: [Null formatting error](http://plugins.trac.wordpress.org/ticket/1430)
44
  * Bug fix: [Deprecated capability](http://plugins.trac.wordpress.org/ticket/1431)
59
 
60
  == Upgrade Notice ==
61
 
62
+ = 0.4 =
63
+ Runs export over 4x faster and adds some nice new features often requested. Upgrade recommended.
64
 
65
+ = 0.2.2 =
66
+ This version fixes a bug that breaks the WordPress core export feature. It is highly recommended that everyone upgrade.
script.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($) {
2
+ $(document).ready(function() {
3
+ $('#replace-guids-info-link').click(function() {
4
+ var $div = $('#replace-guids-info');
5
+ if ( 'none' == $div.css('display') ) {
6
+ $div.show();
7
+ $(this).html('show less');
8
+ return false;
9
+ }
10
+ else {
11
+ $div.hide();
12
+ $(this).html('show more');
13
+ return false;
14
+ }
15
+ });
16
+ });
17
+
18
+ var admin_url = ajaxurl.replace( '/admin-ajax.php', '' ),
19
+ spinner_url = admin_url + '/images/wpspin_light.gif';
20
+
21
+ var spinner = new Image();
22
+ spinner.src = spinner_url;
23
+
24
+ $('#migrate-form').submit(function() {
25
+ $('p.submit', this).append('<img src="' + spinner_url + '" alt="" />');
26
+ });
27
+ })(jQuery);
styles.css ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #migrate-form {
2
+ padding-top: 10px;
3
+ }
4
+
5
+ .form-table .row-new-url th,
6
+ .form-table .row-new-url td,
7
+ .form-table .row-new-path th,
8
+ .form-table .row-new-path td,
9
+ .form-table .row-revisions th,
10
+ .form-table .row-revisions td {
11
+ padding-bottom: 20px;
12
+ border-bottom: 1px solid #ccc;
13
+ }
14
+
15
+ .form-table .row-old-path th,
16
+ .form-table .row-old-path td,
17
+ .form-table .row-save-file th,
18
+ .form-table .row-save-file td,
19
+ .form-table .row-guids th,
20
+ .form-table .row-guids td {
21
+ padding-top: 20px;
22
+ }
23
+
24
+ p.submit {
25
+ overflow: hidden;
26
+ padding-top: 20px;
27
+ border-top: 1px solid #ccc;
28
+ margin-top: 20px;
29
+ }
30
+
31
+ p.submit input {
32
+ float: left;
33
+ }
34
+
35
+ p.submit img {
36
+ float: left;
37
+ margin: 3px 0 0 5px;
38
+ }
wp-migrate-db.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP-Migrate-DB
4
  Plugin URI: http://wordpress.org/extend/plugins/wp-migrate-db/
5
  Description: Exports your database as a MySQL data dump (much like phpMyAdmin), does a find and replace on URLs and file paths, then allows you to save it to your computer.
6
  Author: Brad Touesnard
7
- Version: 0.3
8
  Author URI: http://bradt.ca/
9
  */
10
 
@@ -42,23 +42,54 @@ class WP_Migrate_DB {
42
  var $errors;
43
  var $upload_dir;
44
  var $upload_url;
45
- var $filename;
46
- var $nicename;
47
  var $fp;
48
  var $replaced;
 
49
 
50
  function __construct() {
51
  $this->errors = array();
52
  $this->upload_dir = ( defined('WP_CONTENT_DIR') ) ? WP_CONTENT_DIR . '/uploads' : ABSPATH . 'wp-content' . DS . 'uploads';
53
  $this->upload_url = ( defined('WP_CONTENT_URL') ) ? WP_CONTENT_URL . '/uploads' : get_option('siteurl') . '/wp-content/uploads';
54
 
55
- $hash = substr( md5( md5( DB_PASSWORD ) ), -5 );
56
- $this->filename = DB_NAME . '-migrate-' . $hash . '.sql';
57
- $this->nicename = DB_NAME . '-migrate.sql';
58
 
59
  $this->replaced['serialized']['count'] = 0;
60
  $this->replaced['serialized']['strings'] = '';
61
  $this->replaced['nonserialized']['count'] = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
 
64
  function options_validate() {
@@ -89,14 +120,12 @@ class WP_Migrate_DB {
89
  ?>
90
 
91
  <div class="wrap">
92
- <h2 style="margin-bottom: 0.5em;">WP Migrate DB</h2>
93
 
94
  <?php
95
  if (isset($_POST['Submit'])) {
96
- $this->options_validate();
97
-
98
  if (empty($this->errors)) {
99
- $this->fp = $this->open($this->upload_dir . DS . $this->filename);
100
  $this->db_backup_header();
101
  $this->db_backup();
102
  $this->close($this->fp);
@@ -120,8 +149,9 @@ class WP_Migrate_DB {
120
  else {
121
  ?>
122
  <p>
123
- Your database (SQL) file has been successfully generated.
124
- <a href="<?php echo $this->upload_url, '/', $this->filename; ?>">Click
 
125
  here to download.</a>
126
  </p>
127
  <?php
@@ -152,6 +182,8 @@ class WP_Migrate_DB {
152
  $wp_dir = str_replace('/', DS, $wp_dir);
153
  $form_values['old_path'] = str_replace($wp_dir, '', $form_values['old_path']);
154
  }
 
 
155
  }
156
 
157
  if (!isset($_POST['Submit']) || (isset($_POST['Submit']) && !empty($this->errors))) {
@@ -191,10 +223,11 @@ class WP_Migrate_DB {
191
  <p>
192
  Example: <code>s:5:"hello"</code> becomes <code>s:11:"hello world"</code>
193
  </p>
194
- <form method="post">
 
195
  <table class="form-table">
196
  <tbody>
197
- <tr valign="top">
198
  <th scope="row">
199
  <label for="old_url">Current address (URL)</label>
200
  </th>
@@ -203,7 +236,7 @@ class WP_Migrate_DB {
203
  <?php $this->show_error('old_url'); ?>
204
  </td>
205
  </tr>
206
- <tr valign="top">
207
  <th scope="row">
208
  <label for="new_url">New address (URL)</label>
209
  </th>
@@ -212,14 +245,7 @@ class WP_Migrate_DB {
212
  <?php $this->show_error('new_url'); ?>
213
  </td>
214
  </tr>
215
- </tbody>
216
- </table>
217
-
218
- <br /><br />
219
-
220
- <table class="form-table">
221
- <tbody>
222
- <tr valign="top">
223
  <th scope="row">
224
  <label for="old_path">Current file path</label>
225
  </th>
@@ -228,7 +254,7 @@ class WP_Migrate_DB {
228
  <?php $this->show_error('old_path'); ?>
229
  </td>
230
  </tr>
231
- <tr valign="top">
232
  <th scope="row">
233
  <label for="new_path">New file path</label>
234
  </th>
@@ -237,8 +263,46 @@ class WP_Migrate_DB {
237
  <?php $this->show_error('new_path'); ?>
238
  </td>
239
  </tr>
240
- <tr valign="top">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  <th scope="row">&nbsp;</th>
 
 
 
 
 
 
 
 
 
242
  <td>
243
  <label for="savefile">
244
  <input id="savefile" type="checkbox" checked="checked" value="1" name="savefile"/>
@@ -246,6 +310,17 @@ class WP_Migrate_DB {
246
  </label>
247
  </td>
248
  </tr>
 
 
 
 
 
 
 
 
 
 
 
249
  </tbody>
250
  </table>
251
 
@@ -304,6 +379,25 @@ class WP_Migrate_DB {
304
  return $subject;
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  /**
308
  * Taken partially from phpMyAdmin and partially from
309
  * Alain Wolf, Zurich - Switzerland
@@ -388,12 +482,10 @@ class WP_Migrate_DB {
388
  }
389
 
390
  do {
391
- // don't include extra stuff, if so requested
392
- $excs = (array) get_option('wp_db_backup_excs');
393
  $where = '';
394
- if ( is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) {
395
  $where = ' WHERE comment_approved != "spam"';
396
- } elseif ( is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) {
397
  $where = ' WHERE post_type != "revision"';
398
  }
399
 
@@ -408,14 +500,33 @@ class WP_Migrate_DB {
408
  foreach ($table_data as $row) {
409
  $values = array();
410
  foreach ($row as $key => $value) {
411
- if ($ints[strtolower($key)]) {
412
  // make sure there are no blank spots in the insert syntax,
413
  // yet try to avoid quotation marks around integers
414
  $value = ( null === $value || '' === $value) ? $defs[strtolower($key)] : $value;
415
  $values[] = ( '' === $value ) ? "''" : $value;
416
  } else {
417
- if(null === $value) $values[] = 'NULL';
418
- else $values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
  }
420
  }
421
  $this->stow(" \n" . $entries . implode(', ', $values) . ') ;');
@@ -435,6 +546,11 @@ class WP_Migrate_DB {
435
  }
436
  } // end backup_table()
437
 
 
 
 
 
 
438
  function db_backup() {
439
  global $table_prefix, $wpdb;
440
 
@@ -485,12 +601,12 @@ class WP_Migrate_DB {
485
  }
486
 
487
  function gzip() {
488
- return false; //function_exists('gzopen');
489
  }
490
 
491
  function open($filename = '', $mode = 'w') {
492
  if ('' == $filename) return false;
493
- if ($this->gzip())
494
  $fp = gzopen($filename, $mode);
495
  else
496
  $fp = fopen($filename, $mode);
@@ -498,17 +614,12 @@ class WP_Migrate_DB {
498
  }
499
 
500
  function close($fp) {
501
- if ($this->gzip()) gzclose($fp);
502
  else fclose($fp);
503
  }
504
 
505
  function stow($query_line, $replace = true) {
506
- if ($replace) {
507
- $query_line = $this->replace_sql_strings($_POST['old_url'], $_POST['new_url'], $query_line);
508
- $query_line = $this->replace_sql_strings($_POST['old_path'], $_POST['new_path'], $query_line);
509
- }
510
-
511
- if ($this->gzip()) {
512
  if(! @gzwrite($this->fp, $query_line))
513
  $this->errors['file_write'] = __('There was an error writing a line to the backup script:','wp-db-backup') . ' ' . $query_line . ' ' . $php_errormsg;
514
  } else {
@@ -549,49 +660,49 @@ class WP_Migrate_DB {
549
 
550
  function download_file() {
551
  set_time_limit(0);
552
- $diskfile = $this->upload_dir . DS . $this->filename;
 
553
  if (file_exists($diskfile)) {
554
  header('Content-Description: File Transfer');
555
  header('Content-Type: application/octet-stream');
556
  header('Content-Length: ' . filesize($diskfile));
557
- header("Content-Disposition: attachment; filename={$this->nicename}");
558
  $success = readfile($diskfile);
559
  unlink($diskfile);
560
  exit;
561
  }
562
  else {
563
- wp_die('Could not find the file to download.');
564
  }
565
  }
566
 
567
  function admin_menu() {
568
  if (function_exists('add_management_page')) {
569
- add_management_page('WP Migrate DB','WP Migrate DB','level_8','wp-migrate-db',array($this, 'options_page'));
570
  }
 
 
 
 
 
571
  }
572
 
573
  function admin_head() {
574
- $url = admin_url('tools.php?page=wp-migrate-db&download=true');
 
575
  ?>
576
  <meta http-equiv="refresh" content="1;url=<?php echo $url; ?>"/>
577
  <?php
578
  }
579
  }
580
 
581
- global $wpmdb;
582
- $wpmdb = new WP_Migrate_DB;
583
-
584
- if (is_admin()) {
585
- add_action('admin_menu', array($wpmdb, 'admin_menu'));
586
 
587
- if (isset($_GET['page']) && $_GET['page'] == 'wp-migrate-db') {
588
- if (isset($_POST['savefile']) && $_POST['savefile']) {
589
- add_action('admin_head-tools_page_wp-migrate-db', array($wpmdb, 'admin_head'));
590
- }
591
-
592
- if (isset($_GET['download']) && $_GET['download']) {
593
- add_action('init', array($wpmdb, 'download_file'));
594
- }
595
- }
596
  }
597
- ?>
 
 
 
4
  Plugin URI: http://wordpress.org/extend/plugins/wp-migrate-db/
5
  Description: Exports your database as a MySQL data dump (much like phpMyAdmin), does a find and replace on URLs and file paths, then allows you to save it to your computer.
6
  Author: Brad Touesnard
7
+ Version: 0.4
8
  Author URI: http://bradt.ca/
9
  */
10
 
42
  var $errors;
43
  var $upload_dir;
44
  var $upload_url;
 
 
45
  var $fp;
46
  var $replaced;
47
+ var $datetime;
48
 
49
  function __construct() {
50
  $this->errors = array();
51
  $this->upload_dir = ( defined('WP_CONTENT_DIR') ) ? WP_CONTENT_DIR . '/uploads' : ABSPATH . 'wp-content' . DS . 'uploads';
52
  $this->upload_url = ( defined('WP_CONTENT_URL') ) ? WP_CONTENT_URL . '/uploads' : get_option('siteurl') . '/wp-content/uploads';
53
 
54
+ $this->datetime = date('YmdHis');
 
 
55
 
56
  $this->replaced['serialized']['count'] = 0;
57
  $this->replaced['serialized']['strings'] = '';
58
  $this->replaced['nonserialized']['count'] = 0;
59
+
60
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
61
+
62
+ $this->handle_request();
63
+ }
64
+
65
+ function handle_request() {
66
+ if ( !isset( $_GET['page'] ) || 'wp-migrate-db' != $_GET['page'] )
67
+ return;
68
+
69
+ if (isset($_POST['Submit'])) {
70
+ $this->options_validate();
71
+ }
72
+
73
+ if ( empty( $this->errors ) && isset( $_POST['savefile'] ) && $_POST['savefile'] ) {
74
+ add_action( 'admin_head-tools_page_wp-migrate-db', array( $this, 'admin_head' ) );
75
+ }
76
+
77
+ if ( isset( $_GET['download'] ) && $_GET['download']) {
78
+ add_action( 'admin_init', array( $this, 'download_file' ) );
79
+ }
80
+ }
81
+
82
+ function get_filename( $datetime, $gzip ) {
83
+ $hash = substr( sha1( DB_PASSWORD . AUTH_SALT ), -5 );
84
+ $filename = DB_NAME . '-migrate-' . $datetime . '-' . $hash . '.sql';
85
+ if ( $gzip ) $filename .= '.gz';
86
+ return $filename;
87
+ }
88
+
89
+ function get_nicename( $datetime, $gzip ) {
90
+ $name = DB_NAME . '-migrate-' . $datetime . '.sql';
91
+ if ( $gzip ) $name .= '.gz';
92
+ return $name;
93
  }
94
 
95
  function options_validate() {
120
  ?>
121
 
122
  <div class="wrap">
123
+ <div id="icon-tools" class="icon32"><br /></div><h2>WP Migrate DB</h2>
124
 
125
  <?php
126
  if (isset($_POST['Submit'])) {
 
 
127
  if (empty($this->errors)) {
128
+ $this->fp = $this->open($this->upload_dir . DS . $this->get_filename( $this->datetime, isset( $_POST['gzipfile'] ) ) );
129
  $this->db_backup_header();
130
  $this->db_backup();
131
  $this->close($this->fp);
149
  else {
150
  ?>
151
  <p>
152
+ Your database (SQL) file has been successfully generated and
153
+ saved to <br /><?php echo $this->upload_dir . DS . $this->get_filename( $this->datetime, isset( $_POST['gzipfile'] ) ); ?>.
154
+ <a href="<?php echo $this->upload_url, '/', $this->get_filename( $this->datetime, isset( $_POST['gzipfile'] ) ); ?>">Click
155
  here to download.</a>
156
  </p>
157
  <?php
182
  $wp_dir = str_replace('/', DS, $wp_dir);
183
  $form_values['old_path'] = str_replace($wp_dir, '', $form_values['old_path']);
184
  }
185
+
186
+ $form_values['new_path'] = $form_values['new_url'] = '';
187
  }
188
 
189
  if (!isset($_POST['Submit']) || (isset($_POST['Submit']) && !empty($this->errors))) {
223
  <p>
224
  Example: <code>s:5:"hello"</code> becomes <code>s:11:"hello world"</code>
225
  </p>
226
+
227
+ <form method="post" id="migrate-form">
228
  <table class="form-table">
229
  <tbody>
230
+ <tr valign="top" class="row-old-url">
231
  <th scope="row">
232
  <label for="old_url">Current address (URL)</label>
233
  </th>
236
  <?php $this->show_error('old_url'); ?>
237
  </td>
238
  </tr>
239
+ <tr valign="top" class="row-new-url">
240
  <th scope="row">
241
  <label for="new_url">New address (URL)</label>
242
  </th>
245
  <?php $this->show_error('new_url'); ?>
246
  </td>
247
  </tr>
248
+ <tr valign="top" class="row-old-path">
 
 
 
 
 
 
 
249
  <th scope="row">
250
  <label for="old_path">Current file path</label>
251
  </th>
254
  <?php $this->show_error('old_path'); ?>
255
  </td>
256
  </tr>
257
+ <tr valign="top" class="row-new-path">
258
  <th scope="row">
259
  <label for="new_path">New file path</label>
260
  </th>
263
  <?php $this->show_error('new_path'); ?>
264
  </td>
265
  </tr>
266
+ <tr valign="top" class="row-guids">
267
+ <th scope="row">Data Options</th>
268
+ <td>
269
+ <label for="replace-guids">
270
+ <input id="replace-guids" type="checkbox" checked="checked" value="1" name="replaceguids"/>
271
+ Replace GUIDs</label>
272
+
273
+ <a href="" id="replace-guids-info-link">show more</a>
274
+
275
+ <div id="replace-guids-info" style="display: none;">
276
+ <p>
277
+ Although the <a href="http://codex.wordpress.org/Changing_The_Site_URL#Important_GUID_Note" target="_blank">WordPress Codex emphasizes</a>
278
+ that GUIDs should not be changed, this is limited to sites that are already live.
279
+ If the site has never been live, I recommend replacing the GUIDs. For example, you may be
280
+ developing a new site locally at dev.somedomain.com and want to
281
+ migrate the site live to somedomain.com.
282
+ </p>
283
+ </div>
284
+ </td>
285
+ </tr>
286
+ <tr valign="top" class="row-spam">
287
+ <th scope="row">&nbsp;</th>
288
+ <td>
289
+ <label for="exclude-spam">
290
+ <input id="exclude-spam" type="checkbox" value="1" name="exclude-spam" />
291
+ Do not export spam comments
292
+ </label>
293
+ </td>
294
+ </tr>
295
+ <tr valign="top" class="row-revisions">
296
  <th scope="row">&nbsp;</th>
297
+ <td>
298
+ <label for="exclude-revisions">
299
+ <input id="exclude-revisions" type="checkbox" value="1" name="exclude-revisions" />
300
+ Do not export post revisions
301
+ </label>
302
+ </td>
303
+ </tr>
304
+ <tr valign="top" class="row-save-file">
305
+ <th scope="row">File Options</th>
306
  <td>
307
  <label for="savefile">
308
  <input id="savefile" type="checkbox" checked="checked" value="1" name="savefile"/>
310
  </label>
311
  </td>
312
  </tr>
313
+ <?php if ( $this->gzip() ) : ?>
314
+ <tr valign="top" class="row-gzip">
315
+ <th scope="row">&nbsp;</th>
316
+ <td>
317
+ <label for="gzipfile">
318
+ <input id="gzipfile" type="checkbox" value="1" name="gzipfile" />
319
+ Compress file with gzip
320
+ </label>
321
+ </td>
322
+ </tr>
323
+ <?php endif; ?>
324
  </tbody>
325
  </table>
326
 
379
  return $subject;
380
  }
381
 
382
+ function apply_replaces( $subject, $is_serialized = false ) {
383
+ $search = array( $_POST['old_path'], $_POST['old_url'] );
384
+ $replace = array( $_POST['new_path'], $_POST['new_url'] );
385
+ $new = str_replace( $search, $replace, $subject, $count );
386
+
387
+ if ( $count ) {
388
+ if ( $is_serialized ) {
389
+ $this->replaced['serialized']['strings'] .= $subject . "\n";
390
+ $this->replaced['serialized']['strings'] .= $new . "\n\n";
391
+ $this->replaced['serialized']['count'] += $count;
392
+ }
393
+ else {
394
+ $this->replaced['nonserialized']['count'] += $count;
395
+ }
396
+ }
397
+
398
+ return $new;
399
+ }
400
+
401
  /**
402
  * Taken partially from phpMyAdmin and partially from
403
  * Alain Wolf, Zurich - Switzerland
482
  }
483
 
484
  do {
 
 
485
  $where = '';
486
+ if ( isset( $_POST['exclude-spam'] ) && $wpdb->comments == $table ) {
487
  $where = ' WHERE comment_approved != "spam"';
488
+ } elseif ( isset( $_POST['exclude-revisions'] ) && $wpdb->posts == $table ) {
489
  $where = ' WHERE post_type != "revision"';
490
  }
491
 
500
  foreach ($table_data as $row) {
501
  $values = array();
502
  foreach ($row as $key => $value) {
503
+ if (isset( $ints[strtolower($key)] ) && $ints[strtolower($key)]) {
504
  // make sure there are no blank spots in the insert syntax,
505
  // yet try to avoid quotation marks around integers
506
  $value = ( null === $value || '' === $value) ? $defs[strtolower($key)] : $value;
507
  $values[] = ( '' === $value ) ? "''" : $value;
508
  } else {
509
+ if (null === $value) {
510
+ $values[] = 'NULL';
511
+ }
512
+ else {
513
+ if ( is_serialized( $value ) && false !== ( $data = @unserialize( $value ) ) ) {
514
+ if ( is_array( $data ) ) {
515
+ array_walk_recursive( $data, array( $this, 'replace_array_values' ) );
516
+ }
517
+ elseif ( is_string( $data ) ) {
518
+ $data = $this->apply_replaces( $data, true );
519
+ }
520
+
521
+ $value = serialize( $data );
522
+ }
523
+ // Skip replacing GUID if the option is set
524
+ elseif ( 'guid' != $key || isset( $_POST['replaceguids'] ) ) {
525
+ $value = $this->apply_replaces( $value );
526
+ }
527
+
528
+ $values[] = "'" . str_replace( $search, $replace, $this->sql_addslashes( $value ) ) . "'";
529
+ }
530
  }
531
  }
532
  $this->stow(" \n" . $entries . implode(', ', $values) . ') ;');
546
  }
547
  } // end backup_table()
548
 
549
+ function replace_array_values( &$value, $key ) {
550
+ if ( !is_string( $value ) ) return;
551
+ $value = $this->apply_replaces( $value, true );
552
+ }
553
+
554
  function db_backup() {
555
  global $table_prefix, $wpdb;
556
 
601
  }
602
 
603
  function gzip() {
604
+ return function_exists('gzopen');
605
  }
606
 
607
  function open($filename = '', $mode = 'w') {
608
  if ('' == $filename) return false;
609
+ if ($this->gzip() && isset( $_POST['gzipfile'] ))
610
  $fp = gzopen($filename, $mode);
611
  else
612
  $fp = fopen($filename, $mode);
614
  }
615
 
616
  function close($fp) {
617
+ if ($this->gzip() && isset( $_POST['gzipfile'] )) gzclose($fp);
618
  else fclose($fp);
619
  }
620
 
621
  function stow($query_line, $replace = true) {
622
+ if ($this->gzip() && isset( $_POST['gzipfile'] )) {
 
 
 
 
 
623
  if(! @gzwrite($this->fp, $query_line))
624
  $this->errors['file_write'] = __('There was an error writing a line to the backup script:','wp-db-backup') . ' ' . $query_line . ' ' . $php_errormsg;
625
  } else {
660
 
661
  function download_file() {
662
  set_time_limit(0);
663
+ $datetime = preg_replace( '@[^0-9]@', '', $_GET['download'] );
664
+ $diskfile = $this->upload_dir . DS . $this->get_filename( $datetime, isset( $_GET['gz'] ) );
665
  if (file_exists($diskfile)) {
666
  header('Content-Description: File Transfer');
667
  header('Content-Type: application/octet-stream');
668
  header('Content-Length: ' . filesize($diskfile));
669
+ header('Content-Disposition: attachment; filename=' . $this->get_nicename( $datetime, isset( $_GET['gz'] ) ) );
670
  $success = readfile($diskfile);
671
  unlink($diskfile);
672
  exit;
673
  }
674
  else {
675
+ wp_die("Could not find the file to download:<br />$diskfile.");
676
  }
677
  }
678
 
679
  function admin_menu() {
680
  if (function_exists('add_management_page')) {
681
+ add_management_page('WP Migrate DB','WP Migrate DB','update_core','wp-migrate-db',array($this, 'options_page'));
682
  }
683
+
684
+ $src = plugins_url( 'styles.css', __FILE__ );
685
+ wp_enqueue_style( 'wp-migrate-db-styles', $src );
686
+ $src = plugins_url( 'script.js', __FILE__ );
687
+ wp_enqueue_script( 'wp-migrate-db-script', $src, array( 'jquery' ), false, true );
688
  }
689
 
690
  function admin_head() {
691
+ $url = admin_url('tools.php?page=wp-migrate-db&download=' . urlencode( $this->datetime ) );
692
+ if ( isset( $_POST['gzipfile'] ) ) $url .= '&gz=1';
693
  ?>
694
  <meta http-equiv="refresh" content="1;url=<?php echo $url; ?>"/>
695
  <?php
696
  }
697
  }
698
 
699
+ function wp_migrate_db_init() {
700
+ if ( !is_admin() ) return;
 
 
 
701
 
702
+ global $wpmdb;
703
+ $wpmdb = new WP_Migrate_DB();
 
 
 
 
 
 
 
704
  }
705
+
706
+ add_action( 'init', 'wp_migrate_db_init' );
707
+
708
+ include dirname( __FILE__ ) . DS . '/installer.php';