From c44c501258c7cdada84bfefe90c295623c5b8b6c Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Wed, 6 Aug 2025 09:46:37 +0200 Subject: [PATCH 1/2] Implement a command to copy attachments --- .../attachment/CopyAttachments.class.php | 122 ++++++++++++++++++ .../attachment/AttachmentAction.class.php | 83 ++---------- 2 files changed, 131 insertions(+), 74 deletions(-) create mode 100644 wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php diff --git a/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php b/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php new file mode 100644 index 00000000000..8b67ea44bf5 --- /dev/null +++ b/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php @@ -0,0 +1,122 @@ + + * @since 6.3 + */ +final class CopyAttachments +{ + public function __construct( + public readonly string $sourceObjectType, + public readonly int $sourceObjectID, + public readonly string $targetObjectType, + public readonly int $targetObjectID, + ) { + } + + /** + * @return array + */ + public function __invoke(): array + { + $sourceObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName( + 'com.woltlab.wcf.attachment.objectType', + $this->sourceObjectType + ); + $targetObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName( + 'com.woltlab.wcf.attachment.objectType', + $this->targetObjectType + ); + + $attachments = $this->getAttachments($sourceObjectType, $this->sourceObjectID); + + $newAttachmentIDs = []; + foreach ($attachments as $attachment) { + $newAttachment = $this->copyAttachment($targetObjectType, $attachment); + + $newAttachmentIDs[$attachment->attachmentID] = $newAttachment->attachmentID; + } + + return $newAttachmentIDs; + } + + /** + * @return Attachment[] + */ + private function getAttachments(ObjectType $sourceObjectType, int $sourceObjectID): array + { + $attachmentList = new AttachmentList(); + $attachmentList->getConditionBuilder()->add("attachment.objectTypeID = ?", [$sourceObjectType->objectTypeID]); + $attachmentList->getConditionBuilder()->add("attachment.objectID = ?", [$sourceObjectID]); + $attachmentList->readObjects(); + + return $attachmentList->getObjects(); + } + + private function copyAttachment(ObjectType $targetObjectType, Attachment $oldAttachment): Attachment + { + $file = $oldAttachment->getFile(); + $thumbnailID = null; + $tinyThumbnailID = null; + + if ($file !== null) { + $file = FileProcessor::getInstance()->copy($file, 'com.woltlab.wcf.attachment'); + + if ($oldAttachment->thumbnailID !== null || $oldAttachment->tinyThumbnailID !== null) { + $thumbnailList = new FileThumbnailList(); + $thumbnailList->getConditionBuilder()->add('fileID = ?', [$file->fileID]); + $thumbnailList->readObjects(); + + foreach ($thumbnailList->getObjects() as $thumbnail) { + match ($thumbnail->identifier) { + '' => $thumbnailID = $thumbnail->thumbnailID, + 'tiny' => $tinyThumbnailID = $thumbnail->thumbnailID, + }; + } + } + } + + return AttachmentEditor::create([ + 'objectTypeID' => $targetObjectType->objectTypeID, + 'objectID' => $this->targetObjectID, + 'userID' => $oldAttachment->userID, + 'filename' => $oldAttachment->filename, + 'filesize' => $oldAttachment->filesize, + 'fileType' => $oldAttachment->fileType, + 'fileHash' => $oldAttachment->fileHash, + 'isImage' => $oldAttachment->isImage, + 'width' => $oldAttachment->width, + 'height' => $oldAttachment->height, + 'tinyThumbnailType' => $oldAttachment->tinyThumbnailType, + 'tinyThumbnailSize' => $oldAttachment->tinyThumbnailSize, + 'tinyThumbnailWidth' => $oldAttachment->tinyThumbnailWidth, + 'tinyThumbnailHeight' => $oldAttachment->tinyThumbnailHeight, + 'thumbnailType' => $oldAttachment->thumbnailType, + 'thumbnailSize' => $oldAttachment->thumbnailSize, + 'thumbnailWidth' => $oldAttachment->thumbnailWidth, + 'thumbnailHeight' => $oldAttachment->thumbnailHeight, + 'downloads' => $oldAttachment->downloads, + 'lastDownloadTime' => $oldAttachment->lastDownloadTime, + 'uploadTime' => $oldAttachment->uploadTime, + 'showOrder' => $oldAttachment->showOrder, + 'fileID' => $file?->fileID, + 'thumbnailID' => $thumbnailID, + 'tinyThumbnailID' => $tinyThumbnailID, + ]); + } +} diff --git a/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php b/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php index 11bc81370fd..cafe8f8b726 100644 --- a/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php +++ b/wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php @@ -2,12 +2,11 @@ namespace wcf\data\attachment; +use wcf\command\attachment\CopyAttachments; use wcf\data\AbstractDatabaseObjectAction; -use wcf\data\file\thumbnail\FileThumbnailList; use wcf\data\object\type\ObjectTypeCache; use wcf\system\exception\PermissionDeniedException; use wcf\system\exception\UserInputException; -use wcf\system\file\processor\FileProcessor; use wcf\system\WCF; /** @@ -75,82 +74,18 @@ public function generateThumbnails() * Copies attachments from one object id to another. * * @return array{attachmentIDs: array} + * + * @deprecated 6.3 use `CopyAttachments` instead. */ public function copy() { - $sourceObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName( - 'com.woltlab.wcf.attachment.objectType', - $this->parameters['sourceObjectType'] - ); - $targetObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName( - 'com.woltlab.wcf.attachment.objectType', - $this->parameters['targetObjectType'] - ); - - $attachmentList = new AttachmentList(); - $attachmentList->getConditionBuilder()->add("attachment.objectTypeID = ?", [$sourceObjectType->objectTypeID]); - $attachmentList->getConditionBuilder()->add("attachment.objectID = ?", [$this->parameters['sourceObjectID']]); - $attachmentList->readObjects(); - - $newAttachmentIDs = []; - foreach ($attachmentList as $attachment) { - $file = $attachment->getFile(); - if ($file !== null) { - $file = FileProcessor::getInstance()->copy($file, 'com.woltlab.wcf.attachment'); - - $thumbnailID = $tinyThumbnailID = null; - if ($attachment->thumbnailID !== null || $attachment->tinyThumbnailID !== null) { - $thumbnailList = new FileThumbnailList(); - $thumbnailList->getConditionBuilder()->add('fileID = ?', [$file->fileID]); - $thumbnailList->readObjects(); - - foreach ($thumbnailList as $thumbnail) { - switch ($thumbnail->identifier) { - case '': - $thumbnailID = $thumbnail->thumbnailID; - break; - - case 'tiny': - $tinyThumbnailID = $thumbnail->thumbnailID; - break; - } - } - } - } - - $newAttachment = AttachmentEditor::create([ - 'objectTypeID' => $targetObjectType->objectTypeID, - 'objectID' => $this->parameters['targetObjectID'], - 'userID' => $attachment->userID, - 'filename' => $attachment->filename, - 'filesize' => $attachment->filesize, - 'fileType' => $attachment->fileType, - 'fileHash' => $attachment->fileHash, - 'isImage' => $attachment->isImage, - 'width' => $attachment->width, - 'height' => $attachment->height, - 'tinyThumbnailType' => $attachment->tinyThumbnailType, - 'tinyThumbnailSize' => $attachment->tinyThumbnailSize, - 'tinyThumbnailWidth' => $attachment->tinyThumbnailWidth, - 'tinyThumbnailHeight' => $attachment->tinyThumbnailHeight, - 'thumbnailType' => $attachment->thumbnailType, - 'thumbnailSize' => $attachment->thumbnailSize, - 'thumbnailWidth' => $attachment->thumbnailWidth, - 'thumbnailHeight' => $attachment->thumbnailHeight, - 'downloads' => $attachment->downloads, - 'lastDownloadTime' => $attachment->lastDownloadTime, - 'uploadTime' => $attachment->uploadTime, - 'showOrder' => $attachment->showOrder, - 'fileID' => $file?->fileID, - 'thumbnailID' => $thumbnailID ?? null, - 'tinyThumbnailID' => $tinyThumbnailID ?? null, - ]); - - $newAttachmentIDs[$attachment->attachmentID] = $newAttachment->attachmentID; - } - return [ - 'attachmentIDs' => $newAttachmentIDs, + 'attachmentIDs' => (new CopyAttachments( + $this->parameters['sourceObjectType'], + $this->parameters['sourceObjectID'], + $this->parameters['targetObjectType'], + $this->parameters['targetObjectID'] + ))() ]; } } From 25225d8e0f1f3225fe03951d6b8ee0702a078bd4 Mon Sep 17 00:00:00 2001 From: Olaf Braun Date: Fri, 8 Aug 2025 09:12:57 +0200 Subject: [PATCH 2/2] Update wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php Co-authored-by: Alexander Ebert --- .../lib/command/attachment/CopyAttachments.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php b/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php index 8b67ea44bf5..1f6bb48cb47 100644 --- a/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php +++ b/wcfsetup/install/files/lib/command/attachment/CopyAttachments.class.php @@ -22,10 +22,10 @@ final class CopyAttachments { public function __construct( - public readonly string $sourceObjectType, - public readonly int $sourceObjectID, - public readonly string $targetObjectType, - public readonly int $targetObjectID, + private readonly string $sourceObjectType, + private readonly int $sourceObjectID, + private readonly string $targetObjectType, + private readonly int $targetObjectID, ) { }