Skip to content

Commit b40833b

Browse files
committed
feat(activity): add bulk activity option
Signed-off-by: Anna Larch <anna@nextcloud.com>
1 parent e747500 commit b40833b

2 files changed

Lines changed: 128 additions & 2 deletions

File tree

lib/Consumer.php

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
*/
88
namespace OCA\Activity;
99

10+
use OCP\Activity\ActivitySettings;
11+
use OCP\Activity\IBulkConsumer;
1012
use OCP\Activity\IConsumer;
1113
use OCP\Activity\IEvent;
1214
use OCP\Activity\IManager;
15+
use OCP\Activity\ISetting;
16+
use Throwable;
1317

14-
class Consumer implements IConsumer {
18+
class Consumer implements IConsumer, IBulkConsumer {
1519

1620
public function __construct(
1721
protected Data $data,
@@ -29,7 +33,7 @@ public function __construct(
2933
* @return void
3034
*/
3135
#[\Override]
32-
public function receive(IEvent $event) {
36+
public function receive(IEvent $event): void {
3337
$selfAction = $event->getAffectedUser() === $event->getAuthor();
3438
$notificationSetting = $this->userSettings->getUserSetting($event->getAffectedUser(), 'notification', $event->getType());
3539
$emailSetting = $this->userSettings->getUserSetting($event->getAffectedUser(), 'email', $event->getType());
@@ -47,4 +51,58 @@ public function receive(IEvent $event) {
4751
$this->data->storeMail($event, $latestSend);
4852
}
4953
}
54+
55+
/**
56+
* Send an event to the notifications of a user
57+
*
58+
* @param IEvent $event
59+
* @throws Throwable
60+
*
61+
* @return void
62+
*/
63+
#[\Override]
64+
public function bulkReceive(IEvent $event, array $affectedUserIds, ISetting $setting): void {
65+
if (empty($affectedUserIds)) {
66+
return;
67+
}
68+
$activityIds = $this->data->bulkSend($event, $affectedUserIds);
69+
70+
if (empty($activityIds)) {
71+
return;
72+
}
73+
74+
$canChangeMail = $setting->canChangeMail();
75+
$canChangePush = false;
76+
if ($setting instanceof ActivitySettings && $setting->canChangeNotification() === true) {
77+
$canChangePush = true;
78+
}
79+
80+
if ($canChangePush === false && $canChangeMail === false) {
81+
return;
82+
}
83+
84+
foreach ($activityIds as $activityId => $affectedUser) {
85+
if ($event->getAuthor() === $affectedUser) {
86+
continue;
87+
}
88+
$event->setAffectedUser($affectedUser);
89+
if ($canChangePush === true) {
90+
$notificationSetting = $this->userSettings->getUserSetting($affectedUser, 'notification', $event->getType());
91+
}
92+
93+
if ($canChangeMail === true) {
94+
$emailSetting = $this->userSettings->getUserSetting($event->getAffectedUser(), 'email', $event->getType());
95+
$emailSetting = ($emailSetting) ? $this->userSettings->getUserSetting($event->getAffectedUser(), 'setting', 'batchtime') : false;
96+
}
97+
98+
if (isset($notificationSetting) && $notificationSetting === true) {
99+
$this->notificationGenerator->sendNotificationForEvent($event, $activityId, $notificationSetting);
100+
}
101+
102+
if (isset($emailSetting) && $emailSetting !== false) {
103+
$latestSend = $event->getTimestamp() + $emailSetting;
104+
$this->data->storeMail($event, $latestSend);
105+
}
106+
}
107+
}
50108
}

lib/Data.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
use OCP\Activity\IExtension;
1616
use OCP\Activity\IFilter;
1717
use OCP\Activity\IManager;
18+
use OCP\DB\Exception;
1819
use OCP\DB\QueryBuilder\IQueryBuilder;
1920
use OCP\IConfig;
2021
use OCP\IDBConnection;
2122
use Psr\Log\LoggerInterface;
23+
use Throwable;
2224

2325
/**
2426
* @brief Class for managing the data in the activities
@@ -91,6 +93,72 @@ public function send(IEvent $event): int {
9193
return $this->insertActivity->getLastInsertId();
9294
}
9395

96+
/**
97+
* Bulk sends an event into the activity stream
98+
* for a batch of users that are affected by the same event
99+
* (ex. Call Started, Call ended)
100+
*
101+
* @param IEvent $event
102+
* @param array $affectedUsers
103+
* @return array<int, string>
104+
* @throws Exception
105+
*/
106+
public function bulkSend(IEvent $event, array $affectedUsers): array {
107+
$this->connection->beginTransaction();
108+
109+
$activityIds = [];
110+
try {
111+
$qb = $this->connection->getQueryBuilder();
112+
$qb->insert('activity')
113+
->values([
114+
'app' => $this->insertActivity->createParameter('app'),
115+
'subject' => $this->insertActivity->createParameter('subject'),
116+
'subjectparams' => $this->insertActivity->createParameter('subjectparams'),
117+
'message' => $this->insertActivity->createParameter('message'),
118+
'messageparams' => $this->insertActivity->createParameter('messageparams'),
119+
'file' => $this->insertActivity->createParameter('object_name'),
120+
'link' => $this->insertActivity->createParameter('link'),
121+
'user' => $this->insertActivity->createParameter('user'),
122+
'affecteduser' => $this->insertActivity->createParameter('affecteduser'),
123+
'timestamp' => $this->insertActivity->createParameter('timestamp'),
124+
'priority' => $this->insertActivity->createParameter('priority'),
125+
'type' => $this->insertActivity->createParameter('type'),
126+
'object_type' => $this->insertActivity->createParameter('object_type'),
127+
'object_id' => $this->insertActivity->createParameter('object_id'),
128+
]);
129+
130+
$qb->setParameters([
131+
'app' => $event->getApp(),
132+
'type' => $event->getType(),
133+
'user' => $event->getAuthor(),
134+
'timestamp' => $event->getTimestamp(),
135+
'subject' => $event->getSubject(),
136+
'subjectparams' => json_encode($event->getSubjectParameters()),
137+
'message' => $event->getMessage(),
138+
'messageparams' => json_encode($event->getMessageParameters()),
139+
'priority' => IExtension::PRIORITY_MEDIUM,
140+
'object_type' => $event->getObjectType(),
141+
'object_id' => $event->getObjectId(),
142+
'object_name' => $event->getObjectName(),
143+
'link' => $event->getLink(),
144+
]);
145+
146+
foreach ($affectedUsers as $affectedUser) {
147+
$qb->setParameter('affecteduser', $affectedUser);
148+
$qb->executeStatement();
149+
$activityIds[$qb->getLastInsertId()] = (string)$affectedUser;
150+
}
151+
152+
$this->connection->commit();
153+
} catch (Throwable) {
154+
// Make sure to always roll back, otherwise the outer code runs in a failed transaction
155+
$this->connection->rollBack();
156+
return [];
157+
}
158+
159+
return $activityIds;
160+
}
161+
94162
/**
95163
* Send an event as email
96164
*

0 commit comments

Comments
 (0)