getPlaceholder()   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_Formatter_Type_SingleLines} class.
4
 *
5
 * @package Mailcode
6
 * @subpackage Parser
7
 * @see Mailcode_Parser_Safeguard_Formatter_Type_SingleLines
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode;
13
14
/**
15
 * Abstract safeguard formatter location: this is where the decision
16
 * is made whether a specific placeholder instance needs to be 
17
 * transformed according to the formatter. 
18
 *
19
 * @package Mailcode
20
 * @subpackage Parser
21
 * @author Sebastian Mordziol <[email protected]>
22
 */
23
abstract class Mailcode_Parser_Safeguard_Formatter_Location
24
{
25
    public const ERROR_PLACEHOLDER_NOT_FOUND = 66001;
26
    
27
   /**
28
    * @var Mailcode_Parser_Safeguard_Formatter
29
    */
30
    protected $formatter;
31
    
32
   /**
33
    * @var string
34
    */
35
    protected $append = '';
36
37
   /**
38
    * @var string
39
    */
40
    protected $prepend = '';
41
    
42
   /**
43
    * @var Mailcode_Parser_Safeguard_Placeholder
44
    */
45
    protected $placeholder;
46
    
47
   /**
48
    * @var Mailcode_StringContainer
49
    */
50
    protected $subject;
51
    
52
   /**
53
    * @var string[]
54
    */
55
    protected $log = array();
56
    
57
    public function __construct(Mailcode_Parser_Safeguard_Formatter $formatter, Mailcode_Parser_Safeguard_Placeholder $placeholder)
58
    {
59
        $this->formatter = $formatter;
60
        $this->placeholder = $placeholder;
61
        $this->subject = $formatter->getSubject();
62
        
63
        $this->init();
64
    }
65
    
66
    abstract protected function init() : void; 
67
    
68
    abstract public function requiresAdjustment() : bool;
69
    
70
   /**
71
    * @return int|boolean
72
    */
73
    public function getStartPosition()
74
    {
75
        return $this->subject->getSubstrPosition($this->placeholder->getReplacementText());
76
    }
77
    
78
   /**
79
    * Checks whether the specified position within the string
80
    * is within another command's placeholder (excluding this
81
    * location's placeholder).
82
    * 
83
    * @param int $position
84
    * @return bool
85
    */
86
    public function isWithinCommand(int $position) : bool
87
    {
88
        $placeholders = $this->formatter->getSafeguard()->getPlaceholdersCollection()->getAll();
89
        
90
        $placeholderID = $this->placeholder->getID();
91
        
92
        foreach($placeholders as $placeholder)
93
        {
94
            if($placeholder->getID() === $placeholderID)
95
            {
96
                continue;
97
            }
98
            
99
            $start = $this->subject->getSubstrPosition($placeholder->getReplacementText());
100
            
101
            if($start === false)
102
            {
103
                continue;
104
            }
105
            
106
            $end = $start + $placeholder->getReplacementLength();
107
            
108
            if($position >= $start && $position <= $end)
109
            {
110
                return true;
111
            }
112
        }
113
        
114
        return false;
115
    }
116
    
117
   /**
118
    * @return int|boolean
119
    */
120
    public function getEndPosition()
121
    {
122
        $start = $this->getStartPosition();
123
        
124
        if($start !== false)
125
        {
126
            return $start + $this->placeholder->getReplacementLength();
127
        }
128
        
129
        return false;
130
    }
131
    
132
    public function getSubject() : Mailcode_StringContainer
133
    {
134
        return $this->subject;
135
    }
136
    
137
    public function getPlaceholder() : Mailcode_Parser_Safeguard_Placeholder
138
    {
139
        return $this->placeholder;
140
    }
141
    
142
   /**
143
    * Replaces the placeholder with the specified replacement text.
144
    * 
145
    * @param string $replacementText
146
    * @throws Mailcode_Exception
147
    * 
148
    * @see Mailcode_Parser_Safeguard_Formatter_Location::ERROR_PLACEHOLDER_NOT_FOUND
149
    */
150
    public function replaceWith(string $replacementText) : void
151
    {
152
        $needle = $this->placeholder->getReplacementText();
153
        
154
        if($this->subject->replaceSubstrings($needle, $replacementText))
155
        {
156
            return;
157
        }
158
        
159
        // Complain about missing placeholders only if we
160
        // are not in partial mode.
161
        if(!$this->formatter->getFormatting()->isPartial())
162
        {
163
            throw new Mailcode_Exception(
164
                'Could not find the placeholder to replace',
165
                sprintf(
166
                    'The placeholder [%s] was not found in the string, for command [%s]. Subject string: %s',
167
                    $needle,
168
                    $this->placeholder->getCommand()->getNormalized(),
169
                    PHP_EOL.'<br><pre>'.htmlspecialchars($this->subject->getString()).'</pre>'
170
                ),
171
                self::ERROR_PLACEHOLDER_NOT_FOUND
172
            );
173
        }
174
    }
175
    
176
    public function format() : void
177
    {
178
        if($this->requiresAdjustment() && (!empty($this->prepend) || !empty($this->append)))
179
        {
180
            $this->replaceWith(sprintf(
181
                '%s%s%s',
182
                $this->prepend,
183
                $this->placeholder->getReplacementText(),
184
                $this->append
185
            ));
186
        }
187
    }
188
    
189
    protected function log(string $message) : void
190
    {
191
        $this->log[] = sprintf(
192
            '%s Formatter | Command [%s] | %s',
193
            $this->formatter->getID(),
194
            $this->placeholder->getCommand()->getNormalized(),
195
            $message
196
        );
197
    }
198
    
199
   /**
200
    * Retrieves the location's log messages, if any.
201
    * @return string[]
202
    */
203
    public function getLog() : array
204
    {
205
        return $this->log;
206
    }
207
}
208