fix(2meet-data-optimizer): report entity group name collisions instead of silently dropping
- register_group() keeps the first definition but records a field diff (added/removed/changed) when the same entity/group is re-registered differently; identical re-registration stays silent - Surface collisions via Site Health (wpdo_entity_group_collisions), the admin Doctor tab, and wp wpdo doctor; warning log throttled to once a day - Verify: EntityRegistryCollisionTest (7); core unit 613 / integration 432, HP 141/49, WC 10/22 OK - PR: PR-017
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* TMDO_Site_Health — WordPress Site Health integration (v2.2.0 M3).
|
||||
*
|
||||
* Registers 7 tests under Tools → Site Health → Status:
|
||||
* Registers 8 tests under Tools → Site Health → Status:
|
||||
* 1. wpdo_schema_drift (critical)
|
||||
* 2. wpdo_error_budget (recommended)
|
||||
* 3. wpdo_hook_conflicts (recommended)
|
||||
@@ -10,6 +10,7 @@
|
||||
* 5. wpdo_postmeta_explosion (recommended)
|
||||
* 6. wpdo_orphan_zone_rows (recommended)
|
||||
* 7. wpdo_missing_snapshot (critical)
|
||||
* 8. wpdo_entity_group_collisions (recommended)
|
||||
*
|
||||
* Each test result is cached for 5 minutes to keep Site Health responsive.
|
||||
*
|
||||
@@ -34,13 +35,14 @@ class TMDO_Site_Health {
|
||||
|
||||
/** Test name → callable suffix mapping. */
|
||||
private const TESTS = array(
|
||||
'wpdo_schema_drift' => 'check_schema_drift',
|
||||
'wpdo_error_budget' => 'check_error_budget',
|
||||
'wpdo_hook_conflicts' => 'check_hook_conflicts',
|
||||
'wpdo_autoload_bloat' => 'check_autoload_bloat',
|
||||
'wpdo_postmeta_explosion' => 'check_postmeta_explosion',
|
||||
'wpdo_orphan_zone_rows' => 'check_orphan_zone_rows',
|
||||
'wpdo_missing_snapshot' => 'check_missing_snapshot',
|
||||
'wpdo_schema_drift' => 'check_schema_drift',
|
||||
'wpdo_error_budget' => 'check_error_budget',
|
||||
'wpdo_hook_conflicts' => 'check_hook_conflicts',
|
||||
'wpdo_autoload_bloat' => 'check_autoload_bloat',
|
||||
'wpdo_postmeta_explosion' => 'check_postmeta_explosion',
|
||||
'wpdo_orphan_zone_rows' => 'check_orphan_zone_rows',
|
||||
'wpdo_missing_snapshot' => 'check_missing_snapshot',
|
||||
'wpdo_entity_group_collisions' => 'check_entity_group_collisions',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -53,7 +55,7 @@ class TMDO_Site_Health {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the 7 tests with WP Site Health.
|
||||
* Register the 8 tests with WP Site Health.
|
||||
*
|
||||
* @param array $tests Existing tests.
|
||||
* @return array
|
||||
@@ -76,13 +78,14 @@ class TMDO_Site_Health {
|
||||
*/
|
||||
private static function label_for( string $key ): string {
|
||||
$map = array(
|
||||
'wpdo_schema_drift' => __( 'WPDO schema drift', '2meet-data-optimizer' ),
|
||||
'wpdo_error_budget' => __( 'WPDO error budget', '2meet-data-optimizer' ),
|
||||
'wpdo_hook_conflicts' => __( 'WPDO hook conflicts', '2meet-data-optimizer' ),
|
||||
'wpdo_autoload_bloat' => __( 'WPDO autoload bloat', '2meet-data-optimizer' ),
|
||||
'wpdo_postmeta_explosion' => __( 'WPDO postmeta explosion', '2meet-data-optimizer' ),
|
||||
'wpdo_orphan_zone_rows' => __( 'WPDO orphan zone rows', '2meet-data-optimizer' ),
|
||||
'wpdo_missing_snapshot' => __( 'WPDO missing snapshot', '2meet-data-optimizer' ),
|
||||
'wpdo_schema_drift' => __( 'WPDO schema drift', '2meet-data-optimizer' ),
|
||||
'wpdo_error_budget' => __( 'WPDO error budget', '2meet-data-optimizer' ),
|
||||
'wpdo_hook_conflicts' => __( 'WPDO hook conflicts', '2meet-data-optimizer' ),
|
||||
'wpdo_autoload_bloat' => __( 'WPDO autoload bloat', '2meet-data-optimizer' ),
|
||||
'wpdo_postmeta_explosion' => __( 'WPDO postmeta explosion', '2meet-data-optimizer' ),
|
||||
'wpdo_orphan_zone_rows' => __( 'WPDO orphan zone rows', '2meet-data-optimizer' ),
|
||||
'wpdo_missing_snapshot' => __( 'WPDO missing snapshot', '2meet-data-optimizer' ),
|
||||
'wpdo_entity_group_collisions' => __( 'WPDO entity group collisions', '2meet-data-optimizer' ),
|
||||
);
|
||||
return $map[ $key ] ?? $key;
|
||||
}
|
||||
@@ -425,6 +428,46 @@ class TMDO_Site_Health {
|
||||
|
||||
// ─── helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
// ─── Test 8: Entity group name collisions ───────────────────────────
|
||||
|
||||
/**
|
||||
* Report entity groups registered twice with different definitions.
|
||||
*
|
||||
* Not cached: the collision list is in-memory state rebuilt on every
|
||||
* request, so reading it is free and a transient would only go stale.
|
||||
*
|
||||
* @return array Site Health result.
|
||||
*/
|
||||
public static function check_entity_group_collisions(): array {
|
||||
$collisions = class_exists( 'TMDO_Entity_Registry' ) ? TMDO_Entity_Registry::get_collisions() : array();
|
||||
if ( empty( $collisions ) ) {
|
||||
return self::wrap( 'wpdo_entity_group_collisions', self::pass( __( 'No entity group name collisions.', '2meet-data-optimizer' ) ) );
|
||||
}
|
||||
$lines = array();
|
||||
foreach ( $collisions as $c ) {
|
||||
$lines[] = sprintf(
|
||||
'%s/%s (+%s −%s ~%s)',
|
||||
$c['entity_type'],
|
||||
$c['group'],
|
||||
implode( ',', $c['added'] ) ?: '-',
|
||||
implode( ',', $c['removed'] ) ?: '-',
|
||||
implode( ',', $c['changed'] ) ?: '-'
|
||||
);
|
||||
}
|
||||
return self::wrap(
|
||||
'wpdo_entity_group_collisions',
|
||||
self::fail(
|
||||
__( 'WPDO entity group name collisions', '2meet-data-optimizer' ),
|
||||
sprintf(
|
||||
/* translators: %s: list of entity/group names with field differences */
|
||||
__( 'Another plugin registered these groups with a different field list; its definition was ignored and the first one kept: %s', '2meet-data-optimizer' ),
|
||||
implode( '; ', $lines )
|
||||
),
|
||||
'recommended'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a raw check result with required Site Health envelope fields.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user