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
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Twig Extensions Plugin |
15
|
|
|
* - add more Twig filters to your template |
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
|
|
|
]; |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Add Twig extensions |
38
|
|
|
* |
39
|
|
|
* @see Text extensions http://twig.sensiolabs.org/doc/extensions/text.html |
40
|
|
|
* @see Intl extensions http://twig.sensiolabs.org/doc/extensions/intl.html |
41
|
|
|
* @see Array extension http://twig.sensiolabs.org/doc/extensions/array.html |
42
|
|
|
* @see Time extension http://twig.sensiolabs.org/doc/extensions/date.html |
43
|
|
|
* |
44
|
|
|
* @return array |
45
|
|
|
*/ |
46
|
1 |
|
public function registerMarkupTags() |
47
|
|
|
{ |
48
|
1 |
|
$filters = []; |
49
|
1 |
|
$functions = []; |
50
|
|
|
|
51
|
|
|
// init Twig |
52
|
1 |
|
$twig = App::make('twig.environment'); |
53
|
|
|
|
54
|
|
|
// add String Loader functions |
55
|
1 |
|
$functions += $this->getStringLoaderFunctions($twig); |
56
|
|
|
|
57
|
|
|
// add Config function |
58
|
1 |
|
$functions += $this->getConfigFunction(); |
59
|
|
|
|
60
|
|
|
// add Text extensions |
61
|
1 |
|
$filters += $this->getTextFilters($twig); |
62
|
1 |
|
|
63
|
1 |
|
// add Intl extensions if php5-intl installed |
64
|
|
|
if (class_exists('IntlDateFormatter')) { |
65
|
|
|
$filters += $this->getLocalizedFilters($twig); |
66
|
1 |
|
} |
67
|
|
|
|
68
|
|
|
// add Array extensions |
69
|
1 |
|
$filters += $this->getArrayFilters($twig); |
70
|
|
|
|
71
|
|
|
// add Time extensions |
72
|
1 |
|
$filters += $this->getTimeFilters($twig); |
73
|
|
|
|
74
|
|
|
// add PHP functions |
75
|
1 |
|
$filters += $this->getPhpFunctions(); |
76
|
|
|
|
77
|
1 |
|
return [ |
78
|
|
|
'filters' => $filters, |
79
|
|
|
'functions' => $functions |
80
|
|
|
]; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Returns String Loader functions |
85
|
|
|
* |
86
|
|
|
* @param \Twig_Environment $twig |
87
|
1 |
|
* |
88
|
|
|
* @return array |
89
|
1 |
|
*/ |
90
|
1 |
|
private function getStringLoaderFunctions($twig) |
91
|
|
|
{ |
92
|
|
|
$stringLoader = new Twig_Extension_StringLoader(); |
93
|
|
|
$stringLoaderFunc = $stringLoader->getFunctions(); |
94
|
1 |
|
|
95
|
1 |
|
return [ |
96
|
|
|
'template_from_string' => function($template) use ($twig, $stringLoaderFunc) { |
97
|
1 |
|
$callable = $stringLoaderFunc[0]->getCallable(); |
98
|
|
|
return $callable($twig, $template); |
99
|
|
|
} |
100
|
|
|
]; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Returns Text filters |
105
|
|
|
* |
106
|
|
|
* @param \Twig_Environment $twig |
107
|
3 |
|
* |
108
|
|
|
* @return array |
109
|
1 |
|
*/ |
110
|
1 |
|
private function getTextFilters($twig) |
111
|
|
|
{ |
112
|
|
|
$textExtension = new Twig_Extensions_Extension_Text(); |
113
|
|
|
$textFilters = $textExtension->getFilters(); |
114
|
3 |
|
|
115
|
3 |
|
return [ |
116
|
1 |
View Code Duplication |
'truncate' => function($value, $length = 30, $preserve = false, $separator = '...') use ($twig, $textFilters) { |
|
|
|
|
117
|
|
|
$callable = $textFilters[0]->getCallable(); |
118
|
1 |
|
return $callable($twig, $value, $length, $preserve, $separator); |
119
|
1 |
|
}, |
120
|
|
View Code Duplication |
'wordwrap' => function($value, $length = 80, $separator = "\n", $preserve = false) use ($twig, $textFilters) { |
|
|
|
|
121
|
1 |
|
$callable = $textFilters[1]->getCallable(); |
122
|
|
|
return $callable($twig, $value, $length, $separator, $preserve); |
123
|
|
|
} |
124
|
|
|
]; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Returns Intl filters |
129
|
|
|
* |
130
|
|
|
* @param \Twig_Environment $twig |
131
|
1 |
|
* |
132
|
|
|
* @return array |
133
|
1 |
|
*/ |
134
|
1 |
|
private function getLocalizedFilters($twig) |
135
|
|
|
{ |
136
|
|
|
$intlExtension = new Twig_Extensions_Extension_Intl(); |
137
|
|
|
$intlFilters = $intlExtension->getFilters(); |
138
|
|
|
|
139
|
|
|
return [ |
140
|
1 |
|
'localizeddate' => function($date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null) use ($twig, $intlFilters) { |
141
|
|
|
$callable = $intlFilters[0]->getCallable(); |
142
|
|
|
return $callable($twig, $date, $dateFormat, $timeFormat, $locale, $timezone, $format); |
143
|
|
|
}, |
144
|
1 |
|
'localizednumber' => function($number, $style = 'decimal', $type = 'default', $locale = null) use ($twig, $intlFilters) { |
145
|
|
|
$callable = $intlFilters[1]->getCallable(); |
146
|
|
|
return $callable($twig, $number, $style, $type, $locale); |
147
|
|
|
}, |
148
|
|
|
'localizedcurrency' => function($number, $currency = null, $locale = null) use ($twig, $intlFilters) { |
149
|
1 |
|
$callable = $intlFilters[2]->getCallable(); |
150
|
|
|
return $callable($twig, $number, $currency, $locale); |
151
|
|
|
} |
152
|
|
|
]; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Returns Array filters |
157
|
|
|
* |
158
|
|
|
* @param \Twig_Environment $twig |
159
|
1 |
|
* |
160
|
|
|
* @return array |
161
|
1 |
|
*/ |
162
|
1 |
|
private function getArrayFilters($twig) |
163
|
|
|
{ |
164
|
|
|
$arrayExtension = new Twig_Extensions_Extension_Array(); |
165
|
|
|
$arrayFilters = $arrayExtension->getFilters(); |
166
|
|
|
|
167
|
|
|
return [ |
168
|
|
|
'shuffle' => function($array) use ($twig, $arrayFilters) { |
169
|
1 |
|
$callable = $arrayFilters[0]->getCallable(); |
170
|
|
|
return $callable($twig, $array); |
171
|
|
|
} |
172
|
|
|
]; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Returns Date filters |
177
|
|
|
* |
178
|
|
|
* @param \Twig_Environment $twig |
179
|
1 |
|
* |
180
|
|
|
* @return array |
181
|
1 |
|
*/ |
182
|
1 |
|
private function getTimeFilters($twig) |
183
|
|
|
{ |
184
|
|
|
$timeExtension = new Twig_Extensions_Extension_Date(); |
185
|
|
|
$timeFilters = $timeExtension->getFilters(); |
186
|
1 |
|
|
187
|
1 |
|
return [ |
188
|
|
|
'time_diff' => function($date, $now = null) use ($twig, $timeFilters) { |
189
|
1 |
|
$callable = $timeFilters[0]->getCallable(); |
190
|
|
|
return $callable($twig, $date, $now); |
191
|
|
|
} |
192
|
|
|
]; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Returns plain PHP functions |
197
|
1 |
|
* |
198
|
|
|
* @return array |
199
|
|
|
*/ |
200
|
|
|
private function getPhpFunctions() |
201
|
1 |
|
{ |
202
|
1 |
|
return [ |
203
|
1 |
|
'strftime' => function($time, $format = '%d.%m.%Y %H:%M:%S') { |
204
|
|
|
$timeObj = new Carbon($time); |
205
|
1 |
|
return strftime($format, $timeObj->getTimestamp()); |
206
|
1 |
|
}, |
207
|
|
|
'uppercase' => function($string) { |
208
|
1 |
|
return mb_convert_case($string, MB_CASE_UPPER, "UTF-8"); |
209
|
1 |
|
}, |
210
|
|
|
'lowercase' => function($string) { |
211
|
1 |
|
return mb_convert_case($string, MB_CASE_LOWER, "UTF-8"); |
212
|
1 |
|
}, |
213
|
|
|
'ucfirst' => function($string) { |
214
|
1 |
|
return mb_convert_case($string, MB_CASE_TITLE, "UTF-8"); |
215
|
1 |
|
}, |
216
|
|
|
'lcfirst' => function($string) { |
217
|
1 |
|
return lcfirst($string); |
218
|
1 |
|
}, |
219
|
|
|
'ltrim' => function($string, $charlist = " \t\n\r\0\x0B") { |
220
|
1 |
|
return ltrim($string, $charlist); |
221
|
1 |
|
}, |
222
|
|
|
'rtrim' => function($string, $charlist = " \t\n\r\0\x0B") { |
223
|
1 |
|
return rtrim($string, $charlist); |
224
|
1 |
|
}, |
225
|
|
|
'str_repeat' => function($string, $multiplier = 1) { |
226
|
1 |
|
return str_repeat($string, $multiplier); |
227
|
1 |
|
}, |
228
|
|
|
'plural' => function($string, $count = 2) { |
229
|
1 |
|
return str_plural($string, $count); |
230
|
1 |
|
}, |
231
|
|
|
'strpad' => function($string, $pad_length, $pad_string = ' ') { |
232
|
1 |
|
return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_BOTH); |
233
|
1 |
|
}, |
234
|
1 |
|
'leftpad' => function($string, $pad_length, $pad_string = ' ') { |
235
|
1 |
|
return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_LEFT); |
236
|
1 |
|
}, |
237
|
1 |
|
'rightpad' => function($string, $pad_length, $pad_string = ' ') { |
238
|
|
|
return str_pad($string, $pad_length, $pad_string, $pad_type = STR_PAD_RIGHT); |
239
|
|
|
}, |
240
|
|
|
]; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* Works like the config() function |
245
|
|
|
* |
246
|
|
|
* @return array |
247
|
|
|
*/ |
248
|
|
|
private function getConfigFunction() |
249
|
|
|
{ |
250
|
|
|
return [ |
251
|
|
|
'config' => function($key = null, $default = null) { |
252
|
|
|
return config($key, $default); |
253
|
|
|
}, |
254
|
|
|
]; |
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
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.