diff options
author | Louis <louis@chmn.me> | 2024-12-12 14:28:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-12 14:28:09 +0100 |
commit | cabedbf9c384ddf1f75bd32d3efa0f1d4aa2a3b8 (patch) | |
tree | 428d88d01d4cc7739475ad30d481786940153e4e /apps | |
parent | d8c34258781cea65ad71f2439e2d84038288fc95 (diff) | |
download | nextcloud-server-cabedbf9c384ddf1f75bd32d3efa0f1d4aa2a3b8.tar.gz nextcloud-server-cabedbf9c384ddf1f75bd32d3efa0f1d4aa2a3b8.zip |
Revert "[stable30] fix: Handle copy of folders containing live photos"revert-49650-backport/49293/stable30
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/Connector/Sabre/Directory.php | 8 | ||||
-rw-r--r-- | apps/files/lib/Listener/SyncLivePhotosListener.php | 184 | ||||
-rw-r--r-- | apps/files_versions/lib/Listener/VersionStorageMoveListener.php | 3 |
3 files changed, 69 insertions, 126 deletions
diff --git a/apps/dav/lib/Connector/Sabre/Directory.php b/apps/dav/lib/Connector/Sabre/Directory.php index 8f637455403..d56f56890cc 100644 --- a/apps/dav/lib/Connector/Sabre/Directory.php +++ b/apps/dav/lib/Connector/Sabre/Directory.php @@ -445,13 +445,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol throw new InvalidPath($ex->getMessage()); } - $copyOkay = $this->fileView->copy($sourcePath, $destinationPath); - - if (!$copyOkay) { - throw new \Sabre\DAV\Exception\Forbidden('Copy did not proceed'); - } - - return true; + return $this->fileView->copy($sourcePath, $destinationPath); } catch (StorageNotAvailableException $e) { throw new ServiceUnavailable($e->getMessage(), $e->getCode(), $e); } catch (ForbiddenException $ex) { diff --git a/apps/files/lib/Listener/SyncLivePhotosListener.php b/apps/files/lib/Listener/SyncLivePhotosListener.php index 6df9b8d6e95..02cf85f9917 100644 --- a/apps/files/lib/Listener/SyncLivePhotosListener.php +++ b/apps/files/lib/Listener/SyncLivePhotosListener.php @@ -8,23 +8,18 @@ declare(strict_types=1); namespace OCA\Files\Listener; -use Exception; -use OC\Files\Node\NonExistingFile; -use OC\Files\Node\NonExistingFolder; -use OC\Files\View; use OC\FilesMetadata\Model\FilesMetadata; use OCA\Files\Service\LivePhotosService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Exceptions\AbortedEventException; use OCP\Files\Cache\CacheEntryRemovedEvent; +use OCP\Files\Events\Node\AbstractNodesEvent; use OCP\Files\Events\Node\BeforeNodeCopiedEvent; use OCP\Files\Events\Node\BeforeNodeDeletedEvent; use OCP\Files\Events\Node\BeforeNodeRenamedEvent; use OCP\Files\Events\Node\NodeCopiedEvent; -use OCP\Files\File; use OCP\Files\Folder; -use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\FilesMetadata\IFilesMetadataManager; @@ -42,8 +37,6 @@ class SyncLivePhotosListener implements IEventListener { private ?Folder $userFolder, private IFilesMetadataManager $filesMetadataManager, private LivePhotosService $livePhotosService, - private IRootFolder $rootFolder, - private View $view, ) { } @@ -52,47 +45,61 @@ class SyncLivePhotosListener implements IEventListener { return; } - if ($event instanceof BeforeNodeCopiedEvent || $event instanceof NodeCopiedEvent) { - $this->handleCopyRecursive($event, $event->getSource(), $event->getTarget()); - } else { - $peerFileId = null; - - if ($event instanceof BeforeNodeRenamedEvent) { - $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getSource()->getId()); - } elseif ($event instanceof BeforeNodeDeletedEvent) { - $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getNode()->getId()); - } elseif ($event instanceof CacheEntryRemovedEvent) { - $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getFileId()); - } + $peerFileId = null; - if ($peerFileId === null) { - return; // Not a live photo. - } + if ($event instanceof BeforeNodeRenamedEvent) { + $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getSource()->getId()); + } elseif ($event instanceof BeforeNodeDeletedEvent) { + $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getNode()->getId()); + } elseif ($event instanceof CacheEntryRemovedEvent) { + $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getFileId()); + } elseif ($event instanceof BeforeNodeCopiedEvent || $event instanceof NodeCopiedEvent) { + $peerFileId = $this->livePhotosService->getLivePhotoPeerId($event->getSource()->getId()); + } - // Check the user's folder. - $peerFile = $this->userFolder->getFirstNodeById($peerFileId); + if ($peerFileId === null) { + return; // Not a live photo. + } - if ($peerFile === null) { - return; // Peer file not found. - } + // Check the user's folder. + $peerFile = $this->userFolder->getFirstNodeById($peerFileId); - if ($event instanceof BeforeNodeRenamedEvent) { - $this->runMoveOrCopyChecks($event->getSource(), $event->getTarget(), $peerFile); - $this->handleMove($event->getSource(), $event->getTarget(), $peerFile); - } elseif ($event instanceof BeforeNodeDeletedEvent) { - $this->handleDeletion($event, $peerFile); - } elseif ($event instanceof CacheEntryRemovedEvent) { - $peerFile->delete(); - } + if ($peerFile === null) { + return; // Peer file not found. + } + + if ($event instanceof BeforeNodeRenamedEvent) { + $this->handleMove($event, $peerFile, false); + } elseif ($event instanceof BeforeNodeDeletedEvent) { + $this->handleDeletion($event, $peerFile); + } elseif ($event instanceof CacheEntryRemovedEvent) { + $peerFile->delete(); + } elseif ($event instanceof BeforeNodeCopiedEvent) { + $this->handleMove($event, $peerFile, true); + } elseif ($event instanceof NodeCopiedEvent) { + $this->handleCopy($event, $peerFile); } } - private function runMoveOrCopyChecks(Node $sourceFile, Node $targetFile, Node $peerFile): void { + /** + * During rename events, which also include move operations, + * we rename the peer file using the same name. + * The event listener being singleton, we can store the current state + * of pending renames inside the 'pendingRenames' property, + * to prevent infinite recursive. + */ + private function handleMove(AbstractNodesEvent $event, Node $peerFile, bool $prepForCopyOnly = false): void { + if (!($event instanceof BeforeNodeCopiedEvent) && + !($event instanceof BeforeNodeRenamedEvent)) { + return; + } + + $sourceFile = $event->getSource(); + $targetFile = $event->getTarget(); $targetParent = $targetFile->getParent(); $sourceExtension = $sourceFile->getExtension(); $peerFileExtension = $peerFile->getExtension(); $targetName = $targetFile->getName(); - $peerTargetName = substr($targetName, 0, -strlen($sourceExtension)) . $peerFileExtension; if (!str_ends_with($targetName, "." . $sourceExtension)) { throw new AbortedEventException('Cannot change the extension of a Live Photo'); @@ -104,31 +111,15 @@ class SyncLivePhotosListener implements IEventListener { } catch (NotFoundException) { } - if (!($targetParent instanceof NonExistingFolder)) { - try { - $targetParent->get($peerTargetName); - throw new AbortedEventException('A file already exist at destination path of the Live Photo'); - } catch (NotFoundException) { - } - } - } - - /** - * During rename events, which also include move operations, - * we rename the peer file using the same name. - * The event listener being singleton, we can store the current state - * of pending renames inside the 'pendingRenames' property, - * to prevent infinite recursive. - */ - private function handleMove(Node $sourceFile, Node $targetFile, Node $peerFile): void { - $targetParent = $targetFile->getParent(); - $sourceExtension = $sourceFile->getExtension(); - $peerFileExtension = $peerFile->getExtension(); - $targetName = $targetFile->getName(); $peerTargetName = substr($targetName, 0, -strlen($sourceExtension)) . $peerFileExtension; + try { + $targetParent->get($peerTargetName); + throw new AbortedEventException('A file already exist at destination path of the Live Photo'); + } catch (NotFoundException) { + } // in case the rename was initiated from this listener, we stop right now - if (in_array($peerFile->getId(), $this->pendingRenames)) { + if ($prepForCopyOnly || in_array($peerFile->getId(), $this->pendingRenames)) { return; } @@ -139,37 +130,39 @@ class SyncLivePhotosListener implements IEventListener { throw new AbortedEventException($ex->getMessage()); } - $this->pendingRenames = array_diff($this->pendingRenames, [$sourceFile->getId()]); + array_diff($this->pendingRenames, [$sourceFile->getId()]); } /** * handle copy, we already know if it is doable from BeforeNodeCopiedEvent, so we just copy the linked file + * + * @param NodeCopiedEvent $event + * @param Node $peerFile */ - private function handleCopy(File $sourceFile, File $targetFile, File $peerFile): void { + private function handleCopy(NodeCopiedEvent $event, Node $peerFile): void { + $sourceFile = $event->getSource(); $sourceExtension = $sourceFile->getExtension(); $peerFileExtension = $peerFile->getExtension(); + $targetFile = $event->getTarget(); $targetParent = $targetFile->getParent(); $targetName = $targetFile->getName(); $peerTargetName = substr($targetName, 0, -strlen($sourceExtension)) . $peerFileExtension; - - if ($targetParent->nodeExists($peerTargetName)) { - // If the copy was a folder copy, then the peer file already exists. - $targetPeerFile = $targetParent->get($peerTargetName); - } else { - // If the copy was a file copy, then we need to create the peer file. - $targetPeerFile = $peerFile->copy($targetParent->getPath() . '/' . $peerTargetName); - } - + /** + * let's use freshly set variable. + * we copy the file and get its id. We already have the id of the current copy + * We have everything to update metadata and keep the link between the 2 copies. + */ + $newPeerFile = $peerFile->copy($targetParent->getPath() . '/' . $peerTargetName); /** @var FilesMetadata $targetMetadata */ $targetMetadata = $this->filesMetadataManager->getMetadata($targetFile->getId(), true); $targetMetadata->setStorageId($targetFile->getStorage()->getCache()->getNumericStorageId()); - $targetMetadata->setString('files-live-photo', (string)$targetPeerFile->getId()); + $targetMetadata->setString('files-live-photo', (string)$newPeerFile->getId()); $this->filesMetadataManager->saveMetadata($targetMetadata); /** @var FilesMetadata $peerMetadata */ - $peerMetadata = $this->filesMetadataManager->getMetadata($targetPeerFile->getId(), true); - $peerMetadata->setStorageId($targetPeerFile->getStorage()->getCache()->getNumericStorageId()); + $peerMetadata = $this->filesMetadataManager->getMetadata($newPeerFile->getId(), true); + $peerMetadata->setStorageId($newPeerFile->getStorage()->getCache()->getNumericStorageId()); $peerMetadata->setString('files-live-photo', (string)$targetFile->getId()); $this->filesMetadataManager->saveMetadata($peerMetadata); } @@ -200,47 +193,4 @@ class SyncLivePhotosListener implements IEventListener { } return; } - - /* - * Recursively get all the peer ids of a live photo. - * Needed when coping a folder. - * - * @param BeforeNodeCopiedEvent|NodeCopiedEvent $event - */ - private function handleCopyRecursive(Event $event, Node $sourceNode, Node $targetNode): void { - if ($sourceNode instanceof Folder && $targetNode instanceof Folder) { - foreach ($sourceNode->getDirectoryListing() as $sourceChild) { - if ($event instanceof BeforeNodeCopiedEvent) { - if ($sourceChild instanceof Folder) { - $targetChild = new NonExistingFolder($this->rootFolder, $this->view, $targetNode->getPath() . '/' . $sourceChild->getName(), null, $targetNode); - } else { - $targetChild = new NonExistingFile($this->rootFolder, $this->view, $targetNode->getPath() . '/' . $sourceChild->getName(), null, $targetNode); - } - } elseif ($event instanceof NodeCopiedEvent) { - $targetChild = $targetNode->get($sourceChild->getName()); - } else { - throw new Exception('Event is type is not supported'); - } - - $this->handleCopyRecursive($event, $sourceChild, $targetChild); - } - } elseif ($sourceNode instanceof File && $targetNode instanceof File) { - $peerFileId = $this->livePhotosService->getLivePhotoPeerId($sourceNode->getId()); - if ($peerFileId === null) { - return; - } - $peerFile = $this->userFolder->getFirstNodeById($peerFileId); - if ($peerFile === null) { - return; - } - - if ($event instanceof BeforeNodeCopiedEvent) { - $this->runMoveOrCopyChecks($sourceNode, $targetNode, $peerFile); - } elseif ($event instanceof NodeCopiedEvent) { - $this->handleCopy($sourceNode, $targetNode, $peerFile); - } - } else { - throw new Exception('Source and target type are not matching'); - } - } } diff --git a/apps/files_versions/lib/Listener/VersionStorageMoveListener.php b/apps/files_versions/lib/Listener/VersionStorageMoveListener.php index 8bf1d4dce7b..b4b00108e43 100644 --- a/apps/files_versions/lib/Listener/VersionStorageMoveListener.php +++ b/apps/files_versions/lib/Listener/VersionStorageMoveListener.php @@ -11,7 +11,6 @@ namespace OCA\Files_Versions\Listener; use Exception; use OC\Files\Node\NonExistingFile; -use OC\Files\Node\NonExistingFolder; use OCA\Files_Versions\Versions\IVersionBackend; use OCA\Files_Versions\Versions\IVersionManager; use OCA\Files_Versions\Versions\IVersionsImporterBackend; @@ -131,7 +130,7 @@ class VersionStorageMoveListener implements IEventListener { } private function getNodeStorage(Node $node): IStorage { - if ($node instanceof NonExistingFile || $node instanceof NonExistingFolder) { + if ($node instanceof NonExistingFile) { return $node->getParent()->getStorage(); } else { return $node->getStorage(); |