Test Failed
Push — master ( 9ff364...742ef2 )
by Sebastian
03:58
created

replaceBrackets()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 12
rs 10
1
<?php
2
/**
3
 * File containing the class {\Mailcode\Mailcode_Parser_StringPreProcessor}.
4
 *
5
 * @package Mailcode
6
 * @subpackage Parser
7
 * @see \Mailcode\Mailcode_Parser_StringPreProcessor
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode;
13
14
use AppUtils\ConvertHelper;
15
use Mailcode\Parser\Statement\Tokenizer\SpecialChars;
16
17
/**
18
 * Prepares a string to be parsed by the parser, by rendering
19
 * it compatible through a number of adjustments. This includes
20
 * stripping out `style` tags in HTML strings, since CSS syntax
21
 * conflicts with Mailcode.
22
 *
23
 * @package Mailcode
24
 * @subpackage Parser
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class Mailcode_Parser_StringPreProcessor
28
{
29
    /**
30
     * @var string
31
     */
32
    private string $subject;
33
34
    public function __construct(string $subject)
35
    {
36
        $this->subject = $subject;
37
    }
38
39
    public function process() : string
40
    {
41
        $this->stripStyleTags();
42
        $this->escapeRegexBrackets();
43
        $this->encodeBrackets();
44
45
        return $this->subject;
46
    }
47
48
    /**
49
     * Special case for escaped brackets: to allow regular
50
     * parsing of these, we replace them with placeholders.
51
     */
52
    private function encodeBrackets() : void
53
    {
54
        $this->subject = str_replace('\{', SpecialChars::PLACEHOLDER_BRACKET_OPEN, $this->subject);
55
        $this->subject = str_replace('\}', SpecialChars::PLACEHOLDER_BRACKET_CLOSE, $this->subject);
56
    }
57
58
    /**
59
     * Detects regex size brackets, e.g. `{1,2}` or `{5}`,
60
     * and escapes the brackets as expected by Mailcode commands,
61
     * e.g. `\{5\}`.
62
     *
63
     * @return void
64
     */
65
    private function escapeRegexBrackets() : void
66
    {
67
        preg_match_all('/{[0-9]+,[0-9]+}|{[0-9]+}/xU', $this->subject, $result, PREG_PATTERN_ORDER);
68
69
        $matches = array_unique($result[0]);
70
71
        foreach ($matches as $match)
72
        {
73
            $this->subject = $this->escapeRegexBracketMatch($this->subject, $match);
74
        }
75
    }
76
77
    /**
78
     * Removes all <style> tags to avoid conflicts with CSS code.
79
     */
80
    private function stripStyleTags() : void
81
    {
82
        if(!ConvertHelper::isStringHTML($this->subject))
83
        {
84
            return;
85
        }
86
87
        $this->subject = (string)preg_replace(
88
            '%<style\b[^>]*>(.*?)</style>%six',
89
            '',
90
            $this->subject
91
        );
92
    }
93
94
    private function escapeRegexBracketMatch(string $subject, string $needle) : string
95
    {
96
        $replacement =  str_replace(
97
            array('{', '}'),
98
            array('\{', '\}'),
99
            $needle
100
        );
101
102
        return str_replace($needle, $replacement, $subject);
103
    }
104
}
105