Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Veyssier <eneiluj@posteo.net>2021-11-25 18:38:13 +0300
committerJulien Veyssier <eneiluj@posteo.net>2022-01-03 12:27:37 +0300
commit551729e08d7c044ae34d8972129caa448725f7a9 (patch)
treefa810c00048ae6de3a92ffa965aac2cd57aba51c /lib/Service
parentfc56680d9621a7fb8cc9fd75d0ad0230de3c9884 (diff)
implement auto attachment management for file deletion/move/copy
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
Diffstat (limited to 'lib/Service')
-rw-r--r--lib/Service/ImageService.php116
1 files changed, 105 insertions, 11 deletions
diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php
index ae68a08a0..e9defe1a8 100644
--- a/lib/Service/ImageService.php
+++ b/lib/Service/ImageService.php
@@ -432,6 +432,25 @@ class ImageService {
return null;
}
+ private function getAttachmentDirectoryForFile(File $textFile): ?Folder {
+ $owner = $textFile->getOwner();
+ $ownerId = $owner->getUID();
+ $ownerUserFolder = $this->rootFolder->getUserFolder($ownerId);
+ $ownerTextFile = $ownerUserFolder->getById($textFile->getId());
+ if (count($ownerTextFile) > 0) {
+ $ownerTextFile = $ownerTextFile[0];
+ $ownerParentFolder = $ownerTextFile->getParent();
+ $attachmentFolderName = '.attachments.' . $textFile->getId();
+ if ($ownerParentFolder->nodeExists($attachmentFolderName)) {
+ $attachmentFolder = $ownerParentFolder->get($attachmentFolderName);
+ if ($attachmentFolder instanceof Folder) {
+ return $attachmentFolder;
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Get a user file from file ID
* @param string $filePath
@@ -574,17 +593,7 @@ class ImageService {
$attachmentsById[$attNode->getId()] = $attNode;
}
- // get IDs of attachment listed in the markdown file content
- $matches = [];
- preg_match_all(
- '/\!\[[^\[\]]+\]\(text:\/\/image\?[^)]*imageFileId=([\d]+)[^)]*\)/',
- $textFile->getContent(),
- $matches,
- PREG_SET_ORDER
- );
- $contentAttachmentIds = array_map(function (array $match) {
- return $match[1] ?? null;
- }, $matches);
+ $contentAttachmentIds = $this->getAttachmentIdsFromContent($textFile->getContent());
$toDelete = array_diff(array_keys($attachmentsById), $contentAttachmentIds);
foreach ($toDelete as $id) {
@@ -595,4 +604,89 @@ class ImageService {
}
return 0;
}
+
+
+ /**
+ * Get IDs of attachment listed in the markdown file content
+ *
+ * @param string $content
+ * @return array
+ */
+ private function getAttachmentIdsFromContent(string $content): array {
+ $matches = [];
+ preg_match_all(
+ '/\!\[[^\[\]]+\]\(text:\/\/image\?[^)]*imageFileId=([\d]+)[^)]*\)/',
+ $content,
+ $matches,
+ PREG_SET_ORDER
+ );
+ return array_map(function (array $match) {
+ return $match[1] ?? null;
+ }, $matches);
+ }
+
+ /**
+ * @param File $source
+ * @param File $target
+ * @throws NotFoundException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OCP\Files\NotPermittedException
+ * @throws \OCP\Lock\LockedException
+ */
+ public function moveAttachments(File $source, File $target): void {
+ // if the parent directory has changed
+ if ($source->getParent()->getPath() !== $target->getParent()->getPath()) {
+ // if there is an attachment dir for this file
+ $sourceAttachmentDir = $this->getAttachmentDirectoryForFile($source);
+ if ($sourceAttachmentDir !== null) {
+ $sourceAttachmentDir->move($target->getParent()->getPath() . '/' . $sourceAttachmentDir->getName());
+ }
+ }
+ }
+
+ /**
+ * @param File $source
+ * @throws NotFoundException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function deleteAttachments(File $source): void {
+ // if there is an attachment dir for this file
+ $sourceAttachmentDir = $this->getAttachmentDirectoryForFile($source);
+ if ($sourceAttachmentDir !== null) {
+ $sourceAttachmentDir->delete();
+ }
+ }
+
+ public function copyAttachments(File $source, File $target): void {
+ $sourceAttachmentDir = $this->getAttachmentDirectoryForFile($source);
+ if ($sourceAttachmentDir !== null) {
+ // create a new attachment dir next to the new file
+ $targetAttachmentDir = $this->getOrCreateAttachmentDirectoryForFile($target);
+ $markdownContent = $source->getContent();
+ $sourceAttachmentIds = $this->getAttachmentIdsFromContent($markdownContent);
+ // replace the text file ID in each attachment link in the markdown content
+ $markdownContent = preg_replace(
+ '/\!\[([^\[\]]+)\]\(text:\/\/image\?textFileId=' . $source->getId() . '&imageFileId=([\d]+[^)]*)\)/',
+ '![$1](text://image?textFileId=' . $target->getId() . '&imageFileId=$2)',
+ $markdownContent
+ );
+ // copy the attachments and replace attachment file IDs in the markdown content
+ foreach ($sourceAttachmentIds as $sourceAttachmentId) {
+ $sourceAttachment = $sourceAttachmentDir->getById($sourceAttachmentId);
+ if (count($sourceAttachment) > 0 && $sourceAttachment[0] instanceof File) {
+ $sourceAttachment = $sourceAttachment[0];
+ $copied = $targetAttachmentDir->newFile($sourceAttachment->getName(), $sourceAttachment->getContent());
+ $copiedId = $copied->getId();
+ $markdownContent = preg_replace(
+ '/\!\[([^\[\]]+)\]\(text:\/\/image\?([^)]*)imageFileId=' . $sourceAttachmentId . '([^)]*)\)/',
+ '![$1](text://image?$2imageFileId=' . $copiedId . '$3)',
+ $markdownContent
+ );
+ }
+ }
+ // FIXME this is not possible because the target file is locked at this point
+ $target->putContent($markdownContent);
+ }
+ }
}