hardening 2.4: 2meet-data-optimizer 1.4.0 (index-ordered routed sorts, date copy route, count invalidation) #8

Merged
wpdev merged 8 commits from hardening/2.4 into main 2026-09-27 23:40:31 +08:00
2 changed files with 34 additions and 0 deletions
Showing only changes of commit 2aa9058ee9 - Show all commits
@@ -278,6 +278,15 @@ final class TMDO_Entity_Migration_Engine {
} }
} }
// REPLACE drops columns it is not given: keep a post row's status/date
// copies, or one NULL row turns the copy route off for the group (2.4 PR-127).
if ( 'post' === $entity_type && class_exists( 'TMDO_Post_Status_Sync' ) ) {
foreach ( TMDO_Post_Status_Sync::insert_columns( $entity_id, $group_name ) as $col => $value ) {
$data[ $col ] = $value;
$formats[] = '%s';
}
}
if ( $dry_run ) { if ( $dry_run ) {
return true; return true;
} }
+25
View File
@@ -25,6 +25,7 @@ class PostStatusSyncTest extends TestCase {
'includes/adapters/class-tmdo-adapter-post.php', 'includes/adapters/class-tmdo-adapter-post.php',
'includes/engine/class-tmdo-hook-bus.php', 'includes/engine/class-tmdo-hook-bus.php',
'includes/engine/class-tmdo-post-status-sync.php', 'includes/engine/class-tmdo-post-status-sync.php',
'includes/engine/class-tmdo-entity-migration-engine.php',
) as $file ) { ) as $file ) {
require_once $base . $file; require_once $base . $file;
} }
@@ -173,6 +174,30 @@ class PostStatusSyncTest extends TestCase {
$this->assertNotContains( 'post_status', $wpdb->get_col( 'SHOW COLUMNS FROM `' . self::A . '`' ) ); $this->assertNotContains( 'post_status', $wpdb->get_col( 'SHOW COLUMNS FROM `' . self::A . '`' ) );
} }
/**
* The migration engine (backfill, drift-check --fix) REPLACEs whole rows:
* without the copies, a rebuilt row had NULL post_status, which turns the
* status/date copy route off for the whole group (2.4 PR-127).
*/
public function test_a_row_rebuilt_from_native_keeps_its_copies(): void {
global $wpdb;
TMDO_Post_Status_Sync::run();
$GLOBALS['_wp_posts'][2] = (object) array( 'ID' => 2, 'post_type' => 'hp_listing', 'post_status' => 'draft', 'post_date' => '2026-02-01 10:00:00' );
$GLOBALS['_wp_posts'][3] = (object) array( 'ID' => 3, 'post_type' => 'hp_listing', 'post_status' => 'pending', 'post_date' => '2026-03-01 10:00:00' );
$wpdb->query( "CREATE TABLE IF NOT EXISTS `{$wpdb->postmeta}` ( meta_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, post_id BIGINT UNSIGNED NOT NULL DEFAULT 0, meta_key VARCHAR(255) DEFAULT NULL, meta_value LONGTEXT, PRIMARY KEY (meta_id) ) ENGINE=InnoDB" );
try {
$wpdb->query( "INSERT INTO `{$wpdb->postmeta}` (post_id, meta_key, meta_value) VALUES (2, 'k', 'a2-native'), (3, 'k', 'a3-native')" );
WPDO_Entity_Migration_Engine::migrate_entity( 'post', 'ps_a', 2 ); // Existing row.
WPDO_Entity_Migration_Engine::migrate_entity( 'post', 'ps_a', 3 ); // New row.
} finally {
$wpdb->query( "DROP TABLE IF EXISTS `{$wpdb->postmeta}`" );
}
$this->assertSame( array( 'draft', '2026-02-01 10:00:00' ), $this->copies( self::A )[2] );
$this->assertSame( array( 'pending', '2026-03-01 10:00:00' ), $this->copies( self::A )[3] );
}
public function test_flat_write_that_creates_a_row_fills_the_copies(): void { public function test_flat_write_that_creates_a_row_fills_the_copies(): void {
TMDO_Post_Status_Sync::run(); TMDO_Post_Status_Sync::run();
$mode = new ReflectionProperty( WPDO_Mode_Manager::class, 'cache' ); $mode = new ReflectionProperty( WPDO_Mode_Manager::class, 'cache' );