Passed
Pull Request — master (#134)
by Arman
03:44
created

MailerAdapterTrait::setAddress()   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 2
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.0
13
 */
14
15
namespace Quantum\Libraries\Mailer\Adapters;
16
17
use Quantum\Libraries\Mailer\MailerInterface;
18
use Quantum\Exceptions\DiException;
19
use Quantum\Debugger\Debugger;
20
use Quantum\Logger\FileLogger;
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
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 string|array
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 && config()->get('debug')) {
194
                $this->updateDebugBar($this->httpClient->getErrors());
195
            }
196
        }
197
198
        return $sent;
199
    }
200
201
    /**
202
     * Gets the message ID
203
     * @return string
204
     * @throws Exception
205
     */
206
    public function getMessageId(): string
207
    {
208
        if (self::$messageId) {
209
            return self::$messageId;
210
        }
211
212
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
213
            preg_match('/<(.*?)@/', preg_quote($this->mailer->getLastMessageID()), $matches);
214
            self::$messageId = $matches[1];
215
        } else {
216
            self::$messageId = bin2hex(random_bytes(16));
217
        }
218
219
        return self::$messageId;
220
    }
221
222
    /**
223
     * Create message body from email template
224
     * @return string
225
     */
226
    private function createFromTemplate(): string
227
    {
228
        ob_start();
229
        ob_implicit_flush(0);
230
231
        if (is_array($this->message)) {
232
            extract($this->message, EXTR_OVERWRITE);
233
        }
234
235
        require $this->templatePath . '.php';
236
237
        return ob_get_clean();
238
    }
239
240
    /**
241
     * Gets the complete message
242
     * @return string
243
     * @throws Exception
244
     */
245
    private function getMessageContent(): string
246
    {
247
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
248
            return $this->mailer->getSentMIMEMessage();
249
        }
250
251
        return $this->generateMessage();
252
    }
253
254
    /**
255
     * @return string
256
     * @throws Exception
257
     */
258
    private function generateMessage(): string
259
    {
260
        $message = 'Date: ' . date('D, j M Y H:i:s O') . PHP_EOL;
261
262
        $message .= 'To: ';
263
264
        foreach ($this->addresses as $address) {
265
            $message .= $address['name'] . ' <' . $address['email'] . '>' . PHP_EOL;
266
        }
267
268
        $message .= 'From: ' . $this->from['name'] . ' <' . $this->from['email'] . '>' . PHP_EOL;
269
270
        $message .= 'Subject: ' . $this->subject . PHP_EOL;
271
272
        $message .= 'Message-ID: <' . $this->getMessageId() . '@' . base_url() . '>' . PHP_EOL;
273
274
        $message .= 'X-Mailer: ' . $this->name . PHP_EOL;
275
276
        $message .= 'MIME-Version: 1.0' . PHP_EOL;
277
278
        $message .= 'Content-Type: text/html; charset=UTF-8' . PHP_EOL . PHP_EOL;
279
280
        $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

280
        $message .= /** @scrutinizer ignore-type */ $this->message . PHP_EOL;
Loading history...
281
282
        return $message;
283
    }
284
285
    /**
286
     * Resets the fields
287
     */
288
    private function resetFields()
289
    {
290
        $this->from = [];
291
        $this->addresses = [];
292
        $this->subject = null;
293
        $this->message = null;
294
        $this->templatePath = null;
295
296
        if (__CLASS__ == __NAMESPACE__ . '\\SmtpAdapter') {
0 ignored issues
show
introduced by
The condition __CLASS__ == __NAMESPACE__ . '\SmtpAdapter' is always false.
Loading history...
297
            $this->replyToAddresses = [];
298
            $this->ccAddresses = [];
299
            $this->bccAddresses = [];
300
            $this->attachments = [];
301
            $this->stringAttachments = [];
302
303
            $this->mailer->clearAddresses();
304
            $this->mailer->clearCCs();
305
            $this->mailer->clearBCCs();
306
            $this->mailer->clearReplyTos();
307
            $this->mailer->clearAllRecipients();
308
            $this->mailer->clearAttachments();
309
            $this->mailer->clearCustomHeaders();
310
        }
311
    }
312
313
    /**
314
     * Updates the debug bar
315
     * @param $message
316
     * @throws DiException
317
     * @throws ReflectionException
318
     * @throws ReflectionException
319
     */
320
    private function updateDebugBar($message)
321
    {
322
        Debugger::addToStore(Debugger::MAILS, LogLevel::WARNING, $message);
323
324
        $logFile = logs_dir() . DS . date('Y-m-d') . '.log';
325
        $logMessage = '[' . date('Y-m-d H:i:s') . '] ' . LogLevel::WARNING . ': ' . $message . PHP_EOL;
326
327
        warning($logMessage, new FileLogger($logFile));
328
    }
329
330
}