From 25962e0e39186e270fa4f1a9a57ecf6baf4d7dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 8 Apr 2026 21:32:45 +0200 Subject: [PATCH] Update `setLock` to reuse existing lock without generating new lock ID - Modified `StoredObjectLockManager` logic to prevent unnecessary lock ID regeneration when updating existing locks. - Added `testSetLockExistingUpdatesLockWithoutNewLockId` to verify behavior. - Ensured `persist` is not called again for existing locks. --- .../Service/Lock/StoredObjectLockManager.php | 12 +++++----- .../Lock/StoredObjectLockManagerTest.php | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Service/Lock/StoredObjectLockManager.php b/src/Bundle/ChillDocStoreBundle/Service/Lock/StoredObjectLockManager.php index 49b4c5afc..84d76e30f 100644 --- a/src/Bundle/ChillDocStoreBundle/Service/Lock/StoredObjectLockManager.php +++ b/src/Bundle/ChillDocStoreBundle/Service/Lock/StoredObjectLockManager.php @@ -72,10 +72,6 @@ class StoredObjectLockManager implements EventSubscriberInterface ?\DateTimeImmutable $expiresAt = null, array $users = [], ): StoredObjectLock { - if (null === $lockId) { - $lockId = 'opaquelocktoken:'.Uuid::uuid4(); - } - if (null === $expiresAt) { $expiresAt = $this->clock->now()->add(new \DateInterval('PT60M')); } @@ -83,7 +79,9 @@ class StoredObjectLockManager implements EventSubscriberInterface if ($document->isLockedAt($this->clock->now())) { foreach ($document->getLocks() as $lock) { if ($lock->isActiveAt($this->clock->now())) { - $lock->setToken($lockId); + if (null !== $lockId) { + $lock->setToken($lockId); + } $lock->setExpireAt($expiresAt); foreach ($users as $user) { $lock->addUser($user); @@ -96,6 +94,10 @@ class StoredObjectLockManager implements EventSubscriberInterface } } + if (null === $lockId) { + $lockId = 'opaquelocktoken:'.Uuid::uuid4(); + } + // there is no lock yet, we must create one $lock = new StoredObjectLock( $document, diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/StoredObjectLockManagerTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/StoredObjectLockManagerTest.php index 4dc7ce13a..a3bb9b49f 100644 --- a/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/StoredObjectLockManagerTest.php +++ b/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/StoredObjectLockManagerTest.php @@ -144,6 +144,28 @@ class StoredObjectLockManagerTest extends TestCase $this->assertContains($user, $lock->getUsers()); } + public function testSetLockExistingUpdatesLockWithoutNewLockId(): void + { + $document = new StoredObject(); + $initialExpire = $this->clock->now()->add(new \DateInterval('PT10M')); + $lock = new StoredObjectLock($document, StoredObjectLockMethodEnum::WEBDAV, $this->clock->now(), 'initial-token', $initialExpire); + + $newExpire = $this->clock->now()->add(new \DateInterval('PT20M')); + $user = new User(); + + // Should NOT call persist again + $this->entityManager->persist(Argument::any())->shouldNotBeCalled(); + + $result = $this->manager->setLock($document, StoredObjectLockMethodEnum::WOPI, null, $newExpire, [$user]); + + $this->assertInstanceOf(StoredObjectLock::class, $result); + $this->assertCount(1, $document->getLocks()); + $this->assertSame($lock, $document->getLocks()->first()); + $this->assertSame('initial-token', $lock->getToken()); + $this->assertSame($newExpire, $lock->getExpireAt()); + $this->assertContains($user, $lock->getUsers()); + } + public function testDeleteLock(): void { $document = new StoredObject();