fix(2meet-data-optimizer): forget post status columns of groups whose flat table is gone

- on_transition() skips a recorded group whose table no longer exists and
  removes it from tmdo_post_status_columns; every post status change used to
  UPDATE the missing table and print a database error (seen on dev36 after a
  throwaway group's table was dropped)
- Verify: PostStatusSyncTest (dropped table), integration 578, unit 701, phpcs, stan
- PR: PR-106
This commit is contained in:
2026-09-27 16:59:08 +08:00
parent 303781e68b
commit 5968bcd95d
2 changed files with 35 additions and 0 deletions
@@ -65,6 +65,10 @@ final class TMDO_Post_Status_Sync {
unset( $new_status, $old_status );
foreach ( self::groups_with_columns() as $group ) {
$table = TMDO_Schema_Manager::get_table_name( 'post', $group );
if ( ! TMDO_Schema_Manager::table_exists( $table ) ) {
self::forget( $group ); // The table was dropped (retired or uninstalled group).
continue;
}
$wpdb->query(
$wpdb->prepare(
"UPDATE `{$table}` SET `post_status` = %s, `post_date` = %s WHERE `post_id` = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Registry table name.
@@ -220,6 +224,20 @@ final class TMDO_Post_Status_Sync {
return is_array( $states ) ? array_keys( $states ) : array();
}
/**
* Drop a group from the recorded states.
*
* @param string $group Group name.
* @return void
*/
private static function forget( string $group ): void {
$states = get_option( self::OPTION, array() );
if ( is_array( $states ) && isset( $states[ $group ] ) ) {
unset( $states[ $group ] );
update_option( self::OPTION, $states, true );
}
}
/**
* Record a group's state.
*
+17
View File
@@ -134,6 +134,23 @@ class PostStatusSyncTest extends TestCase {
$this->assertSame( array( 'draft', '2026-02-01 10:00:00' ), $this->copies( self::A )[2], 'other posts untouched' );
}
public function test_a_group_whose_table_was_dropped_is_forgotten(): void {
global $wpdb;
TMDO_Post_Status_Sync::run();
$wpdb->query( 'DROP TABLE `' . self::B . '`' );
$ref = new ReflectionProperty( WPDO_Schema_Manager::class, 'table_exists_cache' );
$ref->setAccessible( true );
$ref->setValue( null, array() );
$wpdb->last_error = '';
TMDO_Post_Status_Sync::on_transition( 'trash', 'publish', (object) array( 'ID' => 1, 'post_status' => 'trash', 'post_date' => '2026-01-05 00:00:00' ) );
$this->assertSame( '', (string) $wpdb->last_error, 'no UPDATE of a missing table' );
$this->assertSame( '', TMDO_Post_Status_Sync::state( 'ps_b' ), 'forgotten' );
$this->assertSame( 'ready', TMDO_Post_Status_Sync::state( 'ps_a' ) );
$this->assertSame( array( 'trash', '2026-01-05 00:00:00' ), $this->copies( self::A )[1] );
}
public function test_transition_leaves_tables_without_the_columns_alone(): void {
global $wpdb;
$wpdb->last_error = '';