PageRenderTime 48ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/backupbuddy/classes/_migrate_database.php

https://bitbucket.org/betaimages/chakalos
PHP | 531 lines | 260 code | 170 blank | 101 comment | 58 complexity | 0092add374ded544e15e08f1b8f9ce27 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. // TODO: Convert this to use proper OOP practices... Sorry it evolved into this.
  3. /**
  4. * _migrate_database.php
  5. *
  6. * Handles all SQL data migration for both importbuddy and multisite importing.
  7. * Handles updating paths, URLs, etc.
  8. *
  9. * Version: 1.0.1
  10. * Author: Dustin Bolton
  11. * Author URI: http://dustinbolton.com/
  12. *
  13. * REQUIREMENTS:
  14. *
  15. * 1) Set up the variable $destination_type to the destination type if non-standalone (default) or Multisite Network (auto-detected). Valid values: standalone, multisite_import, multisite_network
  16. * 2) Mysql should already be connected.
  17. * 3) pb_backupbuddy::$options['dat_file'] should be initialized with the DAT file array.
  18. * 4) If migrating a network -> network then set up the variable $multisite_network_db_prefix to be the database prefix of the network. Needed to access users tables.
  19. * 5) If multisite_import is DESTINATION then $wp_upload_dir (upload_path option), $wp_upload_url (fileupload_url option) must be set.
  20. *
  21. * USED BY:
  22. *
  23. * 1) ImportBuddy
  24. * 2) Multisite Import / Restore
  25. * 3) Future: RepairBuddy?
  26. *
  27. */
  28. // NOTE: dbreplace class intelligently ignores replacing values with identical values for performance.
  29. if ( isset( $destination_type ) && ( $destination_type == 'multisite_import' ) ) {
  30. } else { // Normal importbuddy.
  31. $destination_siteurl = pb_backupbuddy::$options['siteurl'];
  32. $destination_home = pb_backupbuddy::$options['home'];
  33. if ( $destination_home == '' ) { // If no home then we set it equal to site URL.
  34. $destination_home = $destination_siteurl;
  35. }
  36. $destination_db_prefix = pb_backupbuddy::$options['db_prefix'];
  37. $multisite_network_db_prefix = $destination_db_prefix; // non-ms prefix set network same as normal prefix.
  38. // Multisite Network domain & path from site url:
  39. $url_parts = parse_url( pb_backupbuddy::$options['siteurl'] );
  40. $destination_domain = $url_parts['host'];
  41. if ( isset( $url_parts['path'] ) ) {
  42. $destination_path = rtrim( $url_parts['path'], '/\\' ) . '/';
  43. } else {
  44. $destination_path = '/';
  45. }
  46. /*
  47. if ( isset( pb_backupbuddy::$options['domain'] ) ) {
  48. $destination_domain = pb_backupbuddy::$options['domain'];
  49. }
  50. // Currently we don't allow changing the Network path.
  51. if ( isset( pb_backupbuddy::$options['dat_file'][ 'path' ] ) ) {
  52. $destination_path = pb_backupbuddy::$options['dat_file'][ 'path' ]; // Set new Network path to equal old network path.
  53. }
  54. */
  55. }
  56. pb_backupbuddy::status( 'message', 'Migrating database content...' );
  57. pb_backupbuddy::status( 'details', 'Destination site table prefix: ' . $destination_db_prefix );
  58. // ********** BEGIN VARIABLE SETUP **********
  59. // DESTINATION TYPE. Valid values: standalone, multisite_import, multisite_network
  60. if ( !isset( $destination_type ) || ( $destination_type == '' ) ) {
  61. $destination_type = 'standalone'; // Default; overridden if explicitly set or if a full Multisite Network migration.
  62. }
  63. // SOURCE TYPE. Valid values: network, multisite_export (single site exported from multisite network), standalone
  64. if ( isset( pb_backupbuddy::$options['dat_file'][ 'is_multisite' ] ) && ( ( pb_backupbuddy::$options['dat_file'][ 'is_multisite' ] === true ) || ( pb_backupbuddy::$options['dat_file'][ 'is_multisite' ] === 'true' ) ) ) {
  65. $source_type = 'multisite_network';
  66. $destination_type = 'multisite_network';
  67. } elseif ( isset( pb_backupbuddy::$options['dat_file'][ 'is_multisite_export' ] ) && ( ( pb_backupbuddy::$options['dat_file'][ 'is_multisite_export' ] === true ) || ( pb_backupbuddy::$options['dat_file'][ 'is_multisite_export' ] === 'true' ) ) ) {
  68. $source_type = 'multisite_export';
  69. } else {
  70. $source_type = 'standalone';
  71. }
  72. pb_backupbuddy::status( 'details', 'Migration type: ' . $source_type . ' to ' . $destination_type );
  73. $destination_siteurl = preg_replace( '|/*$|', '', $destination_siteurl ); // strips trailing slash(es).
  74. $destination_home = preg_replace( '|/*$|', '', $destination_home ); // strips trailing slash(es).
  75. pb_backupbuddy::status( 'details', 'Destination Site URL: ' . $destination_siteurl );
  76. pb_backupbuddy::status( 'details', 'Destination Home URL: ' . $destination_home );
  77. $count_tables_checked = 0;
  78. $count_items_checked = 0;
  79. $count_items_changed = 0;
  80. // ********** END VARIABLE SETUP **********
  81. // ********** BEGIN ALL **********
  82. pb_backupbuddy::status( 'details', 'Starting migration steps for `all` sites.' );
  83. // ABSPATH
  84. $old_abspath = pb_backupbuddy::$options['dat_file']['abspath'];
  85. //$old_abspath = preg_replace( '|/+$|', '', $old_abspath ); // Remove escaping of windows paths. This is wrong. strips trailing slashes. Why? It shouldnt! Removed Nov 4
  86. $new_abspath = ABSPATH;
  87. pb_backupbuddy::status( 'details', 'ABSPATH change for database. Old Path: ' . $old_abspath . ', New Path: ' . $new_abspath . '.' );
  88. $old_url = pb_backupbuddy::$options['dat_file']['siteurl']; // the value you want to search for
  89. // SITEURL
  90. if ( stristr( $old_url, 'http://www.' ) || stristr( $old_url, 'https://www.' ) ) { // If http://www.blah.... then also we will replace http://blah... and vice versa.
  91. $old_url_alt = str_ireplace( 'http://www.', 'http://', $old_url );
  92. $old_url_alt = str_ireplace( 'https://www.', 'https://', $old_url_alt );
  93. } else {
  94. $old_url_alt = str_ireplace( 'http://', 'http://www.', $old_url );
  95. $old_url_alt = str_ireplace( 'https://', 'https://www.', $old_url_alt );
  96. }
  97. $new_url = $destination_siteurl;
  98. pb_backupbuddy::status( 'details', 'Calculated site URL update. Previous URL: `' . $old_url . '`, New URL: `' . $new_url . '`.' );
  99. $old_fullreplace = array( $old_url, $old_url_alt, $old_abspath );
  100. $new_fullreplace = array( $new_url, $new_url, $new_abspath );
  101. // HOMEURL.
  102. if ( $destination_home != $destination_siteurl ) {
  103. if ( empty( pb_backupbuddy::$options['dat_file']['homeurl'] ) ) { // old BackupBuddy versions did not store the previous homeurl. Hang onto this for backwards compatibility for a while.
  104. pb_backupbuddy::status( 'error', 'Your current backup does not include a home URL. Home URLs will NOT be updated; site URL will be updated though. Make a new backup with the latest BackupBuddy before migrating if you wish to fully update home URL configuration.' );
  105. } else {
  106. $old_urls = array( $old_url, $old_url_alt, pb_backupbuddy::$options['dat_file']['homeurl'] );
  107. $new_urls = array( $new_url, $new_url, $destination_home );
  108. $old_fullreplace[] = pb_backupbuddy::$options['dat_file']['homeurl'];
  109. $new_fullreplace[] = $destination_home;
  110. pb_backupbuddy::status( 'details', 'Calculated home URL update. Previous URL: `' . pb_backupbuddy::$options['dat_file']['homeurl'] . '`, New URL: `' . $destination_home . '`' );
  111. }
  112. } else { // Site URL updates only.
  113. $old_urls = array( $old_url, $old_url_alt );
  114. $new_urls = array( $new_url, $new_url );
  115. }
  116. if ( isset( $wp_upload_dir ) ) {
  117. $wp_upload_url_real = $new_url . '/' . str_replace( ABSPATH, '', $wp_upload_dir );
  118. pb_backupbuddy::status( 'details', '$wp_upload_url_real = `' . $wp_upload_url_real . '`.' );
  119. }
  120. $bruteforce_excluded_tables = array(
  121. $destination_db_prefix . 'posts',
  122. $destination_db_prefix . 'users', // Imported users table will temporarily be here so this is fine for MS imports.
  123. $destination_db_prefix . 'usermeta', // Imported users table will temporarily be here so this is fine for MS imports.
  124. $destination_db_prefix . 'terms',
  125. $destination_db_prefix . 'term_taxonomy',
  126. $destination_db_prefix . 'term_relationships',
  127. $destination_db_prefix . 'postmeta',
  128. $destination_db_prefix . 'options',
  129. $destination_db_prefix . 'comments',
  130. $destination_db_prefix . 'commentmeta',
  131. $destination_db_prefix . 'links',
  132. );
  133. pb_backupbuddy::status( 'details', 'Finished migration steps for `all` sites.' );
  134. // ********** END ALL **********
  135. // ********** BEGIN MULTISITE NETWORK -> MULTISITE NETWORK **********
  136. if ( ( $source_type == 'multisite_network' ) && ( $destination_type == 'multisite_network' ) ) {
  137. pb_backupbuddy::status( 'details', 'Starting migration steps for `Network -> Network` sites.' );
  138. //pb_update_domain_path( pb_backupbuddy::$options['dat_file']['domain'], $destination_domain, pb_backupbuddy::$options['dat_file']['path'], $destination_path ); // $old_domain, $destination_domain, $old_path, $destination_path
  139. $old_domain = pb_backupbuddy::$options['dat_file']['domain'];
  140. $old_path = pb_backupbuddy::$options['dat_file']['path'];
  141. pb_backupbuddy::status( 'details', 'Multisite Network URLs: Old domain: `' . $old_domain . '`; new domain: `' . $destination_domain . '`; old path: `' . $old_path . '`; new path: `' . $destination_path . '`.' );
  142. // BLOGS TABLE-----
  143. // Update blog path for all sites that had the old domain and started with the old path in BLOGS table.
  144. if ( $old_path != '/' ) { // Used to be a subdomain so we can more safely replace.
  145. mysql_query( "UPDATE `" . $destination_db_prefix . "blogs` SET path=REPLACE( path, '" . mysql_real_escape_string( $old_path ) . "', '" . mysql_real_escape_string( $destination_path ) . "') WHERE domain='" . mysql_real_escape_string( $old_domain ) . "' AND path LIKE '" . mysql_real_escape_string( $old_path ) . "%'" );
  146. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating paths in blogs table to `' . mysql_real_escape_string( $destination_path ) . '` (old path was a subdirectory).' );
  147. } else { // Used to be in root so much prepend new path.
  148. mysql_query( "UPDATE `" . $destination_db_prefix . "blogs` SET path=concat( '" . mysql_real_escape_string( rtrim( $destination_path, '/\\' ) ) . "', path ) WHERE domain='" . mysql_real_escape_string( $old_domain ) . "'" );
  149. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating paths in blogs table to `' . mysql_real_escape_string( $destination_path ) . '` (old path was root).' );
  150. }
  151. // Update blog domain for all matching sites.
  152. mysql_query( "UPDATE `" . $destination_db_prefix . "blogs` SET domain='" . mysql_real_escape_string( $destination_domain ) . "' WHERE domain='" . mysql_real_escape_string( $old_domain ) . "'" );
  153. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating domain in blogs table to `' . mysql_real_escape_string( $destination_domain ) . '`.' );
  154. // SITE TABLE-----
  155. // Update blog path for all matching sites in SITE table.
  156. if ( $old_path != '/' ) { // Used to be a subdomain so we can more safely replace.
  157. mysql_query( "UPDATE `" . $destination_db_prefix . "site` SET path=REPLACE( path, '" . mysql_real_escape_string( $old_path ) . "', '" . mysql_real_escape_string( $destination_path ) . "') WHERE domain='" . mysql_real_escape_string( $old_domain ) . "' AND path LIKE '" . mysql_real_escape_string( $old_path ) . "%'" );
  158. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating paths in site table to `' . mysql_real_escape_string( $destination_path ) . '` (old path was a subdirectory).' );
  159. } else { // Used to be in root so much prepend new path.
  160. mysql_query( "UPDATE `" . $destination_db_prefix . "site` SET path=concat( '" . mysql_real_escape_string( rtrim( $destination_path, '/\\' ) ) . "', path ) WHERE domain='" . mysql_real_escape_string( $old_domain ) . "'" );
  161. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating paths in site table to `' . mysql_real_escape_string( $destination_path ) . '` (old path was root).' );
  162. }
  163. // Update blog domain for all matching sites.
  164. mysql_query( "UPDATE `" . $destination_db_prefix . "site` SET domain='" . mysql_real_escape_string( $destination_domain ) . "' WHERE domain='" . mysql_real_escape_string( $old_domain ) . "'" );
  165. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating domain in site table to `' . mysql_real_escape_string( $destination_domain ) . '`.' );
  166. pb_backupbuddy::status( 'details', 'Finished migration steps for `Network -> Network` sites.' );
  167. }
  168. // ********** END MULTISITE NETWORK -> MULTISITE NETWORK **********
  169. // ********** BEGIN STANDALONE -> MULTISITE IMPORT **********
  170. if ( ( $source_type == 'standalone' ) && ( $destination_type == 'multisite_import' ) ) {
  171. pb_backupbuddy::status( 'details', 'Starting migration steps for `Standalone -> Multisite Import` sites.' );
  172. // Note for any destination of multisite_import: Users tables exist temporarily in their normal location so we replace them like a normal standalone site. The next import step will merge them into the multisite tables.
  173. // TODO: add code from ms_importbuddy.php into here for any updates if needed.
  174. // The old uploads URL. Standalone source like: http://getbackupbuddy.com/wp-content/uploads/. BB doesnt currently support moved uploads. Unshifted to place these replacements FIRST in the array of URLs to replace.
  175. pb_backupbuddy::status( 'details', 'Old uploads URL: ' . $old_url . '/wp-content/uploads' );
  176. array_unshift( $old_urls, $old_url . '/wp-content/uploads' );
  177. array_unshift( $old_fullreplace, $old_url . '/wp-content/uploads' );
  178. // The new standalone upload URL. Ex: http://pluginbuddy.com/wp-content/uploads/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  179. pb_backupbuddy::status( 'details', 'New virtual upload URL to replace standalone upload URL: ' . $wp_upload_url );
  180. array_unshift( $new_urls, $wp_upload_url );
  181. array_unshift( $new_fullreplace, $wp_upload_url );
  182. // Update upload_path in options table.
  183. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( str_replace( $new_url . '/', '', $wp_upload_url_real ) ) . "' WHERE option_name='upload_path' LIMIT 1" );
  184. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating uploads URL in options table. New value: ' . str_replace( $new_url . '/', '', $wp_upload_url_real ) );
  185. // Update user roles option_name row.
  186. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_name='" . $destination_db_prefix . "user_roles' WHERE option_name LIKE '%\_user\_roles' LIMIT 1" );
  187. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating user roles option_name to `' . $destination_db_prefix . 'user_roles`.' );
  188. // Update fileupload_url in options table.
  189. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( $wp_upload_url ) . "' WHERE option_name='fileupload_url' LIMIT 1" );
  190. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating fileupload_url in options table. New value: `' . $wp_upload_url . '`.' );
  191. // Update user level meta_key in user_meta table.
  192. // TODO: moved to bottom of this file.
  193. //mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_name='" . $destination_db_prefix . "user_roles' WHERE option_name LIKE '%_user_roles' LIMIT 1" );
  194. //pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating user roles option_name to `' . $destination_db_prefix . 'user_roles`.' );
  195. pb_backupbuddy::status( 'details', 'Finished migration steps for `Standalone -> Multisite Import` sites.' );
  196. }
  197. // ********** END STANDALONE -> MULTISITE IMPORT **********
  198. // ********** BEGIN MULTISITE EXPORT -> MULTISITE IMPORT **********
  199. if ( ( $source_type == 'multisite_export' ) && ( $destination_type == 'multisite_import' ) ) {
  200. pb_backupbuddy::status( 'details', 'Starting migration steps for `Multisite Export -> Multisite Import` sites.' );
  201. // Note for any destination of multisite_import: Users tables exist temporarily in their normal location so we replace them like a normal standalone site. The next import step will merge them into the multisite tables.
  202. // The old virtual uploads URL. Standalone source like: http://getbackupbuddy.com/wp-content/uploads/. BB doesnt currently support moved uploads. Unshifted to place these replacements FIRST in the array of URLs to replace.
  203. pb_backupbuddy::status( 'details', 'Old virtual uploads URL: ' . pb_backupbuddy::$options['dat_file']['upload_url'] );
  204. array_unshift( $old_urls, pb_backupbuddy::$options['dat_file']['upload_url'] );
  205. array_unshift( $old_fullreplace, pb_backupbuddy::$options['dat_file']['upload_url'] );
  206. // The new virtual upload URL. Ex: http://pluginbuddy.com/wp-content/uploads/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  207. pb_backupbuddy::status( 'details', 'New virtual upload URL to replace old virtual uploads URL: ' . $wp_upload_url );
  208. array_unshift( $new_urls, $wp_upload_url );
  209. array_unshift( $new_fullreplace, $wp_upload_url );
  210. // The old real direct uploads URL. Standalone source like: http://getbackupbuddy.com/wp-content/uploads/. BB doesnt currently support moved uploads. Unshifted to place these replacements FIRST in the array of URLs to replace.
  211. pb_backupbuddy::status( 'details', 'Old real direct uploads URL: ' . pb_backupbuddy::$options['dat_file']['upload_url_rewrite'] );
  212. array_unshift( $old_urls, pb_backupbuddy::$options['dat_file']['upload_url_rewrite'] );
  213. array_unshift( $old_fullreplace, pb_backupbuddy::$options['dat_file']['upload_url_rewrite'] );
  214. // The new real direct upload URL. Ex: http://pluginbuddy.com/wp-content/uploads/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  215. pb_backupbuddy::status( 'details', 'New real direct upload URL to replace old virtual uploads URL: ' . $wp_upload_url_real );
  216. array_unshift( $new_urls, $wp_upload_url_real );
  217. array_unshift( $new_fullreplace, $wp_upload_url_real );
  218. // Update upload_path in options table.
  219. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( str_replace( $new_url . '/', '', $wp_upload_url_real ) ) . "' WHERE option_name='upload_path' LIMIT 1" );
  220. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating upload_path in options table. New value: ' . str_replace( $new_url . '/', '', $wp_upload_url_real ) );
  221. // Update fileupload_url in options table.
  222. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( $wp_upload_url ) . "' WHERE option_name='fileupload_url' LIMIT 1" );
  223. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating fileupload_url in options table. New value: `' . $wp_upload_url . '`.' );
  224. // Update user roles option_name row.
  225. // TODO: moved to bottom of this file.
  226. //mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_name='" . $destination_db_prefix . "user_roles' WHERE option_name LIKE '%_user_roles' LIMIT 1" );
  227. //pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating user roles option_name to `' . $destination_db_prefix . 'user_roles`.' );
  228. pb_backupbuddy::status( 'details', 'Finished migration steps for `Multisite Export -> Multisite Import` sites.' );
  229. }
  230. // ********** END MULTISITE EXPORT -> MULTISITE IMPORT **********
  231. // ********** BEGIN MULTISITE EXPORT -> STANDALONE **********
  232. if ( ( $source_type == 'multisite_export' ) && ( $destination_type == 'standalone' ) ) {
  233. pb_backupbuddy::status( 'details', 'Starting migration steps for `Multisite Export -> Standalone` sites.' );
  234. // IMPORTANT: Upload URLs _MUST_ be updated before doing a full URL replacement or else the first portion of the URL will be migrated so these will no longer match. array_unshift() is used to bump these to the top of the list to update.
  235. // These will handle both the REAL url http://.../wp-content/blogs.dir/##/files/ that the virtual path (http://..../wp-content/uploads/).
  236. // The old virtual upload URL. Ex: http://getbackupbuddy.com/files/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  237. pb_backupbuddy::status( 'details', 'Old virtual upload URL: ' . pb_backupbuddy::$options['dat_file'][ 'upload_url' ] );
  238. array_unshift( $old_urls, pb_backupbuddy::$options['dat_file'][ 'upload_url' ] );
  239. array_unshift( $old_fullreplace, pb_backupbuddy::$options['dat_file'][ 'upload_url' ] );
  240. // The new standalone upload URL. Ex: http://pluginbuddy.com/wp-content/uploads/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  241. pb_backupbuddy::status( 'details', 'New upload URL to replace virtual upload URL: ' . $new_url . '/wp-content/uploads/' );
  242. array_unshift( $new_urls, $new_url . '/wp-content/uploads/' );
  243. array_unshift( $new_fullreplace, $new_url . '/wp-content/uploads/' );
  244. // Only update another URL if it differs -- usually will. They will be the same if the virtual url doesn't exist for some reason (no htaccess availability so the virtual url would match the real url)
  245. if ( pb_backupbuddy::$options['dat_file'][ 'upload_url' ] != pb_backupbuddy::$options['dat_file'][ 'upload_url_rewrite' ] ) {
  246. // The old virtual upload URL. Ex: http://getbackupbuddy.com/files/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  247. pb_backupbuddy::status( 'details', 'Old real upload URL: ' . pb_backupbuddy::$options['dat_file'][ 'upload_url_rewrite' ] );
  248. array_unshift( $old_urls, pb_backupbuddy::$options['dat_file'][ 'upload_url_rewrite' ] ); // The old real upload URL.
  249. array_unshift( $old_fullreplace, pb_backupbuddy::$options['dat_file'][ 'upload_url_rewrite' ] );
  250. // The new standalone upload URL. Ex: http://pluginbuddy.com/wp-content/uploads/. Unshifted to place these replacements FIRST in the array of URLs to replace.
  251. pb_backupbuddy::status( 'details', 'New upload URL to replace real upload URL: ' . $new_url . '/wp-content/uploads/' );
  252. array_unshift( $new_urls, $new_url . '/wp-content/uploads/' ); // The new standalone upload URL.
  253. array_unshift( $new_fullreplace, $new_url . '/wp-content/uploads/' ); // The new standalone upload URL.
  254. }
  255. // Update upload_path in options table to be default blank value.
  256. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='' WHERE option_name='upload_path' LIMIT 1" );
  257. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating uploads path in options table. New value: `` (blank default).' );
  258. pb_backupbuddy::status( 'details', 'Finished migration steps for `Multisite Export -> Standalone` sites.' );
  259. }
  260. // ********** END MULTISITE EXPORT -> STANDALONE **********
  261. // Loop through the tables matching this prefix. Does NOT change data in other tables.
  262. // This changes actual data on a column by column basis for very row in every table.
  263. $tables = array();
  264. $result = mysql_query( "SHOW TABLES LIKE '" . str_replace( '_', '\_', $destination_db_prefix ) . "%'" );
  265. while ( $table = mysql_fetch_row( $result ) ) {
  266. $tables[] = $table[0];
  267. }
  268. unset( $table );
  269. pb_backupbuddy::status( 'message', 'Found ' . mysql_num_rows( $result ) . ' WordPress tables. ' );
  270. unset( $result );
  271. $bruteforce_tables = pb_backupbuddy::array_remove( $tables, $bruteforce_excluded_tables ); // Removes all tables listed in $excluded_tables from $tables.
  272. unset( $tables );
  273. if ( $destination_type == 'multisite_import' ) {
  274. require_once( pb_backupbuddy::plugin_path() . '/lib/dbreplace/dbreplace.php' );
  275. } else {
  276. require_once( 'importbuddy/lib/dbreplace/dbreplace.php' );
  277. }
  278. $dbreplace = new pluginbuddy_dbreplace( $this );
  279. // ********** BEGIN MAKING OLD URLS UNIQUE AND TRIMMING CORRESPONDING NEW URLS **********
  280. // This entire section is in place to prevent duplicate replacements.
  281. /* array_pairs_unique_first()
  282. *
  283. * Takes two arrays. Looks for any duplicate values in the first array. That item is removed. The corresponding item in the second array is removed also.
  284. * Resets indexes as a courtesy while maintaining order.
  285. *
  286. * @param array $a First array to make unique.
  287. * @param array $b Second array that has items removed that were in the same position as the removed duplicates found in $a.
  288. * @return
  289. */
  290. function array_pairs_unique_first( $a, $b ) {
  291. $a_uniques = array_unique( $a ); // Get unique values in $a. Keys are maintained.
  292. $result = array();
  293. $result[0] = $a_uniques;
  294. $result[1] = array_intersect_key( $b, $a_uniques ); // Get the part of the $b array that is missing from $a.
  295. $result[0] = array_merge( $result[0] );
  296. $result[1] = array_merge( $result[1] );
  297. return $result;
  298. }
  299. $unique_urls = array_pairs_unique_first( $old_urls, $new_urls );
  300. $old_urls = $unique_urls[0];
  301. $new_urls = $unique_urls[1];
  302. $unique_urls = array_pairs_unique_first( $old_fullreplace, $new_fullreplace );
  303. $old_fullreplace = $unique_urls[0];
  304. $new_fullreplace = $unique_urls[1];
  305. // ********** END MAKING OLD URLS UNIQUE AND TRIMMING CORRESPONDING NEW URLS **********
  306. pb_backupbuddy::status( 'details', 'Old URLs: ' . implode( ', ', $old_urls ) );
  307. pb_backupbuddy::status( 'details', 'New URLs: ' . implode( ', ', $new_urls ) );
  308. pb_backupbuddy::status( 'details', 'Old full replace: ' . implode( ', ', $old_fullreplace ) );
  309. pb_backupbuddy::status( 'details', 'New full replace: ' . implode( ', ', $new_fullreplace ) );
  310. // Update site URL strings in posts table for rows post_content, post_excerpt, and post_content_filtered. DO NOT update the guid even if it contains URL; per Learned BackupBuddy migrations have been updating the post GUID since it launched when it should not have been... http://codex.wordpress.org/Changing_The_Site_URL#Important_GUID_Note
  311. pb_backupbuddy::status( 'message', 'Updating posts table site URLs.' );
  312. $dbreplace->text( $destination_db_prefix . 'posts', $old_urls, $new_urls, array( 'post_content', 'post_excerpt', 'post_content_filtered' ) );
  313. pb_backupbuddy::status( 'message', 'Site URLs updated in posts table.' );
  314. // Misc string replacements
  315. pb_backupbuddy::status( 'message', 'Replacing WordPress core database text data...' );
  316. $dbreplace->text( $destination_db_prefix . 'users', $old_urls, $new_urls, array( 'user_url' ) );
  317. $dbreplace->text( $destination_db_prefix . 'comments', $old_urls, $new_urls, array( 'comment_content', 'comment_author_url' ) );
  318. $dbreplace->text( $destination_db_prefix . 'links', $old_urls, $new_urls, array( 'link_url', 'link_image', 'link_target', 'link_description', 'link_notes', 'link_rss' ) );
  319. pb_backupbuddy::status( 'message', 'WordPress core database text replaced.' );
  320. // Misc serialized data replacements.
  321. pb_backupbuddy::status( 'message', 'Replacing WordPress core database serialized data...' );
  322. $dbreplace->serialized( $destination_db_prefix . 'options', $old_fullreplace, $new_fullreplace, array( 'option_value' ) );
  323. $dbreplace->serialized( $multisite_network_db_prefix . 'usermeta', $old_fullreplace, $new_fullreplace, array( 'meta_value' ) );
  324. $dbreplace->serialized( $destination_db_prefix . 'postmeta', $old_fullreplace, $new_fullreplace, array( 'meta_value' ) );
  325. $dbreplace->serialized( $destination_db_prefix . 'commentmeta', $old_fullreplace, $new_fullreplace, array( 'meta_value' ) );
  326. pb_backupbuddy::status( 'message', 'WordPress core database serialized data replaced.' );
  327. foreach ( $bruteforce_tables as $bruteforce_table ) {
  328. $dbreplace->bruteforce_table( $bruteforce_table, $old_fullreplace, $new_fullreplace );
  329. }
  330. // Update table prefixes in some WordPress meta data. $multisite_network_db_prefix is set to the normal prefix in non-ms environment.
  331. $old_prefix = pb_backupbuddy::$options['dat_file']['db_prefix'];
  332. $new_prefix = mysql_real_escape_string( $destination_db_prefix );
  333. pb_backupbuddy::status( 'details', 'Old DB prefix: `' . $old_prefix . '`; New DB prefix: `' . $new_prefix . '`. Network prefix: `' . $multisite_network_db_prefix . '`' );
  334. if ($old_prefix != $new_prefix ) {
  335. mysql_query("UPDATE `".$new_prefix."usermeta` SET meta_key = REPLACE(meta_key, '".$old_prefix."', '".$new_prefix."' );"); // usermeta table temporarily is in the new subsite's prefix until next step.
  336. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating meta_key\'s for DB prefix in subsite\'s temporary usermeta table from `' . mysql_real_escape_string( $old_prefix ) . '` to `' . mysql_real_escape_string( $new_prefix ) . '`.' );
  337. mysql_query("UPDATE `".$new_prefix."options` SET option_name = '".$new_prefix."user_roles' WHERE option_name ='".$old_prefix."user_roles' LIMIT 1");
  338. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating option_name user_roles DB prefix in subsite\'s options table to `' . mysql_real_escape_string( $new_prefix ) . '`.' );
  339. pb_backupbuddy::status( 'message', 'Updated prefix META data.' );
  340. }
  341. // LASTLY UPDATE SITE/HOME URLS to prevent double replacement; just in case!
  342. // Update SITEURL in options table. Usually mass replacement will cover this but set these here just in case.
  343. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( $destination_siteurl ) . "' WHERE option_name='siteurl' LIMIT 1" );
  344. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Site URL in options table `' . $destination_db_prefix . 'options` to `' . $destination_siteurl . '`.' );
  345. // Update HOME URL in options table. Usually mass replacement will cover this but set these here just in case.
  346. if ( $destination_home != '' ) {
  347. mysql_query( "UPDATE `" . $destination_db_prefix . "options` SET option_value='" . mysql_real_escape_string( $destination_home ) . "' WHERE option_name='home' LIMIT 1" );
  348. pb_backupbuddy::status( 'details', 'Modified ' . mysql_affected_rows() . ' row(s) while updating Home URL in options table to `' . $destination_home . '`.' );
  349. }
  350. pb_backupbuddy::status( 'message', 'Migrated ' . count( $bruteforce_tables ) . ' tables via brute force.' );
  351. pb_backupbuddy::status( 'message', 'Took ' . round( microtime( true ) - pb_backupbuddy::$start_time, 3 ) . ' seconds. Done.' );
  352. pb_backupbuddy::status( 'message', 'Database content migrated.' );
  353. $return = true; // Needed for importbuddy since the following return does not trigger since it's in an include.
  354. return true;
  355. ?>