diff options
-rw-r--r-- | apps/user_status/lib/Connector/UserStatusProvider.php | 4 | ||||
-rw-r--r-- | apps/user_status/lib/Db/UserStatusMapper.php | 19 | ||||
-rw-r--r-- | apps/user_status/lib/Service/StatusService.php | 38 | ||||
-rw-r--r-- | apps/user_status/tests/Unit/Db/UserStatusMapperTest.php | 52 | ||||
-rw-r--r-- | apps/user_status/tests/Unit/Service/StatusServiceTest.php | 58 | ||||
-rw-r--r-- | lib/private/UserStatus/ISettableProvider.php | 11 | ||||
-rw-r--r-- | lib/private/UserStatus/Manager.php | 8 | ||||
-rw-r--r-- | lib/public/UserStatus/IManager.php | 15 |
8 files changed, 201 insertions, 4 deletions
diff --git a/apps/user_status/lib/Connector/UserStatusProvider.php b/apps/user_status/lib/Connector/UserStatusProvider.php index f3f4c5f710e..cec9406d28b 100644 --- a/apps/user_status/lib/Connector/UserStatusProvider.php +++ b/apps/user_status/lib/Connector/UserStatusProvider.php @@ -70,4 +70,8 @@ class UserStatusProvider implements IProvider, ISettableProvider { public function revertUserStatus(string $userId, string $messageId, string $status): void { $this->service->revertUserStatus($userId, $messageId, $status); } + + public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void { + $this->service->revertMultipleUserStatus($userIds, $messageId, $status); + } } diff --git a/apps/user_status/lib/Db/UserStatusMapper.php b/apps/user_status/lib/Db/UserStatusMapper.php index 1bb4ad11be8..496cb5080f0 100644 --- a/apps/user_status/lib/Db/UserStatusMapper.php +++ b/apps/user_status/lib/Db/UserStatusMapper.php @@ -111,7 +111,7 @@ class UserStatusMapper extends QBMapper { * @param array $userIds * @return array */ - public function findByUserIds(array $userIds):array { + public function findByUserIds(array $userIds): array { $qb = $this->db->getQueryBuilder(); $qb ->select('*') @@ -177,4 +177,21 @@ class UserStatusMapper extends QBMapper { ->andWhere($qb->expr()->eq('is_backup', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))); return $qb->executeStatement() > 0; } + + public function deleteByIds(array $ids): void { + $qb = $this->db->getQueryBuilder(); + $qb->delete($this->tableName) + ->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))); + $qb->executeStatement(); + } + + public function restoreBackupStatuses(array $ids): void { + $qb = $this->db->getQueryBuilder(); + $qb->update($this->tableName) + ->set('is_backup', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)) + ->set('user_id', $qb->func()->substring('user_id', $qb->createNamedParameter(2, IQueryBuilder::PARAM_INT))) + ->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))); + + $qb->executeStatement(); + } } diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index e31b1772c4d..0c281314546 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -36,6 +36,7 @@ use OCA\UserStatus\Exception\StatusMessageTooLongException; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; +use OCP\IUser; use OCP\UserStatus\IUserStatus; /** @@ -460,7 +461,7 @@ class StatusService { return true; } - public function revertUserStatus(string $userId, ?string $messageId, string $status): void { + public function revertUserStatus(string $userId, string $messageId, string $status): void { try { /** @var UserStatus $userStatus */ $backupUserStatus = $this->mapper->findByUserId($userId, true); @@ -469,7 +470,7 @@ class StatusService { return; } - $deleted = $this->mapper->deleteCurrentStatusToRestoreBackup($userId, $messageId ?? '', $status); + $deleted = $this->mapper->deleteCurrentStatusToRestoreBackup($userId, $messageId, $status); if (!$deleted) { // Another status is set automatically or no status, do nothing return; @@ -480,4 +481,37 @@ class StatusService { $backupUserStatus->setUserId(substr($backupUserStatus->getUserId(), 1)); $this->mapper->update($backupUserStatus); } + + public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void { + // Get all user statuses and the backups + $findById = $userIds; + foreach ($userIds as $userId) { + $findById[] = '_' . $userId; + } + $userStatuses = $this->mapper->findByUserIds($findById); + + $backups = $restoreIds = $statuesToDelete = []; + foreach ($userStatuses as $userStatus) { + if (!$userStatus->getIsBackup() + && $userStatus->getMessageId() === $messageId + && $userStatus->getStatus() === $status) { + $statuesToDelete[$userStatus->getUserId()] = $userStatus->getId(); + } else if ($userStatus->getIsBackup()) { + $backups[$userStatus->getUserId()] = $userStatus->getId(); + } + } + + // For users with both (normal and backup) delete the status when matching + foreach ($statuesToDelete as $userId => $statusId) { + $backupUserId = '_' . $userId; + if (isset($backups[$backupUserId])) { + $restoreIds[] = $backups[$backupUserId]; + } + } + + $this->mapper->deleteByIds(array_values($statuesToDelete)); + + // For users that matched restore the previous status + $this->mapper->restoreBackupStatuses($restoreIds); + } } diff --git a/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php b/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php index ddb067b862b..c48805b57af 100644 --- a/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php +++ b/apps/user_status/tests/Unit/Db/UserStatusMapperTest.php @@ -251,4 +251,56 @@ class UserStatusMapperTest extends TestCase { $this->mapper->insert($userStatus2); $this->mapper->insert($userStatus3); } + + public function testRestoreBackupStatuses(): void { + $userStatus1 = new UserStatus(); + $userStatus1->setUserId('_user1'); + $userStatus1->setStatus('online'); + $userStatus1->setStatusTimestamp(5000); + $userStatus1->setIsUserDefined(true); + $userStatus1->setIsBackup(true); + $userStatus1->setCustomIcon('🚀'); + $userStatus1->setCustomMessage('Releasing'); + $userStatus1->setClearAt(50000); + $userStatus1 = $this->mapper->insert($userStatus1); + + $userStatus2 = new UserStatus(); + $userStatus2->setUserId('_user2'); + $userStatus2->setStatus('away'); + $userStatus2->setStatusTimestamp(5000); + $userStatus2->setIsUserDefined(true); + $userStatus2->setIsBackup(true); + $userStatus2->setCustomIcon('💩'); + $userStatus2->setCustomMessage('Do not disturb'); + $userStatus2->setClearAt(50000); + $userStatus2 = $this->mapper->insert($userStatus2); + + $userStatus3 = new UserStatus(); + $userStatus3->setUserId('_user3'); + $userStatus3->setStatus('away'); + $userStatus3->setStatusTimestamp(5000); + $userStatus3->setIsUserDefined(true); + $userStatus3->setIsBackup(true); + $userStatus3->setCustomIcon('🏝️'); + $userStatus3->setCustomMessage('Vacationing'); + $userStatus3->setClearAt(50000); + $this->mapper->insert($userStatus3); + + $this->mapper->restoreBackupStatuses([$userStatus1->getId(), $userStatus2->getId()]); + + $user1Status = $this->mapper->findByUserId('user1', false); + $this->assertEquals('user1', $user1Status->getUserId()); + $this->assertEquals(false, $user1Status->getIsBackup()); + $this->assertEquals('Releasing', $user1Status->getCustomMessage()); + + $user2Status = $this->mapper->findByUserId('user2', false); + $this->assertEquals('user2', $user2Status->getUserId()); + $this->assertEquals(false, $user2Status->getIsBackup()); + $this->assertEquals('Do not disturb', $user2Status->getCustomMessage()); + + $user3Status = $this->mapper->findByUserId('user3', true); + $this->assertEquals('_user3', $user3Status->getUserId()); + $this->assertEquals(true, $user3Status->getIsBackup()); + $this->assertEquals('Vacationing', $user3Status->getCustomMessage()); + } } diff --git a/apps/user_status/tests/Unit/Service/StatusServiceTest.php b/apps/user_status/tests/Unit/Service/StatusServiceTest.php index a7c183eae04..e5a39214b26 100644 --- a/apps/user_status/tests/Unit/Service/StatusServiceTest.php +++ b/apps/user_status/tests/Unit/Service/StatusServiceTest.php @@ -771,4 +771,62 @@ class StatusServiceTest extends TestCase { $this->service->backupCurrentStatus('john'); } + + public function testRevertMultipleUserStatus(): void { + $john = new UserStatus(); + $john->setId(1); + $john->setStatus(IUserStatus::AWAY); + $john->setStatusTimestamp(1337); + $john->setIsUserDefined(false); + $john->setMessageId('call'); + $john->setUserId('john'); + $john->setIsBackup(false); + + $johnBackup = new UserStatus(); + $johnBackup->setId(2); + $johnBackup->setStatus(IUserStatus::ONLINE); + $johnBackup->setStatusTimestamp(1337); + $johnBackup->setIsUserDefined(true); + $johnBackup->setMessageId('hello'); + $johnBackup->setUserId('_john'); + $johnBackup->setIsBackup(true); + + $noBackup = new UserStatus(); + $noBackup->setId(3); + $noBackup->setStatus(IUserStatus::AWAY); + $noBackup->setStatusTimestamp(1337); + $noBackup->setIsUserDefined(false); + $noBackup->setMessageId('call'); + $noBackup->setUserId('nobackup'); + $noBackup->setIsBackup(false); + + $backupOnly = new UserStatus(); + $backupOnly->setId(4); + $backupOnly->setStatus(IUserStatus::ONLINE); + $backupOnly->setStatusTimestamp(1337); + $backupOnly->setIsUserDefined(true); + $backupOnly->setMessageId('hello'); + $backupOnly->setUserId('_backuponly'); + $backupOnly->setIsBackup(true); + + $this->mapper->expects($this->once()) + ->method('findByUserIds') + ->with(['john', 'nobackup', 'backuponly', '_john', '_nobackup', '_backuponly']) + ->willReturn([ + $john, + $johnBackup, + $noBackup, + $backupOnly, + ]); + + $this->mapper->expects($this->once()) + ->method('deleteByIds') + ->with([1, 3]); + + $this->mapper->expects($this->once()) + ->method('restoreBackupStatuses') + ->with([2]); + + $this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly'], 'call', IUserStatus::AWAY); + } } diff --git a/lib/private/UserStatus/ISettableProvider.php b/lib/private/UserStatus/ISettableProvider.php index fc0d502845e..88a107d1f86 100644 --- a/lib/private/UserStatus/ISettableProvider.php +++ b/lib/private/UserStatus/ISettableProvider.php @@ -52,4 +52,15 @@ interface ISettableProvider extends IProvider { * @param string $status The expected current status. */ public function revertUserStatus(string $userId, string $messageId, string $status): void; + + /** + * Revert an automatically set user status. For example after leaving a call, + * change back to the previously set status. If the user has already updated + * their status, this method does nothing. + * + * @param string[] $userIds The users for which we want to update the status. + * @param string $messageId The expected current messageId. + * @param string $status The expected current status. + */ + public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void; } diff --git a/lib/private/UserStatus/Manager.php b/lib/private/UserStatus/Manager.php index bca80bc5b03..c93795bea5b 100644 --- a/lib/private/UserStatus/Manager.php +++ b/lib/private/UserStatus/Manager.php @@ -121,4 +121,12 @@ class Manager implements IManager { } $this->provider->revertUserStatus($userId, $messageId, $status); } + + public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void { + $this->setupProvider(); + if (!$this->provider || !($this->provider instanceof ISettableProvider)) { + return; + } + $this->provider->revertMultipleUserStatus($userIds, $messageId, $status); + } } diff --git a/lib/public/UserStatus/IManager.php b/lib/public/UserStatus/IManager.php index 24cef821543..f709768d717 100644 --- a/lib/public/UserStatus/IManager.php +++ b/lib/public/UserStatus/IManager.php @@ -39,7 +39,7 @@ interface IManager { * @return IUserStatus[] * @since 20.0.0 */ - public function getUserStatuses(array $userIds):array; + public function getUserStatuses(array $userIds): array; /** @@ -47,6 +47,7 @@ interface IManager { * * @param string $userId The user for which we want to update the status. * @param string $messageId The id of the predefined message. + * @param string $status The status to assign * @param bool $createBackup If true, this will store the old status so that it is possible to revert it later (e.g. after a call). * @since 23.0.0 */ @@ -58,7 +59,19 @@ interface IManager { * * @param string $userId The user for which we want to update the status. * @param string $messageId The expected current messageId. If the user has already updated their status, this method does nothing. + * @param string $status The expected current status. If the user has already updated their status, this method does nothing. * @since 23.0.0 */ public function revertUserStatus(string $userId, string $messageId, string $status): void; + + /** + * Revert an automatically set user status. For example after leaving a call, + * change back to the previously set status. + * + * @param string[] $userIds The user for which we want to update the status. + * @param string $messageId The expected current messageId. If the user has already updated their status, this method does nothing. + * @param string $status The expected current status. If the user has already updated their status, this method does nothing. + * @since 23.0.0 + */ + public function revertMultipleUserStatus(array $userIds, string $messageId, string $status): void; } |