Issues (536)

src/Mail/Mail.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Mail;
13
14
use BlitzPHP\Contracts\Mail\MailerInterface;
15
use BlitzPHP\Mail\Adapters\AbstractAdapter;
16
use BlitzPHP\Mail\Adapters\PHPMailer;
17
use BlitzPHP\Mail\Adapters\SymfonyMailer;
18
use InvalidArgumentException;
19
20
/**
21
 * Envoi d'e-mail en utilisant Mail, Sendmail ou SMTP.
22
 *
23
 * @method $this charset(string $charset)
24
 * @method $this priority(int $priority)
25
 * @method $this setCharset(string $charset)
26
 * @method $this setDebug(int $debug = 1)
27
 * @method $this setEncryption(?string $encryption)
28
 * @method $this setHost(string $host)
29
 * @method $this setPassword(string $password);
30
 * @method $this setPort(int $port)
31
 * @method $this setPriority(int $priority)
32
 * @method $this setProtocol(string $protocol)
33
 * @method $this setTimeout(int $timeout)
34
 * @method $this setUsername(string $username)
35
 * @method $this timeout(int $timeout)
36
 */
37
class Mail implements MailerInterface
38
{
39
    /**
40
     * Un tableau mappant les schémas d'URL aux noms de classe de moteur d'envoie d'email.
41
     *
42
     * @var array<string, string>
43
     * @psalm-var array<string, class-string>
44
     */
45
    protected static array $validHandlers = [
46
        'phpmailer' => PHPMailer::class,
47
        'symfony'   => SymfonyMailer::class,
48
    ];
49
50
    /**
51
     * Configurations
52
     */
53
    protected array $config = [];
54
55
    /**
56
     * Adapter a utiliser pour envoyer les mails
57
     */
58
    private ?AbstractAdapter $adapter;
59
60
    /**
61
     * Constructeur
62
     */
63
    public function __construct(array $config)
64
    {
65
        $this->init($config);
66
    }
67
68
    /**
69
     * Nettoie les elements d'envoie du message
70
     */
71
    public function clear(bool $reset = false): self
72
    {
73
        $this->factory()->clear();
74
75
        if ($reset) {
76
            $this->adapter = null;
77
        }
78
79
        return $this;
80
    }
81
82
    /**
83
     * Envoi d'un mail de type Mailable
84
     */
85
    public function envoi(Mailable $mailable): bool
86
    {
87
        return $mailable->send($this);
88
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93
    public function init(array $config): static
94
    {
95
        $this->config  = $config;
96
        $this->adapter = null;
97
98
        return $this;
99
    }
100
101
    public function mailer(string $handler): static
102
    {
103
        $this->clear(true);
104
105
        return $this->merge(['handler' => $handler]);
106
    }
107
108
    public function merge(array $config): static
109
    {
110
        $this->config = array_merge($this->config, $config);
111
112
        if (null !== $this->adapter) {
113
            $this->adapter->init($config);
114
        }
115
116
        return $this;
117
    }
118
119
    /**
120
     * Tente de créer le gestionnaire de mail souhaité
121
     */
122
    protected function factory(): AbstractAdapter
123
    {
124
        if (null !== $this->adapter) {
125
            return $this->adapter;
126
        }
127
128
        $handler = $this->config['handler'] ?? null;
129
130
        if (empty($handler)) {
131
            throw new InvalidArgumentException(lang('Mail.undefinedHandler'));
132
        }
133
134
        if (array_key_exists($handler, static::$validHandlers)) {
135
            $handler = static::$validHandlers[$handler];
136
        }
137
138
        if (! class_exists($handler)) {
139
            throw new InvalidArgumentException(lang('Mail.invalidHandler', [$handler]));
140
        }
141
142
        $debug = $this->config['debug'] ?? 'auto';
143
        if ($debug === 'auto') {
144
            $debug = on_dev();
145
        }
146
147
        if (! is_subclass_of($handler, AbstractAdapter::class)) {
148
            throw new InvalidArgumentException(lang('Mail.handlerMustExtendClass', [$handler, AbstractAdapter::class]));
149
        }
150
151
        /** @var AbstractAdapter $adapter */
152
        $adapter = new $handler($debug);
153
154
        return $this->adapter = $adapter->init($this->config)->from(...$this->config['from']);
0 ignored issues
show
$this->config['from'] is expanded, but the parameter $address of BlitzPHP\Contracts\Mail\MailerInterface::from() does not expect variable arguments. ( Ignorable by Annotation )

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

154
        return $this->adapter = $adapter->init($this->config)->from(/** @scrutinizer ignore-type */ ...$this->config['from']);
Loading history...
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160
    public function alt(string $content): static
161
    {
162
        $this->factory()->alt($content);
163
164
        return $this;
165
    }
166
167
    /**
168
     * {@inheritDoc}
169
     */
170
    public function attach(array|string $path, string $name = '', string $type = '', string $encoding = self::ENCODING_BASE64, string $disposition = 'attachment'): static
171
    {
172
        $this->factory()->attach($path, $name, $type, $encoding, $disposition);
173
174
        return $this;
175
    }
176
177
    /**
178
     * {@inheritDoc}
179
     */
180
    public function attachBinary($binary, string $name, string $type = '', string $encoding = self::ENCODING_BASE64, string $disposition = 'attachment'): static
181
    {
182
        $this->factory()->attachBinary($binary, $name, $type, $encoding, $disposition);
183
184
        return $this;
185
    }
186
187
    /**
188
     * {@inheritDoc}
189
     */
190
    public function bcc(array|string $address, bool|string $name = '', bool $set = false): static
191
    {
192
        $this->factory()->bcc($address, $name, $set);
193
194
        return $this;
195
    }
196
197
    /**
198
     * {@inheritDoc}
199
     */
200
    public function cc(array|string $address, bool|string $name = '', bool $set = false): static
201
    {
202
        $this->factory()->cc($address, $name, $set);
203
204
        return $this;
205
    }
206
207
    /**
208
     * {@inheritDoc}
209
     */
210
    public function dkim(string $pk, string $passphrase = '', string $selector = '', string $domain = ''): static
211
    {
212
        $this->factory()->dkim($pk, $passphrase, $selector, $domain);
213
214
        return $this;
215
    }
216
217
    /**
218
     * {@inheritDoc}
219
     */
220
    public function embedded(string $path, string $cid, string $name = '', string $type = '', string $encoding = self::ENCODING_BASE64, string $disposition = 'inline'): static
221
    {
222
        $this->factory()->embedded($path, $cid, $name, $encoding, $type, $disposition);
223
224
        return $this;
225
    }
226
227
    /**
228
     * {@inheritDoc}
229
     */
230
    public function embeddedBinary($binary, string $cid, string $name = '', string $type = '', string $encoding = self::ENCODING_BASE64, string $disposition = 'inline'): static
231
    {
232
        $this->factory()->embeddedBinary($binary, $cid, $name, $encoding, $type, $disposition);
233
234
        return $this;
235
    }
236
237
    /**
238
     * {@inheritDoc}
239
     */
240
    public function from(string $address, string $name = ''): static
241
    {
242
        $this->factory()->from($address, $name);
243
244
        return $this;
245
    }
246
247
    /**
248
     * {@inheritDoc}
249
     */
250
    public function header(array|string $name, ?string $value = null): static
251
    {
252
        $this->factory()->header($name, $value);
253
254
        return $this;
255
    }
256
257
    /**
258
     * {@inheritDoc}
259
     */
260
    public function html(string $content): static
261
    {
262
        $content = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $content);
263
264
        $this->factory()->html($content);
265
266
        return $this;
267
    }
268
269
    /**
270
     * {@inheritDoc}
271
     */
272
    public function lastId(): string
273
    {
274
        return $this->factory()->lastId();
275
    }
276
277
    /**
278
     * {@inheritDoc}
279
     */
280
    public function message(string $message): static
281
    {
282
        return match ($this->config['mailType']) {
283
            'html'  => $this->html($message),
284
            'text'  => $this->text($message),
285
            default => $this
286
        };
287
    }
288
289
    /**
290
     * {@inheritDoc}
291
     */
292
    public function replyTo(array|string $address, bool|string $name = '', bool $set = false): static
293
    {
294
        $this->factory()->replyTo($address, $name, $set);
295
296
        return $this;
297
    }
298
299
    /**
300
     * {@inheritDoc}
301
     */
302
    public function send(): bool
303
    {
304
        if ($this->factory()->send()) {
305
            $this->clear(false);
306
307
            return true;
308
        }
309
310
        return false;
311
    }
312
313
    /**
314
     * {@inheritDoc}
315
     */
316
    public function sign(string $cert_filename, string $key_filename, string $key_pass, string $extracerts_filename = ''): static
317
    {
318
        $this->factory()->sign($cert_filename, $key_filename, $key_pass, $extracerts_filename);
319
320
        return $this;
321
    }
322
323
    /**
324
     * {@inheritDoc}
325
     */
326
    public function subject(string $subject): static
327
    {
328
        $this->factory()->subject($subject);
329
330
        return $this;
331
    }
332
333
    /**
334
     * {@inheritDoc}
335
     */
336
    public function text(string $content): static
337
    {
338
        $this->factory()->text($content);
339
340
        return $this;
341
    }
342
343
    /**
344
     * {@inheritDoc}
345
     */
346
    public function to(array|string $address, bool|string $name = '', bool $set = false): static
347
    {
348
        $this->factory()->to($address, $name, $set);
349
350
        return $this;
351
    }
352
353
    /**
354
     * Utilise une vue html pour generer le message de l'email
355
     */
356
    public function view(string $view, array $data = []): static
357
    {
358
        $path = '';
359
360
        // N'est-il pas namespaced ? on cherche le dossier en fonction du parametre "view_base"
361
        if (! str_contains($view, '\\')) {
362
            $path = $this->config['view_dir'] ?? '';
363
            if (! empty($path)) {
364
                $path .= '/';
365
            }
366
        }
367
368
        $view = view($path . $view, $data);
369
        if (! empty($this->config['template'])) {
370
            $view->layout($this->config['template']);
371
        }
372
373
        return $this->html($view->get(false));
374
    }
375
376
    public function __call(string $method, array $arguments)
377
    {
378
        $result = call_user_func_array([$this->factory(), $method], $arguments);
379
380
        if ($result instanceof AbstractAdapter) {
381
            return $this;
382
        }
383
384
        return $result;
385
    }
386
}
387