AppUpdatedNotifications.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\UpdateNotification\BackgroundJob;
  8. use OCA\UpdateNotification\AppInfo\Application;
  9. use OCA\UpdateNotification\Manager;
  10. use OCP\App\IAppManager;
  11. use OCP\AppFramework\Services\IAppConfig;
  12. use OCP\AppFramework\Utility\ITimeFactory;
  13. use OCP\BackgroundJob\QueuedJob;
  14. use OCP\IConfig;
  15. use OCP\IUser;
  16. use OCP\IUserManager;
  17. use OCP\Notification\IManager;
  18. use OCP\Notification\INotification;
  19. use Psr\Log\LoggerInterface;
  20. class AppUpdatedNotifications extends QueuedJob {
  21. public function __construct(
  22. ITimeFactory $time,
  23. private IConfig $config,
  24. private IAppConfig $appConfig,
  25. private IManager $notificationManager,
  26. private IUserManager $userManager,
  27. private IAppManager $appManager,
  28. private LoggerInterface $logger,
  29. private Manager $manager,
  30. ) {
  31. parent::__construct($time);
  32. }
  33. /**
  34. * @param array{appId: string, timestamp: int} $argument
  35. */
  36. protected function run(mixed $argument): void {
  37. $appId = $argument['appId'];
  38. $timestamp = $argument['timestamp'];
  39. $dateTime = $this->time->getDateTime();
  40. $dateTime->setTimestamp($timestamp);
  41. $this->logger->debug(
  42. 'Running background job to create app update notifications for "' . $appId . '"',
  43. [
  44. 'app' => Application::APP_NAME,
  45. ],
  46. );
  47. if ($this->manager->getChangelogFile($appId, 'en') === null) {
  48. $this->logger->debug('Skipping app updated notification - no changelog provided');
  49. return;
  50. }
  51. $this->stopPreviousNotifications($appId);
  52. // Create new notifications
  53. $notification = $this->notificationManager->createNotification();
  54. $notification->setApp(Application::APP_NAME)
  55. ->setDateTime($dateTime)
  56. ->setSubject('app_updated', [$appId])
  57. ->setObject('app_updated', $appId);
  58. $this->notifyUsers($appId, $notification);
  59. }
  60. /**
  61. * Stop all previous notifications users might not have dismissed until now
  62. * @param string $appId The app to stop update notifications for
  63. */
  64. private function stopPreviousNotifications(string $appId): void {
  65. $notification = $this->notificationManager->createNotification();
  66. $notification->setApp(Application::APP_NAME)
  67. ->setObject('app_updated', $appId);
  68. $this->notificationManager->markProcessed($notification);
  69. }
  70. /**
  71. * Notify all users for which the updated app is enabled
  72. */
  73. private function notifyUsers(string $appId, INotification $notification): void {
  74. $guestsEnabled = $this->appConfig->getAppValueBool('app_updated.notify_guests', false) && class_exists('\OCA\Guests\UserBackend');
  75. $isDefer = $this->notificationManager->defer();
  76. // Notify all seen users about the app update
  77. $this->userManager->callForSeenUsers(function (IUser $user) use ($guestsEnabled, $appId, $notification): void {
  78. if (!$guestsEnabled && ($user->getBackendClassName() === '\OCA\Guests\UserBackend')) {
  79. return;
  80. }
  81. if (!$this->appManager->isEnabledForUser($appId, $user)) {
  82. return;
  83. }
  84. $notification->setUser($user->getUID());
  85. $this->notificationManager->notify($notification);
  86. });
  87. // If we enabled the defer we call the flush
  88. if ($isDefer) {
  89. $this->notificationManager->flush();
  90. }
  91. }
  92. }