Add file processor form field
authorCyperghost <olaf_schmitz_1@t-online.de>
Wed, 12 Jun 2024 10:09:54 +0000 (12:09 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Wed, 12 Jun 2024 10:09:54 +0000 (12:09 +0200)
com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl [new file with mode: 0644]
ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php [new file with mode: 0644]

diff --git a/com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl b/com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl
new file mode 100644 (file)
index 0000000..eb2b68d
--- /dev/null
@@ -0,0 +1,10 @@
+{unsafe:$fileProcessorHtmlElement}
+
+<script data-relocate="true">
+       require(["WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor"], ({ FileProcessor }) => {
+               new FileProcessor(
+                       '{@$field->getPrefixedId()|encodeJS}',
+                       [],
+               );
+       });
+</script>
diff --git a/ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts b/ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts
new file mode 100644 (file)
index 0000000..938d767
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * @author    Olaf Braun
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since     6.1
+ */
+
+import WoltlabCoreFileElement from "WoltLabSuite/Core/Component/File/woltlab-core-file";
+import DomUtil from "WoltLabSuite/Core/Dom/Util";
+
+export class FileProcessor {
+  readonly #container: HTMLElement;
+  readonly #uploadButton: WoltlabCoreFileUploadElement;
+  readonly #files = new Map<number, WoltlabCoreFileElement>();
+  readonly #fieldId: string;
+
+  constructor(fieldId: string, values: string[]) {
+    this.#fieldId = fieldId;
+
+    this.#container = document.getElementById(fieldId + "Container")!;
+    if (this.#container === null) {
+      throw new Error("Unknown field with id '" + fieldId + "'");
+    }
+
+    values.forEach((html) => {
+      const element = document.createElement("template");
+      DomUtil.setInnerHtml(element, html);
+
+      void this.#registerFile(element.content.querySelector<WoltlabCoreFileElement>("woltlab-core-file")!);
+    });
+
+    this.#uploadButton = this.#container.querySelector("woltlab-core-file-upload") as WoltlabCoreFileUploadElement;
+    this.#uploadButton.addEventListener("uploadStart", (event: CustomEvent<WoltlabCoreFileElement>) => {
+      void this.#registerFile(event.detail);
+    });
+  }
+
+  async #registerFile(element: WoltlabCoreFileElement): Promise<void> {
+    this.#uploadButton.insertAdjacentElement("beforebegin", element);
+
+    await element.ready;
+    this.#files.set(element.fileId!, element);
+    const input = document.createElement("input");
+    input.type = "hidden";
+    input.name = this.#fieldId + (this.#uploadButton.maximumCount === 1 ? "" : "[]");
+    input.value = element.fileId!.toString();
+    element.insertAdjacentElement("afterend", input);
+
+    if (this.#uploadButton.maximumCount === 1) {
+      // single file upload
+      element.dataset.previewUrl = element.link!;
+      element.unbounded = true;
+    }
+  }
+}
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js
new file mode 100644 (file)
index 0000000..33807de
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * @author    Olaf Braun
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since     6.1
+ */
+define(["require", "exports", "tslib", "WoltLabSuite/Core/Dom/Util"], function (require, exports, tslib_1, Util_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.FileProcessor = void 0;
+    Util_1 = tslib_1.__importDefault(Util_1);
+    class FileProcessor {
+        #container;
+        #uploadButton;
+        #files = new Map();
+        #fieldId;
+        constructor(fieldId, values) {
+            this.#fieldId = fieldId;
+            this.#container = document.getElementById(fieldId + "Container");
+            if (this.#container === null) {
+                throw new Error("Unknown field with id '" + fieldId + "'");
+            }
+            values.forEach((html) => {
+                const element = document.createElement("template");
+                Util_1.default.setInnerHtml(element, html);
+                void this.#registerFile(element.content.querySelector("woltlab-core-file"));
+            });
+            this.#uploadButton = this.#container.querySelector("woltlab-core-file-upload");
+            this.#uploadButton.addEventListener("uploadStart", (event) => {
+                void this.#registerFile(event.detail);
+            });
+        }
+        async #registerFile(element) {
+            this.#uploadButton.insertAdjacentElement("beforebegin", element);
+            await element.ready;
+            this.#files.set(element.fileId, element);
+            const input = document.createElement("input");
+            input.type = "hidden";
+            input.name = this.#fieldId + (this.#uploadButton.maximumCount === 1 ? "" : "[]");
+            input.value = element.fileId.toString();
+            element.insertAdjacentElement("afterend", input);
+            if (this.#uploadButton.maximumCount === 1) {
+                // single file upload
+                element.dataset.previewUrl = element.link;
+                element.unbounded = true;
+            }
+        }
+    }
+    exports.FileProcessor = FileProcessor;
+});
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php
new file mode 100644 (file)
index 0000000..d1e05e2
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+namespace wcf\system\form\builder\field;
+
+use wcf\system\file\processor\FileProcessor;
+use wcf\system\file\processor\IFileProcessor;
+use wcf\system\form\builder\TObjectTypeFormNode;
+
+/**
+ * Form field for file processors.
+ *
+ * @author      Olaf Braun
+ * @copyright   2001-2024 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+final class FileProcessorFormField extends AbstractFormField
+{
+    use TObjectTypeFormNode;
+
+    /**
+     * @inheritDoc
+     */
+    protected $templateName = 'shared_fileProcessorFormField';
+
+    private array $context = [];
+
+    #[\Override]
+    public function readValue()
+    {
+        \wcfDebug($this->getDocument()->getRequestData());
+        if ($this->getDocument()->hasRequestData($this->getPrefixedId())) {
+            $this->context = $this->getDocument()->getRequestData($this->getPrefixedId());
+        }
+    }
+
+    #[\Override]
+    public function getHtmlVariables()
+    {
+        return [
+            'fileProcessorHtmlElement' => FileProcessor::getInstance()->getHtmlElement(
+                $this->getFileProcessor(),
+                $this->context
+            ),
+            'maxUploads' => $this->getFileProcessor()->getMaximumCount($this->context),
+        ];
+    }
+
+    public function getFileProcessor(): IFileProcessor
+    {
+        return $this->getObjectType()->getProcessor();
+    }
+
+    #[\Override]
+    public function getObjectTypeDefinition()
+    {
+        return 'com.woltlab.wcf.file';
+    }
+
+    /**
+     * Returns the context for the file processor.
+     */
+    public function getContext(): array
+    {
+        return $this->context;
+    }
+
+    /**
+     * Sets the context for the file processor.
+     */
+    public function context(array $context): self
+    {
+        $this->context = $context;
+
+        return $this;
+    }
+}