From 4a5cc454ce49c4c21db604a13697ed9217092e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 24 Feb 2026 22:40:23 +0100 Subject: [PATCH] Show HTML files in the HTML sandbox if enabled --- src/Entity/Attachments/Attachment.php | 16 +++++++++++ .../Attachments/AttachmentURLGenerator.php | 7 ++++- tests/Entity/Attachments/AttachmentTest.php | 28 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php index d4b15ac7..e0d1bd9d 100644 --- a/src/Entity/Attachments/Attachment.php +++ b/src/Entity/Attachments/Attachment.php @@ -296,6 +296,22 @@ abstract class Attachment extends AbstractNamedDBElement return in_array(strtolower($extension), static::MODEL_EXTS, true); } + /** + * Returns true if this is a locally stored HTML file, which can be shown by the sandbox viewer. + * This is the case if we have an internal path with a html extension. + * @return bool + */ + public function isLocalHTMLFile(): bool + { + if($this->hasInternal()){ + + $extension = pathinfo($this->getFilename(), PATHINFO_EXTENSION); + + return in_array(strtolower($extension), ['html', 'htm'], true); + } + return false; + } + /** * Checks if this attachment has a path to an external file * diff --git a/src/Services/Attachments/AttachmentURLGenerator.php b/src/Services/Attachments/AttachmentURLGenerator.php index e505408f..89856650 100644 --- a/src/Services/Attachments/AttachmentURLGenerator.php +++ b/src/Services/Attachments/AttachmentURLGenerator.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Services\Attachments; +use App\Settings\SystemSettings\AttachmentsSettings; use Imagine\Exception\RuntimeException; use App\Entity\Attachments\Attachment; use InvalidArgumentException; @@ -40,7 +41,7 @@ class AttachmentURLGenerator public function __construct(protected Packages $assets, protected AttachmentPathResolver $pathResolver, protected UrlGeneratorInterface $urlGenerator, protected AttachmentManager $attachmentHelper, - protected CacheManager $thumbnailManager, protected LoggerInterface $logger) + protected CacheManager $thumbnailManager, protected LoggerInterface $logger, private readonly AttachmentsSettings $attachmentsSettings) { //Determine a normalized path to the public folder (assets are relative to this folder) $this->public_path = $this->pathResolver->parameterToAbsolutePath('public'); @@ -99,6 +100,10 @@ class AttachmentURLGenerator return null; } + if ($this->attachmentsSettings->showHTMLAttachments && $attachment->isLocalHTMLFile()) { + return $this->urlGenerator->generate('attachment_html_sandbox', ['id' => $attachment->getID()]); + } + $asset_path = $this->absolutePathToAssetPath($absolute_path); //If path is not relative to public path or marked as secure, serve it via controller if (null === $asset_path || $attachment->isSecure()) { diff --git a/tests/Entity/Attachments/AttachmentTest.php b/tests/Entity/Attachments/AttachmentTest.php index ca55424c..9e912b97 100644 --- a/tests/Entity/Attachments/AttachmentTest.php +++ b/tests/Entity/Attachments/AttachmentTest.php @@ -279,4 +279,32 @@ final class AttachmentTest extends TestCase $reflection_property->setAccessible(true); $reflection_property->setValue($object, $value); } + + public function testIsLocalHTMLFile(): void + { + $attachment = new PartAttachment(); + + $attachment->setExternalPath('https://google.de'); + $this->assertFalse($attachment->isLocalHTMLFile()); + + $attachment->setExternalPath('https://google.de/test.html'); + $this->assertFalse($attachment->isLocalHTMLFile()); + + $attachment->setInternalPath('%MEDIA%/test.html'); + $this->assertTrue($attachment->isLocalHTMLFile()); + + $attachment->setInternalPath('%MEDIA%/test.htm'); + $this->assertTrue($attachment->isLocalHTMLFile()); + + $attachment->setInternalPath('%MEDIA%/test.txt'); + $this->assertFalse($attachment->isLocalHTMLFile()); + + //It works however, if the file is stored as txt, and the internal filename ends with .html + $attachment->setInternalPath('%MEDIA%/test.txt'); + $this->setProtectedProperty($attachment, 'original_filename', 'test.html'); + $this->assertTrue($attachment->isLocalHTMLFile()); + + $this->setProtectedProperty($attachment, 'original_filename', 'test.htm'); + $this->assertTrue($attachment->isLocalHTMLFile()); + } }