diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2020-07-09 12:33:04 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-09 12:33:04 +0300 |
commit | ddba5ec6923e8cdf8be22de3fdb1fcac1ef47bd9 (patch) | |
tree | 654ba0fbc5f8b1c410b7b3ed53c7856a13ef1ee8 | |
parent | d38c5bf17d29a19503ce70cbee7d89de2cdc3f8a (diff) | |
parent | d54d5db30856bd6670a83c880dbe94ffbbf5be0b (diff) |
Merge pull request #651 from nextcloud/feature/noid/allow-to-group-push-sending-for-a-whilev19.0.1RC1
[stable19] Allow to group push notifications via an event
-rw-r--r-- | lib/App.php | 18 | ||||
-rw-r--r-- | lib/AppInfo/Application.php | 20 | ||||
-rw-r--r-- | lib/Push.php | 41 |
3 files changed, 68 insertions, 11 deletions
diff --git a/lib/App.php b/lib/App.php index 4744bba..248255f 100644 --- a/lib/App.php +++ b/lib/App.php @@ -50,12 +50,17 @@ class App implements IApp { public function notify(INotification $notification): void { $notificationId = $this->handler->add($notification); + $shouldFlush = $this->push->deferPayloads(); try { $notificationToPush = $this->handler->getById($notificationId, $notification->getUser()); $this->push->pushToDevice($notificationId, $notificationToPush); } catch (NotificationNotFoundException $e) { throw new \InvalidArgumentException('Error while preparing push notification'); } + + if ($shouldFlush) { + $this->push->flushPayloads(); + } } /** @@ -74,10 +79,23 @@ class App implements IApp { public function markProcessed(INotification $notification): void { $deleted = $this->handler->delete($notification); + $shouldFlush = $this->push->deferPayloads(); foreach ($deleted as $user => $notifications) { foreach ($notifications as $notificationId) { $this->push->pushDeleteToDevice($user, $notificationId); } } + + if ($shouldFlush) { + $this->push->flushPayloads(); + } + } + + public function defer(): void { + $this->push->deferPayloads(); + } + + public function flush(): void { + $this->push->flushPayloads(); } } diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 6a9de02..517827b 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -26,7 +26,10 @@ use OCA\Notifications\App; use OCA\Notifications\Capabilities; use OCA\Notifications\Handler; use OCA\Notifications\Notifier\AdminNotifications; +use OCA\Notifications\Push; use OCP\AppFramework\IAppContainer; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Notification\IApp; use OCP\Util; class Application extends \OCP\AppFramework\App { @@ -44,6 +47,7 @@ class Application extends \OCP\AppFramework\App { public function register(): void { $this->registerNotificationApp(); + $this->registerTalkDeferPushing(); $this->registerAdminNotifications(); $this->registerUserInterface(); $this->registerUserDeleteHook(); @@ -77,6 +81,22 @@ class Application extends \OCP\AppFramework\App { } } + protected function registerTalkDeferPushing(): void { + /** @var IEventDispatcher $dispatcher */ + $dispatcher = $this->getContainer()->getServer()->query(IEventDispatcher::class); + + $dispatcher->addListener(IApp::class . '::defer', function() { + /** @var App $app */ + $app = $this->getContainer()->query(App::class); + $app->defer(); + }); + $dispatcher->addListener(IApp::class . '::flush', function() { + /** @var App $app */ + $app = $this->getContainer()->query(App::class); + $app->flush(); + }); + } + protected function registerUserDeleteHook(): void { Util::connectHook('OC_User', 'post_deleteUser', $this, 'deleteUser'); } diff --git a/lib/Push.php b/lib/Push.php index 8e7c00e..67241e0 100644 --- a/lib/Push.php +++ b/lib/Push.php @@ -61,6 +61,10 @@ class Push { protected $log; /** @var OutputInterface */ protected $output; + /** @var array */ + protected $payloadsToSend = []; + /** @var bool */ + protected $deferPayloads = false; public function __construct(IDBConnection $connection, INotificationManager $notificationManager, @@ -92,6 +96,17 @@ class Push { } } + public function deferPayloads(): bool { + $shouldFlush = !$this->deferPayloads; + $this->deferPayloads = true; + return $shouldFlush; + } + + public function flushPayloads(): void { + $this->deferPayloads = false; + $this->sendNotificationsToProxies(); + } + public function pushToDevice(int $id, INotification $notification, ?OutputInterface $output = null): void { $user = $this->userManager->get($notification->getUser()); if (!($user instanceof IUser)) { @@ -157,7 +172,6 @@ class Push { // We don't push to devices that are older than 60 days $maxAge = time() - 60 * 24 * 60 * 60; - $pushNotifications = []; foreach ($devices as $device) { $this->printInfo(''); $this->printInfo('Device token:' . $device['token']); @@ -171,17 +185,19 @@ class Push { $payload = json_encode($this->encryptAndSign($userKey, $device, $id, $notification, $isTalkNotification)); $proxyServer = rtrim($device['proxyserver'], '/'); - if (!isset($pushNotifications[$proxyServer])) { - $pushNotifications[$proxyServer] = []; + if (!isset($this->payloadsToSend[$proxyServer])) { + $this->payloadsToSend[$proxyServer] = []; } - $pushNotifications[$proxyServer][] = $payload; + $this->payloadsToSend[$proxyServer][] = $payload; } catch (\InvalidArgumentException $e) { // Failed to encrypt message for device: public key is invalid $this->deletePushToken($device['token']); } } - $this->sendNotificationsToProxies($pushNotifications); + if (!$this->deferPayloads) { + $this->sendNotificationsToProxies(); + } } public function pushDeleteToDevice(string $userId, int $notificationId): void { @@ -199,7 +215,6 @@ class Push { $maxAge = time() - 60 * 24 * 60 * 60; $userKey = $this->keyManager->getKey($user); - $pushNotifications = []; foreach ($devices as $device) { if (!$this->validateToken($device['token'], $maxAge)) { // Token does not exist anymore @@ -210,20 +225,24 @@ class Push { $payload = json_encode($this->encryptAndSignDelete($userKey, $device, $notificationId)); $proxyServer = rtrim($device['proxyserver'], '/'); - if (!isset($pushNotifications[$proxyServer])) { - $pushNotifications[$proxyServer] = []; + if (!isset($this->payloadsToSend[$proxyServer])) { + $this->payloadsToSend[$proxyServer] = []; } - $pushNotifications[$proxyServer][] = $payload; + $this->payloadsToSend[$proxyServer][] = $payload; } catch (\InvalidArgumentException $e) { // Failed to encrypt message for device: public key is invalid $this->deletePushToken($device['token']); } } - $this->sendNotificationsToProxies($pushNotifications); + if (!$this->deferPayloads) { + $this->sendNotificationsToProxies(); + } } - protected function sendNotificationsToProxies(array $pushNotifications): void { + protected function sendNotificationsToProxies(): void { + $pushNotifications = $this->payloadsToSend; + $this->payloadsToSend = []; if (empty($pushNotifications)) { return; } |