GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

EmailNotifications::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @author Nicolas CARPi <[email protected]>
5
 * @copyright 2021 Nicolas CARPi
6
 * @see https://www.elabftw.net Official website
7
 * @license AGPL-3.0
8
 * @package elabftw
9
 */
10
11
declare(strict_types=1);
12
13
namespace Elabftw\Services;
14
15
use Elabftw\AuditEvent\OnboardingEmailSent;
16
use Elabftw\Elabftw\Db;
0 ignored issues
show
Bug introduced by
The type Elabftw\Elabftw\Db 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...
17
use Elabftw\Enums\Notifications;
18
use Elabftw\Factories\NotificationsFactory;
19
use Elabftw\Models\Notifications\StepDeadline;
0 ignored issues
show
Bug introduced by
The type Elabftw\Models\Notifications\StepDeadline 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...
20
use Elabftw\Models\AuditLogs;
0 ignored issues
show
Bug introduced by
The type Elabftw\Models\AuditLogs 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...
21
use Elabftw\Models\Users;
22
use PDO;
23
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...
24
25
use function bindtextdomain;
26
use function count;
27
use function dirname;
28
use function putenv;
29
use function setlocale;
30
use function textdomain;
31
32
/**
33
 * Email notification system
34 3
 */
35
class EmailNotifications
36 3
{
37
    protected const BASE_SUBJECT = '[eLabFTW] ';
38
39 2
    protected Db $Db;
40
41 2
    public function __construct(protected Email $emailService)
42 2
    {
43 2
        $this->Db = Db::getConnection();
44 2
    }
45 2
46 2
    public function sendEmails(): int
47 2
    {
48 2
        $toSend = $this->getNotificationsToSend();
49 2
        foreach ($toSend as $notif) {
50
            $targetUser = new Users($notif['userid']);
51
            $this->setLang($targetUser->userData['lang']);
52 2
            $to = new Address($targetUser->userData['email'], $targetUser->userData['fullname']);
53
            $Factory = new NotificationsFactory($notif['category'], $notif['body']);
54
            $email = $Factory->getMailable()->getEmail();
55
            $cc = array_key_exists('cc', $email) ? $email['cc'] : null;
56
            $htmlBody = array_key_exists('htmlBody', $email) ? (string) $email['htmlBody'] : null;
57
            $replyTo = null;
58
            if (isset($email['replyTo'])) {
59 3
                $replyTo = new Address($email['replyTo']);
60
            }
61 3
            $isEmailSent = $this->emailService->sendEmail(
62
                $to,
63 3
                self::BASE_SUBJECT . $email['subject'],
64 3
                $email['body'],
65 3
                $cc,
66 3
                $htmlBody,
67 3
                replyTo: $replyTo,
68
            );
69
            if ($isEmailSent) {
70 2
                $this->setEmailSent($notif['id']);
71
                if (Notifications::tryFrom($notif['category']) === Notifications::OnboardingEmail) {
72 2
                    AuditLogs::create(new OnboardingEmailSent($email['team'], $notif['userid'], $email['forAdmin']));
73 2
                }
74 2
            }
75 2
        }
76 2
        return count($toSend);
77
    }
78 2
79
    /**
80
     * set the lang to the one of the target user (see issue #2700)
81 2
     * @psalm-suppress UnusedFunctionCall
82
     */
83 2
    protected function setLang(string $lang = 'en_GB'): void
84 2
    {
85 2
        $locale = $lang . '.utf8';
86 2
        // configure gettext
87
        $domain = 'messages';
88
        putenv("LC_ALL=$locale");
89
        setlocale(LC_ALL, $locale);
90
        bindtextdomain($domain, dirname(__DIR__) . '/langs');
91
        textdomain($domain);
92
    }
93
94
    protected function getNotificationsToSend(): array
95
    {
96
        $sql = 'SELECT id, userid, category, body
97
            FROM notifications
98
            WHERE send_email = 1
99
                AND email_sent = 0
100
                AND (category <> :step_deadline
101
                    OR (category = :step_deadline AND DATE_ADD(NOW(), INTERVAL :notif_lead_time MINUTE) >= body->>"$.deadline"))';
102
        $req = $this->Db->prepare($sql);
103
        $req->bindValue(':step_deadline', Notifications::StepDeadline->value, PDO::PARAM_INT);
104
        $req->bindValue(':notif_lead_time', StepDeadline::NOTIFLEADTIME, PDO::PARAM_INT);
105
        $this->Db->execute($req);
106
107
        return $req->fetchAll();
108
    }
109
110
    private function setEmailSent(int $id): bool
111
    {
112
        $sql = 'UPDATE notifications SET email_sent = 1, email_sent_at = NOW() WHERE id = :id';
113
        $req = $this->Db->prepare($sql);
114
        $req->bindParam(':id', $id, PDO::PARAM_INT);
115
        return $this->Db->execute($req);
116
    }
117
}
118