Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions inc/duplication/data.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,9 @@ public static function db_copy_tables($from_site_id, $to_site_id) {
*
* Runtime-only tables are skipped by default because queues, logs, caches,
* analytics, and sessions are regenerated on the destination site. Empty
* optional/custom tables are also skipped to avoid spending most of the
* duplication time cloning schemas with no template data. WordPress core
* content/config tables are always copied because wpmu_create_blog() creates
* destination defaults that must be replaced with template values.
* per-site tables are copied by default so plugins retain the complete schema
* they expect on the destination. Installations can opt into skipping empty
* optional tables through the dedicated filter.
*
* @since 2.5.1
*
Expand All @@ -182,7 +181,7 @@ public static function should_copy_table($table, $table_base_name, $from_site_id
*
* Returning true forces a table to be copied; returning false skips it.
* This preserves extension control over custom table duplication while
* keeping the default path optimized for empty/runtime template tables.
* keeping runtime table exclusions centralized.
*
* @since 2.5.1
*
Expand Down Expand Up @@ -297,7 +296,7 @@ private static function skip_empty_tables($from_site_id, $to_site_id) {
* @param int $from_site_id Source site ID.
* @param int $to_site_id Target site ID.
*/
return (bool) apply_filters('wu_mucd_skip_empty_tables', true, $from_site_id, $to_site_id);
return (bool) apply_filters('wu_mucd_skip_empty_tables', false, $from_site_id, $to_site_id);
}

/**
Expand Down
38 changes: 32 additions & 6 deletions tests/WP_Ultimo/Duplication/MUCD_Data_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@
* Test try_replace with serialized array data.
*/
public function test_try_replace_serialized_array() {
$data = serialize(['url' => 'https://example.com/old-site/page']);

Check warning on line 93 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

serialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection
$row = ['meta_value' => $data];

Check warning on line 94 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Detected usage of meta_value, possible slow query.

$result = \MUCD_Data::try_replace($row, 'meta_value', 'example.com/old-site', 'example.com/new-site');

$unserialized = unserialize($result);

Check warning on line 98 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

unserialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection
$this->assertEquals('https://example.com/new-site/page', $unserialized['url']);
}

Expand All @@ -103,17 +103,17 @@
* Test try_replace with nested serialized data.
*/
public function test_try_replace_nested_serialized_array() {
$data = serialize([

Check warning on line 106 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

serialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection
'settings' => [
'link' => 'https://example.com/old-site/about',
'icon' => 'fa-home',
],
'content' => 'Visit https://example.com/old-site for more',
]);
$row = ['meta_value' => $data];

Check warning on line 113 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Detected usage of meta_value, possible slow query.

$result = \MUCD_Data::try_replace($row, 'meta_value', 'example.com/old-site', 'example.com/new-site');
$unserialized = unserialize($result);

Check warning on line 116 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

unserialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection

$this->assertEquals('https://example.com/new-site/about', $unserialized['settings']['link']);
$this->assertEquals('Visit https://example.com/new-site for more', $unserialized['content']);
Expand All @@ -135,12 +135,12 @@
* Test try_replace with double-serialized data.
*/
public function test_try_replace_double_serialized() {
$data = serialize(serialize(['url' => 'https://example.com/old-site/page']));

Check warning on line 138 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

serialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection

Check warning on line 138 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

serialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection
$row = ['meta_value' => $data];

Check warning on line 139 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

Detected usage of meta_value, possible slow query.

$result = \MUCD_Data::try_replace($row, 'meta_value', 'example.com/old-site', 'example.com/new-site');

$unserialized = unserialize(unserialize($result));

Check warning on line 143 in tests/WP_Ultimo/Duplication/MUCD_Data_Test.php

View workflow job for this annotation

GitHub Actions / Code Quality Checks

unserialize() found. Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data. See https://www.owasp.org/index.php/PHP_Object_Injection
$this->assertEquals('https://example.com/new-site/page', $unserialized['url']);
}

Expand Down Expand Up @@ -642,18 +642,19 @@
}

/**
* Test empty optional template tables are skipped by default.
* Test empty optional template tables are copied by default.
*/
public function test_should_copy_table_skips_empty_optional_tables() {
public function test_should_copy_table_keeps_empty_optional_tables_by_default() {
global $wpdb;

$table = $wpdb->get_blog_prefix() . 'wu_empty_runtime_fixture';
$table_base_name = 'fc_wp_ultimo_test_subscriber_pivot';
$table = $wpdb->get_blog_prefix() . $table_base_name;

$this->create_table_selection_fixture($table);

try {
$this->assertFalse(
\MUCD_Data::should_copy_table($table, 'wu_empty_runtime_fixture', get_current_blog_id(), 123)
$this->assertTrue(
\MUCD_Data::should_copy_table($table, $table_base_name, get_current_blog_id(), 123)
);
} finally {
$this->drop_table_selection_fixture($table);
Expand Down Expand Up @@ -695,6 +696,30 @@
);
}

/**
* Test installations can opt into skipping empty optional tables.
*/
public function test_should_copy_table_can_skip_empty_optional_tables_when_enabled() {
global $wpdb;

$table = $wpdb->get_blog_prefix() . 'wu_empty_runtime_fixture';
$filter = static function () {
return true;
};

$this->create_table_selection_fixture($table);
add_filter('wu_mucd_skip_empty_tables', $filter, 10, 3);

try {
$this->assertFalse(
\MUCD_Data::should_copy_table($table, 'wu_empty_runtime_fixture', get_current_blog_id(), 123)
);
} finally {
remove_filter('wu_mucd_skip_empty_tables', $filter, 10);
$this->drop_table_selection_fixture($table);
}
}

/**
* Test filters can force-copy a table skipped by default.
*/
Expand Down Expand Up @@ -752,7 +777,8 @@

$this->drop_table_selection_fixture($table);

$wpdb->query( // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Test fixture table name cannot be bound.
$wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Test fixture table name cannot be bound.
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Test fixture table name cannot be bound.
"CREATE TABLE `{$table}` (id bigint(20) unsigned NOT NULL AUTO_INCREMENT, value varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (id))"
);
}
Expand Down
Loading