getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() . "\n" . $e->getTraceAsString()); } public static function log(string $level, string $message): void { $path = self::$path !== '' ? self::$path : (defined('PLUGIN_ROOT') ? PLUGIN_ROOT . '/plugin.log' : __DIR__ . '/../../plugin.log'); $line = '[' . gmdate('c') . '] ' . $level . ' ' . str_replace(["\r\n", "\r"], "\n", $message) . "\n"; $ok = @file_put_contents($path, $line, FILE_APPEND | LOCK_EX); if ($ok !== false && is_file($path)) { @chmod($path, 0600); } } private static function severityName(int $severity): string { return match ($severity) { E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING', E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', E_USER_NOTICE => 'E_USER_NOTICE', E_STRICT => 'E_STRICT', E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', E_DEPRECATED => 'E_DEPRECATED', E_USER_DEPRECATED => 'E_USER_DEPRECATED', default => 'E_' . $severity, }; } private static function ensureLogFile(): void { if (self::$path === '') { return; } $dir = dirname(self::$path); if (!is_dir($dir) || !is_writable($dir)) { return; } if (!is_file(self::$path)) { @file_put_contents(self::$path, ''); } if (is_file(self::$path)) { @chmod(self::$path, 0600); } } }