Passed
Pull Request — master (#18)
by
unknown
09:22
created

ApacheVelocity::renderPrice()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 38
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
c 0
b 0
f 0
dl 0
loc 38
rs 8.5386
cc 7
nc 24
nop 4
1
<?php
2
/**
3
 * File containing the {@see \Mailcode\Translator\Syntax\ApacheVelocity} class.
4
 *
5
 * @package Mailcode
6
 * @subpackage Translator
7
 * @see \Mailcode\Translator\Syntax\ApacheVelocity
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode\Translator\Syntax;
13
14
use Mailcode\Interfaces\Commands\EncodableInterface;
15
use Mailcode\Mailcode_Commands_Command;
16
use Mailcode\Mailcode_Commands_Keywords;
17
use Mailcode\Mailcode_Number_Info;
18
use Mailcode\Mailcode_Number_LocalCurrency;
19
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral;
20
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_Variable;
21
use Mailcode\Translator\BaseCommandTranslation;
22
use function Mailcode\dollarize;
23
24
/**
25
 * Abstract base class for apache velocity command translation classes.
26
 *
27
 * @package Mailcode
28
 * @subpackage Translator
29
 * @author Sebastian Mordziol <[email protected]>
30
 */
31
abstract class ApacheVelocity extends BaseCommandTranslation
32
{
33
    /**
34
     * @var string[]
35
     */
36
    private array $regexSpecialChars = array(
37
        '?',
38
        '.',
39
        '[',
40
        ']',
41
        '|',
42
        '{',
43
        '}',
44
        '$',
45
        '*',
46
        '^',
47
        '+',
48
        '<',
49
        '>',
50
        '(',
51
        ')'
52
    );
53
54
    public function getLabel(): string
55
    {
56
        return 'Apache Velocity';
57
    }
58
59
    /**
60
     * Filters the string for use in an Apache Velocity (Java)
61
     * regex string: escapes all special characters.
62
     *
63
     * Velocity does its own escaping, so no need to escape special
64
     * characters as if they were a javascript string.
65
     *
66
     * @param string $string
67
     * @return string
68
     */
69
    public function filterRegexString(string $string): string
70
    {
71
        // Special case: previously escaped quotes.
72
        // To avoid modifying them, we strip them out.
73
        $string = str_replace('\\"', 'ESCQUOTE', $string);
74
75
        // Any other existing backslashes in the string
76
        // have to be double-escaped, giving four
77
        // backslashes in the java regex.
78
        $string = str_replace('\\', '\\\\', $string);
79
80
        // All other special characters have to be escaped
81
        // with two backslashes.
82
        foreach ($this->regexSpecialChars as $char) {
83
            $string = str_replace($char, '\\' . $char, $string);
84
        }
85
86
        // Restore the escaped quotes, which stay escaped
87
        // with a single backslash.
88
        $string = str_replace('ESCQUOTE', '\\"', $string);
89
90
        return $string;
91
    }
92
93
    protected function renderVariableEncodings(Mailcode_Commands_Command $command, string $varName): string
94
    {
95
        if (!$command instanceof EncodableInterface || !$command->hasActiveEncodings()) {
96
            return sprintf(
97
                '${%s}',
98
                $varName
99
            );
100
        }
101
102
        return $this->renderEncodings($command, dollarize($varName));
103
    }
104
105
    public function renderNumberFormat(string $varName, Mailcode_Number_Info $numberInfo, bool $absolute): string
106
    {
107
        $varName = dollarize($varName);
108
109
        if ($absolute) {
110
            $varName = sprintf('${numeric.abs(%s)}', $varName);
111
        }
112
113
        return sprintf(
114
            "numeric.format(%s, %s, '%s', '%s')",
115
            $varName,
116
            $numberInfo->getDecimals(),
117
            $numberInfo->getDecimalsSeparator(),
118
            $numberInfo->getThousandsSeparator()
119
        );
120
    }
121
122
    public function renderStringToNumber(string $varName): string
123
    {
124
        return sprintf(
125
            '$numeric.toNumber(%s)',
126
            dollarize($varName)
127
        );
128
    }
129
130
    public function renderPrice(string $varName, Mailcode_Number_LocalCurrency $localCurrency, bool $absolute = false, bool $withCurrencyName = true): string
131
    {
132
        $varName = dollarize($varName);
133
134
        if ($absolute) {
135
            $varName = sprintf('${numeric.abs(%s)}', $varName);
136
        }
137
138
        $numberInfo = $localCurrency->getFormatInfo();
139
140
        $currencyToken = $localCurrency->getCurrency();
141
        if ($currencyToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_Variable) {
0 ignored issues
show
introduced by
$currencyToken is always a sub-type of Mailcode\Mailcode_Parser...okenizer_Token_Variable.
Loading history...
142
            $displayedCurrency = $currencyToken->getNormalized();
143
        } else if ($currencyToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral) {
144
            $displayedCurrency = '"' . $currencyToken->getText() . '"';
145
        } else if ($withCurrencyName) {
146
            $displayedCurrency = '"' . $localCurrency->getCurrencyName() . '"';
147
        } else {
148
            $displayedCurrency = '"' . $localCurrency->getCurrencySymbol() . '"';
149
        }
150
151
        $regionToken = $localCurrency->getRegion();
152
        if ($regionToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_Variable) {
0 ignored issues
show
introduced by
$regionToken is always a sub-type of Mailcode\Mailcode_Parser...okenizer_Token_Variable.
Loading history...
153
            $displayedCountry = $regionToken->getNormalized();
154
        } else if ($regionToken instanceof Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral) {
155
            $displayedCountry = '"' . $regionToken->getText() . '"';
156
        } else {
157
            $displayedCountry = '"' . $localCurrency->getCountry() . '"';
158
        }
159
160
        return sprintf(
161
            'money.amount(%s, "%s").group("%s").unit(%s, %s).separator("%s")',
162
            $varName,
163
            $numberInfo->getDecimalsSeparator(),
164
            $numberInfo->getThousandsSeparator(),
165
            $displayedCurrency,
166
            $displayedCountry,
167
            $localCurrency->getUnitSeparator()
168
        );
169
    }
170
171
    public function renderQuotedValue(string $value): string
172
    {
173
        return sprintf(
174
            '"%s"',
175
            str_replace('"', '\"', $value)
176
        );
177
    }
178
179
    public function getSyntaxName(): string
180
    {
181
        return 'ApacheVelocity';
182
    }
183
184
    /**
185
     * @var array<string,string>
186
     */
187
    private array $encodingTemplates = array(
188
        Mailcode_Commands_Keywords::TYPE_URLENCODE => '${esc.url(%s)}',
189
        Mailcode_Commands_Keywords::TYPE_URLDECODE => '${esc.unurl(%s)}',
190
        Mailcode_Commands_Keywords::TYPE_IDN_ENCODE => '${text.idn(%s)}',
191
        Mailcode_Commands_Keywords::TYPE_IDN_DECODE => '${text.unidn(%s)}'
192
    );
193
194
    protected function renderEncodings(EncodableInterface $command, string $statement): string
195
    {
196
        $encodings = $command->getActiveEncodings();
197
        $result = $statement;
198
199
        foreach ($encodings as $encoding) {
200
            $result = $this->renderEncoding($encoding, $result, $command);
201
        }
202
203
        return $result;
204
    }
205
206
    protected function renderEncoding(string $keyword, string $result, EncodableInterface $command): string
0 ignored issues
show
Unused Code introduced by
The parameter $command is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

206
    protected function renderEncoding(string $keyword, string $result, /** @scrutinizer ignore-unused */ EncodableInterface $command): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
207
    {
208
        $template = $this->encodingTemplates[$keyword] ?? '%s';
209
210
        return sprintf($template, $result);
211
    }
212
}
213