Cache the width and height of images
authorAlexander Ebert <ebert@woltlab.com>
Sat, 13 Apr 2024 22:37:11 +0000 (00:37 +0200)
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/data/file/FileEditor.class.php
wcfsetup/install/files/lib/data/file/thumbnail/FileThumbnail.class.php
wcfsetup/install/files/lib/data/file/thumbnail/FileThumbnailEditor.class.php
wcfsetup/setup/db/install.sql

index e5d7e9cc53a6f28414a407f9e2e6a4e9921924fd..0275687f58ef352eff4d06fad935f028ca1f9d7c 100644 (file)
@@ -394,22 +394,14 @@ class Attachment extends DatabaseObject implements ILinkableObject, IRouteContro
             '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,
-
+            'height' => $file->height,
+            'width' => $file->width,
+            'thumbnailType' => $file->getThumbnail('')?->getMimeType() ?: '',
+            'thumbnailWidth' => $file->getThumbnail('')?->width ?: 0,
+            'thumbnailHeight' => $file->getThumbnail('')?->height ?: 0,
+            'tinyThumbnailType' => $file->getThumbnail('tiny')?->getMimeType() ?: '',
+            'tinyThumbnailWidth' => $file->getThumbnail('tiny')?->width ?: 0,
+            'tinyThumbnailHeight' => $file->getThumbnail('tiny')?->height ?: 0,
             default => parent::__get($name),
         };
     }
index 279c20bf532bdded632de62c5e8a9688ea35794d..19fbc329955e899ea02e164eebbbcab1766c35cd 100644 (file)
@@ -22,6 +22,8 @@ use wcf\util\StringUtil;
  * @property-read string $fileHash
  * @property-read string $typeName
  * @property-read string $mimeType
+ * @property-read int|null $width
+ * @property-read int|null $height
  */
 class File extends DatabaseObject
 {
index 88af30cd7b1c6975fc215d27cad6a26edc8695a4..e0fafc292250f907745eb0e60a760c042ed92229 100644 (file)
@@ -26,6 +26,18 @@ class FileEditor extends DatabaseObjectEditor
     public static function createFromTemporary(FileTemporary $fileTemporary): File
     {
         $mimeType = FileUtil::getMimeType($fileTemporary->getPath() . $fileTemporary->getFilename());
+        $isImage = match ($mimeType) {
+            'image/gif' => true,
+            'image/jpeg' => true,
+            'image/png' => true,
+            'image/webp' => true,
+            default => false,
+        };
+
+        $width = $height = null;
+        if ($isImage) {
+            [$width, $height] = \getimagesize($fileTemporary->getPath() . $fileTemporary->getFilename());
+        }
 
         $fileAction = new FileAction([], 'create', ['data' => [
             'filename' => $fileTemporary->filename,
@@ -33,6 +45,8 @@ class FileEditor extends DatabaseObjectEditor
             'fileHash' => $fileTemporary->fileHash,
             'typeName' => $fileTemporary->typeName,
             'mimeType' => $mimeType,
+            'width' => $width,
+            'height' => $height,
         ]]);
         $file = $fileAction->executeAction()['returnValues'];
         \assert($file instanceof File);
index 032f50cc65d7cbaa9e37631d58dc6993dfebf9d3..b12245bf9eda822d58a01588fd85dc6ebbfc0ecd 100644 (file)
@@ -18,6 +18,8 @@ use wcf\system\request\LinkHandler;
  * @property-read string $identifier
  * @property-read string $fileHash
  * @property-read string $fileExtension
+ * @property-read int $width
+ * @property-read int $height
  */
 class FileThumbnail extends DatabaseObject implements ILinkableObject
 {
@@ -46,6 +48,11 @@ class FileThumbnail extends DatabaseObject implements ILinkableObject
         );
     }
 
+    public function getMimeType(): string
+    {
+        return 'image/webp';
+    }
+
     private function getRelativePath(): string
     {
         $folderA = \substr($this->fileHash, 0, 2);
index cf9d3431a7a398b19359f92b395af956fe41fa4b..05118c1b63303bfb76465ee5669af8847db66b21 100644 (file)
@@ -29,20 +29,16 @@ class FileThumbnailEditor extends DatabaseObjectEditor
         ThumbnailFormat $format,
         string $filename
     ): FileThumbnail {
-        $mimeType = FileUtil::getMimeType($filename);
-        $fileExtension = match ($mimeType) {
-            'image/gif' => 'gif',
-            'image/jpg', 'image/jpeg' => 'jpg',
-            'image/png' => 'png',
-            'image/webp' => 'webp',
-        };
+        [$width, $height] = \getimagesize($filename);
 
         $action = new FileThumbnailAction([], 'create', [
             'data' => [
                 'fileID' => $file->fileID,
                 'identifier' => $format->identifier,
                 'fileHash' => hash_file('sha256', $filename),
-                'fileExtension' => $fileExtension,
+                'fileExtension' => 'webp',
+                'width' => $width,
+                'height' => $height,
             ],
         ]);
         $fileThumbnail = $action->executeAction()['returnValues'];
index 95a179cc5e35346f95579cee4841aa433dbce152..f3fbba6b9f9723656150f6b76f5ca2215b53d3e6 100644 (file)
@@ -606,6 +606,8 @@ CREATE TABLE wcf1_file (
        fileHash CHAR(64) NOT NULL,
        typeName VARCHAR(255) NOT NULL,
        mimeType VARCHAR(255) NOT NULL,
+       width INT,
+       height INT
 );
 
 DROP TABLE IF EXISTS wcf1_file_temporary;
@@ -626,7 +628,9 @@ CREATE TABLE wcf1_file_thumbnail (
        fileID INT NOT NULL,
        identifier VARCHAR(50) NOT NULL,
        fileHash CHAR(64) NOT NULL,
-       fileExtension VARCHAR(10) NOT NULL
+       fileExtension VARCHAR(10) NOT NULL,
+       width INT NOT NULL,
+       height INT NOT NULL
 );
 
 /* As the flood control table can be a high traffic table and as it is periodically emptied,