Passed
Push — master ( a51f35...a51f35 )
by Dāvis
05:00
created

SludioExtension   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 251
rs 8.3999
c 2
b 0
f 0
wmc 46

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getAssetVersion() 0 14 4
A cmpOrderBy() 0 9 3
A usortFunction() 0 14 2
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 detectLang() 0 10 4
A statusCodeClass() 0 12 2
A formatDuration() 0 17 3
A isIE() 0 8 4
A prettyPrint() 0 14 3
A shortenUri() 0 5 3
A __construct() 0 6 1
B stripDescr() 0 17 7

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\RequestStack;
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
    public $detector;
17
    protected $appDir;
18
    protected $param;
19
    protected $order;
20
    protected $request;
21
    private $paths = [];
22
23
    public function __construct($shortFunctions, $appDir, RequestStack $requestStack)
24
    {
25
        $this->shortFunctions = $shortFunctions;
26
        $this->appDir = $appDir;
27
        $this->detector = new \Mobile_Detect();
0 ignored issues
show
Bug introduced by
The type Mobile_Detect was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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