From ae99820bbcf1b21eba24edc96369f59fdf631c7e Mon Sep 17 00:00:00 2001 From: wpdev Date: Fri, 31 Jul 2026 08:29:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(logger):=20=E8=A3=9C=E5=9B=9E=20TMDO=5FLogg?= =?UTF-8?q?er::trace=5Fid()=EF=BC=88=E5=AF=A6=E6=A9=9F=E9=A9=97=E8=AD=89?= =?UTF-8?q?=E6=8A=93=E5=88=B0=E7=9A=84=20fatal=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TMDO_Audit_Logger::write_row() 第 160 行呼叫 TMDO_Logger::trace_id(), 但 B 提煉時漏掉了這個方法(A 有,class-wpdo-logger.php:35-47)。 先前 Audit_Logger::init() 從未被註冊,所以這個 fatal 一直藏著; A12 把它掛上之後,任何一次受管 meta 寫入都會炸。 PHPUnit 沒有覆蓋 audit 寫入路徑,是在 dev30 實機跑 WPDO_API::set_entity() 時才暴露的。 trace_id() 產生 request-scoped UUIDv4,讓同一次請求寫出的所有 audit row 共用同一個關聯 id。 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY --- includes/class-tmdo-logger.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/includes/class-tmdo-logger.php b/includes/class-tmdo-logger.php index 324cf38..feac105 100644 --- a/includes/class-tmdo-logger.php +++ b/includes/class-tmdo-logger.php @@ -16,6 +16,35 @@ if ( ! defined( 'ABSPATH' ) ) { */ class TMDO_Logger { + /** + * Request-scoped correlation id, lazily generated. + * + * @var string|null + */ + private static ?string $trace_id = null; + + /** + * Request-scoped UUIDv4 correlation id. + * + * Every audit row written during one request shares this value so a single + * update_*_meta() call can be traced across entity groups. + * + * @return string UUIDv4. + */ + public static function trace_id(): string { + if ( null === self::$trace_id ) { + try { + $bytes = random_bytes( 16 ); + } catch ( \Throwable $e ) { + $bytes = pack( 'H*', md5( (string) microtime( true ) . wp_generate_password( 16, false ) ) ); + } + $bytes[6] = chr( ( ord( $bytes[6] ) & 0x0f ) | 0x40 ); + $bytes[8] = chr( ( ord( $bytes[8] ) & 0x3f ) | 0x80 ); + self::$trace_id = vsprintf( '%s%s-%s-%s-%s-%s%s%s', str_split( bin2hex( $bytes ), 4 ) ); + } + return self::$trace_id; + } + /** * Log an INFO-level event (event-based signature, used by v2.0.0 engine code). *