Completed
Push — master ( 64c14b...60e2f6 )
by Vojta
35:53 queued 28:45
created

Plugin::getSortByField()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
crap 1
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
     * Returns information about this plugin.
24
     *
25
     * @return array
26
     */
27
    public function pluginDetails()
28
    {
29
        return [
30
            'name'        => 'Twig Extensions',
31
            'description' => 'Add more Twig filters to your templates.',
32
            'author'      => 'Vojta Svoboda',
33
            'icon'        => 'icon-plus',
34
            'homepage'    => 'https://github.com/vojtasvoboda/oc-twigextensions-plugin',
35
        ];
36
    }
37
38 View Code Duplication
    public function boot()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

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