Passed
Pull Request — master (#190)
by Arman
02:47
created

MailerTrait::getFrom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
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\Traits;
16
17
use Quantum\Libraries\Mailer\Contracts\MailerInterface;
18
use Quantum\Di\Exceptions\DiException;
19
use Quantum\Libraries\Mailer\MailTrap;
20
use Quantum\Debugger\Debugger;
21
use ReflectionException;
22
use Exception;
23
24
/**
25
 * trait MailerTrait
26
 * @package Quantum\Libraries\Mailer
27
 */
28
trait MailerTrait
29
{
30
31
    /**
32
     * From address and name
33
     * @var array
34
     */
35
    private $from = [];
36
37
    /**
38
     * To addresses
39
     * @var array
40
     */
41
    private $addresses = [];
42
43
    /**
44
     * Email subject
45
     * @var string
46
     */
47
    private $subject = null;
48
49
    /**
50
     * Email body
51
     * @var string|array
52
     */
53
    private $message = null;
54
55
    /**
56
     * @var string
57
     */
58
    private static $messageId = null;
59
60
    /**
61
     * Template path
62
     * @var string
63
     */
64
    private $templatePath = null;
65
66
    /**
67
     * Sets the 'From' email and the name
68
     * @param string $email
69
     * @param string|null $name
70
     * @return MailerInterface
71
     */
72
    public function setFrom(string $email, ?string $name = null): MailerInterface
73
    {
74
        $this->from['email'] = $email;
75
        $this->from['name'] = $name;
76
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer\Traits\MailerTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\Contracts\MailerInterface.
Loading history...
77
    }
78
79
    /**
80
     * Gets 'From' email and the "name"
81
     * @return array
82
     */
83
    public function getFrom(): array
84
    {
85
        return $this->from;
86
    }
87
88
    /**
89
     * Sets 'To' addresses
90
     * @param string $email
91
     * @param string|null $name
92
     * @return MailerInterface
93
     */
94
    public function setAddress(string $email, ?string $name = null): MailerInterface
95
    {
96
        $this->addresses[] = [
97
            'email' => $email,
98
            'name' => $name
99
        ];
100
101
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer\Traits\MailerTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\Contracts\MailerInterface.
Loading history...
102
    }
103
104
    /**
105
     * Gets 'To' addresses
106
     * @return array
107
     */
108
    public function getAddresses(): array
109
    {
110
        return $this->addresses;
111
    }
112
113
    /**
114
     * Sets the subject
115
     * @param string|null $subject
116
     * @return MailerInterface
117
     */
118
    public function setSubject(?string $subject): MailerInterface
119
    {
120
        $this->subject = $subject;
121
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer\Traits\MailerTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\Contracts\MailerInterface.
Loading history...
122
    }
123
124
    /**
125
     * Gets the subject
126
     * @return string
127
     */
128
    public function getSubject(): ?string
129
    {
130
        return $this->subject;
131
    }
132
133
    /**
134
     * Sets the template
135
     * @param string $templatePath
136
     * @return MailerInterface
137
     */
138
    public function setTemplate(string $templatePath): MailerInterface
139
    {
140
        $this->templatePath = $templatePath;
141
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer\Traits\MailerTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\Contracts\MailerInterface.
Loading history...
142
    }
143
144
    /**
145
     * Gets the template
146
     * @return string|null
147
     */
148
    public function getTemplate(): ?string
149
    {
150
        return $this->templatePath;
151
    }
152
153
    /**
154
     * Sets the body
155
     * @param string|array $message
156
     * @return MailerInterface
157
     */
158
    public function setBody($message): MailerInterface
159
    {
160
        $this->message = $message;
161
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Quantum\Libraries\Mailer\Traits\MailerTrait which is incompatible with the type-hinted return Quantum\Libraries\Mailer\Contracts\MailerInterface.
Loading history...
162
    }
163
164
    /**
165
     * Gets the body
166
     * @return array|string|null
167
     */
168
    public function getBody()
169
    {
170
        return $this->message;
171
    }
172
173
    /**
174
     * @inheritDoc
175
     * @throws DiException
176
     * @throws ReflectionException
177
     * @throws Exception
178
     */
179
    public function send(): bool
180
    {
181
        $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

181
        $this->/** @scrutinizer ignore-call */ 
182
               prepare();
Loading history...
182
183
        if (config()->get('mailer.mail_trap')) {
184
            $sent = $this->saveEmail();
185
        } else {
186
            $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

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

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