From bd66aaaf816f2542c56a420444b0f3dcf8e5f327 Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Wed, 12 Jun 2024 12:09:54 +0200 Subject: [PATCH] Add file processor form field --- .../shared_fileProcessorFormField.tpl | 10 +++ .../Builder/Field/Controller/FileProcessor.ts | 55 ++++++++++++++ .../Builder/Field/Controller/FileProcessor.js | 50 ++++++++++++ .../field/FileProcessorFormField.class.php | 76 +++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl create mode 100644 ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts create mode 100644 wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js create mode 100644 wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php diff --git a/com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl b/com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl new file mode 100644 index 0000000000..eb2b68dce7 --- /dev/null +++ b/com.woltlab.wcf/templates/shared_fileProcessorFormField.tpl @@ -0,0 +1,10 @@ +{unsafe:$fileProcessorHtmlElement} + + 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 index 0000000000..938d7672c7 --- /dev/null +++ b/ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts @@ -0,0 +1,55 @@ +/** + * @author Olaf Braun + * @copyright 2001-2024 WoltLab GmbH + * @license GNU Lesser General Public License + * @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(); + 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("woltlab-core-file")!); + }); + + this.#uploadButton = this.#container.querySelector("woltlab-core-file-upload") as WoltlabCoreFileUploadElement; + this.#uploadButton.addEventListener("uploadStart", (event: CustomEvent) => { + void this.#registerFile(event.detail); + }); + } + + async #registerFile(element: WoltlabCoreFileElement): Promise { + 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 index 0000000000..33807de1a1 --- /dev/null +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js @@ -0,0 +1,50 @@ +/** + * @author Olaf Braun + * @copyright 2001-2024 WoltLab GmbH + * @license GNU Lesser General Public License + * @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 index 0000000000..d1e05e2310 --- /dev/null +++ b/wcfsetup/install/files/lib/system/form/builder/field/FileProcessorFormField.class.php @@ -0,0 +1,76 @@ + + */ +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; + } +} -- 2.20.1