AppUpdatedNotifications.php 3.9 KB

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