From 62f844174aa4ddef675e95ae0f3a3bac67919295 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 15 Dec 2024 13:34:56 +0100 Subject: [PATCH] Modify the API of the events to handle competing listeners The generated pathname can now only be set once and all further attempts are rejected. Listeners are expected to test this with `hasFile()` prior to taking any action. --- .../event/file/GenerateThumbnail.class.php | 24 ++++++++++--- .../event/file/GenerateWebpVariant.class.php | 36 ++++++++++++++++--- .../file/processor/FileProcessor.class.php | 4 +-- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/wcfsetup/install/files/lib/event/file/GenerateThumbnail.class.php b/wcfsetup/install/files/lib/event/file/GenerateThumbnail.class.php index 3cdc58424a..827080f0e5 100644 --- a/wcfsetup/install/files/lib/event/file/GenerateThumbnail.class.php +++ b/wcfsetup/install/files/lib/event/file/GenerateThumbnail.class.php @@ -16,13 +16,29 @@ use wcf\system\file\processor\ThumbnailFormat; */ final class GenerateThumbnail implements IPsr14Event { - /** - * The absolute path to the generated WebP image. - */ - public ?string $filename = null; + private string $pathname; public function __construct( public readonly File $file, public readonly ThumbnailFormat $thumbnailFormat, ) {} + + /** + * Sets the pathname of the generated image unless it has already been set + * in which case the call will throw an exception. You must check the result + * of `hasFile()` first. + */ + public function setGeneratedFile(string $pathname): void + { + if (isset($this->pathname)) { + throw new \BadMethodCallException("Cannot set the generated file, a value has already been set."); + } + + $this->pathname = $pathname; + } + + public function getPathname(): ?string + { + return $this->pathname ?? null; + } } diff --git a/wcfsetup/install/files/lib/event/file/GenerateWebpVariant.class.php b/wcfsetup/install/files/lib/event/file/GenerateWebpVariant.class.php index 753e5300e9..c7f180a437 100644 --- a/wcfsetup/install/files/lib/event/file/GenerateWebpVariant.class.php +++ b/wcfsetup/install/files/lib/event/file/GenerateWebpVariant.class.php @@ -2,11 +2,12 @@ namespace wcf\event\file; +use BadMethodCallException; use wcf\data\file\File; use wcf\event\IPsr14Event; /** - * Requests the generation of a WebP variant of the provided file. + * Requests the generation of a WebP variant for the provided image. * * @author Alexander Ebert * @copyright 2001-2024 WoltLab GmbH @@ -15,12 +16,37 @@ use wcf\event\IPsr14Event; */ final class GenerateWebpVariant implements IPsr14Event { - /** - * The absolute path to the generated WebP image. - */ - public ?string $filename = null; + private string $pathname; public function __construct( public readonly File $file ) {} + + /** + * Returns true if a file has already been set and no further files are + * being accepted. + */ + public function hasFile(): bool + { + return isset($this->pathname); + } + + /** + * Sets the pathname of the generated image unless it has already been set + * in which case the call will throw an exception. You must check the result + * of `hasFile()` first. + */ + public function setGeneratedFile(string $pathname): void + { + if (isset($this->pathname)) { + throw new \BadMethodCallException("Cannot set the generated file, a value has already been set."); + } + + $this->pathname = $pathname; + } + + public function getPathname(): ?string + { + return $this->pathname ?? null; + } } diff --git a/wcfsetup/install/files/lib/system/file/processor/FileProcessor.class.php b/wcfsetup/install/files/lib/system/file/processor/FileProcessor.class.php index 09396023ef..cbd3b336e4 100644 --- a/wcfsetup/install/files/lib/system/file/processor/FileProcessor.class.php +++ b/wcfsetup/install/files/lib/system/file/processor/FileProcessor.class.php @@ -165,7 +165,7 @@ final class FileProcessor extends SingletonFactory $event = new GenerateWebpVariant($file); EventHandler::getInstance()->fire($event); - $filename = $event->filename; + $filename = $event->getPathname(); if ($filename === null) { $imageAdapter = ImageHandler::getInstance()->getAdapter(); if (!$imageAdapter->checkMemoryLimit($file->width, $file->height, $file->mimeType)) { @@ -263,7 +263,7 @@ final class FileProcessor extends SingletonFactory $event = new GenerateThumbnail($file, $format); EventHandler::getInstance()->fire($event); - $filename = $event->filename; + $filename = $event->getPathname(); if ($filename === null) { if ($imageAdapter === null) { $imageAdapter = ImageHandler::getInstance()->getAdapter(); -- 2.20.1