Completed
Pull Request — 3.0 (#5)
by Huberty
02:42
created

Mail::autoCreateBodyText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Mouf\Utils\Mailer;
4
5
use Pelago\Emogrifier;
6
7
/**
8
 * This class represents a mail to be sent using a Mailer class extending the MailerInterface.
9
 * + it has special features to add a text mail for any HTML mail that has not been provided the text mail.
10
 *
11
 * Note: default encoding for the mail is UTF-8 if not specified.
12
 *
13
 * @Component
14
 */
15
class Mail implements MailInterface
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $bodyText;
21
22
    /**
23
     * @var string
24
     */
25
    protected $bodyHtml;
26
27
    /**
28
     * @var string
29
     */
30
    protected $title;
31
32
    /**
33
     * @var MailAddressInterface
34
     */
35
    protected $from;
36
37
    /**
38
     * @var MailAddressInterface[]
39
     */
40
    protected $toRecipients = array();
41
42
    /**
43
     * @var MailAddressInterface[]
44
     */
45
    protected $ccRecipients = array();
46
47
    /**
48
     * @var MailAddressInterface[]
49
     */
50
    protected $bccRecipients = array();
51
52
    /**
53
     * @var MailAttachmentInterface[]
54
     */
55
    protected $attachements = array();
56
57
    /**
58
     * @var string
59
     */
60
    protected $encoding = 'utf-8';
61
62
    /**
63
     * @var bool
64
     */
65
    protected $autocreateMissingText = true;
66
67
    /**
68
     * @var string
69
     */
70
    protected $css;
71
72
    public function __construct(string $title, string $bodyText = null)
73
    {
74
        $this->title = $title;
75
        $this->bodyText = $bodyText;
76
    }
77
78
    /**
79
     * Returns the mail text body.
80
     *
81
     * @return string
82
     */
83
    public function getBodyText() :string
84
    {
85
        if ($this->bodyText != null) {
86
            return $this->bodyText;
87
        } elseif ($this->autocreateMissingText == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
88
            return $this->removeHtml($this->getBodyHtml());
89
        }
90
    }
91
92
    /**
93
     * The mail text body.
94
     *
95
     * @Property
96
     *
97
     * @param string $bodyText
98
     */
99
    public function setBodyText($bodyText) :string
100
    {
101
        $this->bodyText = $bodyText;
102
    }
103
104
    /**
105
     * Returns the HTML text before "emogrification".
106
     * This method can be overwritten by subclasses to overwrite the mail body and still applying "emogrification".
107
     *
108
     * @return string
109
     */
110
    protected function getBodyHtmlBeforeEmogrify() :string
111
    {
112
        return $this->bodyHtml;
113
    }
114
115
    /**
116
     * Returns the mail html body.
117
     *
118
     * @return string
119
     */
120 View Code Duplication
    public function getBodyHtml():string
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
    {
122
        if ($this->css) {
123
            $emogrifier = new Emogrifier($this->getBodyHtmlBeforeEmogrify(), $this->css);
124
            $finalHtml = $emogrifier->emogrify();
125
        } else {
126
            $finalHtml = $this->getBodyHtmlBeforeEmogrify();
127
        }
128
129
        return $finalHtml;
130
    }
131
132
    /**
133
     * The mail html body.
134
     *
135
     * @param string $bodyHtml
136
     */
137
    public function setBodyHtml($bodyHtml):string
138
    {
139
        $this->bodyHtml = $bodyHtml;
140
    }
141
142
    /**
143
     * Returns the mail title.
144
     *
145
     * @return string
146
     */
147
    public function getTitle():string
148
    {
149
        return $this->title;
150
    }
151
152
    /**
153
     * The mail title.
154
     *
155
     * @param string $title
156
     */
157
    public function setTitle($title) :string
158
    {
159
        $this->title = $title;
160
    }
161
162
    /**
163
     * Returns the "From" email address.
164
     *
165
     * @return MailAddressInterface The first element is the email address, the second the name to display.
166
     */
167
    public function getFrom():MailAddressInterface
168
    {
169
        return $this->from;
170
    }
171
172
    /**
173
     * The mail from address.
174
     *
175
     * @param MailAddressInterface $from
176
     */
177
    public function setFrom(MailAddressInterface $from)
178
    {
179
        $this->from = $from;
180
    }
181
182
    /**
183
     * Returns an array containing the recipients.
184
     *
185
     * @return MailAddressInterface[]
186
     */
187
    public function getToRecipients(): array
188
    {
189
        return $this->toRecipients;
190
    }
191
192
    /**
193
     * An array containing the recipients.
194
     *
195
     * @param MailAddressInterface[] $toRecipients
196
     */
197
    public function setToRecipients(array $toRecipients)
198
    {
199
        $this->toRecipients = $toRecipients;
200
    }
201
202
    /**
203
     * Adss a recipient.
204
     *
205
     * @param MailAddressInterface $toRecipient
206
     */
207
    public function addToRecipient(MailAddressInterface $toRecipient)
208
    {
209
        $this->toRecipients[] = $toRecipient;
210
    }
211
212
    /**
213
     * Returns an array containing the recipients in Cc.
214
     *
215
     * @return MailAddressInterface[]
216
     */
217
    public function getCcRecipients(): array
218
    {
219
        return $this->ccRecipients;
220
    }
221
222
    /**
223
     * An array containing the recipients.
224
     *
225
     * @Property
226
     *
227
     * @param MailAddressInterface[]$ccRecipients
228
     */
229
    public function setCcRecipients(array $ccRecipients)
230
    {
231
        $this->ccRecipients = $ccRecipients;
232
    }
233
234
    /**
235
     * Adds a recipient.
236
     *
237
     * @param MailAddressInterface $ccRecipient
238
     */
239
    public function addCcRecipient(MailAddressInterface $ccRecipient)
240
    {
241
        $this->ccRecipients[] = $ccRecipient;
242
    }
243
244
    /**
245
     * Returns an array containing the recipients in Bcc.
246
     *
247
     * @return MailAddressInterface[]
248
     */
249
    public function getBccRecipients():array
250
    {
251
        return $this->bccRecipients;
252
    }
253
254
    /**
255
     * An array containing the recipients.
256
     *
257
     * @param MailAddressInterface[] $bccRecipients
258
     */
259
    public function setBccRecipients(array $bccRecipients)
260
    {
261
        $this->bccRecipients = $bccRecipients;
262
    }
263
264
    /**
265
     * Adds a recipient.
266
     *
267
     * @param MailAddressInterface $bccRecipient
268
     */
269
    public function addBccRecipient(MailAddressInterface $bccRecipient)
270
    {
271
        $this->bccRecipients[] = $bccRecipient;
272
    }
273
274
    /**
275
     * Returns an array of attachements for that mail.
276
     *
277
     * @return MailAttachmentInterface[]
278
     */
279
    public function getAttachements():array
280
    {
281
        return $this->attachements;
282
    }
283
284
    /**
285
     * An array containing the attachments.
286
     *
287
     * @param array<MailAttachmentInterface> $attachements
288
     */
289
    public function setAttachements(array $attachements)
290
    {
291
        $this->attachements = $attachements;
292
    }
293
294
    /**
295
     * Adds an attachment.
296
     *
297
     * @param MailAttachmentInterface $attachement
298
     */
299
    public function addAttachement(MailAttachmentInterface $attachement)
300
    {
301
        $this->attachements[] = $attachement;
302
    }
303
304
    /**
305
     * Returns the encoding of the mail.
306
     *
307
     * @return string
308
     */
309
    public function getEncoding():string
310
    {
311
        return $this->encoding;
312
    }
313
314
    /**
315
     * The mail encoding. Defaults to utf-8.
316
     *
317
     * @param string $encoding
318
     */
319
    public function setEncoding($encoding)
320
    {
321
        $this->encoding = $encoding;
322
    }
323
324
    /**
325
     * If no body text is set for that mail, and if autoCreateBodyText is set to true, this object will create the body text from the body HTML text,
326
     * by removing any tags.
327
     *
328
     * @param bool $autoCreate
329
     */
330
    public function autoCreateBodyText($autoCreate)
331
    {
332
        $this->autocreateMissingText = $autoCreate;
333
    }
334
335
    /**
336
     * Removes the HTML tags from the text.
337
     *
338
     * @param string $s
339
     * @param string $keep   The list of tags to keep
340
     * @param string $expand The list of tags to remove completely, along their content
341
     *
342
     * @return string
343
     */
344
    private function removeHtml($s, $keep = '', $expand = 'script|style|noframes|select|option'):string
345
    {
346
        /**///prep the string
347
        $s = ' '.$s;
348
349
        /**///initialize keep tag logic
350
        if (strlen($keep) > 0) {
351
            $k = explode('|', $keep);
352 View Code Duplication
            for ($i = 0;$i < count($k);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
353
                $s = str_replace('<'.$k[$i], '[{('.$k[$i], $s);
354
                $s = str_replace('</'.$k[$i], '[{(/'.$k[$i], $s);
355
            }
356
        }
357
358
        $pos = array();
359
        $len = array();
360
361
        //begin removal
362
        /**///remove comment blocks
363 View Code Duplication
        while (stripos($s, '<!--') > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
364
            $pos[1] = stripos($s, '<!--');
365
            $pos[2] = stripos($s, '-->', $pos[1]);
366
            $len[1] = $pos[2] - $pos[1] + 3;
367
            $x = substr($s, $pos[1], $len[1]);
368
            $s = str_replace($x, '', $s);
369
        }
370
371
        /**///remove tags with content between them
372
        if (strlen($expand) > 0) {
373
            $e = explode('|', $expand);
374
            for ($i = 0;$i < count($e);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
375
                while (stripos($s, '<'.$e[$i]) > 0) {
376
                    $len[1] = strlen('<'.$e[$i]);
377
                    $pos[1] = stripos($s, '<'.$e[$i]);
378
                    $pos[2] = stripos($s, $e[$i].'>', $pos[1] + $len[1]);
379
                    $len[2] = $pos[2] - $pos[1] + $len[1];
380
                    $x = substr($s, $pos[1], $len[2]);
381
                    $s = str_replace($x, '', $s);
382
                }
383
            }
384
        }
385
386
        /**///remove remaining tags
387 View Code Duplication
        while (stripos($s, '<') > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
388
            $pos[1] = stripos($s, '<');
389
            $pos[2] = stripos($s, '>', $pos[1]);
390
            $len[1] = $pos[2] - $pos[1] + 1;
391
            $x = substr($s, $pos[1], $len[1]);
392
            $s = str_replace($x, '', $s);
393
        }
394
395
        /**///finalize keep tag
396
        if (isset($k)) {
397 View Code Duplication
            for ($i = 0;$i < count($k);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
398
                $s = str_replace('[{('.$k[$i], '<'.$k[$i], $s);
399
                $s = str_replace('[{(/'.$k[$i], '</'.$k[$i], $s);
400
            }
401
        }
402
403
        return trim($s);
404
    }
405
406
    /**
407
     * Registers some CSS to be applied to the HTML.
408
     * When sending the mail, the CSS will be DIRECTLY applied to the HTML, resulting in some HTML with inline CSS.
409
     *
410
     * CSS is inlined using the Emogrifier library.
411
     *
412
     * @param string $css The CSS to apply.
413
     */
414
    public function addCssText($css)
415
    {
416
        $this->css .= $css;
417
    }
418
419
    /**
420
     * Registers a CSS file to be applied to the HTML.
421
     * When sending the mail, the CSS will be DIRECTLY applied to the HTML, resulting in some HTML with inline CSS.
422
     *
423
     * CSS is inlined using the Emogrifier library.
424
     *
425
     * @param string $file The CSS file to apply.
426
     */
427
    public function addCssFile($file)
428
    {
429
        $this->css .= file_get_contents($file);
430
    }
431
}
432