{assign var="files" value=$field->getFiles()}
-{if $maxUploads === 1 && $imageOnly}
+{if $field->isSingleFileUpload() === 1 && $imageOnly}
<div class="fileUpload__preview">
{if $field->getValue()}
{assign var="file" value=$files|reset}
</div>
{else}
<ul class="fileUpload__fileList">
+ {foreach from=$files item=file}
+ <li>
+ {unsafe:$file->toHtmlElement()}
+ </li>
+ {/foreach}
</ul>
{/if}
+
{unsafe:$fileProcessorHtmlElement}
<script data-relocate="true">
require(["WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor"], ({ FileProcessor }) => {
new FileProcessor(
'{@$field->getPrefixedId()|encodeJS}',
+ {if $field->isSingleFileUpload()}true{else}false{/if},
+ {if $imageOnly}true{else}false{/if}
);
});
</script>
readonly #fieldId: string;
#replaceElement: WoltlabCoreFileElement | undefined = undefined;
readonly #fileInput: HTMLInputElement;
+ readonly #imageOnly: boolean;
+ readonly #singleFileUpload: boolean;
- constructor(fieldId: string) {
+ constructor(fieldId: string, singleFileUpload: boolean = false, imageOnly: boolean = false) {
this.#fieldId = fieldId;
+ this.#imageOnly = imageOnly;
+ this.#singleFileUpload = singleFileUpload;
this.#container = document.getElementById(fieldId + "Container")!;
if (this.#container === null) {
this.#fileInput = this.#uploadButton.shadowRoot!.querySelector<HTMLInputElement>('input[type="file"]')!;
this.#container.querySelectorAll<WoltlabCoreFileElement>("woltlab-core-file").forEach((element) => {
- void this.#registerFile(element);
+ void this.#registerFile(element, element.parentElement);
});
}
- get isSingleFileUpload(): boolean {
- // TODO check if only images are allowed
- return this.#uploadButton.maximumCount === 1;
+ get classPrefix(): string {
+ return this.showBigPreview ? "fileUpload__preview__" : "fileUpload__fileList__";
}
- async #registerFile(element: WoltlabCoreFileElement): Promise<void> {
- let elementContainer: HTMLElement | null;
+ get showBigPreview(): boolean {
+ return this.#singleFileUpload && this.#imageOnly;
+ }
- if (this.isSingleFileUpload) {
- elementContainer = this.#container.querySelector(".fileUpload__preview");
- if (elementContainer === null) {
- elementContainer = document.createElement("div");
- elementContainer.classList.add("fileUpload__preview");
- this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+ async #registerFile(element: WoltlabCoreFileElement, elementContainer: HTMLElement | null = null): Promise<void> {
+ if (elementContainer === null) {
+ if (this.showBigPreview) {
+ elementContainer = this.#container.querySelector(".fileUpload__preview");
+ if (elementContainer === null) {
+ elementContainer = document.createElement("div");
+ elementContainer.classList.add("fileUpload__preview");
+ this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+ }
+ } else {
+ elementContainer = document.createElement("li");
+ elementContainer.classList.add("fileUpload__fileList__item");
+ this.#container.querySelector(".fileUpload__fileList")!.append(elementContainer);
}
- } else {
- elementContainer = document.createElement("li");
- elementContainer.classList.add("fileUpload__fileList__item");
- this.#container.querySelector(".fileUpload__fileList")!.append(elementContainer);
+ elementContainer.append(element);
}
- elementContainer.append(element);
-
try {
await element.ready;
return;
}
- if (this.isSingleFileUpload) {
+ if (this.showBigPreview) {
element.dataset.previewUrl = element.link!;
element.unbounded = true;
+ } else if (element.isImage()) {
+ const thumbnail = element.thumbnails.find((thumbnail) => thumbnail.identifier === "tiny");
+ if (thumbnail !== undefined) {
+ element.thumbnail = thumbnail;
+ } else {
+ element.dataset.previewUrl = element.link!;
+ element.unbounded = false;
+ }
}
const input = document.createElement("input");
input.type = "hidden";
- input.name = this.isSingleFileUpload ? this.#fieldId : this.#fieldId + "[]";
+ input.name = this.#singleFileUpload ? this.#fieldId : this.#fieldId + "[]";
input.value = element.fileId!.toString();
elementContainer.append(input);
#addButtons(element: WoltlabCoreFileElement): void {
const buttons = document.createElement("ul");
buttons.classList.add("buttonList");
- if (this.isSingleFileUpload) {
- buttons.classList.add("fileUpload__preview__buttons");
- } else {
- buttons.classList.add("fileUpload__fileList__buttons");
- }
+ buttons.classList.add(this.classPrefix + "buttons");
this.#addDeleteButton(element, buttons);
this.#addReplaceButton(element, buttons);
}
#unregisterFile(element: WoltlabCoreFileElement): void {
- if (this.isSingleFileUpload) {
+ if (this.showBigPreview) {
element.parentElement!.innerHTML = "";
} else {
element.parentElement!.remove();
#fieldId;
#replaceElement = undefined;
#fileInput;
- constructor(fieldId) {
+ #imageOnly;
+ #singleFileUpload;
+ constructor(fieldId, singleFileUpload = false, imageOnly = false) {
this.#fieldId = fieldId;
+ this.#imageOnly = imageOnly;
+ this.#singleFileUpload = singleFileUpload;
this.#container = document.getElementById(fieldId + "Container");
if (this.#container === null) {
throw new Error("Unknown field with id '" + fieldId + "'");
});
this.#fileInput = this.#uploadButton.shadowRoot.querySelector('input[type="file"]');
this.#container.querySelectorAll("woltlab-core-file").forEach((element) => {
- void this.#registerFile(element);
+ void this.#registerFile(element, element.parentElement);
});
}
- get isSingleFileUpload() {
- // TODO check if only images are allowed
- return this.#uploadButton.maximumCount === 1;
+ get classPrefix() {
+ return this.showBigPreview ? "fileUpload__preview__" : "fileUpload__fileList__";
}
- async #registerFile(element) {
- let elementContainer;
- if (this.isSingleFileUpload) {
- elementContainer = this.#container.querySelector(".fileUpload__preview");
- if (elementContainer === null) {
- elementContainer = document.createElement("div");
- elementContainer.classList.add("fileUpload__preview");
- this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+ get showBigPreview() {
+ return this.#singleFileUpload && this.#imageOnly;
+ }
+ async #registerFile(element, elementContainer = null) {
+ if (elementContainer === null) {
+ if (this.showBigPreview) {
+ elementContainer = this.#container.querySelector(".fileUpload__preview");
+ if (elementContainer === null) {
+ elementContainer = document.createElement("div");
+ elementContainer.classList.add("fileUpload__preview");
+ this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+ }
}
+ else {
+ elementContainer = document.createElement("li");
+ elementContainer.classList.add("fileUpload__fileList__item");
+ this.#container.querySelector(".fileUpload__fileList").append(elementContainer);
+ }
+ elementContainer.append(element);
}
- else {
- elementContainer = document.createElement("li");
- elementContainer.classList.add("fileUpload__fileList__item");
- this.#container.querySelector(".fileUpload__fileList").append(elementContainer);
- }
- elementContainer.append(element);
try {
await element.ready;
if (this.#replaceElement !== undefined) {
this.#markElementUploadHasFailed(elementContainer, element, reason);
return;
}
- if (this.isSingleFileUpload) {
+ if (this.showBigPreview) {
element.dataset.previewUrl = element.link;
element.unbounded = true;
}
+ else if (element.isImage()) {
+ const thumbnail = element.thumbnails.find((thumbnail) => thumbnail.identifier === "tiny");
+ if (thumbnail !== undefined) {
+ element.thumbnail = thumbnail;
+ }
+ else {
+ element.dataset.previewUrl = element.link;
+ element.unbounded = false;
+ }
+ }
const input = document.createElement("input");
input.type = "hidden";
- input.name = this.isSingleFileUpload ? this.#fieldId : this.#fieldId + "[]";
+ input.name = this.#singleFileUpload ? this.#fieldId : this.#fieldId + "[]";
input.value = element.fileId.toString();
elementContainer.append(input);
this.#addButtons(element);
#addButtons(element) {
const buttons = document.createElement("ul");
buttons.classList.add("buttonList");
- if (this.isSingleFileUpload) {
- buttons.classList.add("fileUpload__preview__buttons");
- }
- else {
- buttons.classList.add("fileUpload__fileList__buttons");
- }
+ buttons.classList.add(this.classPrefix + "buttons");
this.#addDeleteButton(element, buttons);
this.#addReplaceButton(element, buttons);
element.parentElement.append(buttons);
buttons.append(listItem);
}
#unregisterFile(element) {
- if (this.isSingleFileUpload) {
+ if (this.showBigPreview) {
element.parentElement.innerHTML = "";
}
else {
use wcf\data\file\File;
use wcf\data\file\FileList;
+use wcf\data\file\thumbnail\FileThumbnailList;
use wcf\system\file\processor\FileProcessor;
use wcf\system\file\processor\IFileProcessor;
use wcf\system\form\builder\TObjectTypeFormNode;
* @var File[]
*/
private array $files = [];
+ private bool $singleFileUpload = false;
#[\Override]
public function readValue()
return $this->getObjectType()->getProcessor();
}
- private function isSingleFileUpload(): bool
+ public function isSingleFileUpload(): bool
{
- return $this->getFileProcessor()->getMaximumCount($this->context) === 1;
+ return $this->singleFileUpload;
+ }
+
+ /**
+ * Sets whether only a single file can be uploaded.
+ * If set to true, the value of the field will be an integer.
+ * Otherwise, the value will be an array of integers.
+ */
+ public function setSingleFileUpload(bool $singleFileUpload): self
+ {
+ $this->singleFileUpload = $singleFileUpload;
+
+ return $this;
}
#[\Override]
#[\Override]
public function value($value)
{
+ $fileIDs = [];
if ($this->isSingleFileUpload()) {
$file = new File($value);
if ($file->fileID === $value) {
$this->files = [$file];
+ $fileIDs[] = $value;
}
-
- return parent::value($value);
} else {
if (!\is_array($value)) {
$value = [$value];
$fileList->readObjects();
$this->files = $fileList->getObjects();
- return parent::value($value);
+ $fileIDs = $fileList->getObjectIDs();
}
+
+ $thumbnailList = new FileThumbnailList();
+ $thumbnailList->getConditionBuilder()->add("fileID IN (?)", [$fileIDs]);
+ $thumbnailList->readObjects();
+ foreach ($thumbnailList as $thumbnail) {
+ $this->files[$thumbnail->fileID]->addThumbnail($thumbnail);
+ }
+
+ return parent::value($value);
}
/**