hardening 2.2: 2meet-data-optimizer 1.2.0 (drift detection, scope, CLI and diagnostics) #6

Merged
wpdev merged 19 commits from hardening/2.2 into main 2026-09-27 10:56:49 +08:00
3 changed files with 65 additions and 0 deletions
Showing only changes of commit 6c782282c7 - Show all commits
+3
View File
@@ -296,6 +296,9 @@ class TMDO_Core {
// v2.3.0 M6: daily health probe cron.
add_action( 'wpdo_daily_health_check', array( 'TMDO_Health_Cron', 'run' ) );
// 1.2.0: daily flat-vs-native drift sample (read by the post query router).
add_action( 'wpdo_daily_health_check', array( 'TMDO_Drift_Check', 'cron_tick' ) );
// v2.3.0 M6: daily snapshot prune cron (paired with health check).
add_action( 'wpdo_snapshot_prune_daily', array( 'TMDO_Snapshot_Pruner', 'cron_run' ) );
@@ -40,6 +40,11 @@ final class TMDO_Drift_Check {
*/
public const OPTION = 'wpdo_drift_status';
/**
* Entities per group sampled by the daily check.
*/
public const CRON_SAMPLE = 500;
/**
* MySQL regex for a plain decimal number, used to skip rows that obviously match.
* Exact matches compare BINARY: meta and flat tables may differ in collation,
@@ -97,6 +102,24 @@ final class TMDO_Drift_Check {
return $report;
}
/**
* Daily check (wpdo_daily_health_check): sample every entity type whose
* flat tables are written (mode dual_write or higher). The outcome replaces
* the recorded status, so a group found drifting leaves the router at once.
*/
public static function cron_tick(): void {
foreach ( TMDO_Entity_Registry::VALID_ENTITY_TYPES as $entity_type ) {
if ( ! TMDO_Mode_Manager::writes_to_flat( $entity_type ) ) {
continue;
}
try {
self::run( $entity_type, '', self::CRON_SAMPLE );
} catch ( InvalidArgumentException $e ) {
continue; // No adapter for this entity type on this site.
}
}
}
/**
* Rebuild drifted flat rows from native meta, then check again.
*
+39
View File
@@ -181,6 +181,45 @@ class DriftCheckTest extends TestCase {
$this->assertFalse( TMDO_Cache_Orchestrator::get_row( 'user', 2, 'dc_grp' ) );
}
// ── cron_tick() (2.2 PR-073) ────────────────────────────────────────────
private static function set_modes( ?array $modes ): void {
$cache = ( new ReflectionClass( WPDO_Mode_Manager::class ) )->getProperty( 'cache' );
$cache->setAccessible( true );
$cache->setValue( null, $modes );
}
public function test_the_daily_tick_samples_entities_that_write_to_flat(): void {
self::set_modes( array( 'post' => 'disabled', 'user' => 'dual_write', 'term' => 'disabled', 'comment' => 'disabled' ) );
try {
TMDO_Drift_Check::cron_tick();
} finally {
self::set_modes( null );
}
$status = get_option( TMDO_Drift_Check::OPTION );
$this->assertSame( TMDO_Drift_Check::CRON_SAMPLE, $status['user']['dc_grp']['sample'] );
$this->assertSame( 2, $status['user']['dc_grp']['diff'], 'the sample covers all 7 fixture users' );
$this->assertArrayNotHasKey( 'post', $status );
}
public function test_the_daily_tick_skips_entities_that_do_not_write_to_flat(): void {
self::set_modes( array( 'post' => 'disabled', 'user' => 'disabled', 'term' => 'disabled', 'comment' => 'disabled' ) );
try {
TMDO_Drift_Check::cron_tick();
} finally {
self::set_modes( null );
}
$this->assertFalse( get_option( TMDO_Drift_Check::OPTION ) );
}
public function test_the_daily_tick_runs_on_the_daily_health_check_hook(): void {
$source = (string) file_get_contents( WPDO_PLUGIN_DIR . 'includes/class-tmdo-core.php' );
$this->assertStringContainsString( "add_action( 'wpdo_daily_health_check', array( 'TMDO_Drift_Check', 'cron_tick' ) );", $source );
}
public function test_rejects_an_unknown_group(): void {
$this->expectException( InvalidArgumentException::class );
TMDO_Drift_Check::run( 'user', 'no_such_group' );