Changeset 3658562
- Timestamp:
- 08/21/2026 08:33:53 AM (2 months ago)
- Location:
- dave-gerrits-site-migrator/trunk
- Files:
-
- 6 edited
-
admin/class-wmig-admin.php (modified) (2 diffs)
-
assets/export.js (modified) (2 diffs)
-
dave-gerrits-site-migrator.php (modified) (2 diffs)
-
includes/class-wmig-exporter.php (modified) (5 diffs)
-
includes/class-wmig-importer.php (modified) (3 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
dave-gerrits-site-migrator/trunk/admin/class-wmig-admin.php
r3638793 r3658562 226 226 227 227 $config = array( 228 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 229 'nonce' => $this->nonce(), 228 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 229 'nonce' => $this->nonce(), 230 'invalidResponse' => $this->tr( 231 'De server gaf geen geldig antwoord terug.', 232 'The server returned an invalid response.' 233 ), 230 234 ); 231 235 if ( 'import' === $script ) { … … 565 569 'size' => (int) filesize( $path ), 566 570 'chunk_size' => 16 * 1024 * 1024, 567 'fallback_url' => wp_nonce_url( admin_url( 'admin-post.php?action=wmig_download&token=' . rawurlencode( $token ) ), 'wmig_download_' . $token, '_wmig_download_nonce' ), 571 'fallback_url' => add_query_arg( 572 array( 573 'action' => 'wmig_download', 574 'token' => $token, 575 '_wmig_download_nonce' => wp_create_nonce( 'wmig_download_' . $token ), 576 ), 577 admin_url( 'admin-post.php' ) 578 ), 568 579 ) ); 569 580 } -
dave-gerrits-site-migrator/trunk/assets/export.js
r3637551 r3658562 5 5 (() => { 6 6 const ajaxUrl = window.WMIG_ADMIN.ajaxUrl, nonce = window.WMIG_ADMIN.nonce; 7 const invalidResponse = window.WMIG_ADMIN.invalidResponse || "De server gaf geen geldig antwoord terug."; 7 8 const $ = id => document.getElementById(id); 8 9 const start = $("wmig-export-start"), discard = $("wmig-export-discard"), stop = $("wmig-export-stop"), progress = $("wmig-export-progress"), bar = $("wmig-export-bar"), pct = $("wmig-export-percent"), status = $("wmig-export-status"), sub = $("wmig-export-sub"), error = $("wmig-export-error"), success = $("wmig-export-success"), meta = $("wmig-export-meta"), download = $("wmig-download"), delpkg = $("wmig-delete-package"), dstatus = $("wmig-download-status"), message = $("wmig-export-message"); … … 23 24 } 24 25 catch (e) { 25 throw new Error("De server gaf geen geldig antwoord terug."); 26 const preview = text 27 ? text.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim().slice(0, 180) 28 : ""; 29 throw new Error( 30 invalidResponse + 31 " HTTP " + r.status + 32 (preview ? ": " + preview : "") 33 ); 26 34 } 27 35 return j; -
dave-gerrits-site-migrator/trunk/dave-gerrits-site-migrator.php
r3650920 r3658562 3 3 * Plugin Name: Dave Gerrits Site Migrator 4 4 * Description: Export a complete WordPress website to one migration package and import it into a clean WordPress installation. 5 * Version: 1.0. 25 * Version: 1.0.3 6 6 * Author: Dave Gerrits 7 7 * Author URI: https://davegerrits.nl/ 8 8 * Requires at least: 6.0 9 * Tested up to: 7. 09 * Tested up to: 7.1 10 10 * Requires PHP: 7.4 11 11 * License: GPLv2 or later … … 18 18 } 19 19 20 define( 'WMIG_VERSION', '1.0. 2' );20 define( 'WMIG_VERSION', '1.0.3' ); 21 21 define( 'WMIG_FILE', __FILE__ ); 22 22 define( 'WMIG_DIR', plugin_dir_path( __FILE__ ) ); -
dave-gerrits-site-migrator/trunk/includes/class-wmig-exporter.php
r3650920 r3658562 338 338 } 339 339 340 /** 341 * Preserve arbitrary database bytes without forcing them through UTF-8 JSON. 342 * 343 * WordPress tables are usually textual, but plugins may use BINARY/VARBINARY 344 * columns (including primary keys). Invalid UTF-8 bytes must round-trip 345 * exactly; replacing them would corrupt keys and can create duplicates. 346 * 347 * @param mixed $value Database value. 348 * @return mixed Portable JSON-safe value. 349 */ 350 private function encode_database_value( $value ) { 351 if ( ! is_string( $value ) ) { 352 return $value; 353 } 354 355 if ( 1 === preg_match( '//u', $value ) ) { 356 return $value; 357 } 358 359 return array( 360 '__wmig_binary_b64_v1' => base64_encode( $value ), 361 ); 362 } 363 340 364 private function process_database( $state ) { 341 365 global $wpdb; … … 399 423 $sql = "SELECT * FROM `" . esc_sql( $table ) . "` ORDER BY {$pk_sql} ASC LIMIT {$batch}"; 400 424 } else { 425 $cursor_value = $state['table_cursor']; 426 if ( 427 is_array( $cursor_value ) && 428 isset( $cursor_value['__wmig_binary_b64_v1'] ) && 429 is_string( $cursor_value['__wmig_binary_b64_v1'] ) 430 ) { 431 $decoded_cursor = base64_decode( $cursor_value['__wmig_binary_b64_v1'], true ); 432 if ( false === $decoded_cursor ) { 433 fclose( $handle ); 434 return $this->fail( $state, 'Binaire databasecursor kon niet veilig worden hervat voor ' . $table . '.', false ); 435 } 436 $cursor_value = $decoded_cursor; 437 } 438 401 439 $sql = $wpdb->prepare( 402 440 "SELECT * FROM `" . esc_sql( $table ) . "` WHERE {$pk_sql} > %s ORDER BY {$pk_sql} ASC LIMIT {$batch}", 403 (string) $ state['table_cursor']441 (string) $cursor_value 404 442 ); 405 443 } … … 438 476 } 439 477 478 $portable_row = array(); 479 foreach ( $row as $column_name => $column_value ) { 480 $portable_row[ $column_name ] = $this->encode_database_value( $column_value ); 481 } 482 440 483 $encoded = wp_json_encode( 441 array( 'type' => 'row', 'data' => $ row ),442 JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE484 array( 'type' => 'row', 'data' => $portable_row ), 485 JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE 443 486 ); 444 487 if ( false === $encoded ) { … … 460 503 $last = end( $rows ); 461 504 if ( is_array( $last ) && array_key_exists( $pk, $last ) ) { 462 $state['table_cursor'] = $ last[ $pk ];505 $state['table_cursor'] = $this->encode_database_value( $last[ $pk ] ); 463 506 } 464 507 } … … 1640 1683 'progress' => 100, 1641 1684 'message' => 'Export gereed. Het migratiepakket kan worden gedownload.', 1642 'download_url' => wp_nonce_url( 1643 admin_url( 'admin-post.php?action=wmig_download&token=' . rawurlencode( $token ) ), 1644 'wmig_download_' . $token, 1645 '_wmig_download_nonce' 1685 'download_url' => add_query_arg( 1686 array( 1687 'action' => 'wmig_download', 1688 'token' => $token, 1689 '_wmig_download_nonce' => wp_create_nonce( 'wmig_download_' . $token ), 1690 ), 1691 admin_url( 'admin-post.php' ) 1646 1692 ), 1647 1693 'package_token' => $token, -
dave-gerrits-site-migrator/trunk/includes/class-wmig-importer.php
r3637551 r3658562 710 710 } 711 711 712 /** 713 * Restore a database value encoded by encode_database_value(). 714 * 715 * @param mixed $value Portable value from the migration package. 716 * @param string $table Current table, used in diagnostics. 717 * @param string $column Current column, used in diagnostics. 718 * @return mixed|WP_Error Restored database value. 719 */ 720 private function decode_database_value( $value, $table, $column ) { 721 if ( 722 is_array( $value ) && 723 array_key_exists( '__wmig_binary_b64_v1', $value ) 724 ) { 725 $encoded = $value['__wmig_binary_b64_v1']; 726 if ( ! is_string( $encoded ) ) { 727 return new WP_Error( 728 'wmig_db_binary_format', 729 sprintf( 'Ongeldige binaire databasewaarde in %s.%s.', $table, $column ) 730 ); 731 } 732 733 $decoded = base64_decode( $encoded, true ); 734 if ( false === $decoded ) { 735 return new WP_Error( 736 'wmig_db_binary_decode', 737 sprintf( 'Binaire databasewaarde kon niet worden hersteld in %s.%s.', $table, $column ) 738 ); 739 } 740 741 return $decoded; 742 } 743 744 return $value; 745 } 746 712 747 private function process_database( $state ) { 713 748 global $wpdb; … … 813 848 $row=array(); 814 849 foreach($record['data'] as $col=>$value){ 815 if(is_string($value)){ 850 $value = $this->decode_database_value( 851 $value, 852 (string) $state['db_target_table'], 853 (string) $col 854 ); 855 if ( is_wp_error( $value ) ) { 856 fclose( $h ); 857 return $value; 858 } 859 860 if(is_string($value) && 1 === preg_match('//u', $value)){ 816 861 $value=WMIG_Utils::recursive_replace($value,$old_siteurl,$new_siteurl); 817 862 $value=WMIG_Utils::recursive_replace($value,$old_url,$new_url); … … 865 910 866 911 $wpdb->insert($state['db_active_table'],$row); 867 if($wpdb->last_error){fclose($h);return new WP_Error('wmp_db_insert',$wpdb->last_error);} 912 if($wpdb->last_error){ 913 $db_error = $wpdb->last_error; 914 fclose($h); 915 return new WP_Error( 916 'wmp_db_insert', 917 'Databasefout bij tabel ' . (string) $state['db_target_table'] . ': ' . $db_error 918 ); 919 } 868 920 $rows++; 869 921 } -
dave-gerrits-site-migrator/trunk/readme.txt
r3650920 r3658562 3 3 Tags: migration, wordpress migration, site migration, backup, migrate 4 4 Requires at least: 6.0 5 Tested up to: 7. 06 Stable tag: 1.0. 25 Tested up to: 7.1 6 Stable tag: 1.0.3 7 7 Requires PHP: 7.4 8 8 License: GPLv2 or later … … 122 122 == Changelog == 123 123 124 = 1.0.3 = 125 * Improved secure migration package download URLs for broader hosting/browser compatibility. 126 * Database export/import is now binary-safe for plugin tables using binary values or primary keys. 127 * Improved export and database error diagnostics for easier troubleshooting. 128 124 129 = 1.0.2 = 125 130 * Fixed the secure migration package download link after a completed export.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)