All-in-One WP Migration - Version 5.43

Version Description

  • Fix an issue when archiving dynamic files on export
  • Support custom upload path for multisites
  • Add support for various cache plugins
Download this release

Release Info

Developer bangelov
Plugin Icon 128x128 All-in-One WP Migration
Version 5.43
Comparing to
See all releases

Code changes from version 5.42 to 5.43

all-in-one-wp-migration.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Migration tool for all your blog data. Import or Export your blog content with a single click.
6
  * Author: ServMask
7
  * Author URI: https://servmask.com/
8
- * Version: 5.42
9
  * Text Domain: all-in-one-wp-migration
10
  * Domain Path: /languages
11
  * Network: True
5
  * Description: Migration tool for all your blog data. Import or Export your blog content with a single click.
6
  * Author: ServMask
7
  * Author URI: https://servmask.com/
8
+ * Version: 5.43
9
  * Text Domain: all-in-one-wp-migration
10
  * Domain Path: /languages
11
  * Network: True
constants.php CHANGED
@@ -39,7 +39,7 @@ if ( function_exists( 'gethostname' ) && in_array( gethostname(), $local ) ) {
39
  // ==================
40
  // = Plugin Version =
41
  // ==================
42
- define( 'AI1WM_VERSION', '5.42' );
43
 
44
  // ===============
45
  // = Plugin Name =
@@ -258,6 +258,11 @@ if ( ! defined( 'WP_CONTENT_DIR' ) ) {
258
  // ================
259
  define( 'AI1WM_UPLOADS_PATH', 'uploads' );
260
 
 
 
 
 
 
261
  // ==============
262
  // = Sites Path =
263
  // ==============
39
  // ==================
40
  // = Plugin Version =
41
  // ==================
42
+ define( 'AI1WM_VERSION', '5.43' );
43
 
44
  // ===============
45
  // = Plugin Name =
258
  // ================
259
  define( 'AI1WM_UPLOADS_PATH', 'uploads' );
260
 
261
+ // ==============
262
+ // = Blogs Path =
263
+ // ==============
264
+ define( 'AI1WM_BLOGSDIR_PATH', 'blogs.dir' );
265
+
266
  // ==============
267
  // = Sites Path =
268
  // ==============
functions.php CHANGED
@@ -366,6 +366,48 @@ function ai1wm_sites_path( $blog_id = null ) {
366
  return AI1WM_SITES_PATH . DIRECTORY_SEPARATOR . $blog_id;
367
  }
368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
  /**
370
  * Get uploads absolute path by blog ID
371
  *
@@ -587,6 +629,28 @@ function ai1wm_active_plugins() {
587
  return array_values( get_option( AI1WM_ACTIVE_PLUGINS, array() ) );
588
  }
589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  /**
591
  * URL encode
592
  *
366
  return AI1WM_SITES_PATH . DIRECTORY_SEPARATOR . $blog_id;
367
  }
368
 
369
+ /**
370
+ * Get files absolute path by blog ID
371
+ *
372
+ * @param integer $blog_id Blog ID
373
+ * @return string
374
+ */
375
+ function ai1wm_files_path( $blog_id = null ) {
376
+ if ( ai1wm_main_site( $blog_id ) ) {
377
+ return AI1WM_UPLOADS_PATH;
378
+ }
379
+
380
+ return AI1WM_BLOGSDIR_PATH . DIRECTORY_SEPARATOR . $blog_id . DIRECTORY_SEPARATOR . 'files';
381
+ }
382
+
383
+ /**
384
+ * Get blogs.dir absolute path by blog ID
385
+ *
386
+ * @param integer $blog_id Blog ID
387
+ * @return string
388
+ */
389
+ function ai1wm_blogsdir_path( $blog_id = null ) {
390
+ if ( ai1wm_main_site( $blog_id ) ) {
391
+ return "/wp-content/blogs.dir/";
392
+ }
393
+
394
+ return "/wp-content/blogs.dir/{$blog_id}/files/";
395
+ }
396
+
397
+ /**
398
+ * Get blogs.dir URL by blog ID
399
+ *
400
+ * @param integer $blog_id Blog ID
401
+ * @return string
402
+ */
403
+ function ai1wm_blogsdir_url( $blog_id = null ) {
404
+ if ( ai1wm_main_site( $blog_id ) ) {
405
+ return get_site_url( $blog_id, "/wp-content/blogs.dir/" );
406
+ }
407
+
408
+ return get_site_url( $blog_id, "/wp-content/blogs.dir/{$blog_id}/files/" );
409
+ }
410
+
411
  /**
412
  * Get uploads absolute path by blog ID
413
  *
629
  return array_values( get_option( AI1WM_ACTIVE_PLUGINS, array() ) );
630
  }
631
 
632
+ /**
633
+ * Flush WP options cache
634
+ *
635
+ * @return void
636
+ */
637
+ function ai1wm_cache_flush() {
638
+ // Initialize WP cache
639
+ wp_cache_init();
640
+
641
+ // Flush WP cache
642
+ wp_cache_flush();
643
+
644
+ // Set WP cache
645
+ wp_cache_set( 'alloptions', array(), 'options' );
646
+ wp_cache_set( 'notoptions', array(), 'options' );
647
+
648
+ // Delete WP cache
649
+ wp_cache_delete( 'alloptions', 'options' );
650
+ wp_cache_delete( 'notoptions', 'options' );
651
+ }
652
+
653
+
654
  /**
655
  * URL encode
656
  *
lib/model/class-ai1wm-http.php CHANGED
@@ -85,8 +85,8 @@ class Ai1wm_Http {
85
  // HTTP response
86
  for ( $i = 0; $i < 5; $i++, sleep( 1 ) ) {
87
 
88
- // Initialize empty WP cache
89
- wp_cache_init();
90
 
91
  // Is valid transport layer?
92
  if ( get_option( AI1WM_URL_IP ) && get_option( AI1WM_URL_TRANSPORT ) ) {
85
  // HTTP response
86
  for ( $i = 0; $i < 5; $i++, sleep( 1 ) ) {
87
 
88
+ // Flush WP cache
89
+ ai1wm_cache_flush();
90
 
91
  // Is valid transport layer?
92
  if ( get_option( AI1WM_URL_IP ) && get_option( AI1WM_URL_TRANSPORT ) ) {
lib/model/export/class-ai1wm-export-config.php CHANGED
@@ -31,8 +31,8 @@ class Ai1wm_Export_Config {
31
  // Set progress
32
  Ai1wm_Status::info( __( 'Adding configuration to archive...', AI1WM_PLUGIN_NAME ) );
33
 
34
- // Initialize empty WP cache
35
- wp_cache_init();
36
 
37
  // Get options
38
  $options = wp_load_alloptions();
31
  // Set progress
32
  Ai1wm_Status::info( __( 'Adding configuration to archive...', AI1WM_PLUGIN_NAME ) );
33
 
34
+ // Flush WP cache
35
+ ai1wm_cache_flush();
36
 
37
  // Get options
38
  $options = wp_load_alloptions();
lib/model/export/class-ai1wm-export-enumerate.php CHANGED
@@ -33,6 +33,11 @@ class Ai1wm_Export_Enumerate {
33
  // Set exclude filters
34
  $exclude_filters = ai1wm_content_filters();
35
 
 
 
 
 
 
36
  // Exclude themes
37
  if ( isset( $params['options']['no_themes'] ) ) {
38
  $exclude_filters[] = 'themes';
33
  // Set exclude filters
34
  $exclude_filters = ai1wm_content_filters();
35
 
36
+ // Exclude cache
37
+ if ( isset( $params['options']['no_cache'] ) ) {
38
+ $exclude_filters[] = 'cache';
39
+ }
40
+
41
  // Exclude themes
42
  if ( isset( $params['options']['no_themes'] ) ) {
43
  $exclude_filters[] = 'themes';
lib/model/import/class-ai1wm-import-content.php CHANGED
@@ -100,15 +100,41 @@ class Ai1wm_Import_Content {
100
 
101
  // Set extract paths
102
  foreach ( $blogs as $blog ) {
103
- $old_paths[] = ai1wm_sites_path( $blog->Old->Id );
104
- $new_paths[] = ai1wm_sites_path( $blog->New->Id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  }
106
 
107
  while ( $archive->has_not_reached_eof() ) {
108
  try {
109
 
 
 
 
 
 
 
 
 
 
 
 
110
  // Extract a file from archive to WP_CONTENT_DIR
111
- if ( ( $content_offset = $archive->extract_one_file_to( WP_CONTENT_DIR, array( AI1WM_PACKAGE_NAME, AI1WM_MULTISITE_NAME, AI1WM_DATABASE_NAME, AI1WM_MUPLUGINS_NAME ), $old_paths, $new_paths, $content_offset, 10 ) ) ) {
112
 
113
  // Set progress
114
  if ( ( $processed += $content_offset ) ) {
100
 
101
  // Set extract paths
102
  foreach ( $blogs as $blog ) {
103
+ if ( defined( 'UPLOADBLOGSDIR' ) ) {
104
+ // Old sites dir style
105
+ $old_paths[] = ai1wm_files_path( $blog->Old->Id );
106
+ $new_paths[] = ai1wm_files_path( $blogs->New->Id );
107
+
108
+ // New sites dir style
109
+ $old_paths[] = ai1wm_sites_path( $blog->Old->Id );
110
+ $new_paths[] = ai1wm_files_path( $blog->New->Id );
111
+ } else {
112
+ // Old sites dir style
113
+ $old_paths[] = ai1wm_files_path( $blog->Old->Id );
114
+ $new_paths[] = ai1wm_sites_path( $blog->New->Id );
115
+
116
+ // New sites dir style
117
+ $old_paths[] = ai1wm_sites_path( $blog->Old->Id );
118
+ $new_paths[] = ai1wm_sites_path( $blog->New->Id );
119
+ }
120
  }
121
 
122
  while ( $archive->has_not_reached_eof() ) {
123
  try {
124
 
125
+ // Exclude WordPress files
126
+ $exclude_files = array_keys( _get_dropins() );
127
+
128
+ // Exclude plugin files
129
+ $exclude_files = array_merge( $exclude_files, array(
130
+ AI1WM_PACKAGE_NAME,
131
+ AI1WM_MULTISITE_NAME,
132
+ AI1WM_DATABASE_NAME,
133
+ AI1WM_MUPLUGINS_NAME,
134
+ ) );
135
+
136
  // Extract a file from archive to WP_CONTENT_DIR
137
+ if ( ( $content_offset = $archive->extract_one_file_to( WP_CONTENT_DIR, $exclude_files, $old_paths, $new_paths, $content_offset, 10 ) ) ) {
138
 
139
  // Set progress
140
  if ( ( $processed += $content_offset ) ) {
lib/model/import/class-ai1wm-import-database.php CHANGED
@@ -68,16 +68,70 @@ class Ai1wm_Import_Database {
68
  // Get Blog URLs
69
  foreach ( $blogs as $blog ) {
70
 
71
- // Get Upload Path
72
- if ( ! in_array( ai1wm_uploads_path( $blog->Old->Id ), $old_values ) ) {
73
- $old_values[] = ai1wm_uploads_path( $blog->Old->Id );
74
- $new_values[] = ai1wm_uploads_path( $blog->New->Id );
75
  }
76
 
77
- // Get escaped Upload Path
78
- if ( ! in_array( addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) ), $old_values ) ) {
79
- $old_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) );
80
- $new_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->New->Id ), '\/' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  // Get Site URL
@@ -378,8 +432,8 @@ class Ai1wm_Import_Database {
378
  // Import database
379
  $client->import( ai1wm_database_path( $params ) );
380
 
381
- // Initialize empty WP cache
382
- wp_cache_init();
383
 
384
  // Activate plugins
385
  activate_plugins( $active_servmask_plugins, null, is_multisite() );
68
  // Get Blog URLs
69
  foreach ( $blogs as $blog ) {
70
 
71
+ // Get blogs dir Upload Path
72
+ if ( ! in_array( sprintf( "'%s'", trim( ai1wm_blogsdir_path( $blog->Old->Id ), '/' ) ), $old_values ) ) {
73
+ $old_values[] = sprintf( "'%s'", trim( ai1wm_blogsdir_path( $blog->Old->Id ), '/' ) );
74
+ $new_values[] = sprintf( "'%s'", get_blog_option( $blog->New->Id, 'upload_path' ) );
75
  }
76
 
77
+ // Get sites Upload Path
78
+ if ( ! in_array( sprintf( "'%s'", trim( ai1wm_uploads_path( $blog->Old->Id ), '/' ) ), $old_values ) ) {
79
+ $old_values[] = sprintf( "'%s'", trim( ai1wm_uploads_path( $blog->Old->Id ), '/' ) );
80
+ $new_values[] = sprintf( "'%s'", get_blog_option( $blog->New->Id, 'upload_path' ) );
81
+ }
82
+
83
+ // Handle old and new sites dir style
84
+ if ( defined( 'UPLOADBLOGSDIR' ) ) {
85
+
86
+ // Get Upload Path
87
+ if ( ! in_array( ai1wm_blogsdir_path( $blog->Old->Id ), $old_values ) ) {
88
+ $old_values[] = ai1wm_blogsdir_path( $blog->Old->Id );
89
+ $new_values[] = ai1wm_blogsdir_path( $blog->New->Id );
90
+ }
91
+
92
+ // Get escaped Upload Path
93
+ if ( ! in_array( addslashes( addcslashes( ai1wm_blogsdir_path( $blog->Old->Id ), '\/' ) ), $old_values ) ) {
94
+ $old_values[] = addslashes( addcslashes( ai1wm_blogsdir_path( $blog->Old->Id ), '\/' ) );
95
+ $new_values[] = addslashes( addcslashes( ai1wm_blogsdir_path( $blog->New->Id ), '\/' ) );
96
+ }
97
+
98
+ // Get Upload Path
99
+ if ( ! in_array( ai1wm_uploads_path( $blog->Old->Id ), $old_values ) ) {
100
+ $old_values[] = ai1wm_uploads_path( $blog->Old->Id );
101
+ $new_values[] = ai1wm_blogsdir_path( $blog->New->Id );
102
+ }
103
+
104
+ // Get escaped Upload Path
105
+ if ( ! in_array( addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) ), $old_values ) ) {
106
+ $old_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) );
107
+ $new_values[] = addslashes( addcslashes( ai1wm_blogsdir_path( $blog->New->Id ), '\/' ) );
108
+ }
109
+
110
+ } else {
111
+
112
+ // Get Upload Path
113
+ if ( ! in_array( ai1wm_blogsdir_path( $blog->Old->Id ), $old_values ) ) {
114
+ $old_values[] = ai1wm_blogsdir_path( $blog->Old->Id );
115
+ $new_values[] = ai1wm_uploads_path( $blog->New->Id );
116
+ }
117
+
118
+ // Get escaped Upload Path
119
+ if ( ! in_array( addslashes( addcslashes( ai1wm_blogsdir_path( $blog->Old->Id ), '\/' ) ), $old_values ) ) {
120
+ $old_values[] = addslashes( addcslashes( ai1wm_blogsdir_path( $blog->Old->Id ), '\/' ) );
121
+ $new_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->New->Id ), '\/' ) );
122
+ }
123
+
124
+ // Get Upload Path
125
+ if ( ! in_array( ai1wm_uploads_path( $blog->Old->Id ), $old_values ) ) {
126
+ $old_values[] = ai1wm_uploads_path( $blog->Old->Id );
127
+ $new_values[] = ai1wm_uploads_path( $blog->New->Id );
128
+ }
129
+
130
+ // Get escaped Upload Path
131
+ if ( ! in_array( addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) ), $old_values ) ) {
132
+ $old_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->Old->Id ), '\/' ) );
133
+ $new_values[] = addslashes( addcslashes( ai1wm_uploads_path( $blog->New->Id ), '\/' ) );
134
+ }
135
  }
136
 
137
  // Get Site URL
432
  // Import database
433
  $client->import( ai1wm_database_path( $params ) );
434
 
435
+ // Flush WP cache
436
+ ai1wm_cache_flush();
437
 
438
  // Activate plugins
439
  activate_plugins( $active_servmask_plugins, null, is_multisite() );
lib/model/import/class-ai1wm-import-done.php CHANGED
@@ -52,16 +52,17 @@ class Ai1wm_Import_Done {
52
  }
53
  }
54
 
55
- // Set the new MS files rewriting
56
- if ( get_site_option( AI1WM_MS_FILES_REWRITING ) ) {
57
- update_site_option( AI1WM_MS_FILES_REWRITING, 0 );
58
- }
59
-
60
  // Open the archive file for reading
61
  $archive = new Ai1wm_Extractor( ai1wm_archive_path( $params ) );
62
 
63
- // Unpack must-use plugins
64
- $archive->extract_by_files_array( WP_CONTENT_DIR, array( AI1WM_MUPLUGINS_NAME ) );
 
 
 
 
 
 
65
 
66
  // Close the archive file
67
  $archive->close();
52
  }
53
  }
54
 
 
 
 
 
 
55
  // Open the archive file for reading
56
  $archive = new Ai1wm_Extractor( ai1wm_archive_path( $params ) );
57
 
58
+ // Include WordPress files
59
+ $include_files = array_keys( _get_dropins() );
60
+
61
+ // Include mu-plugins files
62
+ $include_files = array_merge( $include_files, array( AI1WM_MUPLUGINS_NAME ) );
63
+
64
+ // Unpack WordPress files and mu-plugins files
65
+ $archive->extract_by_files_array( WP_CONTENT_DIR, $include_files );
66
 
67
  // Close the archive file
68
  $archive->close();
lib/vendor/servmask/archiver/class-ai1wm-compressor.php CHANGED
@@ -63,12 +63,22 @@ class Ai1wm_Compressor extends Ai1wm_Archiver {
63
  $this->write_to_handle( $this->file_handle, $block, $this->filename );
64
  }
65
 
 
 
 
66
  // start time
67
  $start = microtime( true );
68
 
69
  // read the file in 512KB chunks
70
- while ( false === feof( $handle ) ) {
71
- $content = $this->read_from_handle( $handle, 512000, $file );
 
 
 
 
 
 
 
72
 
73
  // write file contents
74
  $this->write_to_handle( $this->file_handle, $content, $this->filename );
63
  $this->write_to_handle( $this->file_handle, $block, $this->filename );
64
  }
65
 
66
+ // set file size
67
+ $current_filesize = $this->get_current_filesize() - $offset;
68
+
69
  // start time
70
  $start = microtime( true );
71
 
72
  // read the file in 512KB chunks
73
+ while ( $current_filesize > 0 ) {
74
+ // read the file in chunks of 512KB
75
+ $chunk_size = $current_filesize > 512000 ? 512000 : $current_filesize;
76
+
77
+ // read the file in chunks of 512KB
78
+ $content = $this->read_from_handle( $handle, $chunk_size, $file );
79
+
80
+ // remove the amount of bytes we read
81
+ $current_filesize -= $chunk_size;
82
 
83
  // write file contents
84
  $this->write_to_handle( $this->file_handle, $content, $this->filename );
lib/vendor/servmask/archiver/class-ai1wm-extractor.php CHANGED
@@ -300,7 +300,7 @@ class Ai1wm_Extractor extends Ai1wm_Archiver {
300
  // read the file in chunks of 512KB from archiver
301
  $content = $this->read_from_handle( $this->file_handle, $chunk_size, $this->filename );
302
 
303
- // remote the amount of bytes we read
304
  $data['size'] -= $chunk_size;
305
 
306
  // write file contents
@@ -372,6 +372,11 @@ class Ai1wm_Extractor extends Ai1wm_Archiver {
372
  return ! feof( $this->file_handle );
373
  }
374
 
 
 
 
 
 
375
  public function get_file_pointer() {
376
  $result = ftell( $this->file_handle );
377
 
300
  // read the file in chunks of 512KB from archiver
301
  $content = $this->read_from_handle( $this->file_handle, $chunk_size, $this->filename );
302
 
303
+ // remove the amount of bytes we read
304
  $data['size'] -= $chunk_size;
305
 
306
  // write file contents
372
  return ! feof( $this->file_handle );
373
  }
374
 
375
+ /**
376
+ * Get current file pointer
377
+ *
378
+ * return int
379
+ */
380
  public function get_file_pointer() {
381
  $result = ftell( $this->file_handle );
382
 
lib/view/export/advanced-settings.php CHANGED
@@ -26,6 +26,15 @@
26
  <input type="checkbox" id="ai1wm-no-plugins" name="options[no_plugins]" />
27
  <label for="ai1wm-no-plugins"><?php _e( 'Do <strong>not</strong> export plugins (files)', AI1WM_PLUGIN_NAME ); ?></label>
28
  </li>
 
 
 
 
 
 
 
 
 
29
  <li>
30
  <input type="checkbox" id="ai1wm-no-database" name="options[no_database]" />
31
  <label for="ai1wm-no-database"><?php _e( 'Do <strong>not</strong> export database (sql)', AI1WM_PLUGIN_NAME ); ?></label>
26
  <input type="checkbox" id="ai1wm-no-plugins" name="options[no_plugins]" />
27
  <label for="ai1wm-no-plugins"><?php _e( 'Do <strong>not</strong> export plugins (files)', AI1WM_PLUGIN_NAME ); ?></label>
28
  </li>
29
+
30
+ <?php if ( apply_filters( 'ai1wm_max_file_size', AI1WM_MAX_FILE_SIZE ) === 0 ): ?>
31
+ <li>
32
+ <input type="checkbox" id="ai1wm-no-cache" name="options[no_cache]" />
33
+ <label for="ai1wm-no-cache"><?php _e( 'Do <strong>not</strong> export cache (files)', AI1WM_PLUGIN_NAME ); ?></label>
34
+ <small style="color:red"><?php _e( 'new', AI1WM_PLUGIN_NAME ); ?></small>
35
+ </li>
36
+ <?php endif; ?>
37
+
38
  <li>
39
  <input type="checkbox" id="ai1wm-no-database" name="options[no_database]" />
40
  <label for="ai1wm-no-database"><?php _e( 'Do <strong>not</strong> export database (sql)', AI1WM_PLUGIN_NAME ); ?></label>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: yani.iliev, bangelov, pimjitsawang
3
  Tags: db migration, migration, wordpress migration, db backup, db restore, website backup, website restore, website migration, website deploy, wordpress deploy, db backup, database export, database serialization, database find replace
4
  Requires at least: 3.3
5
  Tested up to: 4.5
6
- Stable tag: 5.42
7
  License: GPLv2 or later
8
 
9
  All-in-One WP Migration is the only tool that you will ever need to migrate a WordPress site.
@@ -75,6 +75,11 @@ All in One WP Plugin is the first plugin to offer true mobile experience on Word
75
  3. Plugin Menu
76
 
77
  == Changelog ==
 
 
 
 
 
78
  = 5.42 =
79
  * Catch E_PARSE error on mu-plugins import
80
  * Fix an issue with stop export that doesn't clean up the storage directory
3
  Tags: db migration, migration, wordpress migration, db backup, db restore, website backup, website restore, website migration, website deploy, wordpress deploy, db backup, database export, database serialization, database find replace
4
  Requires at least: 3.3
5
  Tested up to: 4.5
6
+ Stable tag: 5.43
7
  License: GPLv2 or later
8
 
9
  All-in-One WP Migration is the only tool that you will ever need to migrate a WordPress site.
75
  3. Plugin Menu
76
 
77
  == Changelog ==
78
+ = 5.43 =
79
+ * Fix an issue when archiving dynamic files on export
80
+ * Support custom upload path for multisites
81
+ * Add support for various cache plugins
82
+
83
  = 5.42 =
84
  * Catch E_PARSE error on mu-plugins import
85
  * Fix an issue with stop export that doesn't clean up the storage directory