1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Sludio\HelperBundle\Script\Twig; |
4
|
|
|
|
5
|
|
|
use Symfony\Component\HttpFoundation\Request; |
6
|
|
|
|
7
|
|
|
class SludioExtension extends \Twig_Extension |
8
|
|
|
{ |
9
|
|
|
use TwigTrait; |
10
|
|
|
|
11
|
|
|
const INFO = 'info'; |
12
|
|
|
const SUCCESS = 'success'; |
13
|
|
|
const REDIRECT = 'redirect'; |
14
|
|
|
const CLIENT = 'client_error'; |
15
|
|
|
const SERVER = 'server_error'; |
16
|
|
|
|
17
|
|
|
protected $appDir; |
18
|
|
|
private $paths = []; |
19
|
|
|
protected $param; |
20
|
|
|
protected $order; |
21
|
|
|
protected $detector; |
22
|
|
|
|
23
|
|
|
public function __construct($shortFunctions) |
24
|
|
|
{ |
25
|
|
|
global $kernel; |
26
|
|
|
|
27
|
|
|
$this->shortFunctions = $shortFunctions; |
28
|
|
|
$this->appDir = $kernel->getRootDir(); |
29
|
|
|
$this->detector = new \Mobile_Detect(); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
public function getName() |
33
|
|
|
{ |
34
|
|
|
return 'sludio_helper.twig.extension'; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
public function getFilters() |
38
|
|
|
{ |
39
|
|
|
$input = [ |
40
|
|
|
'beautify' => 'beautify', |
41
|
|
|
'urldecode' => 'url_decode', |
42
|
|
|
'parse' => 'parse', |
43
|
|
|
'file_exists' => 'file_exists', |
44
|
|
|
'html_entity_decode' => 'html_entity_decode', |
45
|
|
|
'strip_descr' => 'strip_descr', |
46
|
|
|
'pretty_print' => 'prettyPrint', |
47
|
|
|
'status_code_class' => 'statusCodeClass', |
48
|
|
|
'format_duration' => 'formatDuration', |
49
|
|
|
'short_uri' => 'shorthenUri', |
50
|
|
|
'is_ie' => 'isIE', |
51
|
|
|
'asset_version' => 'getAssetVersion', |
52
|
|
|
'usort' => 'usortFunction', |
53
|
|
|
]; |
54
|
|
|
|
55
|
|
|
return $this->makeArray($input); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function getFunctions() |
59
|
|
|
{ |
60
|
|
|
$input = [ |
61
|
|
|
'detect_lang' => 'detectLang', |
62
|
|
|
'get_available_devices' => 'getAvailableDevices', |
63
|
|
|
'is_mobile' => 'isMobile', |
64
|
|
|
'is_tablet' => 'isTablet', |
65
|
|
|
]; |
66
|
|
|
foreach ($this->getAvailableDevices() as $device => $fixed) { |
67
|
|
|
$input['is_'.$fixed] = 'is'.$device; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return $this->makeArray($input, 'function'); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
public function getAvailableDevices() |
74
|
|
|
{ |
75
|
|
|
$availableDevices = []; |
76
|
|
|
$rules = array_change_key_case($this->detector->getRules()); |
|
|
|
|
77
|
|
|
|
78
|
|
|
foreach ($rules as $device => $rule) { |
79
|
|
|
$availableDevices[$device] = static::fromCamelCase($device); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
return $availableDevices; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function __call($name, $arguments) |
86
|
|
|
{ |
87
|
|
|
return call_user_func_array([ |
88
|
|
|
$this->detector, |
89
|
|
|
$name, |
90
|
|
|
], $arguments); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
protected static function toCamelCase($string) |
94
|
|
|
{ |
95
|
|
|
return preg_replace('~\s+~', '', lcfirst(ucwords(strtr($string, '_', ' ')))); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
protected static function fromCamelCase($string, $separator = '_') |
99
|
|
|
{ |
100
|
|
|
return strtolower(preg_replace('/(?!^)[[:upper:]]+/', $separator.'$0', $string)); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
public function url_decode($string) |
104
|
|
|
{ |
105
|
|
|
return urldecode($string); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
public function parse($string) |
109
|
|
|
{ |
110
|
|
|
$str = parse_url($string); |
111
|
|
|
|
112
|
|
|
$argv = []; |
113
|
|
|
if (isset($str['query'])) { |
114
|
|
|
$args = explode('&', $str['query']); |
115
|
|
|
|
116
|
|
|
foreach ($args as $arg) { |
117
|
|
|
$tmp = explode('=', $arg, 2); |
118
|
|
|
$argv[$tmp[0]] = $tmp[1]; |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return $argv; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
public function file_exists($file) |
126
|
|
|
{ |
127
|
|
|
return file_exists(getcwd().$file); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
public function beautify($string) |
131
|
|
|
{ |
132
|
|
|
$explode = explode('/', strip_tags($string)); |
133
|
|
|
$string = implode(' / ', $explode); |
134
|
|
|
|
135
|
|
|
return $string; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
public function html_entity_decode($str) |
139
|
|
|
{ |
140
|
|
|
$str = html_entity_decode($str); |
141
|
|
|
$str = preg_replace('#\R+#', '', $str); |
142
|
|
|
|
143
|
|
|
return $str; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
public function strip_descr($body, $fallback = null, $type = null, $lengthIn = 300) |
147
|
|
|
{ |
148
|
|
|
if ($type && $fallback) { |
149
|
|
|
$length = isset($fallback[$type]) ? $fallback[$type] : null; |
150
|
|
|
} |
151
|
|
|
if (!isset($length)) { |
152
|
|
|
$length = $lengthIn; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
if (strlen($body) > $length) { |
156
|
|
|
$body = substr($body, 0, strpos($body, ' ', $length)).'...'; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
return $body; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
public function detectLang($body) |
163
|
|
|
{ |
164
|
|
|
switch (true) { |
165
|
|
|
case 0 === strpos($body, '<?xml'): |
166
|
|
|
return 'xml'; |
167
|
|
|
case 0 === strpos($body, '{'): |
168
|
|
|
case 0 === strpos($body, '['): |
169
|
|
|
return 'json'; |
170
|
|
|
default: |
171
|
|
|
return 'markup'; |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
public function prettyPrint($code, $lang) |
176
|
|
|
{ |
177
|
|
|
switch ($lang) { |
178
|
|
|
case 'json': |
179
|
|
|
return json_encode(json_decode($code), JSON_PRETTY_PRINT); |
180
|
|
|
case 'xml': |
181
|
|
|
$xml = new \DomDocument('1.0'); |
182
|
|
|
$xml->preserveWhiteSpace = false; |
183
|
|
|
$xml->formatOutput = true; |
184
|
|
|
$xml->loadXml($code); |
185
|
|
|
|
186
|
|
|
return $xml->saveXml(); |
187
|
|
|
default: |
188
|
|
|
return $code; |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
public function statusCodeClass($statusCode) |
193
|
|
|
{ |
194
|
|
|
$codes = [ |
195
|
|
|
5 => self::SERVER, |
196
|
|
|
4 => self::CLIENT, |
197
|
|
|
3 => self::REDIRECT, |
198
|
|
|
2 => self::SUCCESS, |
199
|
|
|
1 => self::INFO, |
200
|
|
|
]; |
201
|
|
|
$code = (int)floor(intval($statusCode) / 100); |
202
|
|
|
|
203
|
|
|
return isset($codes[$code]) ? $codes[$code] : 'unknown'; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
public function formatDuration($seconds) |
207
|
|
|
{ |
208
|
|
|
$formats = [ |
209
|
|
|
'%.2f s', |
210
|
|
|
'%d ms', |
211
|
|
|
'%d µs', |
212
|
|
|
]; |
213
|
|
|
|
214
|
|
|
while ($format = array_shift($formats)) { |
215
|
|
|
if ($seconds > 1) { |
216
|
|
|
break; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
$seconds *= 1000; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
return sprintf($format, $seconds); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
public function shortenUri($uri) |
226
|
|
|
{ |
227
|
|
|
$parts = parse_url($uri); |
228
|
|
|
|
229
|
|
|
return sprintf('%s://%s%s', isset($parts['scheme']) ? $parts['scheme'] : 'http', $parts['host'], isset($parts['port']) ? (':'.$parts['port']) : ''); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
public function isIE() |
233
|
|
|
{ |
234
|
|
|
$request = Request::createFromGlobals(); |
235
|
|
|
$agent = $request->server->get('HTTP_USER_AGENT'); |
236
|
|
|
if (strpos($agent, 'MSIE') || strpos($agent, 'Edge') || strpos($agent, 'Trident/7')) { |
237
|
|
|
return 1; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
return 0; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
public function getAssetVersion($filename) |
244
|
|
|
{ |
245
|
|
|
if (count($this->paths) === 0) { |
246
|
|
|
$manifestPath = $this->appDir.'/Resources/assets/rev-manifest.json'; |
247
|
|
|
if (!file_exists($manifestPath)) { |
248
|
|
|
return $filename; |
249
|
|
|
} |
250
|
|
|
$this->paths = json_decode(file_get_contents($manifestPath), true); |
251
|
|
|
if (!isset($this->paths[$filename])) { |
252
|
|
|
return $filename; |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
return $this->paths[$filename]; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
public function cmpOrderBy($aVar, $bVar) |
260
|
|
|
{ |
261
|
|
|
$aValue = $aVar->{'get'.ucfirst($this->param)}(); |
262
|
|
|
$bValue = $bVar->{'get'.ucfirst($this->param)}(); |
263
|
|
|
switch ($this->order) { |
264
|
|
|
case 'asc': |
265
|
|
|
return $aValue > $bValue; |
266
|
|
|
case 'desc': |
267
|
|
|
return $aValue < $bValue; |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
public function usortFunction($objects, $parameter, $order = 'asc') |
272
|
|
|
{ |
273
|
|
|
$this->param = $parameter; |
274
|
|
|
$this->order = strtolower($order); |
275
|
|
|
|
276
|
|
|
if (is_object($objects)) { |
277
|
|
|
$objects = $objects->toArray(); |
278
|
|
|
} |
279
|
|
|
usort($objects, [ |
280
|
|
|
__CLASS__, |
281
|
|
|
'cmpOrderBy', |
282
|
|
|
]); |
283
|
|
|
|
284
|
|
|
return $objects; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.