Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
95.08% |
58 / 61 |
|
72.73% |
8 / 11 |
CRAP | |
0.00% |
0 / 1 |
extension | |
95.08% |
58 / 61 |
|
72.73% |
8 / 11 |
17 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getTokenParsers | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
getFilters | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getFunctions | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
getOperators | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
1 | |||
loop_subset | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
5 | |||
lang | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
3.04 | |||
lang_defined | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
lang_js | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
lang_raw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\template\twig; |
15 | |
16 | use Twig\Error\RuntimeError; |
17 | |
18 | class extension extends \Twig\Extension\AbstractExtension |
19 | { |
20 | /** @var \phpbb\template\context */ |
21 | protected $context; |
22 | |
23 | /** @var \phpbb\template\twig\environment */ |
24 | protected $environment; |
25 | |
26 | /** @var \phpbb\language\language */ |
27 | protected $language; |
28 | |
29 | /** |
30 | * Constructor |
31 | * |
32 | * @param \phpbb\template\context $context |
33 | * @param \phpbb\template\twig\environment $environment |
34 | * @param \phpbb\language\language $language |
35 | */ |
36 | public function __construct(\phpbb\template\context $context, \phpbb\template\twig\environment $environment, $language) |
37 | { |
38 | $this->context = $context; |
39 | $this->environment = $environment; |
40 | $this->language = $language; |
41 | } |
42 | |
43 | /** |
44 | * Get the name of this extension |
45 | * |
46 | * @return string |
47 | */ |
48 | public function getName() |
49 | { |
50 | return 'phpbb'; |
51 | } |
52 | |
53 | /** |
54 | * Returns the token parser instance to add to the existing list. |
55 | * |
56 | * @return \Twig\TokenParser\TokenParserInterface[] An array of \Twig\TokenParser\AbstractTokenParser instances |
57 | */ |
58 | public function getTokenParsers() |
59 | { |
60 | return array( |
61 | new \phpbb\template\twig\tokenparser\defineparser, |
62 | new \phpbb\template\twig\tokenparser\includeparser, |
63 | new \phpbb\template\twig\tokenparser\includejs, |
64 | new \phpbb\template\twig\tokenparser\includecss, |
65 | new \phpbb\template\twig\tokenparser\event($this->environment), |
66 | ); |
67 | } |
68 | |
69 | /** |
70 | * Returns a list of filters to add to the existing list. |
71 | * |
72 | * @return \Twig\TwigFilter[] An array of filters |
73 | */ |
74 | public function getFilters() |
75 | { |
76 | return array( |
77 | new \Twig\TwigFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), |
78 | // @deprecated 3.2.0 Uses twig's JS escape method instead of addslashes |
79 | new \Twig\TwigFilter('addslashes', 'addslashes'), |
80 | new \Twig\TwigFilter('int', 'intval'), |
81 | new \Twig\TwigFilter('float', 'floatval'), |
82 | ); |
83 | } |
84 | |
85 | /** |
86 | * Returns a list of global functions to add to the existing list. |
87 | * |
88 | * @return \Twig\TwigFunction[] An array of global functions |
89 | */ |
90 | public function getFunctions() |
91 | { |
92 | return array( |
93 | new \Twig\TwigFunction('lang', array($this, 'lang')), |
94 | new \Twig\TwigFunction('lang_defined', array($this, 'lang_defined')), |
95 | new \Twig\TwigFunction('lang_js', [$this, 'lang_js']), |
96 | new \Twig\TwigFunction('lang_raw', [$this, 'lang_raw']), |
97 | new \Twig\TwigFunction('get_class', 'get_class'), |
98 | ); |
99 | } |
100 | |
101 | /** |
102 | * Returns a list of operators to add to the existing list. |
103 | * |
104 | * @return array[] An array of operators |
105 | * @psalm-suppress LessSpecificImplementedReturnType |
106 | */ |
107 | public function getOperators() |
108 | { |
109 | return array( |
110 | array( |
111 | '!' => array('precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'), |
112 | ), |
113 | array( |
114 | // precedence settings are copied from similar operators in Twig core extension |
115 | '||' => array('precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
116 | '&&' => array('precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
117 | |
118 | 'eq' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
119 | |
120 | 'ne' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
121 | 'neq' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
122 | '<>' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
123 | |
124 | '===' => array('precedence' => 20, 'class' => '\phpbb\template\twig\node\expression\binary\equalequal', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
125 | '!==' => array('precedence' => 20, 'class' => '\phpbb\template\twig\node\expression\binary\notequalequal', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
126 | |
127 | 'gt' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
128 | 'gte' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
129 | 'ge' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
130 | 'lt' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
131 | 'lte' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
132 | 'le' => array('precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
133 | |
134 | 'mod' => array('precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\ModBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT), |
135 | ), |
136 | ); |
137 | } |
138 | |
139 | /** |
140 | * Grabs a subset of a loop |
141 | * |
142 | * @param \Twig\Environment $env A Twig\Environment instance |
143 | * @param mixed $item A variable |
144 | * @param integer $start Start of the subset |
145 | * @param integer $end End of the subset |
146 | * @param boolean $preserveKeys Whether to preserve key or not (when the input is an array) |
147 | * |
148 | * @return mixed The sliced variable |
149 | */ |
150 | public function loop_subset(\Twig\Environment $env, $item, $start, $end = null, $preserveKeys = false) |
151 | { |
152 | // We do almost the same thing as Twig's slice (array_slice), except when $end is positive |
153 | if ($end >= 1) |
154 | { |
155 | // When end is > 1, subset will end on the last item in an array with the specified $end |
156 | // This is different from slice in that it is the number we end on rather than the number |
157 | // of items to grab (length) |
158 | |
159 | // Start must always be the actual starting number for this calculation (not negative) |
160 | $start = ($start < 0) ? count($item) + $start : $start; |
161 | $end = $end - $start; |
162 | } |
163 | |
164 | // We always include the last element (this was the past design) |
165 | $end = ($end == -1 || $end === null) ? null : $end + 1; |
166 | |
167 | return twig_slice($env, $item, $start, $end, $preserveKeys); |
168 | } |
169 | |
170 | /** |
171 | * Get output for a language variable (L_FOO, LA_FOO) |
172 | * |
173 | * This function checks to see if the language var was outputted to $context |
174 | * (e.g. in the ACP, L_TITLE) |
175 | * If not, we return the result of $user->lang() |
176 | * |
177 | * @return string |
178 | */ |
179 | public function lang() |
180 | { |
181 | $args = func_get_args(); |
182 | $key = $args[0]; |
183 | |
184 | $context_vars = $this->context->get_root_ref(); |
185 | |
186 | if (is_string($key) && isset($context_vars['L_' . $key])) |
187 | { |
188 | return $context_vars['L_' . $key]; |
189 | } |
190 | |
191 | // LA_ is transformed into lang(\'$1\')|escape('js'), so we should not |
192 | // need to check for it |
193 | |
194 | return call_user_func_array(array($this->language, 'lang'), $args); |
195 | } |
196 | |
197 | /** |
198 | * Check if a language variable exists |
199 | * |
200 | * @return bool |
201 | */ |
202 | public function lang_defined($key) |
203 | { |
204 | return call_user_func_array([$this->language, 'is_set'], [$key]); |
205 | } |
206 | |
207 | /** |
208 | * Get output for language variable in JS code |
209 | * |
210 | * @throws RuntimeError When data passed to twig_escape_filter is not a UTF8 string |
211 | */ |
212 | public function lang_js(): string |
213 | { |
214 | $args = func_get_args(); |
215 | |
216 | return twig_escape_filter($this->environment, call_user_func_array([$this, 'lang'], $args), 'js'); |
217 | } |
218 | |
219 | /** |
220 | * Get raw value associated with lang key |
221 | * |
222 | * @param string $key |
223 | * |
224 | * @return array|string Raw value associated with lang key |
225 | */ |
226 | public function lang_raw(string $key): array|string |
227 | { |
228 | return call_user_func_array(array($this->language, 'lang_raw'), [$key]); |
229 | } |
230 | } |