UserLiveStatusListener.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2020, Georg Ehrke
  5. *
  6. * @author Georg Ehrke <oc.list@georgehrke.com>
  7. *
  8. * @license GNU AGPL version 3 or any later version
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. namespace OCA\UserStatus\Listener;
  25. use OCA\UserStatus\Db\UserStatus;
  26. use OCA\UserStatus\Connector\UserStatus as ConnectorUserStatus;
  27. use OCA\UserStatus\Db\UserStatusMapper;
  28. use OCA\UserStatus\Service\StatusService;
  29. use OCP\AppFramework\Db\DoesNotExistException;
  30. use OCP\AppFramework\Utility\ITimeFactory;
  31. use OCP\EventDispatcher\IEventListener;
  32. use OCP\EventDispatcher\Event;
  33. use OCP\User\Events\UserLiveStatusEvent;
  34. use OCP\UserStatus\IUserStatus;
  35. /**
  36. * Class UserDeletedListener
  37. *
  38. * @package OCA\UserStatus\Listener
  39. */
  40. class UserLiveStatusListener implements IEventListener {
  41. private UserStatusMapper $mapper;
  42. private StatusService $statusService;
  43. private ITimeFactory $timeFactory;
  44. public function __construct(UserStatusMapper $mapper,
  45. StatusService $statusService,
  46. ITimeFactory $timeFactory) {
  47. $this->mapper = $mapper;
  48. $this->statusService = $statusService;
  49. $this->timeFactory = $timeFactory;
  50. }
  51. /**
  52. * @inheritDoc
  53. */
  54. public function handle(Event $event): void {
  55. if (!($event instanceof UserLiveStatusEvent)) {
  56. // Unrelated
  57. return;
  58. }
  59. $user = $event->getUser();
  60. try {
  61. $userStatus = $this->statusService->findByUserId($user->getUID());
  62. } catch (DoesNotExistException $ex) {
  63. $userStatus = new UserStatus();
  64. $userStatus->setUserId($user->getUID());
  65. $userStatus->setStatus(IUserStatus::OFFLINE);
  66. $userStatus->setStatusTimestamp(0);
  67. $userStatus->setIsUserDefined(false);
  68. }
  69. // If the status is user-defined and one of the persistent statuses, we
  70. // will not override it.
  71. if ($userStatus->getIsUserDefined() &&
  72. \in_array($userStatus->getStatus(), StatusService::PERSISTENT_STATUSES, true)) {
  73. return;
  74. }
  75. $needsUpdate = false;
  76. // If the current status is older than 5 minutes,
  77. // treat it as outdated and update
  78. if ($userStatus->getStatusTimestamp() < ($this->timeFactory->getTime() - StatusService::INVALIDATE_STATUS_THRESHOLD)) {
  79. $needsUpdate = true;
  80. }
  81. // If the emitted status is more important than the current status
  82. // treat it as outdated and update
  83. if (array_search($event->getStatus(), StatusService::PRIORITY_ORDERED_STATUSES) < array_search($userStatus->getStatus(), StatusService::PRIORITY_ORDERED_STATUSES)) {
  84. $needsUpdate = true;
  85. }
  86. if ($needsUpdate) {
  87. $userStatus->setStatus($event->getStatus());
  88. $userStatus->setStatusTimestamp($event->getTimestamp());
  89. $userStatus->setIsUserDefined(false);
  90. if ($userStatus->getId() === null) {
  91. $this->mapper->insert($userStatus);
  92. } else {
  93. $this->mapper->update($userStatus);
  94. }
  95. }
  96. $event->setUserStatus(new ConnectorUserStatus($userStatus));
  97. }
  98. }