init.body = JSON.stringify(this.#payload);
}
}
+ } else if (this.#type === RequestType.DELETE) {
+ init.method = "DELETE";
} else {
init.method = "GET";
}
--- /dev/null
+import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
+import { ApiResult, apiResultFromError, apiResultFromValue } from "../Result";
+
+export async function deleteFile(fileId: number): Promise<ApiResult<[]>> {
+ try {
+ await prepareRequest(`${window.WSC_API_URL}index.php?api/rpc/core/files/${fileId}`).delete().fetchAsJson();
+ } catch (e) {
+ return apiResultFromError(e);
+ }
+
+ return apiResultFromValue([]);
+}
+import { deleteFile } from "WoltLabSuite/Core/Api/Files/DeleteFile";
import { dispatchToCkeditor } from "../Ckeditor/Event";
import WoltlabCoreFileElement from "../File/woltlab-core-file";
return;
}
+ const fileId = file.fileId;
+ if (fileId === undefined) {
+ // TODO: error handling
+ return;
+ }
+
element.append(
+ getDeleteAttachButton(fileId, (data as FileProcessorData).attachmentID, editorId, element),
getInsertAttachBbcodeButton(
(data as FileProcessorData).attachmentID,
file.isImage() && file.link ? file.link : "",
});
}
+function getDeleteAttachButton(
+ fileId: number,
+ attachmentId: number,
+ editorId: string,
+ element: HTMLElement,
+): HTMLButtonElement {
+ const button = document.createElement("button");
+ button.type = "button";
+ button.classList.add("button", "small");
+ button.textContent = "TODO: delete";
+
+ button.addEventListener("click", () => {
+ const editor = document.getElementById(editorId);
+ if (editor === null) {
+ // TODO: error handling
+ return;
+ }
+
+ void deleteFile(fileId).then((result) => {
+ result.unwrap();
+
+ dispatchToCkeditor(editor).removeAttachment({
+ attachmentId,
+ });
+
+ element.remove();
+ });
+ });
+
+ return button;
+}
+
function getInsertAttachBbcodeButton(attachmentId: number, url: string, editorId: string): HTMLButtonElement {
const button = document.createElement("button");
button.type = "button";
-import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
import { wheneverFirstSeen } from "WoltLabSuite/Core/Helper/Selector";
import { upload as filesUpload } from "WoltLabSuite/Core/Api/Files/Upload";
import WoltlabCoreFileElement from "./woltlab-core-file";
}
}
}
+ else if (this.#type === 0 /* RequestType.DELETE */) {
+ init.method = "DELETE";
+ }
else {
init.method = "GET";
}
--- /dev/null
+define(["require", "exports", "WoltLabSuite/Core/Ajax/Backend", "../Result"], function (require, exports, Backend_1, Result_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.deleteFile = void 0;
+ async function deleteFile(fileId) {
+ try {
+ await (0, Backend_1.prepareRequest)(`${window.WSC_API_URL}index.php?api/rpc/core/files/${fileId}`).delete().fetchAsJson();
+ }
+ catch (e) {
+ return (0, Result_1.apiResultFromError)(e);
+ }
+ return (0, Result_1.apiResultFromValue)([]);
+ }
+ exports.deleteFile = deleteFile;
+});
-define(["require", "exports", "../Ckeditor/Event"], function (require, exports, Event_1) {
+define(["require", "exports", "WoltLabSuite/Core/Api/Files/DeleteFile", "../Ckeditor/Event"], function (require, exports, DeleteFile_1, Event_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setup = void 0;
// TODO: error handling
return;
}
- element.append(getInsertAttachBbcodeButton(data.attachmentID, file.isImage() && file.link ? file.link : "", editorId));
+ const fileId = file.fileId;
+ if (fileId === undefined) {
+ // TODO: error handling
+ return;
+ }
+ element.append(getDeleteAttachButton(fileId, data.attachmentID, editorId, element), getInsertAttachBbcodeButton(data.attachmentID, file.isImage() && file.link ? file.link : "", editorId));
if (file.isImage()) {
const thumbnail = file.thumbnails.find((thumbnail) => thumbnail.identifier === "tiny");
if (thumbnail !== undefined) {
}
});
}
+ function getDeleteAttachButton(fileId, attachmentId, editorId, element) {
+ const button = document.createElement("button");
+ button.type = "button";
+ button.classList.add("button", "small");
+ button.textContent = "TODO: delete";
+ button.addEventListener("click", () => {
+ const editor = document.getElementById(editorId);
+ if (editor === null) {
+ // TODO: error handling
+ return;
+ }
+ void (0, DeleteFile_1.deleteFile)(fileId).then((result) => {
+ result.unwrap();
+ (0, Event_1.dispatchToCkeditor)(editor).removeAttachment({
+ attachmentId,
+ });
+ element.remove();
+ });
+ });
+ return button;
+ }
function getInsertAttachBbcodeButton(attachmentId, url, editorId) {
const button = document.createElement("button");
button.type = "button";
$eventHandler->register(
\wcf\event\endpoint\ControllerCollecting::class,
static function (\wcf\event\endpoint\ControllerCollecting $event) {
+ $event->register(new \wcf\system\endpoint\controller\core\files\DeleteFile);
$event->register(new \wcf\system\endpoint\controller\core\files\PostGenerateThumbnails);
$event->register(new \wcf\system\endpoint\controller\core\files\PostUpload);
$event->register(new \wcf\system\endpoint\controller\core\files\upload\PostChunk);
default => false,
};
}
+
+ public function canDelete(): bool
+ {
+ $processor = $this->getProcessor();
+ if ($processor === null) {
+ return true;
+ }
+
+ return $processor->canDelete($this);
+ }
}
--- /dev/null
+<?php
+
+namespace wcf\system\endpoint\controller\core\files;
+
+use Laminas\Diactoros\Response\JsonResponse;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use wcf\data\file\File;
+use wcf\data\file\FileAction;
+use wcf\system\endpoint\DeleteRequest;
+use wcf\system\endpoint\IController;
+use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\UserInputException;
+
+#[DeleteRequest('/core/files/{id}')]
+final class DeleteFile implements IController
+{
+ #[\Override]
+ public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
+ {
+ $file = new File($variables['id']);
+ if (!$file->fileID) {
+ throw new UserInputException('id');
+ }
+
+ if (!$file->canDelete()) {
+ throw new PermissionDeniedException();
+ }
+
+ // TODO: How do we handle the cleanup of files?
+ $fileAction = new FileAction([$file], 'delete');
+ $fileAction->executeAction();
+
+ return new JsonResponse([]);
+ }
+}
return FileProcessorPreflightResult::Passed;
}
+ #[\Override]
+ public function canDelete(File $file): bool
+ {
+ // TODO
+ return true;
+ }
+
#[\Override]
public function canDownload(File $file): bool
{
public function adoptThumbnail(FileThumbnail $thumbnail): void;
+ public function canDelete(File $file): bool;
+
public function canDownload(File $file): bool;
public function getAllowedFileExtensions(array $context): array;