entity_type → 結果('promoted'|'not_ready'|'no_diff_yet'|'disabled_globally') */ public static function check_all(): array { $results = array(); if ( ! (bool) get_option( self::OPT_ENABLED, false ) ) { foreach ( array( 'post', 'user', 'term', 'comment' ) as $type ) { $results[ $type ] = 'disabled_globally'; } return $results; } $min_days = (int) get_option( self::OPT_MIN_DAYS, self::DEFAULT_MIN_DAYS ); $entered_all = get_option( TMDO_Mode_Manager::OPT_ENTERED_AT, array() ); foreach ( array( 'post', 'user', 'term', 'comment' ) as $type ) { $results[ $type ] = self::check_entity( $type, $min_days, $entered_all ); } return $results; } /** * 評估單一 entity 是否可升級。 * * @return string 'promoted' | 'not_shadow_read' | 'not_ready' | 'has_diff' | 'vetoed' */ public static function check_entity( string $type, int $min_days, array $entered_all ): string { $current = TMDO_Mode_Manager::get( $type ); if ( $current !== TMDO_Mode_Manager::MODE_SHADOW_READ ) { return 'not_shadow_read'; } $entered_at = isset( $entered_all[ $type ] ) ? (int) $entered_all[ $type ] : 0; if ( $entered_at === 0 || ( time() - $entered_at ) < $min_days * DAY_IN_SECONDS ) { return 'not_ready'; } $diff_counts = TMDO_Shadow_Diff_Logger::count_by_entity(); $count = (int) ( $diff_counts[ $type ] ?? 0 ); if ( $count > 0 ) { return 'has_diff'; } // 讓外部 filter 最後一次 veto(例如:還在外部驗證期間) $should = apply_filters( 'wpdo_auto_promote_should_run', true, $type, $entered_at, $count ); if ( ! $should ) { return 'vetoed'; } $result = TMDO_Mode_Manager::set( $type, TMDO_Mode_Manager::MODE_AEAV_ONLY ); if ( is_wp_error( $result ) ) { TMDO_Logger::error( 'auto_promoter', 'auto_promote_failed', $result->get_error_message(), array( 'entity_type' => $type ) ); return 'error'; } TMDO_Logger::info( 'auto_promote_success', array( 'entity_type' => $type, 'entered_at' => gmdate( 'c', $entered_at ), 'days_elapsed' => (int) ( ( time() - $entered_at ) / DAY_IN_SECONDS ), 'min_days' => $min_days, ) ); do_action( 'wpdo_auto_promoted', $type, $entered_at, $min_days ); return 'promoted'; } }