renderPrice()   B
last analyzed

Complexity

Conditions 7
Paths 24

Size

Total Lines 38
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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

193
    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...
194
    {
195
        $template = $this->encodingTemplates[$keyword] ?? '%s';
196
197
        return sprintf($template, $result);
198
    }
199
}
200