EmailNotifications   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 28
dl 0
loc 59
ccs 32
cts 32
cp 1
rs 10
c 1
b 1
f 0
wmc 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A sendEmails() 0 14 3
A setEmailSent() 0 6 1
A setLang() 0 9 1
A getNotificationsToSend() 0 9 1
1
<?php declare(strict_types=1);
2
/**
3
 * @author Nicolas CARPi <[email protected]>
4
 * @copyright 2021 Nicolas CARPi
5
 * @see https://www.elabftw.net Official website
6
 * @license AGPL-3.0
7
 * @package elabftw
8
 */
9
10
namespace Elabftw\Services;
11
12
use function bindtextdomain;
13
use function count;
14
use function dirname;
15
use Elabftw\Elabftw\Db;
16
use Elabftw\Enums\Notifications;
17
use Elabftw\Factories\NotificationsFactory;
18
use Elabftw\Models\Users;
19
use PDO;
20
use function putenv;
21
use function setlocale;
22
use Symfony\Component\Mime\Address;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Mime\Address was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use function textdomain;
24
25
/**
26
 * Email notification system
27
 */
28
class EmailNotifications
29
{
30
    protected const BASE_SUBJECT = '[eLabFTW] ';
31
32
    protected Db $Db;
33
34 3
    public function __construct(protected Email $emailService)
35
    {
36 3
        $this->Db = Db::getConnection();
37
    }
38
39 2
    public function sendEmails(): int
40
    {
41 2
        $toSend = $this->getNotificationsToSend();
42 2
        foreach ($toSend as $notif) {
43 2
            $targetUser = new Users((int) $notif['userid']);
44 2
            $this->setLang($targetUser->userData['lang']);
45 2
            $to = new Address($targetUser->userData['email'], $targetUser->userData['fullname']);
46 2
            $Factory = new NotificationsFactory((int) $notif['category'], $notif['body']);
47 2
            $email = $Factory->getMailable()->getEmail();
48 2
            if ($this->emailService->sendEmail($to, self::BASE_SUBJECT . $email['subject'], $email['body'])) {
49 2
                $this->setEmailSent((int) $notif['id']);
50
            }
51
        }
52 2
        return count($toSend);
53
    }
54
55
    /**
56
     * set the lang to the one of the target user (see issue #2700)
57
     * @psalm-suppress UnusedFunctionCall
58
     */
59 3
    protected function setLang(string $lang = 'en_GB'): void
60
    {
61 3
        $locale = $lang . '.utf8';
62
        // configure gettext
63 3
        $domain = 'messages';
64 3
        putenv("LC_ALL=$locale");
65 3
        setlocale(LC_ALL, $locale);
66 3
        bindtextdomain($domain, dirname(__DIR__) . '/langs');
67 3
        textdomain($domain);
68
    }
69
70 2
    protected function getNotificationsToSend(): array
71
    {
72 2
        $sql='SELECT id, userid, category, body FROM notifications
73 2
            WHERE send_email = 1 AND email_sent = 0 AND (category <> :deadline OR (category = :deadline AND CAST(NOW() AS DATETIME) > CAST(DATE_ADD(CAST(JSON_EXTRACT(body, "$.deadline") AS DATETIME), INTERVAL - 30 MINUTE) AS DATETIME)))';
74 2
        $req = $this->Db->prepare($sql);
75 2
        $req->bindValue(':deadline', Notifications::StepDeadline->value, PDO::PARAM_INT);
76 2
        $this->Db->execute($req);
77
78 2
        return $req->fetchAll();
79
    }
80
81 2
    private function setEmailSent(int $id): bool
82
    {
83 2
        $sql = 'UPDATE notifications SET email_sent = 1, email_sent_at = NOW() WHERE id = :id';
84 2
        $req = $this->Db->prepare($sql);
85 2
        $req->bindParam(':id', $id, PDO::PARAM_INT);
86 2
        return $this->Db->execute($req);
87
    }
88
}
89