images->supports('image/png', $request)) { return false; } $this->wopi->configuration($this->tenant->requireIdentifier()); return true; } catch (Throwable) { return false; } } public function generate(PreviewSource $source, PreviewRequest $request): PreviewResult { if (!$this->supports($source->mimeType, $request)) { throw new PreviewGenerationException('WOPI does not support the requested preview conversion'); } $config = $this->wopi->configuration($this->tenant->requireIdentifier()); $limit = min($request->maxSourceSize, $config->maxBytes); if ($source->size !== null && $source->size > $limit) { throw new PreviewGenerationException('Preview source exceeds the configured size limit'); } $content = ''; foreach ($source->open()->stream() as $chunk) { if (!is_string($chunk) || strlen($content) + strlen($chunk) > $limit) { throw new PreviewGenerationException('Invalid or oversized preview source'); } $content .= $chunk; } if ($content === '') { throw new PreviewGenerationException('Preview source is empty'); } $pdf = $this->client->pdf($config->office, $content, array_search($source->mimeType, WopiService::FORMATS, true), $source->mimeType); $file = tmpfile(); if ($file === false) { throw new PreviewGenerationException('Cannot create preview temporary file'); } $image = new Imagick(); try { if (fwrite($file, $pdf) !== strlen($pdf)) { throw new PreviewGenerationException('Cannot write preview temporary file'); } $image->setResolution(96, 96); $image->readImage('pdf:' . stream_get_meta_data($file)['uri'] . '[0]'); $image->setImageFormat('png'); $png = $image->getImageBlob(); return $this->images->generate(new PreviewSource( $source->sourceType, $source->identity, $source->signature, 'image/png', strlen($png), static fn () => new BinaryResource('page.png', 'image/png', (static function () use ($png): \Generator { yield $png; })()), ), new PreviewRequest($request->maxWidth, $request->maxHeight, $request->preferredMimeType, $request->quality, ConversionClient::MAX_RESPONSE_BYTES)); } catch (Throwable $error) { throw new PreviewGenerationException('Could not render the office preview', previous: $error); } finally { $image->clear(); fclose($file); } } }