Test Failed
Push — master ( 81711e...bf8774 )
by Sebastian
03:41
created

validateFormatters()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 26
rs 9.8333
1
<?php
2
/**
3
 * File containing the {@see Mailcode_Parser_Safeguard} class.
4
 *
5
 * @package Mailcode
6
 * @subpackage Parser
7
 * @see Mailcode_Parser_Safeguard
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode;
13
14
use function AppUtils\parseVariable;
15
16
/**
17
 * Command syntax formatters collection: handles the formatters
18
 * that will be used to format all commands in the safeguard's 
19
 * subject strings. 
20
 * 
21
 * By default, commands are formatted using the normalize formatter,
22
 * which ensures that all commands are normalized. Additional 
23
 * formatters can be added at will.
24
 *
25
 * @package Mailcode
26
 * @subpackage Parser
27
 * @author Sebastian Mordziol <[email protected]>
28
 */
29
class Mailcode_Parser_Safeguard_Formatting
30
{
31
    const ERROR_UNKNOWN_FORMATTER = 65901;
32
    const ERROR_TOO_MANY_REPLACERS = 65902;
33
    const ERROR_NO_FORMATTERS_ADDED = 65903;
34
    
35
   /**
36
    * @var Mailcode_Parser_Safeguard
37
    */
38
    private $safeguard;
39
    
40
   /**
41
    * @var Mailcode_Parser_Safeguard_Formatter[]
42
    */
43
    private $formatters = array();
44
    
45
   /**
46
    * @var Mailcode_StringContainer
47
    */
48
    private $subject;
49
    
50
   /**
51
    * @var boolean
52
    */
53
    private $applied = false;
54
    
55
    public function __construct(Mailcode_Parser_Safeguard $safeguard, Mailcode_StringContainer $subject)
56
    {
57
        $this->safeguard = $safeguard;
58
        $this->subject = $subject;
59
    }
60
    
61
    public function getSubject() : Mailcode_StringContainer
62
    {
63
        return $this->subject;
64
    }
65
    
66
    public function getSafeguard() : Mailcode_Parser_Safeguard
67
    {
68
        return $this->safeguard;
69
    }
70
    
71
    public function addFormatter(Mailcode_Parser_Safeguard_Formatter $formatter) : void
72
    {
73
        $this->formatters[$formatter->getID()] = $formatter;
74
    }
75
    
76
    public function replaceWithNormalized() : Mailcode_Parser_Safeguard_Formatter_Type_Normalized
77
    {
78
        $formatter = $this->createNormalized();
79
        
80
        $this->addFormatter($formatter);
81
        
82
        return $formatter;
83
    }
84
85
    public function formatWithSingleLines() : Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
86
    {
87
        $formatter = $this->createSingleLines();
88
        
89
        $this->addFormatter($formatter);
90
        
91
        return $formatter;
92
    }
93
    
94
   /**
95
    * Adds a formatter that will surround all variables with
96
    * markup to highlight them independently of command syntax
97
    * highlighting.
98
    * 
99
    * This is used to mark variables visually even after commands
100
    * have been replaced by the target system's post processing.
101
    * Can be combined with a replacer and other formats.
102
    * 
103
    * @return Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
104
    */
105
    public function formatWithMarkedVariables() : Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
106
    {
107
        $formatter = $this->createMarkVariables();
108
        
109
        $this->addFormatter($formatter);
110
        
111
        return $formatter;
112
    }
113
    
114
    public function replaceWithPlaceholders() : Mailcode_Parser_Safeguard_Formatter_Type_Placeholders
115
    {
116
        $formatter = $this->createPlaceholders();
117
        
118
        $this->addFormatter($formatter);
119
        
120
        return $formatter;
121
    }
122
    
123
    public function replaceWithHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
124
    {
125
        $formatter = $this->createHTMLHighlighting();
126
        
127
        $this->addFormatter($formatter);
128
        
129
        return $formatter;
130
    }
131
    
132
    public function applyFormatting() : void
133
    {
134
        if($this->applied)
135
        {
136
            return;
137
        }
138
        
139
        $this->applied = true;
140
        
141
        $this->validateFormatters();
142
        
143
        $this->applyFormatTypes();
144
        $this->applyReplaceTypes();
145
    }
146
147
    private function applyFormatTypes() : void
148
    {
149
        foreach($this->formatters as $formatter)
150
        {
151
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_FormatType)
152
            {
153
                $formatter->format();
154
            }
155
        }
156
    }
157
    
158
    private function applyReplaceTypes() : void
159
    {
160
        foreach($this->formatters as $formatter)
161
        {
162
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
163
            {
164
                $formatter->replace();
165
            }
166
        }
167
    }
168
    
169
    private function validateFormatters() : void
170
    {
171
        if(empty($this->formatters))
172
        {
173
            throw new Mailcode_Exception(
174
                'No formatters selected',
175
                'At least one formatter needs to be added for the formatting to work.',
176
                self::ERROR_NO_FORMATTERS_ADDED
177
            );
178
        }
179
        
180
        $amount = $this->countReplacers();
181
        
182
        if($amount > 1) 
183
        {
184
            throw new Mailcode_Exception(
185
                'More than one replacer formatter selected',
186
                'A maximum of 1 replacer formatter may be selected.',
187
                self::ERROR_TOO_MANY_REPLACERS
188
            );
189
        }
190
        
191
        // by default, at minimum the normalized formatter must be selected.
192
        if($amount === 0)
193
        {
194
            $this->replaceWithNormalized();
195
        }
196
    }
197
    
198
   /**
199
    * Counts the amount of replacer formatters that have been added.
200
    * 
201
    * @return int
202
    */
203
    private function countReplacers() : int
204
    {
205
        $count = 0;
206
        
207
        foreach($this->formatters as $formatter)
208
        {
209
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
210
            {
211
                $count++;
212
            }
213
        }
214
        
215
        return $count;
216
    }
217
218
   /**
219
    * Creates a formatter that adds HTML syntax highlighting
220
    * for all commands in the specified string, intelligently
221
    * checking the location of the commands to ensure that they
222
    * can be syntax highlighted.
223
    * 
224
    * For example, commands in HTML attributes will not be
225
    * highlighted, as this would break the HTML.
226
    *  
227
    * @return Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
228
    */
229
    public function createHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
230
    {
231
        return new Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting($this);
232
    }
233
234
   /**
235
    * Creates the formatter that ensures that all commands
236
    * are placed on a separate line in the subject string.
237
    */
238
    public function createSingleLines() : Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
239
    {
240
        return new Mailcode_Parser_Safeguard_Formatter_Type_SingleLines($this);
241
    }
242
    
243
   /**
244
    * Creates the formatter that replaces all commands by
245
    * their normalized variants.
246
    * 
247
    * @return Mailcode_Parser_Safeguard_Formatter_Type_Normalized
248
    */
249
    public function createNormalized() : Mailcode_Parser_Safeguard_Formatter_Type_Normalized
250
    {
251
        return new Mailcode_Parser_Safeguard_Formatter_Type_Normalized($this);
252
    }
253
    
254
    public function createPlaceholders() : Mailcode_Parser_Safeguard_Formatter_Type_Placeholders
255
    {
256
        return new Mailcode_Parser_Safeguard_Formatter_Type_Placeholders($this);
257
    }
258
    
259
    public function createMarkVariables() : Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
260
    {
261
        return new Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables($this);
262
    }
263
    
264
    public function toString() : string
265
    {
266
        $this->applyFormatting();
267
        
268
        return $this->subject->getString();
269
    }
270
}
271