Total Complexity | 51 |
Total Lines | 278 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like SludioExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SludioExtension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
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) |
||
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) |
||
257 | } |
||
258 | |||
259 | public function cmpOrderBy($aVar, $bVar) |
||
260 | { |
||
261 | $aValue = $aVar->{'get'.ucfirst($this->param)}(); |
||
262 | $bValue = $bVar->{'get'.ucfirst($this->param)}(); |
||
268 | } |
||
269 | } |
||
270 | |||
271 | public function usortFunction($objects, $parameter, $order = 'asc') |
||
272 | { |
||
273 | $this->param = $parameter; |
||
274 | $this->order = strtolower($order); |
||
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.