AbsenceService.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\DAV\Service;
  8. use InvalidArgumentException;
  9. use OCA\DAV\BackgroundJob\OutOfOfficeEventDispatcherJob;
  10. use OCA\DAV\CalDAV\TimezoneService;
  11. use OCA\DAV\Db\Absence;
  12. use OCA\DAV\Db\AbsenceMapper;
  13. use OCP\AppFramework\Db\DoesNotExistException;
  14. use OCP\AppFramework\Utility\ITimeFactory;
  15. use OCP\BackgroundJob\IJobList;
  16. use OCP\EventDispatcher\IEventDispatcher;
  17. use OCP\IUser;
  18. use OCP\User\Events\OutOfOfficeChangedEvent;
  19. use OCP\User\Events\OutOfOfficeClearedEvent;
  20. use OCP\User\Events\OutOfOfficeScheduledEvent;
  21. use OCP\User\IOutOfOfficeData;
  22. class AbsenceService {
  23. public function __construct(
  24. private AbsenceMapper $absenceMapper,
  25. private IEventDispatcher $eventDispatcher,
  26. private IJobList $jobList,
  27. private TimezoneService $timezoneService,
  28. private ITimeFactory $timeFactory,
  29. ) {
  30. }
  31. /**
  32. * @param string $firstDay The first day (inclusive) of the absence formatted as YYYY-MM-DD.
  33. * @param string $lastDay The last day (inclusive) of the absence formatted as YYYY-MM-DD.
  34. *
  35. * @throws \OCP\DB\Exception
  36. * @throws InvalidArgumentException If no user with the given user id exists.
  37. */
  38. public function createOrUpdateAbsence(
  39. IUser $user,
  40. string $firstDay,
  41. string $lastDay,
  42. string $status,
  43. string $message,
  44. ): Absence {
  45. try {
  46. $absence = $this->absenceMapper->findByUserId($user->getUID());
  47. } catch (DoesNotExistException) {
  48. $absence = new Absence();
  49. }
  50. $absence->setUserId($user->getUID());
  51. $absence->setFirstDay($firstDay);
  52. $absence->setLastDay($lastDay);
  53. $absence->setStatus($status);
  54. $absence->setMessage($message);
  55. if ($absence->getId() === null) {
  56. $absence = $this->absenceMapper->insert($absence);
  57. $eventData = $absence->toOutOufOfficeData(
  58. $user,
  59. $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
  60. );
  61. $this->eventDispatcher->dispatchTyped(new OutOfOfficeScheduledEvent($eventData));
  62. } else {
  63. $absence = $this->absenceMapper->update($absence);
  64. $eventData = $absence->toOutOufOfficeData(
  65. $user,
  66. $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
  67. );
  68. $this->eventDispatcher->dispatchTyped(new OutOfOfficeChangedEvent($eventData));
  69. }
  70. $now = $this->timeFactory->getTime();
  71. if ($eventData->getStartDate() > $now) {
  72. $this->jobList->scheduleAfter(
  73. OutOfOfficeEventDispatcherJob::class,
  74. $eventData->getStartDate(),
  75. [
  76. 'id' => $absence->getId(),
  77. 'event' => OutOfOfficeEventDispatcherJob::EVENT_START,
  78. ],
  79. );
  80. }
  81. if ($eventData->getEndDate() > $now) {
  82. $this->jobList->scheduleAfter(
  83. OutOfOfficeEventDispatcherJob::class,
  84. $eventData->getEndDate(),
  85. [
  86. 'id' => $absence->getId(),
  87. 'event' => OutOfOfficeEventDispatcherJob::EVENT_END,
  88. ],
  89. );
  90. }
  91. return $absence;
  92. }
  93. /**
  94. * @throws \OCP\DB\Exception
  95. */
  96. public function clearAbsence(IUser $user): void {
  97. try {
  98. $absence = $this->absenceMapper->findByUserId($user->getUID());
  99. } catch (DoesNotExistException $e) {
  100. // Nothing to clear
  101. return;
  102. }
  103. $this->absenceMapper->delete($absence);
  104. $this->jobList->remove(OutOfOfficeEventDispatcherJob::class);
  105. $eventData = $absence->toOutOufOfficeData(
  106. $user,
  107. $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
  108. );
  109. $this->eventDispatcher->dispatchTyped(new OutOfOfficeClearedEvent($eventData));
  110. }
  111. public function getAbsence(string $userId): ?Absence {
  112. try {
  113. return $this->absenceMapper->findByUserId($userId);
  114. } catch (DoesNotExistException $e) {
  115. return null;
  116. }
  117. }
  118. public function getCurrentAbsence(IUser $user): ?IOutOfOfficeData {
  119. try {
  120. $absence = $this->absenceMapper->findByUserId($user->getUID());
  121. $oooData = $absence->toOutOufOfficeData(
  122. $user,
  123. $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(),
  124. );
  125. if ($this->isInEffect($oooData)) {
  126. return $oooData;
  127. }
  128. } catch (DoesNotExistException) {
  129. // Nothing there to process
  130. }
  131. return null;
  132. }
  133. public function isInEffect(IOutOfOfficeData $absence): bool {
  134. $now = $this->timeFactory->getTime();
  135. return $absence->getStartDate() <= $now && $absence->getEndDate() >= $now;
  136. }
  137. }