diff options
author | Julien Veyssier <eneiluj@posteo.net> | 2021-11-22 20:45:27 +0300 |
---|---|---|
committer | Julien Veyssier <eneiluj@posteo.net> | 2022-01-03 12:27:36 +0300 |
commit | 2f6a92b502153d32f71ffec47c3e287283d479f0 (patch) | |
tree | 6af93390d2231025a87f057a7763967790073559 | |
parent | 65c69ffa91a7b8d777370dc3ff2b1d745d63c0a1 (diff) |
use attachment folder when inserting image from Files
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
-rw-r--r-- | appinfo/routes.php | 1 | ||||
-rw-r--r-- | lib/Controller/ImageController.php | 20 | ||||
-rw-r--r-- | lib/Service/ImageService.php | 78 | ||||
-rw-r--r-- | src/components/MenuBar.vue | 43 |
4 files changed, 118 insertions, 24 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 1519b9c8e..471076d05 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -27,6 +27,7 @@ namespace OCA\Text\AppInfo; return [ 'routes' => [ + ['name' => 'Image#insertImageFile', 'url' => '/image/filepath', 'verb' => 'POST'], ['name' => 'Image#insertImageLink', 'url' => '/image/link', 'verb' => 'POST'], ['name' => 'Image#uploadImage', 'url' => '/image/upload', 'verb' => 'POST'], ['name' => 'Image#getImage', 'url' => '/image', 'verb' => 'GET'], diff --git a/lib/Controller/ImageController.php b/lib/Controller/ImageController.php index ee66e7272..81214b7a8 100644 --- a/lib/Controller/ImageController.php +++ b/lib/Controller/ImageController.php @@ -78,6 +78,26 @@ class ImageController extends Controller { * @NoAdminRequired * * @param int $textFileId + * @param string $imagePath + * @return DataResponse + */ + public function insertImageFile(int $textFileId, string $imagePath): DataResponse { + try { + $insertResult = $this->imageService->insertImageFile($textFileId, $imagePath, $this->userId); + if (isset($insertResult['error'])) { + return new DataResponse($insertResult, Http::STATUS_BAD_REQUEST); + } else { + return new DataResponse($insertResult); + } + } catch (Exception $e) { + return new DataResponse(['error' => 'File insertion error: ' . $e->getMessage()], Http::STATUS_BAD_REQUEST); + } + } + + /** + * @NoAdminRequired + * + * @param int $textFileId * @param string $link * @return DataResponse */ diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php index a38e189d6..ae18b80a3 100644 --- a/lib/Service/ImageService.php +++ b/lib/Service/ImageService.php @@ -215,6 +215,64 @@ class ImageService { } /** + * Copy a file from a user's storage in the attachment folder + * + * @param int $textFileId + * @param string $path + * @param string $userId + * @return array + * @throws NotFoundException + * @throws \OCP\Files\InvalidPathException + * @throws \OCP\Files\NotPermittedException + * @throws \OCP\Lock\LockedException + * @throws \OC\User\NoUserException + */ + public function insertImageFile(int $textFileId, string $path, string $userId): array { + $textFile = $this->getTextFile($textFileId, $userId); + if (!$textFile->isUpdateable()) { + throw new Exception('No write permissions'); + } + $imageFile = $this->getFileFromPath($path, $userId); + $saveDir = $this->getOrCreateAttachmentDirectoryForFile($textFile); + if ($saveDir !== null) { + return $this->copyImageFile($imageFile, $saveDir, $textFile); + } else { + return [ + 'error' => 'Impossible to get attachment directory', + ]; + } + } + + /** + * @param File $imageFile + * @param Folder $saveDir + * @param File $textFile + * @return array|string[] + * @throws NotFoundException + * @throws \OCP\Files\InvalidPathException + */ + private function copyImageFile(File $imageFile, Folder $saveDir, File $textFile): array { + $mimeType = $imageFile->getMimeType(); + if (in_array($mimeType, ImageController::IMAGE_MIME_TYPES)) { + $fileName = (string) time() . '-' . $imageFile->getName(); + $targetPath = $saveDir->getPath() . '/' . $fileName; + $targetFile = $imageFile->copy($targetPath); + $path = preg_replace('/^files/', '', $targetFile->getInternalPath()); + // get file type and name + return [ + 'name' => $fileName, + 'path' => $path, + 'id' => $targetFile->getId(), + 'textFileId' => $textFile->getId(), + ]; + } else { + return [ + 'error' => 'Unsupported file type', + ]; + } + } + + /** * Download and save an image from a link in the attachment folder * * @param int $textFileId @@ -397,6 +455,26 @@ class ImageService { /** * Get a user file from file ID * + * @param int $filePath + * @param string $userId + * @return Folder|null + * @throws \OCP\Files\NotPermittedException + * @throws \OC\User\NoUserException + */ + private function getFileFromPath(string $filePath, string $userId): ?File { + $userFolder = $this->rootFolder->getUserFolder($userId); + if ($userFolder->nodeExists($filePath)) { + $file = $userFolder->get($filePath); + if ($file instanceof File) { + return $file; + } + } + return null; + } + + /** + * Get a user file from file ID + * * @param int $textFileId * @param string $userId * @return Folder|null diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index a1a8d6a3d..622a4e7e0 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -391,7 +391,6 @@ export default { 'Content-Type': 'multipart/form-data', }, }).then((response) => { - // this.insertImage(response.data?.path, this.imageCommand) this.insertAttachmentImage(response.data?.name, this.imageCommand, response.data?.textFileId) }).catch((error) => { console.error(error) @@ -421,7 +420,6 @@ export default { ? generateUrl('/apps/text/public/image/link') : generateUrl('/apps/text/image/link') axios.post(url, params).then((response) => { - // this.insertImage(response.data?.path, command) this.insertAttachmentImage(response.data?.name, command, response.data?.textFileId) }).catch((error) => { console.error(error) @@ -431,13 +429,31 @@ export default { this.imageLink = '' }) }, + onImagePathSubmit(imagePath, command) { + this.uploadingImage = true + this.$refs.imageActions[0].closeMenu() + + const params = { + textFileId: this.fileId, + imagePath, + } + const url = generateUrl('/apps/text/image/filepath') + axios.post(url, params).then((response) => { + this.insertAttachmentImage(response.data?.name, command, response.data?.textFileId) + }).catch((error) => { + console.error(error) + showError(error?.response?.data?.error) + }).then(() => { + this.uploadingImage = false + }) + }, showImagePrompt(command) { const currentUser = getCurrentUser() if (!currentUser) { return } OC.dialogs.filepicker(t('text', 'Insert an image'), (file) => { - this.insertImage(file, command) + this.onImagePathSubmit(file, command) }, false, [], true, undefined, this.imagePath) }, insertAttachmentImage(name, command, textFileId) { @@ -447,27 +463,6 @@ export default { alt: name, }) }, - insertImage(path, command) { - const client = OC.Files.getClient() - client.getFileInfo(path).then((_status, fileInfo) => { - this.lastImagePath = fileInfo.path - - // dirty but works so we have the information stored in markdown - const appendMeta = { - mimetype: fileInfo.mimetype, - hasPreview: fileInfo.hasPreview, - } - const path = optimalPath(this.filePath, `${fileInfo.path}/${fileInfo.name}`) - const encodedPath = path.split('/').map(encodeURIComponent).join('/') - const meta = Object.entries(appendMeta).map(([key, val]) => `${key}=${encodeURIComponent(val)}`).join('&') - const src = `${encodedPath}?fileId=${fileInfo.id}#${meta}` - - command({ - src, - alt: fileInfo.name, - }) - }) - }, showLinkPrompt(command) { const currentUser = getCurrentUser() if (!currentUser) { |