Completed
Push — 5.0 ( a6dbd7...bb6719 )
by Huberty
26s
created

SwiftTwigMailTemplate::removeHtml()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 42
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 0
cts 23
cp 0
rs 8.439
c 0
b 0
f 0
cc 6
eloc 23
nc 8
nop 3
crap 42
1
<?php
2
3
namespace TheCodingMachine\Mail\Template;
4
5
use TheCodingMachine\Mail\SwiftMailTemplate;
6
7
class SwiftTwigMailTemplate implements SwiftMailTemplate
8
{
9
    /**
10
     * @var \Twig_Environment
11
     */
12
    protected $twigEnvironment;
13
14
    /**
15
     * @var string
16
     */
17
    protected $twigPath;
18
19
    /**
20
     * @var string|array
21
     */
22
    protected $fromAddresses;
23
24
    /**
25
     * @var string
26
     */
27
    protected $fromName = null;
28
29
    /**
30
     * @var string|array
31
     */
32
    protected $toAddresses;
33
34
    /**
35
     * @var string
36
     */
37
    protected $toName = null;
38
39
    /**
40
     * @var string|array
41
     */
42
    protected $bccAddresses;
43
44
    /**
45
     * @var string
46
     */
47
    protected $bccName = null;
48
49
    /**
50
     * @var string|array
51
     */
52
    protected $ccAddresses;
53
54
    /**
55
     * @var string
56
     */
57
    protected $ccName = null;
58
59
    /**
60
     * @var string|array
61
     */
62
    protected $replyToAddresses;
63
64
    /**
65
     * @var string
66
     */
67
    protected $replyToName = null;
68
69
    /**
70
     * @var int
71
     */
72
    protected $maxLineLength = 1000;
73
74
    /**
75
     * @var int
76
     */
77
    protected $priority;
78
79
    /**
80
     * @var string
81
     */
82
    protected $readReceiptTo;
83
84
    /**
85
     * @var string
86
     */
87
    protected $returnPath;
88
89
    /**
90
     * SwiftTwigMailGenerator constructor.
91
     *
92
     * @param \Twig_Environment $twig_Environment
93
     * @param string            $twigPath
94
     */
95 2
    public function __construct(\Twig_Environment $twig_Environment, string $twigPath)
96
    {
97 2
        $this->twigEnvironment = $twig_Environment;
98 2
        $this->twigPath = $twigPath;
99 2
    }
100
101
    /**
102
     * @param array $data
103
     *
104
     * @return \Swift_Message
105
     */
106 2
    public function renderMail(array $data = []) :\Swift_Message
107
    {
108 2
        $mail = new \Swift_Message();
109
110 2
        $twigEnvironment = clone $this->twigEnvironment;
111 2
        $function = new \Twig_SimpleFunction('embedImage', function ($imgPath) use ($mail) {
112
            return $mail->embed(\Swift_Image::fromPath($imgPath));
113 2
        });
114 2
        $twigEnvironment->addFunction($function);
115
116 2
        $template = $twigEnvironment->loadTemplate($this->twigPath);
117
118 2
        if (!$template->hasBlock('subject') || !$template->hasBlock('body_html')) {
119 1
            throw MissingBlockException::missingBlock($template->getBlockNames());
120
        }
121
122 1
        $subject = $template->renderBlock('subject', $data);
0 ignored issues
show
Bug introduced by
The method renderBlock() does not exist on Twig_TemplateInterface. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
123 1
        $bodyHtml = $template->renderBlock('body_html', $data);
0 ignored issues
show
Bug introduced by
The method renderBlock() does not exist on Twig_TemplateInterface. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
124 1
        if (!$template->hasBlock('body_text')) {
125
            $bodyText = $this->removeHtml($bodyHtml);
126
        } else {
127 1
            $bodyText = $template->renderBlock('body_text', $data);
0 ignored issues
show
Bug introduced by
The method renderBlock() does not exist on Twig_TemplateInterface. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
128
        }
129
130 1
        $mail->setSubject($subject);
131 1
        $mail->setBody($bodyHtml);
132 1
        $mail->addPart($bodyText);
133
134
        switch (true) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->maxLineLength of type integer to the boolean true. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
Bug Best Practice introduced by
It seems like you are loosely comparing $this->priority of type integer to the boolean true. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
Bug Best Practice introduced by
It seems like you are loosely comparing $this->readReceiptTo of type string to the boolean true. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
Bug Best Practice introduced by
It seems like you are loosely comparing $this->returnPath of type string to the boolean true. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
135 1
            case $this->fromAddresses:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
136 1
                $mail->setFrom($this->fromAddresses, $this->fromName);
137 1
                $mail->setSender($this->fromAddresses, $this->fromName);
138
            case $this->toAddresses:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
139 1
                $mail->setTo($this->toAddresses, $this->toName);
140
            case $this->bccAddresses:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
141 1
                $mail->setBcc($this->bccAddresses, $this->bccName);
142
            case $this->ccAddresses:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
143 1
                $mail->setCc($this->ccAddresses, $this->ccName);
144
            case $this->replyToAddresses:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
145 1
                $mail->setReplyTo($this->replyToAddresses, $this->replyToName);
146
            case $this->maxLineLength:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
147 1
                $mail->setMaxLineLength($this->maxLineLength);
148
            case $this->priority:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
149 1
                $mail->setPriority($this->priority);
150
            case $this->readReceiptTo:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
151 1
                $mail->setReadReceiptTo($this->readReceiptTo);
0 ignored issues
show
Documentation introduced by
$this->readReceiptTo is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
152
            case $this->returnPath:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
153 1
                $mail->setReturnPath($this->returnPath);
154
            default:
155 1
                break;
156
        }
157
158 1
        return $mail;
159
    }
160
161
    /**
162
     * @param array|string $fromAddresses
163
     */
164 1
    public function setFromAddresses($fromAddresses)
165
    {
166 1
        $this->fromAddresses = $fromAddresses;
167 1
    }
168
169
    /**
170
     * @param string $fromName
171
     */
172 1
    public function setFromName($fromName)
173
    {
174 1
        $this->fromName = $fromName;
175 1
    }
176
177
    /**
178
     * @param array|string $toAddresses
179
     */
180 1
    public function setToAddresses($toAddresses)
181
    {
182 1
        $this->toAddresses = $toAddresses;
183 1
    }
184
185
    /**
186
     * @param string $toName
187
     */
188 1
    public function setToName($toName)
189
    {
190 1
        $this->toName = $toName;
191 1
    }
192
193
    /**
194
     * @param array|string $bccAddresses
195
     */
196 1
    public function setBccAddresses($bccAddresses)
197
    {
198 1
        $this->bccAddresses = $bccAddresses;
199 1
    }
200
201
    /**
202
     * @param string $bccName
203
     */
204 1
    public function setBccName($bccName)
205
    {
206 1
        $this->bccName = $bccName;
207 1
    }
208
209
    /**
210
     * @param array|string $ccAddresses
211
     */
212 1
    public function setCcAddresses($ccAddresses)
213
    {
214 1
        $this->ccAddresses = $ccAddresses;
215 1
    }
216
217
    /**
218
     * @param string $ccName
219
     */
220 1
    public function setCcName($ccName)
221
    {
222 1
        $this->ccName = $ccName;
223 1
    }
224
225
    /**
226
     * @param array|string $replyToAddresses
227
     */
228 1
    public function setReplyToAddresses($replyToAddresses)
229
    {
230 1
        $this->replyToAddresses = $replyToAddresses;
231 1
    }
232
233
    /**
234
     * @param string $replyToName
235
     */
236 1
    public function setReplyToName($replyToName)
237
    {
238 1
        $this->replyToName = $replyToName;
239 1
    }
240
241
    /**
242
     * @param int $maxLineLength
243
     */
244 1
    public function setMaxLineLength($maxLineLength)
245
    {
246 1
        $this->maxLineLength = $maxLineLength;
247 1
    }
248
249
    /**
250
     * @param int $priority
251
     */
252 1
    public function setPriority($priority)
253
    {
254 1
        $this->priority = $priority;
255 1
    }
256
257
    /**
258
     * @param string $readReceiptTo
259
     */
260 1
    public function setReadReceiptTo($readReceiptTo)
261
    {
262 1
        $this->readReceiptTo = $readReceiptTo;
263 1
    }
264
265
    /**
266
     * @param string $returnPath
267
     */
268 1
    public function setReturnPath($returnPath)
269
    {
270 1
        $this->returnPath = $returnPath;
271 1
    }
272
273
    /**
274
     * Removes the HTML tags from the text.
275
     *
276
     * @param string $s
277
     * @param string $keep   The list of tags to keep
278
     * @param string $expand The list of tags to remove completely, along their content
279
     */
280
    private function removeHtml(string $s, string $keep = '', string $expand = 'script|style|noframes|select|option') :string
281
    {
282
        /**///prep the string
283
        $s = ' '.$s;
284
285
        /**///initialize keep tag logic
286
        if (strlen($keep) > 0) {
287
            $k = explode('|', $keep);
288
            $s = $this->keepTag($s, $k, '<', '[{(');
289
        }
290
        //begin removal
291
        /**///remove comment blocks
292
        $s = $this->removeElement($s, '<!--', '-->');
293
294
        /**///remove tags with content between them
295
        if (strlen($expand) > 0) {
296
            $e = explode('|', $expand);
297
            $count = count($e);
298
            $pos = [];
299
            $len = [];
300
            for ($i = 0;$i < $count;++$i) {
301
                while (stripos($s, '<'.$e[$i]) > 0) {
302
                    $len[1] = strlen('<'.$e[$i]);
303
                    $pos[1] = stripos($s, '<'.$e[$i]);
304
                    $pos[2] = stripos($s, $e[$i].'>', $pos[1] + $len[1]);
305
                    $len[2] = $pos[2] - $pos[1] + $len[1];
306
                    $x = substr($s, $pos[1], $len[2]);
307
                    $s = str_replace($x, '', $s);
308
                }
309
            }
310
        }
311
312
        /**///remove remaining tags
313
        $s = $this->removeElement($s, '<', '>');
314
315
        /**///finalize keep tag
316
        if (isset($k)) {
317
            $s = $this->keepTag($s, $k, '[{(', '<');
318
        }
319
320
        return trim($s);
321
    }
322
323
    /**
324
     * @param string $s
325
     * @param string $openTag
326
     * @param string $closeTag
327
     *
328
     * @return mixed|string
329
     */
330
    private function removeElement(string $s, string $openTag, string $closeTag)
331
    {
332
        $pos = [];
333
        $len = [];
334
        while (stripos($s, $openTag) > 0) {
335
            $pos[1] = stripos($s, $openTag);
336
            $pos[2] = stripos($s, $closeTag, $pos[1]);
337
            $len[1] = $pos[2] - $pos[1] + 1;
338
            $x = substr($s, $pos[1], $len[1]);
339
            $s = str_replace($x, '', $s);
340
        }
341
342
        return $s;
343
    }
344
345
    /**
346
     * @param string $s
347
     * @param array  $tagToKeep
348
     * @param string $initial
349
     * @param string $finalize
350
     *
351
     * @return string
352
     */
353
    private function keepTag(string $s, array $tagToKeep, string $initial, string $finalize):string
354
    {
355
        $count = count($tagToKeep);
356
        for ($i = 0;$i < $count;++$i) {
357
            $s = str_replace($initial.$tagToKeep[$i], $finalize.$tagToKeep[$i], $s);
358
            $s = str_replace($initial.'/'.$tagToKeep[$i], $finalize.'/'.$tagToKeep[$i], $s);
359
        }
360
361
        return $s;
362
    }
363
}
364