From 3ece3ab15b1a98f3417351dda0a8b940f15f7020 Mon Sep 17 00:00:00 2001 From: Simon Holzman Date: Sun, 28 Jun 2026 17:22:23 -0400 Subject: [PATCH] fix: avoid mime_content_type warning on wrapped streams mime_content_type() requires stream_cast() support to operate on a stream resource directly. Streams returned by File::fopen() can be wrapped in Icewind\Streams\CallbackWrapper, which does not implement stream_cast(), causing a PHP warning to be logged on every preview/output-file request even though the mime type is still detected correctly. This drains the stream into a temporary file first, then calls mime_content_type() against the file path instead. No behavior change; only removes log noise. Signed-off-by: Simon Holzman --- lib/Service/AssistantService.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index ee6e3fbd..5e3dad77 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -743,7 +743,7 @@ public function saveOutputFile(string $userId, int $ocpTaskId, int $fileId): arr * @throws NotPermittedException */ private function getTargetFileName(File $file): string { - $mimeType = mime_content_type($file->fopen('rb')); + $mimeType = $this->detectMimeType($file->fopen('rb')); $fileName = $file->getName(); $mimes = new \Mimey\MimeTypes; @@ -755,6 +755,29 @@ private function getTargetFileName(File $file): string { return $fileName; } + /** + * Wraps mime_content_type() to avoid a PHP warning when given a stream + * that does not implement stream_cast() (e.g. Icewind\Streams\CallbackWrapper, + * returned by File::fopen() for some storage backends). The stream is + * drained into a temp file first so mime_content_type() can operate on a + * real path instead of the unsupported stream resource. + * + * @param resource $stream + * @return string|false + */ + private function detectMimeType($stream) { + $tmpFile = tempnam(sys_get_temp_dir(), 'nc_assistant_mime_'); + $tmpHandle = fopen($tmpFile, 'wb'); + stream_copy_to_stream($stream, $tmpHandle); + fclose($tmpHandle); + if (is_resource($stream)) { + fclose($stream); + } + $mimeType = mime_content_type($tmpFile); + unlink($tmpFile); + return $mimeType; + } + /** * @param Task $task * @return array @@ -807,7 +830,7 @@ private function extractFileIdsFromTask(Task $task): array { */ public function getOutputFilePreviewFile(string $userId, int $taskId, int $fileId, ?int $x = 100, ?int $y = 100): ?array { $taskOutputFile = $this->getTaskOutputFile($userId, $taskId, $fileId); - $realMime = mime_content_type($taskOutputFile->fopen('rb')); + $realMime = $this->detectMimeType($taskOutputFile->fopen('rb')); return $this->previewService->getFilePreviewFile($taskOutputFile, $x, $y, $realMime ?: null); }