Passed
Push — master ( cd2614...13a961 )
by Sebastian
03:27
created

makePartial()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 10
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
   /**
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
    public function replaceWithHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
129
    {
130
        $formatter = $this->createHTMLHighlighting();
131
        
132
        $this->addFormatter($formatter);
133
        
134
        return $formatter;
135
    }
136
    
137
    public function applyFormatting() : void
138
    {
139
        if($this->applied)
140
        {
141
            return;
142
        }
143
        
144
        $this->applied = true;
145
        
146
        $this->validateFormatters();
147
        
148
        $this->applyFormatTypes();
149
        $this->applyReplaceTypes();
150
    }
151
152
    private function applyFormatTypes() : void
153
    {
154
        foreach($this->formatters as $formatter)
155
        {
156
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_FormatType)
157
            {
158
                $formatter->format();
159
            }
160
        }
161
    }
162
    
163
    private function applyReplaceTypes() : void
164
    {
165
        foreach($this->formatters as $formatter)
166
        {
167
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
168
            {
169
                $formatter->replace();
170
            }
171
        }
172
    }
173
    
174
    private function validateFormatters() : void
175
    {
176
        if(empty($this->formatters))
177
        {
178
            throw new Mailcode_Exception(
179
                'No formatters selected',
180
                'At least one formatter needs to be added for the formatting to work.',
181
                self::ERROR_NO_FORMATTERS_ADDED
182
            );
183
        }
184
        
185
        $amount = $this->countReplacers();
186
        
187
        if($amount > 1) 
188
        {
189
            throw new Mailcode_Exception(
190
                'More than one replacer formatter selected',
191
                'A maximum of 1 replacer formatter may be selected.',
192
                self::ERROR_TOO_MANY_REPLACERS
193
            );
194
        }
195
        
196
        // by default, at minimum the normalized formatter must be selected.
197
        if($amount === 0)
198
        {
199
            $this->replaceWithNormalized();
200
        }
201
    }
202
    
203
   /**
204
    * Counts the amount of replacer formatters that have been added.
205
    * 
206
    * @return int
207
    */
208
    private function countReplacers() : int
209
    {
210
        $count = 0;
211
        
212
        foreach($this->formatters as $formatter)
213
        {
214
            if($formatter instanceof Mailcode_Parser_Safeguard_Formatter_ReplacerType)
215
            {
216
                $count++;
217
            }
218
        }
219
        
220
        return $count;
221
    }
222
223
   /**
224
    * Creates a formatter that adds HTML syntax highlighting
225
    * for all commands in the specified string, intelligently
226
    * checking the location of the commands to ensure that they
227
    * can be syntax highlighted.
228
    * 
229
    * For example, commands in HTML attributes will not be
230
    * highlighted, as this would break the HTML.
231
    *  
232
    * @return Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
233
    */
234
    public function createHTMLHighlighting() : Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting
235
    {
236
        return new Mailcode_Parser_Safeguard_Formatter_Type_HTMLHighlighting($this);
237
    }
238
239
   /**
240
    * Creates the formatter that ensures that all commands
241
    * are placed on a separate line in the subject string.
242
    */
243
    public function createSingleLines() : Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
244
    {
245
        return new Mailcode_Parser_Safeguard_Formatter_Type_SingleLines($this);
246
    }
247
    
248
   /**
249
    * Creates the formatter that replaces all commands by
250
    * their normalized variants.
251
    * 
252
    * @return Mailcode_Parser_Safeguard_Formatter_Type_Normalized
253
    */
254
    public function createNormalized() : Mailcode_Parser_Safeguard_Formatter_Type_Normalized
255
    {
256
        return new Mailcode_Parser_Safeguard_Formatter_Type_Normalized($this);
257
    }
258
    
259
    public function createPlaceholders() : Mailcode_Parser_Safeguard_Formatter_Type_Placeholders
260
    {
261
        return new Mailcode_Parser_Safeguard_Formatter_Type_Placeholders($this);
262
    }
263
    
264
    public function createMarkVariables() : Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables
265
    {
266
        return new Mailcode_Parser_Safeguard_Formatter_Type_MarkVariables($this);
267
    }
268
    
269
    public function toString() : string
270
    {
271
        $this->applyFormatting();
272
        
273
        return $this->subject->getString();
274
    }
275
276
   /**
277
    * Whether the formatting is done partially: missing placeholders
278
    * will simply be ignored.
279
    * 
280
    * @return bool
281
    */
282
    public function isPartial() : bool
283
    {
284
        return $this->partial;
285
    }
286
    
287
   /**
288
    * The formatting will ignore missing placeholders. Use this if the
289
    * formatting will be done on a text that may not contain all of the
290
    * initial placeholders anymore.
291
    * 
292
    * This is like the safeguard's makeWholePartial() method.
293
    * 
294
    * @return Mailcode_Parser_Safeguard_Formatting
295
    */
296
    public function makePartial() : Mailcode_Parser_Safeguard_Formatting
297
    {
298
        $this->partial = true;
299
        
300
        return $this;
301
    }
302
}
303