Completed
Pull Request — master (#28)
by Vojta
10:05
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 1
        $filters += $this->getPhpFunctions();
105 1
106
        return [
107
            'filters'   => $filters,
108
            'functions' => $functions,
109
        ];
110
    }
111
112
    /**
113
     * Returns String Loader functions.
114
     *
115 1
     * @param \Twig_Environment $twig
116
     *
117 1
     * @return array
118 1
     */
119
    private function getStringLoaderFunctions($twig)
120
    {
121
        $stringLoader = new Twig_Extension_StringLoader();
122 1
        $stringLoaderFunc = $stringLoader->getFunctions();
123 1
124
        return [
125 1
            'template_from_string' => function($template) use ($twig, $stringLoaderFunc) {
126
                $callable = $stringLoaderFunc[0]->getCallable();
127
                return $callable($twig, $template);
128
            }
129
        ];
130
    }
131
132
    /**
133
     * Returns Text filters.
134
     *
135 3
     * @param \Twig_Environment $twig
136
     *
137 1
     * @return array
138 1
     */
139
    private function getTextFilters($twig)
140
    {
141
        $textExtension = new Twig_Extensions_Extension_Text();
142 3
        $textFilters = $textExtension->getFilters();
143 3
144 1
        return [
145
            'truncate' => function($value, $length = 30, $preserve = false, $separator = '...') use ($twig, $textFilters) {
146 1
                $callable = $textFilters[0]->getCallable();
147 1
                return $callable($twig, $value, $length, $preserve, $separator);
148
            },
149 1
            'wordwrap' => function($value, $length = 80, $separator = "\n", $preserve = false) use ($twig, $textFilters) {
150
                $callable = $textFilters[1]->getCallable();
151
                return $callable($twig, $value, $length, $separator, $preserve);
152
            }
153
        ];
154
    }
155
156
    /**
157
     * Returns Intl filters.
158
     *
159 1
     * @param \Twig_Environment $twig
160
     *
161 1
     * @return array
162 1
     */
163
    private function getLocalizedFilters($twig)
164
    {
165
        $intlExtension = new Twig_Extensions_Extension_Intl();
166
        $intlFilters = $intlExtension->getFilters();
167
168 1
        return [
169
            'localizeddate' => function($date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null) use ($twig, $intlFilters) {
170
                $callable = $intlFilters[0]->getCallable();
171
                return $callable($twig, $date, $dateFormat, $timeFormat, $locale, $timezone, $format);
172 1
            },
173
            'localizednumber' => function($number, $style = 'decimal', $type = 'default', $locale = null) use ($twig, $intlFilters) {
174
                $callable = $intlFilters[1]->getCallable();
175
                return $callable($number, $style, $type, $locale);
176
            },
177 1
            'localizedcurrency' => function($number, $currency = null, $locale = null) use ($twig, $intlFilters) {
178
                $callable = $intlFilters[2]->getCallable();
179
                return $callable($number, $currency, $locale);
180
            }
181
        ];
182
    }
183
184
    /**
185 2
     * Returns Array filters.
186
     *
187 1
     * @return array
188 1
     */
189
    private function getArrayFilters()
190
    {
191
        $arrayExtension = new Twig_Extensions_Extension_Array();
192 2
        $arrayFilters = $arrayExtension->getFilters();
193 2
194
        return [
195 1
            'shuffle' => function($array) use ($arrayFilters) {
196
                $callable = $arrayFilters[0]->getCallable();
197
                return $callable($array);
198
            }
199
        ];
200
    }
201
202
    /**
203
     * Returns Date filters.
204
     *
205 1
     * @param \Twig_Environment $twig
206
     *
207 1
     * @return array
208 1
     */
209 1
    private function getTimeFilters($twig)
210
    {
211
        $translator = $this->app->make('time_diff_translator');
212
        $timeExtension = new Twig_Extensions_Extension_Date($translator);
213
        $timeFilters = $timeExtension->getFilters();
214
215
        return [
216 1
            'time_diff' => function($date, $now = null) use ($twig, $timeFilters) {
217
                $callable = $timeFilters[0]->getCallable();
218
                return $callable($twig, $date, $now);
219
            }
220
        ];
221
    }
222
223
    /**
224 1
     * Returns Sort by Field filters.
225
     *
226
     * @return array
227
     */
228 1
    private function getSortByField()
229
    {
230 1
        $extension = new SortByFieldExtension();
231
        $filters = $extension->getFilters();
232
233
        return [
234
            'sortbyfield' => function($array, $sort_by = null, $direction = 'asc') use ($filters) {
235
                $callable = $filters[0]->getCallable();
236
                return $callable($array, $sort_by, $direction);
237
            }
238 1
        ];
239
    }
240
241
    /**
242 1
     * Returns mail filters.
243 1
     *
244 1
     * @return array
245
     */
246 1
    private function getMailFilters()
247 1
    {
248
        return [
249 1
            'mailto' => function($string, $link = true, $protected = true, $text = null) {
250 1
                return $this->hideEmail($string, $link, $protected, $text);
251
            }
252 1
        ];
253 1
    }
254
255 1
    /**
256 1
     * Returns plain PHP functions.
257
     *
258 1
     * @return array
259 1
     */
260
    private function getPhpFunctions()
261 1
    {
262 1
        return [
263
            'strftime' => function($time, $format = '%d.%m.%Y %H:%M:%S') {
264 1
                $timeObj = new Carbon($time);
265 1
                return strftime($format, $timeObj->getTimestamp());
266
            },
267 1
            'uppercase' => function($string) {
268 1
                return mb_convert_case($string, MB_CASE_UPPER, "UTF-8");
269
            },
270 1
            'lowercase' => function($string) {
271 1
                return mb_convert_case($string, MB_CASE_LOWER, "UTF-8");
272
            },
273 1
            'ucfirst' => function($string) {
274 1
                return mb_convert_case($string, MB_CASE_TITLE, "UTF-8");
275
            },
276 1
            'lcfirst' => function($string) {
277 1
                return lcfirst($string);
278
            },
279 1
            'ltrim' => function($string, $charlist = " \t\n\r\0\x0B") {
280 1
                return ltrim($string, $charlist);
281
            },
282 1
            'rtrim' => function($string, $charlist = " \t\n\r\0\x0B") {
283 1
                return rtrim($string, $charlist);
284 1
            },
285
            'str_repeat' => function($string, $multiplier = 1) {
286 1
                return str_repeat($string, $multiplier);
287 1
            },
288 1
            'plural' => function($string, $count = 2) {
289
                return str_plural($string, $count);
290
            },
291
            'strpad' => function($string, $pad_length, $pad_string = ' ') {
292
                return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_BOTH);
293
            },
294
            'leftpad' => function($string, $pad_length, $pad_string = ' ') {
295
                return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_LEFT);
296 1
            },
297
            'rightpad' => function($string, $pad_length, $pad_string = ' ') {
298
                return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_RIGHT);
299
            },
300 1
            'rtl' => function($string) {
301 1
                return strrev($string);
302 1
            },
303
            'var_dump' => function($expression) {
304
                ob_start();
305
                var_dump($expression);
306
                $result = ob_get_clean();
307
308
                return $result;
309
            },
310 1
        ];
311
    }
312
313
    /**
314 1
     * Works like the config() helper function.
315 1
     *
316 1
     * @return array
317
     */
318
    private function getConfigFunction()
319
    {
320
        return [
321
            'config' => function($key = null, $default = null) {
322
                return config($key, $default);
323
            },
324 1
        ];
325
    }
326
327
    /**
328 1
     * Works like the session() helper function.
329 1
     *
330 1
     * @return array
331
     */
332
    private function getSessionFunction()
333
    {
334
        return [
335
            'session' => function($key = null) {
336
                return session($key);
337
            },
338
        ];
339
    }
340
341 1
    /**
342 1
     * Works like the trans() helper function.
343 1
     *
344 1
     * @return array
345
     */
346 1
    private function getTransFunction()
347 1
    {
348 1
        return [
349
            'trans' => function($key = null) {
350
                return trans($key);
351
            },
352
        ];
353
    }
354
355
    /**
356
     * Dumps information about a variable.
357
     *
358
     * @return array
359
     */
360
    private function getVarDumpFunction()
361
    {
362
        return [
363 1
            'var_dump' => function($expression) {
364
                ob_start();
365
                var_dump($expression);
366 1
                $result = ob_get_clean();
367 1
368 1
                return $result;
369 1
            },
370
        ];
371
    }
372 1
373 1
    /**
374
     * Create protected link with mailto:
375
     *
376
     * @param string $email Email to render.
377 1
     * @param bool $link If email should be rendered as link.
378 1
     * @param bool $protected If email should be protected.
379 1
     * @param string $text Link text. Render email by default.
380 1
     *
381 1
     * @see http://www.maurits.vdschee.nl/php_hide_email/
382 1
     *
383 1
     * @return string
384 1
     */
385 1
    private function hideEmail($email, $link = true, $protected = true, $text = null)
386 1
    {
387 1
        // email link text
388 1
        $linkText = $email;
389 1
        if ($text !== null) {
390 1
            $linkText = $text;
391 1
        }
392
393 1
        // if we want just unprotected link
394 1
        if (!$protected) {
395
            return $link ? '<a href="mailto:' . $email . '">' . $linkText . '</a>' : $linkText;
396 1
        }
397
398
        // turn on protection
399
        $character_set = '+-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
400
        $key = str_shuffle($character_set);
401
        $cipher_text = '';
402
        $id = 'e' . rand(1, 999999999);
403
        for ($i = 0; $i < strlen($email); $i += 1) $cipher_text .= $key[strpos($character_set, $email[$i])];
404
        $script = 'var a="' . $key . '";var b=a.split("").sort().join("");var c="' . $cipher_text . '";var d="";';
405
        $script .= 'for(var e=0;e<c.length;e++)d+=b.charAt(a.indexOf(c.charAt(e)));';
406
        $script .= 'var y = d;';
407
        if ($text !== null) {
408
            $script .= 'var y = "'.$text.'";';
409
        }
410
        if ($link) {
411
            $script .= 'document.getElementById("' . $id . '").innerHTML="<a href=\\"mailto:"+d+"\\">"+y+"</a>"';
412
        } else {
413
            $script .= 'document.getElementById("' . $id . '").innerHTML=y';
414
        }
415
        $script = "eval(\"" . str_replace(array("\\", '"'), array("\\\\", '\"'), $script) . "\")";
416
        $script = '<script type="text/javascript">/*<![CDATA[*/' . $script . '/*]]>*/</script>';
417
418
        return '<span id="' . $id . '">[javascript protected email address]</span>' . $script;
419
    }
420
}
421