Passed
Push — master ( d093e3...81fa39 )
by Dāvis
03:13 queued 25s
created

SludioExtension   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 252
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 252
rs 8.3673
wmc 45

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A getFilters() 0 19 1
A getFunctions() 0 15 1
A parse() 0 15 3
A fileExists() 0 3 1
A urlDecode() 0 3 1
A htmlEntityDecode() 0 6 1
A beautify() 0 6 1
A getAssetVersion() 0 14 4
A detectLang() 0 10 4
A statusCodeClass() 0 12 2
A cmpOrderBy() 0 9 3
A formatDuration() 0 17 3
A isIE() 0 8 4
A usortFunction() 0 14 2
B stripDescr() 0 16 6
A prettyPrint() 0 14 3
A shortenUri() 0 5 3
A __construct() 0 6 1

How to fix   Complexity   

Complex Class

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