Skip to content

Commit

Permalink
Add events to delegate the WebP/thumbnail generation
Browse files Browse the repository at this point in the history
This allows to bypass the image adapter when generating the WebP variant and the thumbnails.
  • Loading branch information
dtdesign committed Dec 15, 2024
1 parent 560572b commit c189423
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 42 deletions.
28 changes: 28 additions & 0 deletions wcfsetup/install/files/lib/event/file/GenerateThumbnail.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace wcf\event\file;

use wcf\data\file\File;
use wcf\event\IPsr14Event;
use wcf\system\file\processor\ThumbnailFormat;

/**
* Requests the generation of a thumbnail.
*
* @author Alexander Ebert
* @copyright 2001-2024 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.1
*/
final class GenerateThumbnail implements IPsr14Event
{
/**
* The absolute path to the generated WebP image.
*/
public ?string $filename = null;

public function __construct(
public readonly File $file,
public readonly ThumbnailFormat $thumbnailFormat,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace wcf\event\file;

use wcf\data\file\File;
use wcf\event\IPsr14Event;

/**
* Requests the generation of a WebP variant of the provided file.
*
* @author Alexander Ebert
* @copyright 2001-2024 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.1
*/
final class GenerateWebpVariant implements IPsr14Event
{
/**
* The absolute path to the generated WebP image.
*/
public ?string $filename = null;

public function __construct(
public readonly File $file
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
use wcf\data\file\thumbnail\FileThumbnailList;
use wcf\data\object\type\ObjectType;
use wcf\data\object\type\ObjectTypeCache;
use wcf\event\file\GenerateThumbnail;
use wcf\event\file\GenerateWebpVariant;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\event\EventHandler;
use wcf\system\exception\SystemException;
use wcf\system\file\processor\exception\DamagedImage;
use wcf\system\image\adapter\exception\ImageNotProcessable;
Expand Down Expand Up @@ -159,32 +162,38 @@ public function generateWebpVariant(File $file): void
}
}

$imageAdapter = ImageHandler::getInstance()->getAdapter();
if (!$imageAdapter->checkMemoryLimit($file->width, $file->height, $file->mimeType)) {
return;
}
$event = new GenerateWebpVariant($file);
EventHandler::getInstance()->fire($event);

try {
$imageAdapter->loadSingleFrameFromFile($file->getPathname());
} catch (SystemException | ImageNotReadable) {
throw new DamagedImage($file->fileID);
} catch (ImageNotProcessable $e) {
logThrowable($e);

return;
}
$filename = $event->filename;
if ($filename === null) {
$imageAdapter = ImageHandler::getInstance()->getAdapter();
if (!$imageAdapter->checkMemoryLimit($file->width, $file->height, $file->mimeType)) {
return;
}

$filename = FileUtil::getTemporaryFilename(extension: 'webp');
try {
$imageAdapter->loadSingleFrameFromFile($file->getPathname());
} catch (SystemException | ImageNotReadable) {
throw new DamagedImage($file->fileID);
} catch (ImageNotProcessable $e) {
logThrowable($e);

try {
$imageAdapter->saveImageAs($imageAdapter->getImage(), $filename, 'webp', 80);
} catch (\Throwable $e) {
// Ignore any errors trying to save the file unless in debug mode.
if (\ENABLE_DEBUG_MODE) {
throw $e;
return;
}

return;
$filename = FileUtil::getTemporaryFilename(extension: 'webp');

try {
$imageAdapter->saveImageAs($imageAdapter->getImage(), $filename, 'webp', 80);
} catch (\Throwable $e) {
// Ignore any errors trying to save the file unless in debug mode.
if (\ENABLE_DEBUG_MODE) {
throw $e;
}

return;
}
}

(new FileEditor($file))->update([
Expand Down Expand Up @@ -251,36 +260,42 @@ public function generateThumbnails(File $file): void
}
}

if ($imageAdapter === null) {
$imageAdapter = ImageHandler::getInstance()->getAdapter();
if (!$imageAdapter->checkMemoryLimit($file->width, $file->height, $file->mimeType)) {
return;
$event = new GenerateThumbnail($file, $format);
EventHandler::getInstance()->fire($event);

$filename = $event->filename;
if ($filename === null) {
if ($imageAdapter === null) {
$imageAdapter = ImageHandler::getInstance()->getAdapter();
if (!$imageAdapter->checkMemoryLimit($file->width, $file->height, $file->mimeType)) {
return;
}

try {
$imageAdapter->loadSingleFrameFromFile($file->getPathname());
} catch (SystemException | ImageNotReadable $e) {
throw new DamagedImage($file->fileID, $e);
} catch (ImageNotProcessable $e) {
logThrowable($e);

return;
}
}

\assert($imageAdapter instanceof ImageAdapter);

try {
$imageAdapter->loadSingleFrameFromFile($file->getPathname());
} catch (SystemException | ImageNotReadable $e) {
throw new DamagedImage($file->fileID, $e);
} catch (ImageNotProcessable $e) {
$image = $imageAdapter->createThumbnail($format->width, $format->height, $format->retainDimensions);
} catch (\Throwable $e) {
logThrowable($e);

return;
continue;
}
}

\assert($imageAdapter instanceof ImageAdapter);

try {
$image = $imageAdapter->createThumbnail($format->width, $format->height, $format->retainDimensions);
} catch (\Throwable $e) {
logThrowable($e);

continue;
$filename = FileUtil::getTemporaryFilename(extension: 'webp');
$imageAdapter->saveImageAs($image, $filename, 'webp', 80);
}

$filename = FileUtil::getTemporaryFilename(extension: 'webp');
$imageAdapter->saveImageAs($image, $filename, 'webp', 80);

$fileThumbnail = FileThumbnailEditor::createFromTemporaryFile($file, $format, $filename);
$processor->adoptThumbnail($fileThumbnail);
}
Expand Down

0 comments on commit c189423

Please sign in to comment.