Add support for attachment thumbnail
authorAlexander Ebert <ebert@woltlab.com>
Wed, 27 Mar 2024 22:28:14 +0000 (23:28 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 8 Jun 2024 10:19:38 +0000 (12:19 +0200)
wcfsetup/install/files/lib/data/attachment/Attachment.class.php
wcfsetup/install/files/lib/data/file/File.class.php
wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php
wcfsetup/install/files/lib/system/message/embedded/object/AttachmentMessageEmbeddedObjectHandler.class.php

index 25643d4688d70468ac3eba206db2f50b210aeec0..30ae35d43352c21fa00454e7573cb62132545407 100644 (file)
@@ -235,17 +235,21 @@ class Attachment extends DatabaseObject implements ILinkableObject, IRouteContro
      */
     public function getThumbnailLink($size = '')
     {
-        $parameters = [
-            'object' => $this,
-        ];
+        $file = $this->getFile();
+        if ($file === null) {
+            return '';
+        }
 
-        if ($size == 'tiny') {
-            $parameters['tiny'] = 1;
-        } elseif ($size == 'thumbnail') {
-            $parameters['thumbnail'] = 1;
+        if ($size === '') {
+            return $file->getLink();
+        }
+
+        $thumbnail = $file->getThumbnail($size !== 'tiny' ? '' : $size);
+        if ($this === null) {
+            return '';
         }
 
-        return LinkHandler::getInstance()->getLink('Attachment', $parameters);
+        return $thumbnail->getLink();
     }
 
     /**
@@ -373,15 +377,33 @@ class Attachment extends DatabaseObject implements ILinkableObject, IRouteContro
     public function __get($name)
     {
         $file = $this->getFile();
-        if ($file !== null) {
-            return match ($name) {
-                'filename' => $file->filename,
-                'filesize' => $file->fileSize,
-                default => parent::__get($name),
-            };
+        if ($file === null) {
+            return parent::__get($name);
         }
 
-        return parent::__get($name);
+        return match ($name) {
+            'filename' => $file->filename,
+            'filesize' => $file->fileSize,
+            'fileType' => $file->mimeType,
+            'isImage' => $file->isImage(),
+
+            // TODO: Do we want to cache this data?
+            'height' => \getimagesize($file->getPath() . $file->getSourceFilename())[1],
+            // TODO: Do we want to cache this data?
+            'width' => \getimagesize($file->getPath() . $file->getSourceFilename())[0],
+
+            // TODO: This is awful.
+            'thumbnailType' => $file->getThumbnail('') ? $file->mimeType : '',
+            'thumbnailWidth' => $file->getThumbnail('') ? \getimagesize($file->getThumbnail('')->getPath() . $file->getThumbnail('')->getSourceFilename())[0] : 0,
+            'thumbnailHeight' => $file->getThumbnail('') ? \getimagesize($file->getThumbnail('')->getPath() . $file->getThumbnail('')->getSourceFilename())[1] : 0,
+
+            // TODO: This is awful.
+            'tinyThumbnailType' => $file->getThumbnail('tiny') ? $file->mimeType : '',
+            'tinyThumbnailWidth' => $file->getThumbnail('tiny') ? \getimagesize($file->getThumbnail('tiny')->getPath() . $file->getThumbnail('tiny')->getSourceFilename())[0] : 0,
+            'tinyThumbnailHeight' => $file->getThumbnail('tiny') ? \getimagesize($file->getThumbnail('tiny')->getPath() . $file->getThumbnail('tiny')->getSourceFilename())[1] : 0,
+
+            default => parent::__get($name),
+        };
     }
 
     public static function findByFileID(int $fileID): ?Attachment
index fcba2c03a07ed903055e42318876f9946f2c736c..455f41b4320f44b4751f37da14fd74d2ebceeb8f 100644 (file)
@@ -4,6 +4,7 @@ namespace wcf\data\file;
 
 use wcf\action\FileDownloadAction;
 use wcf\data\DatabaseObject;
+use wcf\data\file\thumbnail\FileThumbnail;
 use wcf\system\file\processor\FileProcessor;
 use wcf\system\file\processor\IFileProcessor;
 use wcf\system\request\LinkHandler;
@@ -23,6 +24,9 @@ use wcf\system\request\LinkHandler;
  */
 class File extends DatabaseObject
 {
+    /** @var array<string, FileThumbnail> */
+    private array $thumbnails = [];
+
     public function getPath(): string
     {
         $folderA = \substr($this->fileHash, 0, 2);
@@ -77,4 +81,14 @@ class File extends DatabaseObject
 
         return $processor->canDelete($this);
     }
+
+    public function addThumbnail(FileThumbnail $thumbnail): void
+    {
+        $this->thumbnails[$thumbnail->identifier] = $thumbnail;
+    }
+
+    public function getThumbnail(string $identifier): ?FileThumbnail
+    {
+        return $this->thumbnails[$identifier] ?? null;
+    }
 }
index f8ed9bcbae570da886b001c9435c091d40f93459..ef4af5bc774e66842fbbb639ce3a5a41c35973cd 100644 (file)
@@ -134,13 +134,6 @@ final class AttachmentBBCode extends AbstractBBCode
             FontAwesomeIcon::fromValues('magnifying-glass')->toHtml(24),
         );
 
-        $linkParameters = [
-            'object' => $attachment,
-        ];
-        if ($attachment->hasThumbnail()) {
-            $linkParameters['thumbnail'] = 1;
-        }
-
         $class = match ($alignment) {
             "left" => "messageFloatObjectLeft",
             "right" => "messageFloatObjectRight",
@@ -156,9 +149,11 @@ final class AttachmentBBCode extends AbstractBBCode
             $imageClasses .= ' ' . $class;
         }
 
+        $src = $attachment->hasThumbnail() ? $attachment->getThumbnailLink('thumbnail') : $attachment->getLink();
+
         $imageElement = \sprintf(
             '<img src="%s" class="%s" width="%d" height="%d" alt="" loading="lazy">',
-            StringUtil::encodeHTML(LinkHandler::getInstance()->getLink('Attachment', $linkParameters)),
+            StringUtil::encodeHTML($src),
             $imageClasses,
             $attachment->hasThumbnail() ? $attachment->thumbnailWidth : $attachment->width,
             $attachment->hasThumbnail() ? $attachment->thumbnailHeight : $attachment->height,
index 218198f9b0302e8a7269f4021982f7c68b371b58..eca8bdf9571d31e25007cf9f7009bb47818d3017 100644 (file)
@@ -2,7 +2,10 @@
 
 namespace wcf\system\message\embedded\object;
 
+use wcf\data\attachment\Attachment;
 use wcf\data\attachment\AttachmentList;
+use wcf\data\file\FileList;
+use wcf\data\file\thumbnail\FileThumbnailList;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\system\html\input\HtmlInputProcessor;
 
@@ -71,6 +74,46 @@ class AttachmentMessageEmbeddedObjectHandler extends AbstractMessageEmbeddedObje
             }
         }
 
-        return $attachmentList->getObjects();
+        $attachments = $attachmentList->getObjects();
+
+        $this->loadFiles($attachments);
+
+        return $attachments;
+    }
+
+    /**
+     * @param Attachment[] $attachments
+     */
+    private function loadFiles(array $attachments): void
+    {
+        $fileIDs = [];
+        foreach ($attachments as $attachment) {
+            if ($attachment->fileID) {
+                $fileIDs[] = $attachment->fileID;
+            }
+        }
+
+        if ($fileIDs === []) {
+            return;
+        }
+
+        $fileList = new FileList();
+        $fileList->getConditionBuilder()->add("fileID IN (?)", [$fileIDs]);
+        $fileList->readObjects();
+        $files = $fileList->getObjects();
+
+        $thumbnailList = new FileThumbnailList();
+        $thumbnailList->getConditionBuilder()->add("fileID IN (?)", [$fileIDs]);
+        $thumbnailList->readObjects();
+        foreach ($thumbnailList as $thumbnail) {
+            $files[$thumbnail->fileID]->addThumbnail($thumbnail);
+        }
+
+        foreach ($attachments as $attachment) {
+            $file = $files[$attachment->fileID] ?? null;
+            if ($file !== null) {
+                $attachment->setFile($file);
+            }
+        }
     }
 }