Passed
Pull Request — master (#182)
by Arman
03:14
created

MailerAdapterTrait::updateDebugBar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.5
13
 */
14
15
namespace Quantum\Libraries\Mailer\Adapters;
16
17
use Quantum\Libraries\Mailer\MailerInterface;
18
use Quantum\Libraries\Mailer\MailerException;
19
use Quantum\Exceptions\DiException;
20
use Quantum\Debugger\Debugger;
21
use ReflectionException;
22
use Psr\Log\LogLevel;
23
use Exception;
24
25
/**
26
 * trait MailerAdapterTrait
27
 * @package Quantum\Libraries\Mailer
28
 */
29
trait MailerAdapterTrait
30
{
31
32
    /**
33
     * From address and name
34
     * @var array
35
     */
36
    private $from = [];
37
38
    /**
39
     * To addresses
40
     * @var array
41
     */
42
    private $addresses = [];
43
44
    /**
45
     * Email subject
46
     * @var string
47
     */
48
    private $subject = null;
49
50
    /**
51
     * Email body
52
     * @var string|array
53
     */
54
    private $message = null;
55
56
    /**
57
     * @var string
58
     */
59
    private static $messageId = null;
60
61
    /**
62
     * Template path
63
     * @var string
64
     */
65
    private $templatePath = null;
66
67
    /**
68
     * Sets the 'From' email and the name
69
     * @param string $email
70
     * @param string|null $name
71
     * @return MailerInterface
72
     */
73
    public function setFrom(string $email, ?string $name = null): MailerInterface
74
    {
75
        $this->from['email'] = $email;
76
        $this->from['name'] = $name;
77
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer...ters\MailerAdapterTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\MailerInterface.
Loading history...
78
    }
79
80
    /**
81
     * Gets 'From' email and the "name"
82
     * @return array
83
     */
84
    public function getFrom(): array
85
    {
86
        return $this->from;
87
    }
88
89
    /**
90
     * Sets 'To' addresses
91
     * @param string $email
92
     * @param string|null $name
93
     * @return MailerInterface
94
     */
95
    public function setAddress(string $email, ?string $name = null): MailerInterface
96
    {
97
        $this->addresses[] = [
98
            'email' => $email,
99
            'name' => $name
100
        ];
101
102
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer...ters\MailerAdapterTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\MailerInterface.
Loading history...
103
    }
104
105
    /**
106
     * Gets 'To' addresses
107
     * @return array
108
     */
109
    public function getAddresses(): array
110
    {
111
        return $this->addresses;
112
    }
113
114
    /**
115
     * Sets the subject
116
     * @param string|null $subject
117
     * @return MailerInterface
118
     */
119
    public function setSubject(?string $subject): MailerInterface
120
    {
121
        $this->subject = $subject;
122
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer...ters\MailerAdapterTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\MailerInterface.
Loading history...
123
    }
124
125
    /**
126
     * Gets the subject
127
     * @return string
128
     */
129
    public function getSubject(): ?string
130
    {
131
        return $this->subject;
132
    }
133
134
    /**
135
     * Sets the template
136
     * @param string $templatePath
137
     * @return MailerInterface
138
     */
139
    public function setTemplate(string $templatePath): MailerInterface
140
    {
141
        $this->templatePath = $templatePath;
142
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer...ters\MailerAdapterTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\MailerInterface.
Loading history...
143
    }
144
145
    /**
146
     * Gets the template
147
     * @return string|null
148
     */
149
    public function getTemplate(): ?string
150
    {
151
        return $this->templatePath;
152
    }
153
154
    /**
155
     * Sets the body
156
     * @param string|array $message
157
     * @return MailerInterface
158
     */
159
    public function setBody($message): MailerInterface
160
    {
161
        $this->message = $message;
162
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer...ters\MailerAdapterTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\MailerInterface.
Loading history...
163
    }
164
165
    /**
166
     * Gets the body
167
     * @return array|string|null
168
     */
169
    public function getBody()
170
    {
171
        return $this->message;
172
    }
173
174
    /**
175
     * @inheritDoc
176
     * @throws DiException
177
     * @throws ReflectionException
178
     * @throws Exception
179
     */
180
    public function send(): bool
181
    {
182
        $this->prepare();
0 ignored issues
show
Bug introduced by
It seems like prepare() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

182
        $this->/** @scrutinizer ignore-call */ 
183
               prepare();
Loading history...
183
184
        if (config()->get('mailer.mail_trap')) {
185
            $sent = $this->saveEmail();
0 ignored issues
show
Bug introduced by
It seems like saveEmail() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
            /** @scrutinizer ignore-call */ 
186
            $sent = $this->saveEmail();
Loading history...
186
        } else {
187
            $sent = $this->sendEmail();
0 ignored issues
show
Bug introduced by
It seems like sendEmail() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

187
            /** @scrutinizer ignore-call */ 
188
            $sent = $this->sendEmail();
Loading history...
188
        }
189
190
        $this->resetFields();
191
192
        if (__CLASS__ != __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ != __NAMESPACE__ . '\SmtpAdapter' is always true.
Loading history...
193
            if (!$sent) {
194
                $errors = $this->httpClient->getErrors();
195
196
                if (Debugger::getInstance()->isEnabled()) {
197
                    Debugger::getInstance()->addToStoreCell(Debugger::MAILS, LogLevel::WARNING, $errors);
198
                }
199
200
                throw MailerException::unableToSend(json_encode($errors, JSON_PRETTY_PRINT));
201
            }
202
        }
203
204
        return $sent;
205
    }
206
207
    /**
208
     * Gets the message ID
209
     * @return string
210
     * @throws Exception
211
     */
212
    public function getMessageId(): string
213
    {
214
        if (self::$messageId) {
215
            return self::$messageId;
216
        }
217
218
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
219
            preg_match('/<(.*?)@/', preg_quote($this->mailer->getLastMessageID()), $matches);
220
            self::$messageId = $matches[1];
221
        } else {
222
            self::$messageId = bin2hex(random_bytes(16));
223
        }
224
225
        return self::$messageId;
226
    }
227
228
    /**
229
     * Create message body from email template
230
     * @return string
231
     */
232
    private function createFromTemplate(): string
233
    {
234
        ob_start();
235
        ob_implicit_flush(0);
236
237
        if (is_array($this->message)) {
238
            extract($this->message, EXTR_OVERWRITE);
239
        }
240
241
        require $this->templatePath . '.php';
242
243
        return ob_get_clean();
244
    }
245
246
    /**
247
     * Gets the complete message
248
     * @return string
249
     * @throws Exception
250
     */
251
    private function getMessageContent(): string
252
    {
253
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
254
            return $this->mailer->getSentMIMEMessage();
255
        }
256
257
        return $this->generateMessage();
258
    }
259
260
    /**
261
     * Generates the message content
262
     * @return string
263
     * @throws Exception
264
     */
265
    private function generateMessage(): string
266
    {
267
        $message = 'Date: ' . date('D, j M Y H:i:s O') . PHP_EOL;
268
269
        $message .= 'To: ';
270
271
        foreach ($this->addresses as $address) {
272
            $message .= $address['name'] . ' <' . $address['email'] . '>' . PHP_EOL;
273
        }
274
275
        $message .= 'From: ' . $this->from['name'] . ' <' . $this->from['email'] . '>' . PHP_EOL;
276
277
        $message .= 'Subject: ' . $this->subject . PHP_EOL;
278
279
        $message .= 'Message-ID: <' . $this->getMessageId() . '@' . base_url() . '>' . PHP_EOL;
280
281
        $message .= 'X-Mailer: ' . $this->name . PHP_EOL;
282
283
        $message .= 'MIME-Version: 1.0' . PHP_EOL;
284
285
        $message .= 'Content-Type: text/html; charset=UTF-8' . PHP_EOL . PHP_EOL;
286
287
        $message .= $this->message . PHP_EOL;
0 ignored issues
show
Bug introduced by
Are you sure $this->message of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

287
        $message .= /** @scrutinizer ignore-type */ $this->message . PHP_EOL;
Loading history...
288
289
        return $message;
290
    }
291
292
    /**
293
     * Resets the fields
294
     */
295
    private function resetFields()
296
    {
297
        $this->from = [];
298
        $this->addresses = [];
299
        $this->subject = null;
300
        $this->message = null;
301
        $this->templatePath = null;
302
303
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
304
            $this->replyToAddresses = [];
305
            $this->ccAddresses = [];
306
            $this->bccAddresses = [];
307
            $this->attachments = [];
308
            $this->stringAttachments = [];
309
310
            $this->mailer->clearAddresses();
311
            $this->mailer->clearCCs();
312
            $this->mailer->clearBCCs();
313
            $this->mailer->clearReplyTos();
314
            $this->mailer->clearAllRecipients();
315
            $this->mailer->clearAttachments();
316
            $this->mailer->clearCustomHeaders();
317
        }
318
    }
319
}