Passed
Push — noreply ( b9bebf )
by Angel Fernando Quiroz
13:27
created

MailHelper::send()   F

Complexity

Conditions 17
Paths 1609

Size

Total Lines 95
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 48
nc 1609
nop 11
dl 0
loc 95
rs 1.0499
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Helpers;
8
9
use Chamilo\CoreBundle\Settings\SettingsManager;
10
use Exception;
11
use Notification;
12
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
13
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
14
use Symfony\Component\Mailer\MailerInterface;
15
use Symfony\Component\Mime\Address;
16
use Symfony\Component\Mime\BodyRendererInterface;
17
use Symfony\Component\Mime\Part\DataPart;
18
use Symfony\Component\Validator\Constraints as Assert;
19
use Symfony\Component\Validator\Validator\ValidatorInterface;
20
21
final class MailHelper
22
{
23
    public function __construct(
24
        private readonly MailerInterface $mailer,
25
        private readonly BodyRendererInterface $bodyRenderer,
26
        private readonly ThemeHelper $themeHelper,
27
        private readonly ValidatorInterface $validator,
28
        private readonly SettingsManager $settingsManager,
29
    ) {}
30
31
    private function setNoreplyAndFromAddress(
32
        TemplatedEmail $email,
33
        array $sender,
34
        array $replyToAddress = []
35
    ): void {
36
        $emailConstraint = new Assert\Email();
37
38
        // Default values
39
        $notification = new Notification();
40
        $defaultSenderName = $notification->getDefaultPlatformSenderName();
41
        $defaultSenderEmail = $notification->getDefaultPlatformSenderEmail();
42
43
        // If the parameter is set, don't use the admin.
44
        $senderName = !empty($sender['name']) ? $sender['name'] : $defaultSenderName;
45
        $senderEmail = !empty($sender['email']) ? $sender['email'] : $defaultSenderEmail;
46
47
        // Send errors to the platform admin
48
        $adminEmail = $this->settingsManager->getSetting('admin.administrator_email');
49
50
        $adminEmailValidation = $this->validator->validate($adminEmail, $emailConstraint);
51
52
        if (!empty($adminEmail) && 0 === $adminEmailValidation->count()) {
53
            $email
54
                ->getHeaders()
55
                ->addIdHeader('Errors-To', $adminEmail)
56
            ;
57
        }
58
59
        // Reply to first
60
        if (!empty($replyToAddress)) {
61
            $replyToEmailValidation = $this->validator->validate($replyToAddress['mail'], $emailConstraint);
62
63
            if (0 === $replyToEmailValidation->count()) {
64
                $email->addReplyTo(new Address($replyToAddress['mail'], $replyToAddress['name']));
65
            }
66
        }
67
68
        $email->from(new Address($senderEmail, $senderName));
69
    }
70
71
    public function send(
72
        string $recipientName,
73
        string $recipientEmail,
74
        string $subject,
75
        string $body,
76
        ?string $senderName = null,
77
        ?string $senderEmail = null,
78
        array $extra_headers = [],
79
        array $data_file = [],
80
        bool $embeddedImage = false,
81
        array $additionalParameters = [],
82
        ?string $sendErrorTo = null,
83
    ): bool {
84
        if (!api_valid_email($recipientEmail)) {
85
            return false;
86
        }
87
88
        $templatedEmail = new TemplatedEmail();
89
90
        $this->setNoreplyAndFromAddress(
91
            $templatedEmail,
92
            ['name' => $senderName, 'email' => $senderEmail],
93
            !empty($extra_headers['reply_to']) ? $extra_headers['reply_to'] : []
94
        );
95
96
        if ($sendErrorTo) {
97
            $templatedEmail
98
                ->getHeaders()
99
                ->addIdHeader('Errors-To', $sendErrorTo)
100
            ;
101
        }
102
103
        // Reply to first
104
        $replyToName = '';
105
        $replyToEmail = '';
106
        if (isset($extra_headers['reply_to'])) {
107
            $replyToEmail = $extra_headers['reply_to']['mail'];
108
            $replyToName = $extra_headers['reply_to']['name'];
109
        }
110
111
        try {
112
            $templatedEmail->subject($subject);
113
114
            $list = api_get_setting('announcement.send_all_emails_to', true);
115
116
            if (!empty($list) && isset($list['emails'])) {
117
                foreach ($list['emails'] as $email) {
118
                    $templatedEmail->cc($email);
119
                }
120
            }
121
122
            // Attachment
123
            if (!empty($data_file)) {
124
                foreach ($data_file as $file_attach) {
125
                    if (!empty($file_attach['path']) && !empty($file_attach['filename'])) {
126
                        $templatedEmail->attachFromPath($file_attach['path'], $file_attach['filename']);
127
                    }
128
129
                    if (!empty($file_attach['stream']) && !empty($file_attach['filename'])) {
130
                        $templatedEmail->addPart(new DataPart($file_attach['stream'], $file_attach['filename']));
131
                    }
132
                }
133
            }
134
135
            $automaticEmailText = '<br />'.get_lang('This is an automatic email message. Please do not reply to it.');
136
137
            $params = [
138
                'mail_header_style' => api_get_setting('mail.mail_header_style'),
139
                'mail_content_style' => api_get_setting('mail.mail_content_style'),
140
                'link' => $additionalParameters['link'] ?? '',
141
                'automatic_email_text' => $automaticEmailText,
142
                'content' => $body,
143
            ];
144
145
            if (!empty($recipientEmail)) {
146
                $templatedEmail->to(new Address($recipientEmail, $recipientName));
147
            }
148
149
            if (!empty($replyToEmail)) {
150
                $templatedEmail->replyTo(new Address($replyToEmail, $replyToName));
151
            }
152
153
            $templatedEmail
154
                ->htmlTemplate('@ChamiloCore/Mailer/Default/default.html.twig')
155
                ->context($params)
156
            ;
157
158
            $this->bodyRenderer->render($templatedEmail);
159
            $this->mailer->send($templatedEmail);
160
161
            return true;
162
        } catch (Exception|TransportExceptionInterface $e) {
163
            error_log($e->getMessage());
164
165
            return false;
166
        }
167
    }
168
}
169