Implement `canAdopt()` in `IFileProcessor` and `FileProcessor` to check if the file...
authorCyperghost <olaf_schmitz_1@t-online.de>
Tue, 1 Oct 2024 10:14:48 +0000 (12:14 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Tue, 1 Oct 2024 10:14:48 +0000 (12:14 +0200)
wcfsetup/install/files/lib/system/endpoint/controller/core/files/upload/SaveChunk.class.php
wcfsetup/install/files/lib/system/file/processor/AttachmentFileProcessor.class.php
wcfsetup/install/files/lib/system/file/processor/FileProcessor.class.php
wcfsetup/install/files/lib/system/file/processor/IFileProcessor.class.php
wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 0a03944b78fcd417ecd2da0d49691d17f973ed24..8983b774f04b0efb9a9b1007fcfc9e3103395d69 100644 (file)
@@ -12,6 +12,7 @@ use wcf\http\Helper;
 use wcf\system\endpoint\IController;
 use wcf\system\endpoint\PostRequest;
 use wcf\system\exception\UserInputException;
+use wcf\system\file\processor\FileProcessor;
 use wcf\system\io\File;
 
 #[PostRequest('/core/files/upload/{identifier}/chunk/{sequenceNo:\d+}')]
@@ -118,9 +119,11 @@ final class SaveChunk implements IController
 
                     throw new UserInputException('validation', $exception->getType());
                 }
-            }
 
-            $processor?->adopt($file, $context);
+                if (FileProcessor::getInstance()->canAdopt($processor, $file, $context)) {
+                    $processor->adopt($file, $context);
+                }
+            }
 
             $generateThumbnails = false;
             if ($processor !== null && $file->isImage()) {
index bfc054b3dc6b2dbd985db0c4874e83088b19e47a..c3ec1624a2ec588327304e8a0a98c6d104c29c25 100644 (file)
@@ -40,6 +40,18 @@ final class AttachmentFileProcessor extends AbstractFileProcessor
         return $attachmentHandler->getAllowedExtensions();
     }
 
+    #[\Override]
+    public function canAdopt(File $file, array $context): bool
+    {
+        $attachment = Attachment::findByFileID($file->fileID);
+
+        if ($attachment === null) {
+            return true;
+        }
+
+        return false;
+    }
+
     #[\Override]
     public function adopt(File $file, array $context): void
     {
index e09a201fb89865d5f48b6b0b2797d4650bcbeb29..8ecd6b751ed8d9a506df9087b90e20901df76335 100644 (file)
@@ -125,6 +125,16 @@ final class FileProcessor extends SingletonFactory
         );
     }
 
+    public function canAdopt(IFileProcessor $fileProcessor, File $file, array $context): bool
+    {
+        $objectType = $this->getObjectType($fileProcessor->getObjectTypeName());
+        if ($objectType->objectTypeID !== $file->objectTypeID) {
+            return false;
+        }
+
+        return $fileProcessor->canAdopt($file, $context);
+    }
+
     public function generateWebpVariant(File $file): void
     {
         $canGenerateThumbnail = match ($file->mimeType) {
index bb8f9b01d12ec5c9de48efcc6e3fa4c8249a2d46..701d22ce1a6080357f391e516fb4ca50c44014b1 100644 (file)
@@ -36,12 +36,22 @@ interface IFileProcessor
      */
     public function validateUpload(File $file): void;
 
+    /**
+     * Checks if the given `$file` can be assigned to the object referenced by the information
+     * contained in `$context`.
+     *
+     * The `$file` can be assigned if one of the following conditions is met:
+     * - The file has not yet been assigned to any object
+     * - The file is already assigned to the object referenced by `$context`
+     */
+    public function canAdopt(File $file, array $context): bool;
+
     /**
      * Notifies the file processor that the upload of a file has been completed
      * that belongs to this type.
      *
      * `$context` are the exact same values that have previously been passed to
-     * `acceptUpload()` before.
+     * `canAdopt()` before.
      */
     public function adopt(File $file, array $context): void;
 
index 500353548f0b9c81d1a216db9d0230671310493e..2093900ac917120ffa1c22360dac4b6fc0bf7ab9 100644 (file)
@@ -194,7 +194,7 @@ final class FileProcessorFormField extends AbstractFormField
             $this->addValidationError(
                 new FormFieldValidationError(
                     'maximumFiles',
-                    'wcf.form.field.fileProcessor.error.maximumFiles',
+                    'wcf.upload.error.maximumCountReached',
                     [
                         'maximumCount' => $fileProcessor->getMaximumCount($this->context),
                         'count' => \count($this->files),
@@ -203,6 +203,18 @@ final class FileProcessorFormField extends AbstractFormField
             );
         }
 
+        foreach ($this->files as $file) {
+            if (!FileProcessor::getInstance()->canAdopt($fileProcessor, $file, $this->context)) {
+                $this->addValidationError(
+                    new FormFieldValidationError(
+                        'adopt',
+                        'wcf.form.field.fileProcessor.error.adopt',
+                        ['file' => $file]
+                    )
+                );
+            }
+        }
+
         parent::validate();
     }
 
index d478f069b309cf4b57d30a6516254ad7fa820a60..dc89e19e1a2d8c020ffa8dd2a8b023b07ae83e4b 100644 (file)
@@ -4099,6 +4099,7 @@ Dateianhänge:
                <item name="wcf.form.field.upload.error.maximumImageHeight"><![CDATA[Die Datei „{$file->getFilename()}“ darf maximal {#$maximumImageHeight} Pixel hoch sein.]]></item>
                <item name="wcf.form.field.upload.error.minimum"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du musst{else}Sie müssen{/if} mindestens {if $minimum > 1}{#$minimum} Dateien{else}eine Datei{/if} hochladen.]]></item>
                <item name="wcf.form.field.upload.error.maximum"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du darfst{else}Sie dürfen{/if} maximal {if $maximum > 1}{#$maximum} Dateien{else}eine Datei{/if} hochladen.]]></item>
+               <item name="wcf.form.field.fileProcessor.error.adopt"><![CDATA[Die Datei „{$file->filename}“ kann nicht zugewiesen werden.]]></item>
        </category>
        <category name="wcf.image">
                <item name="wcf.image.coverPhoto"><![CDATA[Titelbild]]></item>
index ca0f31be040c9c8367a3398542ee759fef3380e0..da60a803d6d0e06772c09da699de54eefeac9bdf 100644 (file)
@@ -4045,6 +4045,7 @@ Attachments:
                <item name="wcf.form.field.upload.error.maximumImageHeight"><![CDATA[The file “{$file->getFilename()}” may have a maximum height of {#$maximumImageHeight} pixels.]]></item>
                <item name="wcf.form.field.upload.error.minimum"><![CDATA[You must upload at least {if $minimum > 1}{#$minimum} files{else}one file{/if}.]]></item>
                <item name="wcf.form.field.upload.error.maximum"><![CDATA[You can upload a maximum of {if $maximum > 1}{#$maximum} files{else}one file{/if}.]]></item>
+               <item name="wcf.form.field.fileProcessor.error.adopt"><![CDATA[The file „{$file->filename}“ cannot be assigned.]]></item>
        </category>
        <category name="wcf.image">
                <item name="wcf.image.coverPhoto"><![CDATA[Cover Photo]]></item>