aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/BackgroundJob
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/BackgroundJob')
-rw-r--r--apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php35
-rw-r--r--apps/dav/lib/BackgroundJob/CalendarRetentionJob.php10
-rw-r--r--apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php9
-rw-r--r--apps/dav/lib/BackgroundJob/CleanupInvitationTokenJob.php9
-rw-r--r--apps/dav/lib/BackgroundJob/CleanupOrphanedChildrenJob.php89
-rw-r--r--apps/dav/lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php2
-rw-r--r--apps/dav/lib/BackgroundJob/EventReminderJob.php25
-rw-r--r--apps/dav/lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php19
-rw-r--r--apps/dav/lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php2
-rw-r--r--apps/dav/lib/BackgroundJob/PruneOutdatedSyncTokensJob.php21
-rw-r--r--apps/dav/lib/BackgroundJob/RefreshWebcalJob.php6
-rw-r--r--apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php18
-rw-r--r--apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php415
-rw-r--r--apps/dav/lib/BackgroundJob/UploadCleanup.php21
-rw-r--r--apps/dav/lib/BackgroundJob/UserStatusAutomation.php31
15 files changed, 180 insertions, 532 deletions
diff --git a/apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php b/apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php
index d908cd3ae82..1165367c33f 100644
--- a/apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php
+++ b/apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php
@@ -22,41 +22,28 @@ use Psr\Log\LoggerInterface;
*/
class BuildReminderIndexBackgroundJob extends QueuedJob {
- /** @var IDBConnection */
- private $db;
-
- /** @var ReminderService */
- private $reminderService;
-
- private LoggerInterface $logger;
-
- /** @var IJobList */
- private $jobList;
-
/** @var ITimeFactory */
private $timeFactory;
/**
* BuildReminderIndexBackgroundJob constructor.
*/
- public function __construct(IDBConnection $db,
- ReminderService $reminderService,
- LoggerInterface $logger,
- IJobList $jobList,
- ITimeFactory $timeFactory) {
+ public function __construct(
+ private IDBConnection $db,
+ private ReminderService $reminderService,
+ private LoggerInterface $logger,
+ private IJobList $jobList,
+ ITimeFactory $timeFactory,
+ ) {
parent::__construct($timeFactory);
- $this->db = $db;
- $this->reminderService = $reminderService;
- $this->logger = $logger;
- $this->jobList = $jobList;
$this->timeFactory = $timeFactory;
}
public function run($argument) {
- $offset = (int) $argument['offset'];
- $stopAt = (int) $argument['stopAt'];
+ $offset = (int)$argument['offset'];
+ $stopAt = (int)$argument['stopAt'];
- $this->logger->info('Building calendar reminder index (' . $offset .'/' . $stopAt . ')');
+ $this->logger->info('Building calendar reminder index (' . $offset . '/' . $stopAt . ')');
$offset = $this->buildIndex($offset, $stopAt);
@@ -88,7 +75,7 @@ class BuildReminderIndexBackgroundJob extends QueuedJob {
$result = $query->executeQuery();
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
- $offset = (int) $row['id'];
+ $offset = (int)$row['id'];
if (is_resource($row['calendardata'])) {
$row['calendardata'] = stream_get_contents($row['calendardata']);
}
diff --git a/apps/dav/lib/BackgroundJob/CalendarRetentionJob.php b/apps/dav/lib/BackgroundJob/CalendarRetentionJob.php
index 2de9c6d00ee..c6edac4f228 100644
--- a/apps/dav/lib/BackgroundJob/CalendarRetentionJob.php
+++ b/apps/dav/lib/BackgroundJob/CalendarRetentionJob.php
@@ -13,13 +13,11 @@ use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
class CalendarRetentionJob extends TimedJob {
- /** @var RetentionService */
- private $service;
-
- public function __construct(ITimeFactory $time,
- RetentionService $service) {
+ public function __construct(
+ ITimeFactory $time,
+ private RetentionService $service,
+ ) {
parent::__construct($time);
- $this->service = $service;
// Run four times a day
$this->setInterval(6 * 60 * 60);
diff --git a/apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php b/apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php
index 8895159d6ad..49b6b1607ef 100644
--- a/apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php
+++ b/apps/dav/lib/BackgroundJob/CleanupDirectLinksJob.php
@@ -13,12 +13,11 @@ use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
class CleanupDirectLinksJob extends TimedJob {
- /** @var DirectMapper */
- private $mapper;
-
- public function __construct(ITimeFactory $timeFactory, DirectMapper $mapper) {
+ public function __construct(
+ ITimeFactory $timeFactory,
+ private DirectMapper $mapper,
+ ) {
parent::__construct($timeFactory);
- $this->mapper = $mapper;
// Run once a day at off-peak time
$this->setInterval(24 * 60 * 60);
diff --git a/apps/dav/lib/BackgroundJob/CleanupInvitationTokenJob.php b/apps/dav/lib/BackgroundJob/CleanupInvitationTokenJob.php
index 1479cd363b3..7b664d03181 100644
--- a/apps/dav/lib/BackgroundJob/CleanupInvitationTokenJob.php
+++ b/apps/dav/lib/BackgroundJob/CleanupInvitationTokenJob.php
@@ -14,12 +14,11 @@ use OCP\IDBConnection;
class CleanupInvitationTokenJob extends TimedJob {
- /** @var IDBConnection */
- private $db;
-
- public function __construct(IDBConnection $db, ITimeFactory $time) {
+ public function __construct(
+ private IDBConnection $db,
+ ITimeFactory $time,
+ ) {
parent::__construct($time);
- $this->db = $db;
// Run once a day at off-peak time
$this->setInterval(24 * 60 * 60);
diff --git a/apps/dav/lib/BackgroundJob/CleanupOrphanedChildrenJob.php b/apps/dav/lib/BackgroundJob/CleanupOrphanedChildrenJob.php
new file mode 100644
index 00000000000..8a5e34381a7
--- /dev/null
+++ b/apps/dav/lib/BackgroundJob/CleanupOrphanedChildrenJob.php
@@ -0,0 +1,89 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\DAV\BackgroundJob;
+
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\IJobList;
+use OCP\BackgroundJob\QueuedJob;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use Psr\Log\LoggerInterface;
+
+class CleanupOrphanedChildrenJob extends QueuedJob {
+ public const ARGUMENT_CHILD_TABLE = 'childTable';
+ public const ARGUMENT_PARENT_TABLE = 'parentTable';
+ public const ARGUMENT_PARENT_ID = 'parentId';
+ public const ARGUMENT_LOG_MESSAGE = 'logMessage';
+
+ private const BATCH_SIZE = 1000;
+
+ public function __construct(
+ ITimeFactory $time,
+ private readonly IDBConnection $connection,
+ private readonly LoggerInterface $logger,
+ private readonly IJobList $jobList,
+ ) {
+ parent::__construct($time);
+ }
+
+ protected function run($argument): void {
+ $childTable = $argument[self::ARGUMENT_CHILD_TABLE];
+ $parentTable = $argument[self::ARGUMENT_PARENT_TABLE];
+ $parentId = $argument[self::ARGUMENT_PARENT_ID];
+ $logMessage = $argument[self::ARGUMENT_LOG_MESSAGE];
+
+ $orphanCount = $this->cleanUpOrphans($childTable, $parentTable, $parentId);
+ $this->logger->debug(sprintf($logMessage, $orphanCount));
+
+ // Requeue if there might be more orphans
+ if ($orphanCount >= self::BATCH_SIZE) {
+ $this->jobList->add(self::class, $argument);
+ }
+ }
+
+ private function cleanUpOrphans(
+ string $childTable,
+ string $parentTable,
+ string $parentId,
+ ): int {
+ // We can't merge both queries into a single one here as DELETEing from a table while
+ // SELECTing it in a sub query is not supported by Oracle DB.
+ // Ref https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/delete.html#idm46006185488144
+
+ $selectQb = $this->connection->getQueryBuilder();
+
+ $selectQb->select('c.id')
+ ->from($childTable, 'c')
+ ->leftJoin('c', $parentTable, 'p', $selectQb->expr()->eq('c.' . $parentId, 'p.id'))
+ ->where($selectQb->expr()->isNull('p.id'))
+ ->setMaxResults(self::BATCH_SIZE);
+
+ if (\in_array($parentTable, ['calendars', 'calendarsubscriptions'], true)) {
+ $calendarType = $parentTable === 'calendarsubscriptions' ? CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION : CalDavBackend::CALENDAR_TYPE_CALENDAR;
+ $selectQb->andWhere($selectQb->expr()->eq('c.calendartype', $selectQb->createNamedParameter($calendarType, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
+ }
+
+ $result = $selectQb->executeQuery();
+ $rows = $result->fetchAll();
+ $result->closeCursor();
+ if (empty($rows)) {
+ return 0;
+ }
+
+ $orphanItems = array_map(static fn ($row) => $row['id'], $rows);
+ $deleteQb = $this->connection->getQueryBuilder();
+ $deleteQb->delete($childTable)
+ ->where($deleteQb->expr()->in('id', $deleteQb->createNamedParameter($orphanItems, IQueryBuilder::PARAM_INT_ARRAY)));
+ $deleteQb->executeStatement();
+
+ return count($orphanItems);
+ }
+}
diff --git a/apps/dav/lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php b/apps/dav/lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php
index fa53a8be4f0..bc306d58fe1 100644
--- a/apps/dav/lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php
+++ b/apps/dav/lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php
@@ -30,6 +30,6 @@ class DeleteOutdatedSchedulingObjects extends TimedJob {
protected function run($argument): void {
$time = $this->time->getTime() - (60 * 60);
$this->calDavBackend->deleteOutdatedSchedulingObjects($time, 50000);
- $this->logger->info("Removed outdated scheduling objects");
+ $this->logger->info('Removed outdated scheduling objects');
}
}
diff --git a/apps/dav/lib/BackgroundJob/EventReminderJob.php b/apps/dav/lib/BackgroundJob/EventReminderJob.php
index 5025919c84f..0e21e06fc35 100644
--- a/apps/dav/lib/BackgroundJob/EventReminderJob.php
+++ b/apps/dav/lib/BackgroundJob/EventReminderJob.php
@@ -8,6 +8,9 @@ declare(strict_types=1);
*/
namespace OCA\DAV\BackgroundJob;
+use OC\User\NoUserException;
+use OCA\DAV\CalDAV\Reminder\NotificationProvider\ProviderNotAvailableException;
+use OCA\DAV\CalDAV\Reminder\NotificationTypeDoesNotExistException;
use OCA\DAV\CalDAV\Reminder\ReminderService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
@@ -15,18 +18,12 @@ use OCP\IConfig;
class EventReminderJob extends TimedJob {
- /** @var ReminderService */
- private $reminderService;
-
- /** @var IConfig */
- private $config;
-
- public function __construct(ITimeFactory $time,
- ReminderService $reminderService,
- IConfig $config) {
+ public function __construct(
+ ITimeFactory $time,
+ private ReminderService $reminderService,
+ private IConfig $config,
+ ) {
parent::__construct($time);
- $this->reminderService = $reminderService;
- $this->config = $config;
// Run every 5 minutes
$this->setInterval(5 * 60);
@@ -34,9 +31,9 @@ class EventReminderJob extends TimedJob {
}
/**
- * @throws \OCA\DAV\CalDAV\Reminder\NotificationProvider\ProviderNotAvailableException
- * @throws \OCA\DAV\CalDAV\Reminder\NotificationTypeDoesNotExistException
- * @throws \OC\User\NoUserException
+ * @throws ProviderNotAvailableException
+ * @throws NotificationTypeDoesNotExistException
+ * @throws NoUserException
*/
public function run($argument):void {
if ($this->config->getAppValue('dav', 'sendEventReminders', 'yes') !== 'yes') {
diff --git a/apps/dav/lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php b/apps/dav/lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php
index a6b0346908c..6d94f4810ed 100644
--- a/apps/dav/lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php
+++ b/apps/dav/lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php
@@ -15,26 +15,19 @@ use OCP\IConfig;
class GenerateBirthdayCalendarBackgroundJob extends QueuedJob {
- /** @var BirthdayService */
- private $birthdayService;
-
- /** @var IConfig */
- private $config;
-
- public function __construct(ITimeFactory $time,
- BirthdayService $birthdayService,
- IConfig $config) {
+ public function __construct(
+ ITimeFactory $time,
+ private BirthdayService $birthdayService,
+ private IConfig $config,
+ ) {
parent::__construct($time);
-
- $this->birthdayService = $birthdayService;
- $this->config = $config;
}
public function run($argument) {
$userId = $argument['userId'];
$purgeBeforeGenerating = $argument['purgeBeforeGenerating'] ?? false;
- // make sure admin didn't change his mind
+ // make sure admin didn't change their mind
$isGloballyEnabled = $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes');
if ($isGloballyEnabled !== 'yes') {
return;
diff --git a/apps/dav/lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php b/apps/dav/lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php
index 8293b370996..cc4fd5dce9d 100644
--- a/apps/dav/lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php
+++ b/apps/dav/lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php
@@ -41,7 +41,7 @@ class OutOfOfficeEventDispatcherJob extends QueuedJob {
try {
$absence = $this->absenceMapper->findById($id);
- } catch (DoesNotExistException | \OCP\DB\Exception $e) {
+ } catch (DoesNotExistException|\OCP\DB\Exception $e) {
$this->logger->error('Failed to dispatch out-of-office event: ' . $e->getMessage(), [
'exception' => $e,
'argument' => $argument,
diff --git a/apps/dav/lib/BackgroundJob/PruneOutdatedSyncTokensJob.php b/apps/dav/lib/BackgroundJob/PruneOutdatedSyncTokensJob.php
index 1ef33410f4f..8746588acc7 100644
--- a/apps/dav/lib/BackgroundJob/PruneOutdatedSyncTokensJob.php
+++ b/apps/dav/lib/BackgroundJob/PruneOutdatedSyncTokensJob.php
@@ -18,24 +18,21 @@ use Psr\Log\LoggerInterface;
class PruneOutdatedSyncTokensJob extends TimedJob {
- private IConfig $config;
- private LoggerInterface $logger;
- private CardDavBackend $cardDavBackend;
- private CalDavBackend $calDavBackend;
-
- public function __construct(ITimeFactory $timeFactory, CalDavBackend $calDavBackend, CardDavBackend $cardDavBackend, IConfig $config, LoggerInterface $logger) {
+ public function __construct(
+ ITimeFactory $timeFactory,
+ private CalDavBackend $calDavBackend,
+ private CardDavBackend $cardDavBackend,
+ private IConfig $config,
+ private LoggerInterface $logger,
+ ) {
parent::__construct($timeFactory);
- $this->calDavBackend = $calDavBackend;
- $this->cardDavBackend = $cardDavBackend;
- $this->config = $config;
- $this->logger = $logger;
$this->setInterval(60 * 60 * 24); // One day
$this->setTimeSensitivity(self::TIME_INSENSITIVE);
}
public function run($argument) {
- $limit = max(1, (int) $this->config->getAppValue(Application::APP_ID, 'totalNumberOfSyncTokensToKeep', '10000'));
- $retention = max(7, (int) $this->config->getAppValue(Application::APP_ID, 'syncTokensRetentionDays', '60')) * 24 * 3600;
+ $limit = max(1, (int)$this->config->getAppValue(Application::APP_ID, 'totalNumberOfSyncTokensToKeep', '10000'));
+ $retention = max(7, (int)$this->config->getAppValue(Application::APP_ID, 'syncTokensRetentionDays', '60')) * 24 * 3600;
$prunedCalendarSyncTokens = $this->calDavBackend->pruneOutdatedSyncTokens($limit, $retention);
$prunedAddressBookSyncTokens = $this->cardDavBackend->pruneOutdatedSyncTokens($limit, $retention);
diff --git a/apps/dav/lib/BackgroundJob/RefreshWebcalJob.php b/apps/dav/lib/BackgroundJob/RefreshWebcalJob.php
index 982d6040fd7..e96735ca50b 100644
--- a/apps/dav/lib/BackgroundJob/RefreshWebcalJob.php
+++ b/apps/dav/lib/BackgroundJob/RefreshWebcalJob.php
@@ -41,8 +41,8 @@ class RefreshWebcalJob extends Job {
$this->fixSubscriptionRowTyping($subscription);
- // if no refresh rate was configured, just refresh once a week
- $defaultRefreshRate = $this->config->getAppValue('dav', 'calendarSubscriptionRefreshRate', 'P1W');
+ // if no refresh rate was configured, just refresh once a day
+ $defaultRefreshRate = $this->config->getAppValue('dav', 'calendarSubscriptionRefreshRate', 'P1D');
$refreshRate = $subscription[RefreshWebcalService::REFRESH_RATE] ?? $defaultRefreshRate;
$subscriptionId = $subscription['id'];
@@ -104,7 +104,7 @@ class RefreshWebcalJob extends Job {
foreach ($forceInt as $column) {
if (isset($row[$column])) {
- $row[$column] = (int) $row[$column];
+ $row[$column] = (int)$row[$column];
}
}
}
diff --git a/apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php b/apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php
index 61fe4cd8483..7ec5b7fba79 100644
--- a/apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php
+++ b/apps/dav/lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php
@@ -16,12 +16,6 @@ use OCP\IUserManager;
class RegisterRegenerateBirthdayCalendars extends QueuedJob {
- /** @var IUserManager */
- private $userManager;
-
- /** @var IJobList */
- private $jobList;
-
/**
* RegisterRegenerateBirthdayCalendars constructor.
*
@@ -29,19 +23,19 @@ class RegisterRegenerateBirthdayCalendars extends QueuedJob {
* @param IUserManager $userManager
* @param IJobList $jobList
*/
- public function __construct(ITimeFactory $time,
- IUserManager $userManager,
- IJobList $jobList) {
+ public function __construct(
+ ITimeFactory $time,
+ private IUserManager $userManager,
+ private IJobList $jobList,
+ ) {
parent::__construct($time);
- $this->userManager = $userManager;
- $this->jobList = $jobList;
}
/**
* @inheritDoc
*/
public function run($argument) {
- $this->userManager->callForSeenUsers(function (IUser $user) {
+ $this->userManager->callForSeenUsers(function (IUser $user): void {
$this->jobList->add(GenerateBirthdayCalendarBackgroundJob::class, [
'userId' => $user->getUID(),
'purgeBeforeGenerating' => true
diff --git a/apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php b/apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php
index 3ce90c72019..b7688ea32d8 100644
--- a/apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php
+++ b/apps/dav/lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php
@@ -9,427 +9,26 @@ declare(strict_types=1);
namespace OCA\DAV\BackgroundJob;
-use OCA\DAV\CalDAV\CalDavBackend;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
-use OCP\Calendar\BackendTemporarilyUnavailableException;
-use OCP\Calendar\IMetadataProvider;
-use OCP\Calendar\Resource\IBackend as IResourceBackend;
use OCP\Calendar\Resource\IManager as IResourceManager;
-use OCP\Calendar\Resource\IResource;
use OCP\Calendar\Room\IManager as IRoomManager;
-use OCP\Calendar\Room\IRoom;
-use OCP\IDBConnection;
class UpdateCalendarResourcesRoomsBackgroundJob extends TimedJob {
-
- /** @var IResourceManager */
- private $resourceManager;
-
- /** @var IRoomManager */
- private $roomManager;
-
- /** @var IDBConnection */
- private $dbConnection;
-
- /** @var CalDavBackend */
- private $calDavBackend;
-
- public function __construct(ITimeFactory $time,
- IResourceManager $resourceManager,
- IRoomManager $roomManager,
- IDBConnection $dbConnection,
- CalDavBackend $calDavBackend) {
+ public function __construct(
+ ITimeFactory $time,
+ private IResourceManager $resourceManager,
+ private IRoomManager $roomManager,
+ ) {
parent::__construct($time);
- $this->resourceManager = $resourceManager;
- $this->roomManager = $roomManager;
- $this->dbConnection = $dbConnection;
- $this->calDavBackend = $calDavBackend;
// Run once an hour
$this->setInterval(60 * 60);
$this->setTimeSensitivity(self::TIME_SENSITIVE);
}
- /**
- * @param $argument
- */
public function run($argument): void {
- $this->runForBackend(
- $this->resourceManager,
- 'calendar_resources',
- 'calendar_resources_md',
- 'resource_id',
- 'principals/calendar-resources'
- );
- $this->runForBackend(
- $this->roomManager,
- 'calendar_rooms',
- 'calendar_rooms_md',
- 'room_id',
- 'principals/calendar-rooms'
- );
- }
-
- /**
- * Run background-job for one specific backendManager
- * either ResourceManager or RoomManager
- *
- * @param IResourceManager|IRoomManager $backendManager
- * @param string $dbTable
- * @param string $dbTableMetadata
- * @param string $foreignKey
- * @param string $principalPrefix
- */
- private function runForBackend($backendManager,
- string $dbTable,
- string $dbTableMetadata,
- string $foreignKey,
- string $principalPrefix): void {
- $backends = $backendManager->getBackends();
-
- foreach ($backends as $backend) {
- $backendId = $backend->getBackendIdentifier();
-
- try {
- if ($backend instanceof IResourceBackend) {
- $list = $backend->listAllResources();
- } else {
- $list = $backend->listAllRooms();
- }
- } catch (BackendTemporarilyUnavailableException $ex) {
- continue;
- }
-
- $cachedList = $this->getAllCachedByBackend($dbTable, $backendId);
- $newIds = array_diff($list, $cachedList);
- $deletedIds = array_diff($cachedList, $list);
- $editedIds = array_intersect($list, $cachedList);
-
- foreach ($newIds as $newId) {
- try {
- if ($backend instanceof IResourceBackend) {
- $resource = $backend->getResource($newId);
- } else {
- $resource = $backend->getRoom($newId);
- }
-
- $metadata = [];
- if ($resource instanceof IMetadataProvider) {
- $metadata = $this->getAllMetadataOfBackend($resource);
- }
- } catch (BackendTemporarilyUnavailableException $ex) {
- continue;
- }
-
- $id = $this->addToCache($dbTable, $backendId, $resource);
- $this->addMetadataToCache($dbTableMetadata, $foreignKey, $id, $metadata);
- // we don't create the calendar here, it is created lazily
- // when an event is actually scheduled with this resource / room
- }
-
- foreach ($deletedIds as $deletedId) {
- $id = $this->getIdForBackendAndResource($dbTable, $backendId, $deletedId);
- $this->deleteFromCache($dbTable, $id);
- $this->deleteMetadataFromCache($dbTableMetadata, $foreignKey, $id);
-
- $principalName = implode('-', [$backendId, $deletedId]);
- $this->deleteCalendarDataForResource($principalPrefix, $principalName);
- }
-
- foreach ($editedIds as $editedId) {
- $id = $this->getIdForBackendAndResource($dbTable, $backendId, $editedId);
-
- try {
- if ($backend instanceof IResourceBackend) {
- $resource = $backend->getResource($editedId);
- } else {
- $resource = $backend->getRoom($editedId);
- }
-
- $metadata = [];
- if ($resource instanceof IMetadataProvider) {
- $metadata = $this->getAllMetadataOfBackend($resource);
- }
- } catch (BackendTemporarilyUnavailableException $ex) {
- continue;
- }
-
- $this->updateCache($dbTable, $id, $resource);
-
- if ($resource instanceof IMetadataProvider) {
- $cachedMetadata = $this->getAllMetadataOfCache($dbTableMetadata, $foreignKey, $id);
- $this->updateMetadataCache($dbTableMetadata, $foreignKey, $id, $metadata, $cachedMetadata);
- }
- }
- }
- }
-
- /**
- * add entry to cache that exists remotely but not yet in cache
- *
- * @param string $table
- * @param string $backendId
- * @param IResource|IRoom $remote
- *
- * @return int Insert id
- */
- private function addToCache(string $table,
- string $backendId,
- $remote): int {
- $query = $this->dbConnection->getQueryBuilder();
- $query->insert($table)
- ->values([
- 'backend_id' => $query->createNamedParameter($backendId),
- 'resource_id' => $query->createNamedParameter($remote->getId()),
- 'email' => $query->createNamedParameter($remote->getEMail()),
- 'displayname' => $query->createNamedParameter($remote->getDisplayName()),
- 'group_restrictions' => $query->createNamedParameter(
- $this->serializeGroupRestrictions(
- $remote->getGroupRestrictions()
- ))
- ])
- ->executeStatement();
- return $query->getLastInsertId();
- }
-
- /**
- * @param string $table
- * @param string $foreignKey
- * @param int $foreignId
- * @param array $metadata
- */
- private function addMetadataToCache(string $table,
- string $foreignKey,
- int $foreignId,
- array $metadata): void {
- foreach ($metadata as $key => $value) {
- $query = $this->dbConnection->getQueryBuilder();
- $query->insert($table)
- ->values([
- $foreignKey => $query->createNamedParameter($foreignId),
- 'key' => $query->createNamedParameter($key),
- 'value' => $query->createNamedParameter($value),
- ])
- ->executeStatement();
- }
- }
-
- /**
- * delete entry from cache that does not exist anymore remotely
- *
- * @param string $table
- * @param int $id
- */
- private function deleteFromCache(string $table,
- int $id): void {
- $query = $this->dbConnection->getQueryBuilder();
- $query->delete($table)
- ->where($query->expr()->eq('id', $query->createNamedParameter($id)))
- ->executeStatement();
- }
-
- /**
- * @param string $table
- * @param string $foreignKey
- * @param int $id
- */
- private function deleteMetadataFromCache(string $table,
- string $foreignKey,
- int $id): void {
- $query = $this->dbConnection->getQueryBuilder();
- $query->delete($table)
- ->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id)))
- ->executeStatement();
- }
-
- /**
- * update an existing entry in cache
- *
- * @param string $table
- * @param int $id
- * @param IResource|IRoom $remote
- */
- private function updateCache(string $table,
- int $id,
- $remote): void {
- $query = $this->dbConnection->getQueryBuilder();
- $query->update($table)
- ->set('email', $query->createNamedParameter($remote->getEMail()))
- ->set('displayname', $query->createNamedParameter($remote->getDisplayName()))
- ->set('group_restrictions', $query->createNamedParameter(
- $this->serializeGroupRestrictions(
- $remote->getGroupRestrictions()
- )))
- ->where($query->expr()->eq('id', $query->createNamedParameter($id)))
- ->executeStatement();
- }
-
- /**
- * @param string $dbTable
- * @param string $foreignKey
- * @param int $id
- * @param array $metadata
- * @param array $cachedMetadata
- */
- private function updateMetadataCache(string $dbTable,
- string $foreignKey,
- int $id,
- array $metadata,
- array $cachedMetadata): void {
- $newMetadata = array_diff_key($metadata, $cachedMetadata);
- $deletedMetadata = array_diff_key($cachedMetadata, $metadata);
-
- foreach ($newMetadata as $key => $value) {
- $query = $this->dbConnection->getQueryBuilder();
- $query->insert($dbTable)
- ->values([
- $foreignKey => $query->createNamedParameter($id),
- 'key' => $query->createNamedParameter($key),
- 'value' => $query->createNamedParameter($value),
- ])
- ->executeStatement();
- }
-
- foreach ($deletedMetadata as $key => $value) {
- $query = $this->dbConnection->getQueryBuilder();
- $query->delete($dbTable)
- ->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id)))
- ->andWhere($query->expr()->eq('key', $query->createNamedParameter($key)))
- ->executeStatement();
- }
-
- $existingKeys = array_keys(array_intersect_key($metadata, $cachedMetadata));
- foreach ($existingKeys as $existingKey) {
- if ($metadata[$existingKey] !== $cachedMetadata[$existingKey]) {
- $query = $this->dbConnection->getQueryBuilder();
- $query->update($dbTable)
- ->set('value', $query->createNamedParameter($metadata[$existingKey]))
- ->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id)))
- ->andWhere($query->expr()->eq('key', $query->createNamedParameter($existingKey)))
- ->executeStatement();
- }
- }
- }
-
- /**
- * serialize array of group restrictions to store them in database
- *
- * @param array $groups
- *
- * @return string
- */
- private function serializeGroupRestrictions(array $groups): string {
- return \json_encode($groups, JSON_THROW_ON_ERROR);
- }
-
- /**
- * Gets all metadata of a backend
- *
- * @param IResource|IRoom $resource
- *
- * @return array
- */
- private function getAllMetadataOfBackend($resource): array {
- if (!($resource instanceof IMetadataProvider)) {
- return [];
- }
-
- $keys = $resource->getAllAvailableMetadataKeys();
- $metadata = [];
- foreach ($keys as $key) {
- $metadata[$key] = $resource->getMetadataForKey($key);
- }
-
- return $metadata;
- }
-
- /**
- * @param string $table
- * @param string $foreignKey
- * @param int $id
- *
- * @return array
- */
- private function getAllMetadataOfCache(string $table,
- string $foreignKey,
- int $id): array {
- $query = $this->dbConnection->getQueryBuilder();
- $query->select(['key', 'value'])
- ->from($table)
- ->where($query->expr()->eq($foreignKey, $query->createNamedParameter($id)));
- $result = $query->executeQuery();
- $rows = $result->fetchAll();
- $result->closeCursor();
-
- $metadata = [];
- foreach ($rows as $row) {
- $metadata[$row['key']] = $row['value'];
- }
-
- return $metadata;
- }
-
- /**
- * Gets all cached rooms / resources by backend
- *
- * @param $tableName
- * @param $backendId
- *
- * @return array
- */
- private function getAllCachedByBackend(string $tableName,
- string $backendId): array {
- $query = $this->dbConnection->getQueryBuilder();
- $query->select('resource_id')
- ->from($tableName)
- ->where($query->expr()->eq('backend_id', $query->createNamedParameter($backendId)));
- $result = $query->executeQuery();
- $rows = $result->fetchAll();
- $result->closeCursor();
-
- return array_map(function ($row): string {
- return $row['resource_id'];
- }, $rows);
- }
-
- /**
- * @param $principalPrefix
- * @param $principalUri
- */
- private function deleteCalendarDataForResource(string $principalPrefix,
- string $principalUri): void {
- $calendar = $this->calDavBackend->getCalendarByUri(
- implode('/', [$principalPrefix, $principalUri]),
- CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI);
-
- if ($calendar !== null) {
- $this->calDavBackend->deleteCalendar(
- $calendar['id'],
- true // Because this wasn't deleted by a user
- );
- }
- }
-
- /**
- * @param $table
- * @param $backendId
- * @param $resourceId
- *
- * @return int
- */
- private function getIdForBackendAndResource(string $table,
- string $backendId,
- string $resourceId): int {
- $query = $this->dbConnection->getQueryBuilder();
- $query->select('id')
- ->from($table)
- ->where($query->expr()->eq('backend_id', $query->createNamedParameter($backendId)))
- ->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resourceId)));
- $result = $query->executeQuery();
-
- $id = (int) $result->fetchOne();
- $result->closeCursor();
- return $id;
+ $this->resourceManager->update();
+ $this->roomManager->update();
}
}
diff --git a/apps/dav/lib/BackgroundJob/UploadCleanup.php b/apps/dav/lib/BackgroundJob/UploadCleanup.php
index 59a28626ecd..230cde61578 100644
--- a/apps/dav/lib/BackgroundJob/UploadCleanup.php
+++ b/apps/dav/lib/BackgroundJob/UploadCleanup.php
@@ -10,7 +10,6 @@ namespace OCA\DAV\BackgroundJob;
use OC\User\NoUserException;
use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\BackgroundJob\IJob;
use OCP\BackgroundJob\IJobList;
use OCP\BackgroundJob\TimedJob;
use OCP\Files\File;
@@ -20,19 +19,17 @@ use OCP\Files\NotFoundException;
use Psr\Log\LoggerInterface;
class UploadCleanup extends TimedJob {
- private IRootFolder $rootFolder;
- private IJobList $jobList;
- private LoggerInterface $logger;
-
- public function __construct(ITimeFactory $time, IRootFolder $rootFolder, IJobList $jobList, LoggerInterface $logger) {
+ public function __construct(
+ ITimeFactory $time,
+ private IRootFolder $rootFolder,
+ private IJobList $jobList,
+ private LoggerInterface $logger,
+ ) {
parent::__construct($time);
- $this->rootFolder = $rootFolder;
- $this->jobList = $jobList;
- $this->logger = $logger;
// Run once a day
$this->setInterval(60 * 60 * 24);
- $this->setTimeSensitivity(IJob::TIME_INSENSITIVE);
+ $this->setTimeSensitivity(self::TIME_INSENSITIVE);
}
protected function run($argument) {
@@ -45,7 +42,7 @@ class UploadCleanup extends TimedJob {
/** @var Folder $uploads */
$uploads = $userRoot->get('uploads');
$uploadFolder = $uploads->get($folder);
- } catch (NotFoundException | NoUserException $e) {
+ } catch (NotFoundException|NoUserException $e) {
$this->jobList->remove(self::class, $argument);
return;
}
@@ -54,7 +51,7 @@ class UploadCleanup extends TimedJob {
$time = $this->time->getTime() - 60 * 60 * 24;
if (!($uploadFolder instanceof Folder)) {
- $this->logger->error("Found a file inside the uploads folder. Uid: " . $uid . ' folder: ' . $folder);
+ $this->logger->error('Found a file inside the uploads folder. Uid: ' . $uid . ' folder: ' . $folder);
if ($uploadFolder->getMTime() < $time) {
$uploadFolder->delete();
}
diff --git a/apps/dav/lib/BackgroundJob/UserStatusAutomation.php b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php
index e17fa604ab9..027b3349802 100644
--- a/apps/dav/lib/BackgroundJob/UserStatusAutomation.php
+++ b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php
@@ -28,18 +28,21 @@ use Sabre\VObject\Reader;
use Sabre\VObject\Recur\RRuleIterator;
class UserStatusAutomation extends TimedJob {
- public function __construct(private ITimeFactory $timeFactory,
+ public function __construct(
+ private ITimeFactory $timeFactory,
private IDBConnection $connection,
private IJobList $jobList,
private LoggerInterface $logger,
private IManager $manager,
private IConfig $config,
private IAvailabilityCoordinator $coordinator,
- private IUserManager $userManager) {
+ private IUserManager $userManager,
+ ) {
parent::__construct($timeFactory);
- // Interval 0 might look weird, but the last_checked is always moved
- // to the next time we need this and then it's 0 seconds ago.
+ // interval = 0 might look odd, but it's intentional. last_run is set to
+ // the user's next available time, so the job runs immediately when
+ // that time comes.
$this->setInterval(0);
}
@@ -55,14 +58,14 @@ class UserStatusAutomation extends TimedJob {
$userId = $argument['userId'];
$user = $this->userManager->get($userId);
- if($user === null) {
+ if ($user === null) {
return;
}
$ooo = $this->coordinator->getCurrentOutOfOfficeData($user);
$continue = $this->processOutOfOfficeData($user, $ooo);
- if($continue === false) {
+ if ($continue === false) {
return;
}
@@ -196,20 +199,18 @@ class UserStatusAutomation extends TimedJob {
return;
}
- if(!$hasDndForOfficeHours) {
+ if (!$hasDndForOfficeHours) {
// Office hours are not set to DND, so there is nothing to do.
return;
}
- $this->logger->debug('User is currently NOT available, reverting call status if applicable and then setting DND');
- // The DND status automation is more important than the "Away - In call" so we also restore that one if it exists.
- $this->manager->revertUserStatus($userId, IUserStatus::MESSAGE_CALL, IUserStatus::AWAY);
+ $this->logger->debug('User is currently NOT available, reverting call and meeting status if applicable and then setting DND');
$this->manager->setUserStatus($userId, IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true);
$this->logger->debug('User status automation ran');
}
private function processOutOfOfficeData(IUser $user, ?IOutOfOfficeData $ooo): bool {
- if(empty($ooo)) {
+ if (empty($ooo)) {
// Reset the user status if the absence doesn't exist
$this->logger->debug('User has no OOO period in effect, reverting DND status if applicable');
$this->manager->revertUserStatus($user->getUID(), IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND);
@@ -217,12 +218,12 @@ class UserStatusAutomation extends TimedJob {
return true;
}
- if(!$this->coordinator->isInEffect($ooo)) {
+ if (!$this->coordinator->isInEffect($ooo)) {
// Reset the user status if the absence is (no longer) in effect
$this->logger->debug('User has no OOO period in effect, reverting DND status if applicable');
$this->manager->revertUserStatus($user->getUID(), IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND);
- if($ooo->getStartDate() > $this->time->getTime()) {
+ if ($ooo->getStartDate() > $this->time->getTime()) {
// Set the next run to take place at the start of the ooo period if it is in the future
// This might be overwritten if there is an availability setting, but we can't determine
// if this is the case here
@@ -232,10 +233,8 @@ class UserStatusAutomation extends TimedJob {
}
$this->logger->debug('User is currently in an OOO period, reverting other automated status and setting OOO DND status');
- // Revert both a possible 'CALL - away' and 'office hours - DND' status
- $this->manager->revertUserStatus($user->getUID(), IUserStatus::MESSAGE_CALL, IUserStatus::DND);
- $this->manager->revertUserStatus($user->getUID(), IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND);
$this->manager->setUserStatus($user->getUID(), IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND, true, $ooo->getShortMessage());
+
// Run at the end of an ooo period to return to availability / regular user status
// If it's overwritten by a custom status in the meantime, there's nothing we can do about it
$this->setLastRunToNextToggleTime($user->getUID(), $ooo->getEndDate());