Passed
Push — master ( 05db97...b4e254 )
by Vojta
08:44
created

Plugin   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 414
Duplicated Lines 2.66 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 72.87%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 25
c 4
b 0
f 0
lcom 1
cbo 7
dl 11
loc 414
ccs 137
cts 188
cp 0.7287
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A pluginDetails() 0 10 1
A boot() 11 11 1
A getVarDumpFunction() 0 12 1
A registerMarkupTags() 0 51 2
A getStringLoaderFunctions() 0 12 1
A getTextFilters() 0 16 1
A getLocalizedFilters() 0 20 1
A getArrayFilters() 0 12 1
A getTimeFilters() 0 13 1
A getMailFilters() 0 8 1
A getPhpFunctions() 0 52 1
A getConfigFunction() 0 8 1
A getSessionFunction() 0 8 1
A getTransFunction() 0 8 1
C hideEmail() 0 35 7
A getFileRevision() 0 19 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
410
     *
411
     * @return string
412
     */
413
    private function getFileRevision()
414
    {
415
        return  [
416 1
                'revision' => function($filename, $format = null){
417
                    // Remove http/web address from the file name if there is one to load it locally
418
                    $prefix = url("/");
419
                    $filename_ = trim(preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $filename), '/');
420
                    if (file_exists($filename_))
421
                    {
422
                      $timestamp = filemtime($filename_);
423
                      $prepend = ($format) ? date($fomat, $timestamp) : $timestamp;
0 ignored issues
show
Bug introduced by
The variable $fomat does not exist. Did you mean $format?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
424
                      return $filename . "?" . $prepend;
425
                    }else
426
                    {
427
                      return $filename;
428
                    }
429 1
                },
430 1
             ];
431
    }
432
}
433