• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 20472217448

23 Dec 2025 09:41PM UTC coverage: 42.655%. First build
20472217448

Pull #6242

github

web-flow
Merge 5e8e97740 into 4f1a71d46
Pull Request #6242: feat: envelope support

301 of 1003 new or added lines in 21 files covered. (30.01%)

6159 of 14439 relevant lines covered (42.66%)

4.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.79
/lib/Listener/MailNotifyListener.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8

9
namespace OCA\Libresign\Listener;
10

11
use OCA\Libresign\Db\File as FileEntity;
12
use OCA\Libresign\Db\SignRequest;
13
use OCA\Libresign\Db\SignRequestMapper;
14
use OCA\Libresign\Events\SendSignNotificationEvent;
15
use OCA\Libresign\Events\SignedEvent;
16
use OCA\Libresign\Events\SignRequestCanceledEvent;
17
use OCA\Libresign\Service\IdentifyMethod\IdentifyService;
18
use OCA\Libresign\Service\IdentifyMethod\IIdentifyMethod;
19
use OCA\Libresign\Service\MailService;
20
use OCP\EventDispatcher\Event;
21
use OCP\EventDispatcher\IEventListener;
22
use OCP\IUser;
23
use OCP\IUserManager;
24
use OCP\IUserSession;
25
use Psr\Log\LoggerInterface;
26

27
/** @template-implements IEventListener<Event> */
28
class MailNotifyListener implements IEventListener {
29
        public function __construct(
30
                protected IUserSession $userSession,
31
                protected IUserManager $userManager,
32
                protected IdentifyService $identifyService,
33
                protected MailService $mail,
34
                private SignRequestMapper $signRequestMapper,
35
                private LoggerInterface $logger,
36
        ) {
37
        }
13✔
38

39
        #[\Override]
40
        public function handle(Event $event): void {
41
                /** @var SendSignNotificationEvent|SignedEvent|SignRequestCanceledEvent $event */
42
                match ($event::class) {
13✔
43
                        SendSignNotificationEvent::class => $this->sendSignMailNotification(
13✔
44
                                $event->getSignRequest(),
13✔
45
                                $event->getIdentifyMethod(),
13✔
46
                        ),
13✔
47
                        SignedEvent::class => $this->sendSignedMailNotification(
×
48
                                $event->getSignRequest(),
×
49
                                $event->getIdentifyMethod(),
×
50
                                $event->getLibreSignFile(),
×
51
                                $event->getUser(),
×
52
                        ),
×
53
                        SignRequestCanceledEvent::class => $this->sendCanceledMailNotification(
2✔
54
                                $event->getSignRequest(),
2✔
55
                                $event->getIdentifyMethod(),
2✔
56
                                $event->getLibreSignFile(),
2✔
57
                        ),
2✔
58
                };
13✔
59
        }
60

61
        protected function sendSignMailNotification(
62
                SignRequest $signRequest,
63
                IIdentifyMethod $identifyMethod,
64
        ): void {
65
                try {
66
                        if ($identifyMethod->getEntity()->isDeletedAccount()) {
13✔
67
                                return;
×
68
                        }
69
                        $email = '';
13✔
70
                        if ($identifyMethod->getName() === 'account') {
13✔
71
                                $userId = $identifyMethod->getEntity()->getIdentifierValue();
2✔
72
                                $email = $this->userManager
2✔
73
                                        ->get($userId)
2✔
74
                                        ->getEMailAddress();
2✔
75
                        } elseif ($identifyMethod->getName() === 'email') {
11✔
76
                                $email = $identifyMethod->getEntity()->getIdentifierValue();
11✔
77
                        }
78
                        if (empty($email)) {
13✔
79
                                return;
×
80
                        }
81

82
                        $users = $this->userManager->getByEmail($email);
13✔
83
                        if (count($users) === 1) {
13✔
84
                                $userId = $users[0]->getUID();
9✔
85
                                if ($this->isNotificationDisabledAtActivity($userId, SendSignNotificationEvent::FILE_TO_SIGN)) {
9✔
86
                                        return;
×
87
                                }
88
                        }
89

90
                        $isFirstNotification = $this->signRequestMapper->incrementNotificationCounter($signRequest, 'mail');
13✔
91
                        if ($isFirstNotification) {
13✔
92
                                $this->mail->notifyUnsignedUser($signRequest, $email, $signRequest->getDescription());
13✔
93
                                return;
13✔
94
                        }
95
                        $this->mail->notifySignDataUpdated($signRequest, $email, $signRequest->getDescription());
×
96
                } catch (\InvalidArgumentException $e) {
×
97
                        $this->logger->error($e->getMessage(), ['exception' => $e]);
×
98
                        return;
×
99
                }
100
        }
101

102
        protected function sendSignedMailNotification(
103
                SignRequest $signRequest,
104
                IIdentifyMethod $identifyMethod,
105
                FileEntity $libreSignFile,
106
                IUser $user,
107
        ): void {
108
                try {
NEW
109
                        if ($libreSignFile->hasParent()) {
×
NEW
110
                                return;
×
111
                        }
112
                        if ($identifyMethod->getEntity()->isDeletedAccount()) {
×
113
                                return;
×
114
                        }
115
                        if ($this->isNotificationDisabledAtActivity($libreSignFile->getUserId(), SignedEvent::FILE_SIGNED)) {
×
116
                                return;
×
117
                        }
118

119
                        $email = $user->getEMailAddress();
×
120

121
                        if (empty($email)) {
×
122
                                return;
×
123
                        }
124

125
                        $this->mail->notifySignedUser($signRequest, $email, $libreSignFile, $user->getDisplayName());
×
126

127
                } catch (\InvalidArgumentException $e) {
×
128
                        $this->logger->error($e->getMessage(), ['exception' => $e]);
×
129
                        return;
×
130
                }
131
        }
132

133
        protected function sendCanceledMailNotification(
134
                SignRequest $signRequest,
135
                IIdentifyMethod $identifyMethod,
136
                FileEntity $libreSignFile,
137
        ): void {
138
                try {
139
                        if ($identifyMethod->getEntity()->isDeletedAccount()) {
2✔
140
                                return;
×
141
                        }
142

143
                        $email = '';
2✔
144
                        if ($identifyMethod->getName() === 'account') {
2✔
145
                                $userId = $identifyMethod->getEntity()->getIdentifierValue();
×
146
                                $user = $this->userManager->get($userId);
×
147
                                if ($user) {
×
148
                                        $email = $user->getEMailAddress();
×
149
                                }
150
                        } elseif ($identifyMethod->getName() === 'email') {
2✔
151
                                $email = $identifyMethod->getEntity()->getIdentifierValue();
2✔
152
                        }
153

154
                        if (empty($email)) {
2✔
155
                                return;
×
156
                        }
157

158
                        $users = $this->userManager->getByEmail($email);
2✔
159
                        if (count($users) === 1) {
2✔
160
                                $userId = $users[0]->getUID();
1✔
161
                                if ($this->isNotificationDisabledAtActivity($userId, SignRequestCanceledEvent::SIGN_REQUEST_CANCELED)) {
1✔
162
                                        return;
×
163
                                }
164
                        }
165

166
                        $this->mail->notifyCanceledRequest($signRequest, $email, $libreSignFile);
2✔
167

168
                } catch (\InvalidArgumentException $e) {
×
169
                        $this->logger->error($e->getMessage(), ['exception' => $e]);
×
170
                        return;
×
171
                }
172
        }
173

174
        private function isNotificationDisabledAtActivity(string $userId, string $type): bool {
175
                if (!class_exists(\OCA\Activity\UserSettings::class)) {
9✔
176
                        return false;
9✔
177
                }
178
                $activityUserSettings = \OCP\Server::get(\OCA\Activity\UserSettings::class);
×
179
                if ($activityUserSettings) {
×
180
                        $manager = \OCP\Server::get(\OCP\Activity\IManager::class);
×
181
                        try {
182
                                $manager->getSettingById($type);
×
183
                        } catch (\Exception $e) {
×
184
                                return false;
×
185
                        }
186

187
                        $adminSetting = $activityUserSettings->getAdminSetting('email', $type);
×
188
                        if (!$adminSetting) {
×
189
                                return true;
×
190
                        }
191
                        $notificationSetting = $activityUserSettings->getUserSetting(
×
192
                                $userId,
×
193
                                'email',
×
194
                                $type
×
195
                        );
×
196
                        if (!$notificationSetting) {
×
197
                                return true;
×
198
                        }
199
                }
200
                return false;
×
201
        }
202
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc