These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace VojtaSvoboda\TwigExtensions; |
||
2 | |||
3 | use App; |
||
4 | use Backend; |
||
5 | use Carbon\Carbon; |
||
6 | use Snilius\Twig\SortByFieldExtension; |
||
7 | use System\Classes\PluginBase; |
||
8 | use Twig_Extension_StringLoader; |
||
9 | use Twig_Extensions_Extension_Array; |
||
10 | use Twig_Extensions_Extension_Date; |
||
11 | use Twig_Extensions_Extension_Intl; |
||
12 | use Twig_Extensions_Extension_Text; |
||
13 | use VojtaSvoboda\TwigExtensions\Classes\TimeDiffTranslator; |
||
14 | |||
15 | /** |
||
16 | * Twig Extensions Plugin. |
||
17 | * |
||
18 | * @see http://twig.sensiolabs.org/doc/extensions/index.html#extensions-install |
||
19 | */ |
||
20 | class Plugin extends PluginBase |
||
21 | { |
||
22 | /** |
||
23 | * @var boolean Determine if this plugin should have elevated privileges. |
||
24 | */ |
||
25 | public $elevated = true; |
||
26 | |||
27 | /** |
||
28 | * Returns information about this plugin. |
||
29 | * |
||
30 | * @return array |
||
31 | */ |
||
32 | public function pluginDetails() |
||
33 | { |
||
34 | return [ |
||
35 | 'name' => 'Twig Extensions', |
||
36 | 'description' => 'Add more Twig filters to your templates.', |
||
37 | 'author' => 'Vojta Svoboda', |
||
38 | 'icon' => 'icon-plus', |
||
39 | 'homepage' => 'https://github.com/vojtasvoboda/oc-twigextensions-plugin', |
||
40 | ]; |
||
41 | } |
||
42 | |||
43 | View Code Duplication | public function boot() |
|
0 ignored issues
–
show
|
|||
44 | { |
||
45 | $this->app->singleton('time_diff_translator', function ($app) { |
||
46 | $loader = $app->make('translation.loader'); |
||
47 | $locale = $app->config->get('app.locale'); |
||
48 | $translator = $app->make(TimeDiffTranslator::class, [$loader, $locale]); |
||
49 | $translator->setFallback($app->config->get('app.fallback_locale')); |
||
50 | |||
51 | return $translator; |
||
52 | }); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Add Twig extensions. |
||
57 | * |
||
58 | * @see Text extensions http://twig.sensiolabs.org/doc/extensions/text.html |
||
59 | * @see Intl extensions http://twig.sensiolabs.org/doc/extensions/intl.html |
||
60 | * @see Array extension http://twig.sensiolabs.org/doc/extensions/array.html |
||
61 | * @see Time extension http://twig.sensiolabs.org/doc/extensions/date.html |
||
62 | * |
||
63 | * @return array |
||
64 | */ |
||
65 | public function registerMarkupTags() |
||
66 | { |
||
67 | $filters = []; |
||
68 | $functions = []; |
||
69 | |||
70 | // init Twig |
||
71 | $twig = $this->app->make('twig.environment'); |
||
72 | |||
73 | // add String Loader functions |
||
74 | $functions += $this->getStringLoaderFunctions($twig); |
||
75 | |||
76 | // add Config function |
||
77 | $functions += $this->getConfigFunction(); |
||
78 | |||
79 | // add Env function |
||
80 | $functions += $this->getEnvFunction(); |
||
81 | |||
82 | // add Session function |
||
83 | $functions += $this->getSessionFunction(); |
||
84 | |||
85 | // add Trans function |
||
86 | $functions += $this->getTransFunction(); |
||
87 | |||
88 | // add var_dump function |
||
89 | $functions += $this->getVarDumpFunction(); |
||
90 | |||
91 | // add Text extensions |
||
92 | $filters += $this->getTextFilters($twig); |
||
93 | |||
94 | // add Intl extensions if php5-intl installed |
||
95 | if (class_exists('IntlDateFormatter')) { |
||
96 | $filters += $this->getLocalizedFilters($twig); |
||
97 | } |
||
98 | |||
99 | // add Array extensions |
||
100 | $filters += $this->getArrayFilters(); |
||
101 | |||
102 | // add Time extensions |
||
103 | $filters += $this->getTimeFilters($twig); |
||
104 | |||
105 | // add Sort by Field extensions |
||
106 | $filters += $this->getSortByField(); |
||
107 | |||
108 | // add Mail filters |
||
109 | $filters += $this->getMailFilters(); |
||
110 | |||
111 | // add PHP functions |
||
112 | $filters += $this->getPhpFunctions(); |
||
113 | |||
114 | // add File Version filter |
||
115 | $filters += $this->getFileRevision(); |
||
116 | |||
117 | return [ |
||
118 | 'filters' => $filters, |
||
119 | 'functions' => $functions, |
||
120 | ]; |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * Returns String Loader functions. |
||
125 | * |
||
126 | * @param \Twig_Environment $twig |
||
127 | * |
||
128 | * @return array |
||
129 | */ |
||
130 | private function getStringLoaderFunctions($twig) |
||
131 | { |
||
132 | $stringLoader = new Twig_Extension_StringLoader(); |
||
133 | $stringLoaderFunc = $stringLoader->getFunctions(); |
||
134 | |||
135 | return [ |
||
136 | 'template_from_string' => function ($template) use ($twig, $stringLoaderFunc) { |
||
137 | $callable = $stringLoaderFunc[0]->getCallable(); |
||
138 | return $callable($twig, $template); |
||
139 | } |
||
140 | ]; |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Returns Text filters. |
||
145 | * |
||
146 | * @param \Twig_Environment $twig |
||
147 | * |
||
148 | * @return array |
||
149 | */ |
||
150 | private function getTextFilters($twig) |
||
151 | { |
||
152 | $textExtension = new Twig_Extensions_Extension_Text(); |
||
153 | $textFilters = $textExtension->getFilters(); |
||
154 | |||
155 | return [ |
||
156 | 'truncate' => function ($value, $length = 30, $preserve = false, $separator = '...') use ($twig, $textFilters) { |
||
157 | $callable = $textFilters[0]->getCallable(); |
||
158 | return $callable($twig, $value, $length, $preserve, $separator); |
||
159 | }, |
||
160 | 'wordwrap' => function ($value, $length = 80, $separator = "\n", $preserve = false) use ($twig, $textFilters) { |
||
161 | $callable = $textFilters[1]->getCallable(); |
||
162 | return $callable($twig, $value, $length, $separator, $preserve); |
||
163 | } |
||
164 | ]; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Returns Intl filters. |
||
169 | * |
||
170 | * @param \Twig_Environment $twig |
||
171 | * |
||
172 | * @return array |
||
173 | */ |
||
174 | private function getLocalizedFilters($twig) |
||
175 | { |
||
176 | $intlExtension = new Twig_Extensions_Extension_Intl(); |
||
177 | $intlFilters = $intlExtension->getFilters(); |
||
178 | |||
179 | return [ |
||
180 | 'localizeddate' => function ($date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null) use ($twig, $intlFilters) { |
||
181 | $callable = $intlFilters[0]->getCallable(); |
||
182 | return $callable($twig, $date, $dateFormat, $timeFormat, $locale, $timezone, $format); |
||
183 | }, |
||
184 | 'localizednumber' => function ($number, $style = 'decimal', $type = 'default', $locale = null) use ($twig, $intlFilters) { |
||
185 | $callable = $intlFilters[1]->getCallable(); |
||
186 | return $callable($number, $style, $type, $locale); |
||
187 | }, |
||
188 | 'localizedcurrency' => function ($number, $currency = null, $locale = null) use ($twig, $intlFilters) { |
||
189 | $callable = $intlFilters[2]->getCallable(); |
||
190 | return $callable($number, $currency, $locale); |
||
191 | } |
||
192 | ]; |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * Returns Array filters. |
||
197 | * |
||
198 | * @return array |
||
199 | */ |
||
200 | private function getArrayFilters() |
||
201 | { |
||
202 | $arrayExtension = new Twig_Extensions_Extension_Array(); |
||
203 | $arrayFilters = $arrayExtension->getFilters(); |
||
204 | |||
205 | return [ |
||
206 | 'shuffle' => function ($array) use ($arrayFilters) { |
||
207 | $callable = $arrayFilters[0]->getCallable(); |
||
208 | return $callable($array); |
||
209 | } |
||
210 | ]; |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Returns Date filters. |
||
215 | * |
||
216 | * @param \Twig_Environment $twig |
||
217 | * |
||
218 | * @return array |
||
219 | */ |
||
220 | private function getTimeFilters($twig) |
||
221 | { |
||
222 | $translator = $this->app->make('time_diff_translator'); |
||
223 | $timeExtension = new Twig_Extensions_Extension_Date($translator); |
||
224 | $timeFilters = $timeExtension->getFilters(); |
||
225 | |||
226 | return [ |
||
227 | 'time_diff' => function ($date, $now = null) use ($twig, $timeFilters) { |
||
228 | $callable = $timeFilters[0]->getCallable(); |
||
229 | return $callable($twig, $date, $now); |
||
230 | } |
||
231 | ]; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Returns Sort by Field filters. |
||
236 | * |
||
237 | * @return array |
||
238 | */ |
||
239 | private function getSortByField() |
||
240 | { |
||
241 | $extension = new SortByFieldExtension(); |
||
242 | $filters = $extension->getFilters(); |
||
243 | |||
244 | return [ |
||
245 | 'sortbyfield' => function ($array, $sort_by = null, $direction = 'asc') use ($filters) { |
||
246 | $callable = $filters[0]->getCallable(); |
||
247 | return $callable($array, $sort_by, $direction); |
||
248 | } |
||
249 | ]; |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Returns mail filters. |
||
254 | * |
||
255 | * @return array |
||
256 | */ |
||
257 | private function getMailFilters() |
||
258 | { |
||
259 | return [ |
||
260 | 'mailto' => function ($string, $link = true, $protected = true, $text = null, $class = "") { |
||
261 | return $this->hideEmail($string, $link, $protected, $text, $class); |
||
262 | } |
||
263 | ]; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Returns plain PHP functions. |
||
268 | * |
||
269 | * @return array |
||
270 | */ |
||
271 | private function getPhpFunctions() |
||
272 | { |
||
273 | return [ |
||
274 | 'strftime' => function ($time, $format = '%d.%m.%Y %H:%M:%S') { |
||
275 | $timeObj = new Carbon($time); |
||
276 | return strftime($format, $timeObj->getTimestamp()); |
||
277 | }, |
||
278 | 'uppercase' => function ($string) { |
||
279 | return mb_convert_case($string, MB_CASE_UPPER, "UTF-8"); |
||
280 | }, |
||
281 | 'lowercase' => function ($string) { |
||
282 | return mb_convert_case($string, MB_CASE_LOWER, "UTF-8"); |
||
283 | }, |
||
284 | 'ucfirst' => function ($string) { |
||
285 | return ucfirst($string); |
||
286 | }, |
||
287 | 'lcfirst' => function ($string) { |
||
288 | return lcfirst($string); |
||
289 | }, |
||
290 | 'ltrim' => function ($string, $charlist = " \t\n\r\0\x0B") { |
||
291 | return ltrim($string, $charlist); |
||
292 | }, |
||
293 | 'rtrim' => function ($string, $charlist = " \t\n\r\0\x0B") { |
||
294 | return rtrim($string, $charlist); |
||
295 | }, |
||
296 | 'str_repeat' => function ($string, $multiplier = 1) { |
||
297 | return str_repeat($string, $multiplier); |
||
298 | }, |
||
299 | 'plural' => function ($string, $count = 2) { |
||
300 | return str_plural($string, $count); |
||
301 | }, |
||
302 | 'strpad' => function ($string, $pad_length, $pad_string = ' ') { |
||
303 | return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_BOTH); |
||
304 | }, |
||
305 | 'leftpad' => function ($string, $pad_length, $pad_string = ' ') { |
||
306 | return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_LEFT); |
||
307 | }, |
||
308 | 'rightpad' => function ($string, $pad_length, $pad_string = ' ') { |
||
309 | return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_RIGHT); |
||
310 | }, |
||
311 | 'rtl' => function ($string) { |
||
312 | return strrev($string); |
||
313 | }, |
||
314 | 'str_replace' => function ($string, $search, $replace) { |
||
315 | return str_replace($search, $replace, $string); |
||
316 | }, |
||
317 | 'strip_tags' => function ($string, $allow = '') { |
||
318 | return strip_tags($string, $allow); |
||
319 | }, |
||
320 | 'var_dump' => function ($expression) { |
||
321 | ob_start(); |
||
322 | var_dump($expression); |
||
323 | $result = ob_get_clean(); |
||
324 | |||
325 | return $result; |
||
326 | }, |
||
327 | ]; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Works like the config() helper function. |
||
332 | * |
||
333 | * @return array |
||
334 | */ |
||
335 | private function getConfigFunction() |
||
336 | { |
||
337 | return [ |
||
338 | 'config' => function ($key = null, $default = null) { |
||
339 | return config($key, $default); |
||
340 | }, |
||
341 | ]; |
||
342 | } |
||
343 | |||
344 | /** |
||
345 | * Works like the env() helper function. |
||
346 | * |
||
347 | * @return array |
||
348 | */ |
||
349 | private function getEnvFunction() |
||
350 | { |
||
351 | return [ |
||
352 | 'env' => function ($key, $default = null) { |
||
353 | return env($key, $default); |
||
354 | }, |
||
355 | ]; |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Works like the session() helper function. |
||
360 | * |
||
361 | * @return array |
||
362 | */ |
||
363 | private function getSessionFunction() |
||
364 | { |
||
365 | return [ |
||
366 | 'session' => function ($key = null) { |
||
367 | return session($key); |
||
368 | }, |
||
369 | ]; |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * Works like the trans() helper function. |
||
374 | * |
||
375 | * @return array |
||
376 | */ |
||
377 | private function getTransFunction() |
||
378 | { |
||
379 | return [ |
||
380 | 'trans' => function ($key = null, $parameters = []) { |
||
381 | return trans($key, $parameters); |
||
382 | }, |
||
383 | ]; |
||
384 | } |
||
385 | |||
386 | /** |
||
387 | * Dumps information about a variable. |
||
388 | * |
||
389 | * @return array |
||
390 | */ |
||
391 | private function getVarDumpFunction() |
||
392 | { |
||
393 | return [ |
||
394 | 'var_dump' => function ($expression) { |
||
395 | ob_start(); |
||
396 | var_dump($expression); |
||
397 | $result = ob_get_clean(); |
||
398 | |||
399 | return $result; |
||
400 | }, |
||
401 | ]; |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * Create protected link with mailto: |
||
406 | * |
||
407 | * @param string $email Email to render. |
||
408 | * @param bool $link If email should be rendered as link. |
||
409 | * @param bool $protected If email should be protected. |
||
410 | * @param string $text Link text. Render email by default. |
||
411 | * |
||
412 | * @see http://www.maurits.vdschee.nl/php_hide_email/ |
||
413 | * |
||
414 | * @return string |
||
415 | */ |
||
416 | private function hideEmail($email, $link = true, $protected = true, $text = null, $class = "") |
||
417 | { |
||
418 | // email link text |
||
419 | $linkText = $email; |
||
420 | if ($text !== null) { |
||
421 | $linkText = $text; |
||
422 | } |
||
423 | |||
424 | // if we want just unprotected link |
||
425 | if (!$protected) { |
||
426 | return $link ? '<a href="mailto:' . $email . '">' . $linkText . '</a>' : $linkText; |
||
427 | } |
||
428 | |||
429 | // turn on protection |
||
430 | $character_set = '+-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; |
||
431 | $key = str_shuffle($character_set); |
||
432 | $cipher_text = ''; |
||
433 | $id = 'e' . rand(1, 999999999); |
||
434 | for ($i = 0; $i < strlen($email); $i += 1) { |
||
435 | $cipher_text .= $key[strpos($character_set, $email[$i])]; |
||
436 | } |
||
437 | $script = 'var a="' . $key . '";var b=a.split("").sort().join("");var c="' . $cipher_text . '";var d=""; var cl="'.$class.'";'; |
||
438 | $script .= 'for(var e=0;e<c.length;e++)d+=b.charAt(a.indexOf(c.charAt(e)));'; |
||
439 | $script .= 'var y = d;'; |
||
440 | if ($text !== null) { |
||
441 | $script .= 'var y = "'.$text.'";'; |
||
442 | } |
||
443 | if ($link) { |
||
444 | $script .= 'document.getElementById("' . $id . '").innerHTML="<a class=\""+cl+"\" href=\\"mailto:"+d+"\\">"+y+"</a>"'; |
||
445 | } else { |
||
446 | $script .= 'document.getElementById("' . $id . '").innerHTML=y'; |
||
447 | } |
||
448 | $script = "eval(\"" . str_replace(array("\\", '"'), array("\\\\", '\"'), $script) . "\")"; |
||
449 | $script = '<script type="text/javascript">/*<![CDATA[*/' . $script . '/*]]>*/</script>'; |
||
450 | |||
451 | return '<span id="' . $id . '">[javascript protected email address]</span>' . $script; |
||
452 | } |
||
453 | |||
454 | /** |
||
455 | * Appends this pattern: ? . {last modified date} |
||
456 | * to an assets filename to force browser to reload |
||
457 | * cached modified file. |
||
458 | * |
||
459 | * See: https://github.com/vojtasvoboda/oc-twigextensions-plugin/issues/25 |
||
460 | * |
||
461 | * @return array |
||
462 | */ |
||
463 | private function getFileRevision() |
||
464 | { |
||
465 | return [ |
||
466 | 'revision' => function ($filename, $format = null) { |
||
467 | // Remove http/web address from the file name if there is one to load it locally |
||
468 | $prefix = url('/'); |
||
469 | $filename_ = trim(preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $filename), '/'); |
||
470 | if (file_exists($filename_)) { |
||
471 | $timestamp = filemtime($filename_); |
||
472 | $prepend = ($format) ? date($format, $timestamp) : $timestamp; |
||
473 | |||
474 | return $filename . "?" . $prepend; |
||
475 | } |
||
476 | |||
477 | return $filename; |
||
478 | }, |
||
479 | ]; |
||
480 | } |
||
481 | } |
||
482 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.