|null */ private static ?array $cache = null; public static function init(): void { // init:25 — register_default_fields 於 init:20 觸發 wpdo_register_fields, // UAEPG 亦在 init:20 觸發 uaepg_register_fields;此時 priority 25 可確保雙邊皆完成登錄。 add_action( 'init', array( self::class, 'scan' ), 25 ); if ( is_admin() ) { add_action( 'admin_notices', array( self::class, 'maybe_render_admin_notice' ) ); } } /** * 掃描並 cache 衝突清單。 * * @return array */ public static function scan(): array { if ( self::$cache !== null ) { return self::$cache; } if ( ! class_exists( 'UAEPG_Registry' ) ) { return self::$cache = array(); } $conflicts = array(); foreach ( TMDO_Entity_Registry::get_all_fields() as $entity_type => $fields_by_key ) { foreach ( $fields_by_key as $meta_key => $wpdo_field ) { if ( ! UAEPG_Registry::is_managed( $entity_type, $meta_key ) ) { continue; } $uaepg_field = UAEPG_Registry::get_field( $entity_type, $meta_key ); $conflicts[] = array( 'entity_type' => $entity_type, 'meta_key' => $meta_key, 'wpdo_group' => $wpdo_field['group'] ?? '(unknown)', 'uaepg_group' => $uaepg_field['group'] ?? '(unknown)', ); } } if ( $conflicts ) { TMDO_Logger::error( 'schema_registry', 'field_registration_conflict', sprintf( 'Field registration conflict: %d field(s) affected', count( $conflicts ) ), $conflicts ); } return self::$cache = $conflicts; } /** * 取得衝突清單(若尚未掃描,觸發掃描)。 */ public static function get_conflicts(): array { return self::$cache ?? self::scan(); } /** * 測試用:強制清除 cache,下次 scan() 會重跑。 * * @internal */ public static function reset_cache(): void { self::$cache = null; } /** * 若有衝突則輸出管理後台紅色通知。 */ public static function maybe_render_admin_notice(): void { $conflicts = self::get_conflicts(); if ( ! $conflicts ) { return; } if ( ! TMDO_Capability::current_user_can_admin() ) { return; } $count = count( $conflicts ); $lines = array(); foreach ( array_slice( $conflicts, 0, 5 ) as $c ) { $lines[] = sprintf( '%s / %s(UAE 群組「%s」 ↔ UAEPG 群組「%s」)', esc_html( $c['entity_type'] ), esc_html( $c['meta_key'] ), esc_html( $c['wpdo_group'] ), esc_html( $c['uaepg_group'] ) ); } $extra = $count > 5 ? sprintf( __( '… 另有 %d 個欄位未顯示', '2meet-data-optimizer' ), $count - 5 ) : ''; printf( '

%s

%s

%s wp uae conflicts

', esc_html( sprintf( /* translators: %d: conflict count */ __( 'UAE × UAEPG 欄位衝突偵測:發現 %d 個同 meta_key 被雙方 Registry 重複登錄 — UAEPG 會搶先短路,UAE 寫入將被靜默跳過', '2meet-data-optimizer' ), $count ) ), // $lines elements were each individually esc_html()'d above (lines 121-124). // implode joins escaped strings with literal HTML markers — safe. implode( '
  • ', $lines ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- pre-escaped above. $extra ? '

    ' . esc_html( $extra ) . '

    ' : '', esc_html__( '查看完整清單:', '2meet-data-optimizer' ) ); } }