createSingleLines()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
    public const ERROR_UNKNOWN_FORMATTER = 65901;
32
    public const ERROR_TOO_MANY_REPLACERS = 65902;
33
    public 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
   /**
56
    * @var boolean
57
    */
58
    private $partial = false;
59
    
60
    public function __construct(Mailcode_Parser_Safeguard $safeguard, Mailcode_StringContainer $subject)
61
    {
62
        $this->safeguard = $safeguard;
63
        $this->subject = $subject;
64
    }
65
    
66
    public function getSubject() : Mailcode_StringContainer
67
    {
68
        return $this->subject;
69
    }
70
    
71
    public function getSafeguard() : Mailcode_Parser_Safeguard
72
    {
73
        return $this->safeguard;
74
    }
75
    
76
    public function addFormatter(Mailcode_Parser_Safeguard_Formatter $formatter) : void
77
    {
78
        $this->formatters[$formatter->getID()] = $formatter;
79
    }
80
    
81
    public function replaceWithNormalized() : Mailcode_Parser_Safeguard_Formatter_Type_Normalized
82
    {
83
        $formatter = $this->createNormalized();
84
        
85
        $this->addFormatter($formatter);
86
        
87
        return $formatter;
88
    }
89
90
    public function formatWithSingleLines() : Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
91
    {
92
        $formatter = $this->createSingleLines();
93
        
94
        $this->addFormatter($formatter);
95
        
96
        return $formatter;
97
    }
98
    
99
   /**
100
    * Adds a formatter that will surround all variables with
101
    * markup to highlight them independently of command syntax
102
    * highlighting.
103
    * 
104
    * This is used to mark variables visually even after commands
105
    * have been replaced by the target system's post processing.
106
    * Can be combined with a replacer and other formats.
107
    * 
108
    * @return Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
109
    */
110
    public function formatWithMarkedVariables() : Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
111
    {
112
        $formatter = $this->createMarkVariables();
113
        
114
        $this->addFormatter($formatter);
115
        
116
        return $formatter;
117
    }
118
    
119
    public function replaceWithPlaceholders() : Mailcode_Parser_Safeguard_Formatter_Type_Placeholders
120
    {
121
        $formatter = $this->createPlaceholders();
122
        
123
        $this->addFormatter($formatter);
124
        
125
        return $formatter;
126
    }
127
128
    /**
129
     * Adds a formatter that removes all Mailcode commands.
130
     *
131
     * @return Mailcode_Parser_Safeguard_Formatter_Type_Remove
132
     */
133
    public function replaceWithRemovedCommands() : Mailcode_Parser_Safeguard_Formatter_Type_Remove
134
    {
135
        $formatter = $this->createRemoveCommands();
136
137
        $this->addFormatter($formatter);
138
139
        return $formatter;
140
    }
141
    
142
    public function replaceWithHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
143
    {
144
        $formatter = $this->createHTMLHighlighting();
145
        
146
        $this->addFormatter($formatter);
147
        
148
        return $formatter;
149
    }
150
    
151
    public function applyFormatting() : void
152
    {
153
        if($this->applied)
154
        {
155
            return;
156
        }
157
        
158
        $this->applied = true;
159
        
160
        $this->validateFormatters();
161
        
162
        $this->applyFormatTypes();
163
        $this->applyReplaceTypes();
164
    }
165
166
    private function applyFormatTypes() : void
167
    {
168
        foreach($this->formatters as $formatter)
169
        {
170
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_FormatType)
171
            {
172
                $formatter->format();
173
            }
174
        }
175
    }
176
    
177
    private function applyReplaceTypes() : void
178
    {
179
        foreach($this->formatters as $formatter)
180
        {
181
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
182
            {
183
                $formatter->replace();
184
            }
185
        }
186
    }
187
    
188
    private function validateFormatters() : void
189
    {
190
        if(empty($this->formatters))
191
        {
192
            throw new Mailcode_Exception(
193
                'No formatters selected',
194
                'At least one formatter needs to be added for the formatting to work.',
195
                self::ERROR_NO_FORMATTERS_ADDED
196
            );
197
        }
198
        
199
        $amount = $this->countReplacers();
200
        
201
        if($amount > 1) 
202
        {
203
            throw new Mailcode_Exception(
204
                'More than one replacer formatter selected',
205
                'A maximum of 1 replacer formatter may be selected.',
206
                self::ERROR_TOO_MANY_REPLACERS
207
            );
208
        }
209
        
210
        // by default, at minimum the normalized formatter must be selected.
211
        if($amount === 0)
212
        {
213
            $this->replaceWithNormalized();
214
        }
215
    }
216
    
217
   /**
218
    * Counts the amount of replacer formatters that have been added.
219
    * 
220
    * @return int
221
    */
222
    private function countReplacers() : int
223
    {
224
        $count = 0;
225
        
226
        foreach($this->formatters as $formatter)
227
        {
228
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
229
            {
230
                $count++;
231
            }
232
        }
233
        
234
        return $count;
235
    }
236
237
   /**
238
    * Creates a formatter that adds HTML syntax highlighting
239
    * for all commands in the specified string, intelligently
240
    * checking the location of the commands to ensure that they
241
    * can be syntax highlighted.
242
    * 
243
    * For example, commands in HTML attributes will not be
244
    * highlighted, as this would break the HTML.
245
    *  
246
    * @return Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
247
    */
248
    public function createHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
249
    {
250
        return new Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting($this);
251
    }
252
253
   /**
254
    * Creates the formatter that ensures that all commands
255
    * are placed on a separate line in the subject string.
256
    */
257
    public function createSingleLines() : Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
258
    {
259
        return new Mailcode_Parser_Safeguard_Formatter_Type_SingleLines($this);
260
    }
261
    
262
   /**
263
    * Creates the formatter that replaces all commands by
264
    * their normalized variants.
265
    * 
266
    * @return Mailcode_Parser_Safeguard_Formatter_Type_Normalized
267
    */
268
    public function createNormalized() : Mailcode_Parser_Safeguard_Formatter_Type_Normalized
269
    {
270
        return new Mailcode_Parser_Safeguard_Formatter_Type_Normalized($this);
271
    }
272
    
273
    public function createPlaceholders() : Mailcode_Parser_Safeguard_Formatter_Type_Placeholders
274
    {
275
        return new Mailcode_Parser_Safeguard_Formatter_Type_Placeholders($this);
276
    }
277
278
    public function createRemoveCommands() : Mailcode_Parser_Safeguard_Formatter_Type_Remove
279
    {
280
        return new Mailcode_Parser_Safeguard_Formatter_Type_Remove($this);
281
    }
282
283
    public function createMarkVariables() : Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
284
    {
285
        return new Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables($this);
286
    }
287
288
    public function createPreProcessing() : Mailcode_Parser_Safeguard_Formatter_Type_PreProcessing
289
    {
290
        return new Mailcode_Parser_Safeguard_Formatter_Type_PreProcessing($this);
291
    }
292
    
293
    public function toString() : string
294
    {
295
        $this->applyFormatting();
296
        
297
        return $this->subject->getString();
298
    }
299
300
   /**
301
    * Whether the formatting is done partially: missing placeholders
302
    * will simply be ignored.
303
    * 
304
    * @return bool
305
    */
306
    public function isPartial() : bool
307
    {
308
        return $this->partial;
309
    }
310
    
311
   /**
312
    * The formatting will ignore missing placeholders. Use this if the
313
    * formatting will be done on a text that may not contain all of the
314
    * initial placeholders anymore.
315
    * 
316
    * This is like the safeguard's makeWholePartial() method.
317
    * 
318
    * @return Mailcode_Parser_Safeguard_Formatting
319
    */
320
    public function makePartial() : Mailcode_Parser_Safeguard_Formatting
321
    {
322
        $this->partial = true;
323
        
324
        return $this;
325
    }
326
}
327