diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ae6e085..6f6bba53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to Roadiz will be documented in this file. +## [2.3.28](https://github.com/roadiz/core-bundle-dev-app/compare/v2.3.27...v2.3.28) - 2024-09-24 + +### Bug Fixes + +- **(Documents)** Do not throw `UnableToMoveFile` when document `filename` changes because we update the whole file - ([da5386e](https://github.com/roadiz/core-bundle-dev-app/commit/da5386e0cab580ec1a414f91779c1a1fbcc14160)) + ## [2.3.27](https://github.com/roadiz/core-bundle-dev-app/compare/v2.3.26...v2.3.27) - 2024-09-13 ### Bug Fixes diff --git a/lib/Documents/src/Events/DocumentLifeCycleSubscriber.php b/lib/Documents/src/Events/DocumentLifeCycleSubscriber.php index db941616..8865ff52 100644 --- a/lib/Documents/src/Events/DocumentLifeCycleSubscriber.php +++ b/lib/Documents/src/Events/DocumentLifeCycleSubscriber.php @@ -10,7 +10,6 @@ use Doctrine\ORM\Events; use League\Flysystem\FilesystemException; use League\Flysystem\FilesystemOperator; -use League\Flysystem\UnableToMoveFile; use League\Flysystem\Visibility; use RZ\Roadiz\Documents\Exceptions\DocumentWithoutFileException; use RZ\Roadiz\Documents\Models\DocumentInterface; @@ -20,9 +19,9 @@ */ #[AsDoctrineListener(event: Events::postRemove)] #[AsDoctrineListener(event: Events::preUpdate)] -final class DocumentLifeCycleSubscriber +final readonly class DocumentLifeCycleSubscriber { - public function __construct(private readonly FilesystemOperator $documentsStorage) + public function __construct(private FilesystemOperator $documentsStorage) { } @@ -43,19 +42,9 @@ public function preUpdate(PreUpdateEventArgs $args): void && is_string($args->getNewValue('filename')) && $args->getOldValue('filename') !== '' ) { - $oldPath = $this->getDocumentMountPathForFilename($document, $args->getOldValue('filename')); - $newPath = $this->getDocumentMountPathForFilename($document, $args->getNewValue('filename')); - - if ($oldPath !== $newPath) { - if ($this->documentsStorage->fileExists($oldPath) && !$this->documentsStorage->fileExists($newPath)) { - /* - * Only perform IO rename if old file exists and new path is free. - */ - $this->documentsStorage->move($oldPath, $newPath); - } else { - throw new UnableToMoveFile('Cannot rename file from ' . $oldPath . ' to ' . $newPath); - } - } + // This method must not throw any exception + // because filename WILL change if document file is updated too. + $this->renameDocumentFilename($document, $args); } if ($args->hasChangedField('private')) { if ($document->isPrivate() === true) { @@ -66,6 +55,29 @@ public function preUpdate(PreUpdateEventArgs $args): void } } + private function renameDocumentFilename(DocumentInterface $document, PreUpdateEventArgs $args): void + { + $oldPath = $this->getDocumentMountPathForFilename($document, $args->getOldValue('filename')); + $newPath = $this->getDocumentMountPathForFilename($document, $args->getNewValue('filename')); + + if ($oldPath === $newPath) { + return; + } + + if (!$this->documentsStorage->fileExists($oldPath)) { + // Do not throw, just return + return; + } + if ($this->documentsStorage->fileExists($newPath)) { + // Do not throw, just return + return; + } + /* + * Only perform IO rename if old file exists and new path is free. + */ + $this->documentsStorage->move($oldPath, $newPath); + } + private function makePublic(DocumentInterface $document): void { $this->validateDocument($document);