From 43d204b9740d665642bbdb0b0a11ffd4a50c76a8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 5 Dec 2022 07:20:36 -0800 Subject: [PATCH 1/4] Restore @jmdodd code from #91 --- src/Export_Command.php | 26 ++++++++++++++++++++++++++ src/WP_Export_Split_Files_Writer.php | 25 +++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/Export_Command.php b/src/Export_Command.php index 31381adb..313344c7 100644 --- a/src/Export_Command.php +++ b/src/Export_Command.php @@ -29,6 +29,7 @@ class Export_Command extends WP_CLI_Command { private $stdout; private $max_file_size; + private $include_once; private $wxr_path; /** @@ -100,6 +101,11 @@ class Export_Command extends WP_CLI_Command { * [--filename_format=] * : Use a custom format for export filenames. Defaults to '{site}.wordpress.{date}.{n}.xml'. * + * [--include_once=] + * : Include specified export section only in the first export file. Valid options + * are categories, tags, nav_menu_items, custom_taxonomies_terms. Separate multiple + * sections with a comma. Defaults to none. + * * ## EXAMPLES * * # Export posts published by the user between given start and end date @@ -138,6 +144,7 @@ public function __invoke( $_, $assoc_args ) { 'skip_comments' => null, 'max_file_size' => 15, 'filename_format' => '{site}.wordpress.{date}.{n}.xml', + 'include_once' => null, ]; if ( ! empty( $assoc_args['stdout'] ) && ( ! empty( $assoc_args['dir'] ) || ! empty( $assoc_args['filename_format'] ) ) ) { @@ -192,6 +199,7 @@ static function ( $file_path ) { 'max_file_size' => $this->max_file_size, 'destination_directory' => $this->wxr_path, 'filename_template' => self::get_filename_template( $assoc_args['filename_format'] ), + 'include_once' => $this->include_once, ], ] ); @@ -466,4 +474,22 @@ private function check_max_file_size( $size ) { return true; } + + private function check_include_once( $include_once ) { + if ( null === $include_once ) { + return true; + } + + $separator = false !== stripos( $include_once, ' ' ) ? ' ' : ','; + $include_once = array_filter( array_unique( array_map( 'strtolower', explode( $separator, $include_once ) ) ) ); + $include_once = array_intersect( $include_once, array( 'categories', 'tags', 'nav_menu_terms', 'custom_taxonomies_terms' ) ); + if ( empty( $include_once ) ) { + WP_CLI::warning( 'include_once should be comma-separated values for optional before_posts sections.' ); + return false; + } + + $this->include_once = $include_once; + + return true; + } } diff --git a/src/WP_Export_Split_Files_Writer.php b/src/WP_Export_Split_Files_Writer.php index 77ab4db9..91f1633a 100644 --- a/src/WP_Export_Split_Files_Writer.php +++ b/src/WP_Export_Split_Files_Writer.php @@ -8,8 +8,19 @@ class WP_Export_Split_Files_Writer extends WP_Export_Base_Writer { private $after_posts_xml; private $f; - private $next_file_number = 0; - private $current_file_size = 0; + private $next_file_number = 0; + private $current_file_size = 0; + private $available_sections = array( + 'header', + 'site_metadata', + 'authors', + 'categories', + 'tags', + 'nav_menu_terms', + 'custom_taxonomies_terms', + 'rss2_head_action', + ); + private $subsequent_sections = array(); public function __construct( $formatter, $writer_args = [] ) { parent::__construct( $formatter ); @@ -28,6 +39,12 @@ public function __construct( $formatter, $writer_args = [] ) { $this->max_file_size = $writer_args['max_file_size'] * MB_IN_BYTES; } + // Filter and handle condition where subsequent export files should not contain + // all of the export sections + if ( is_array( $writer_args['include_once'] ) && ! empty( $writer_args['include_once'] ) ) { + $this->subsequent_sections = array_diff( $this->available_sections, $writer_args['include_once'] ); + } + $this->destination_directory = $writer_args['destination_directory']; $this->filename_template = $writer_args['filename_template']; $this->before_posts_xml = $this->formatter->before_posts(); @@ -65,7 +82,11 @@ private function start_new_file() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Possibly used by third party extension. do_action( 'wp_export_new_file', $file_path ); $this->current_file_size = 0; + $this->write( $this->before_posts_xml ); + if ( 1 === $this->next_file_number && ! empty( $this->subsequent_sections ) ) { + $this->before_posts_xml = $this->formatter->before_posts( $this->subsequent_sections ); + } } private function close_current_file() { From c484aa11f4e7f134c1dee5de1f1c2999fc199646 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 5 Dec 2022 07:37:28 -0800 Subject: [PATCH 2/4] Add a test case for `--include_once=
` --- features/export.feature | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/features/export.feature b/features/export.feature index b6849d05..79c2235e 100644 --- a/features/export.feature +++ b/features/export.feature @@ -652,13 +652,47 @@ Feature: Export content. Scenario: Export splitting the dump Given a WP install - When I run `wp export --max_file_size=0.0001` + When I run `wp export --max_file_size=0.0001 --filename_format='{n}.xml'` Then STDOUT should contain: """ 001.xml """ And STDERR should be empty + When I run `cat 000.xml` + Then STDOUT should contain: + """ + + """ + + When I run `cat 001.xml` + Then STDOUT should contain: + """ + + """ + + Scenario: Export splitting the dump with --include_once + Given a WP install + + When I run `wp export --max_file_size=0.0001 --include_once=categories --filename_format='{n}.xml'` + Then STDOUT should contain: + """ + 001.xml + """ + And STDERR should be empty + + When I run `cat 000.xml` + Then STDOUT should contain: + """ + + """ + + When I run `cat 001.xml` + Then STDOUT should not contain: + """ + + """ + Scenario: Export without splitting the dump Given a WP install # Make export file > 15MB so will split by default. Need to split into 4 * 4MB to stay below 10% of default redo log size of 48MB, otherwise get MySQL error. From 1008fa22d3ca76fc271d33431acfe2e89958ce60 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 5 Dec 2022 07:38:18 -0800 Subject: [PATCH 3/4] Move options to OPTIONS instead of FILTERS --- src/Export_Command.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Export_Command.php b/src/Export_Command.php index 313344c7..6cb5461f 100644 --- a/src/Export_Command.php +++ b/src/Export_Command.php @@ -57,6 +57,14 @@ class Export_Command extends WP_CLI_Command { * default: 15 * --- * + * [--filename_format=] + * : Use a custom format for export filenames. Defaults to '{site}.wordpress.{date}.{n}.xml'. + * + * [--include_once=] + * : Include specified export section only in the first export file. Valid options + * are categories, tags, nav_menu_items, custom_taxonomies_terms. Separate multiple + * sections with a comma. Defaults to none. + * * ## FILTERS * * [--start_date=] @@ -98,14 +106,6 @@ class Export_Command extends WP_CLI_Command { * [--post_status=] * : Export only posts with this status. * - * [--filename_format=] - * : Use a custom format for export filenames. Defaults to '{site}.wordpress.{date}.{n}.xml'. - * - * [--include_once=] - * : Include specified export section only in the first export file. Valid options - * are categories, tags, nav_menu_items, custom_taxonomies_terms. Separate multiple - * sections with a comma. Defaults to none. - * * ## EXAMPLES * * # Export posts published by the user between given start and end date From 149acfb1d2f2b49e99dda4d75faa81007a72428c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Thu, 8 Dec 2022 13:32:07 -0800 Subject: [PATCH 4/4] Add a couple more test cases for full coverage --- features/export.feature | 52 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/features/export.feature b/features/export.feature index 4b497b1a..0c330c26 100644 --- a/features/export.feature +++ b/features/export.feature @@ -682,8 +682,19 @@ Feature: Export content. """ - Scenario: Export splitting the dump with --include_once + Scenario: Export splitting the dump with a bad --include_once value Given a WP install + And I run `wp term generate post_tag --count=1` + + When I try `wp export --max_file_size=0.0001 --include_once=invalid --filename_format='{n}.xml'` + Then STDERR should contain: + """ + Warning: include_once should be comma-separated values for optional before_posts sections + """ + + Scenario: Export splitting the dump with a single --include_once value + Given a WP install + And I run `wp term generate post_tag --count=1` When I run `wp export --max_file_size=0.0001 --include_once=categories --filename_format='{n}.xml'` Then STDOUT should contain: @@ -697,12 +708,51 @@ Feature: Export content. """ """ + And STDOUT should contain: + """ + + """ + + When I run `cat 001.xml` + Then STDOUT should not contain: + """ + + """ + And STDOUT should contain: + """ + + """ + + Scenario: Export splitting the dump with multiple --include_once values + Given a WP install + And I run `wp term generate post_tag --count=1` + + When I run `wp export --max_file_size=0.0001 --include_once=categories,tags --filename_format='{n}.xml'` + Then STDOUT should contain: + """ + 001.xml + """ + And STDERR should be empty + + When I run `cat 000.xml` + Then STDOUT should contain: + """ + + """ + And STDOUT should contain: + """ + + """ When I run `cat 001.xml` Then STDOUT should not contain: """ """ + And STDOUT should not contain: + """ + + """ Scenario: Export without splitting the dump Given a WP install