Formatter   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 393
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 43
lcom 1
cbo 1
dl 0
loc 393
ccs 107
cts 107
cp 1
rs 8.96
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A isDebug() 0 4 1
A setDebug() 0 4 1
A getIndentationStep() 0 4 1
A setIndentationStep() 0 4 1
A renderClass() 0 12 3
A renderConstant() 0 4 1
A renderObject() 0 14 1
A renderProperty() 0 8 2
A renderObjectCall() 0 14 1
A renderCall() 0 8 1
A renderClosure() 0 19 4
A renderObjectAssignment() 0 8 1
A renderContainerAssignment() 0 15 1
A renderContainerVariable() 0 17 3
A renderAssignment() 0 6 1
A renderStatement() 0 19 3
A renderCode() 0 8 2
A renderIndentation() 0 9 3
A renderLines() 0 11 3
A renderLine() 0 8 4
A renderEscape() 0 4 1
A renderSeparator() 0 4 2
A renderArguments() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Formatter 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Formatter, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the Ivory Google Map package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source declaration.
10
 */
11
12
namespace Ivory\GoogleMap\Helper\Formatter;
13
14
use Ivory\GoogleMap\Utility\VariableAwareInterface;
15
16
/**
17
 * @author GeLo <[email protected]>
18
 */
19
class Formatter
20
{
21
    /**
22
     * @var bool
23
     */
24
    private $debug;
25
26
    /**
27
     * @var int
28
     */
29
    private $indentationStep;
30
31
    /**
32
     * @param bool $debug
33
     * @param int  $indentationStep
34
     */
35 1544
    public function __construct($debug = false, $indentationStep = 4)
36
    {
37 1544
        $this->setDebug($debug);
38 1544
        $this->setIndentationStep($indentationStep);
39 1544
    }
40
41
    /**
42
     * @return bool
43
     */
44 200
    public function isDebug()
45
    {
46 200
        return $this->debug;
47
    }
48
49
    /**
50
     * @param bool $debug
51
     */
52 1544
    public function setDebug($debug)
53
    {
54 1544
        $this->debug = $debug;
55 1544
    }
56
57
    /**
58
     * @return int
59
     */
60 8
    public function getIndentationStep()
61
    {
62 8
        return $this->indentationStep;
63
    }
64
65
    /**
66
     * @param int $indentationStep
67
     */
68 1544
    public function setIndentationStep($indentationStep)
69
    {
70 1544
        $this->indentationStep = $indentationStep;
71 1544
    }
72
73
    /**
74
     * @param string|null       $name
75
     * @param string|false|null $namespace
76
     *
77
     * @return string
78
     */
79 316
    public function renderClass($name = null, $namespace = null)
80
    {
81 316
        if (null === $namespace) {
82 272
            $namespace = $this->renderProperty('google', 'maps');
83
        }
84
85 316
        if (empty($namespace)) {
86 16
            return $name;
87
        }
88
89 300
        return $this->renderProperty($namespace, $name);
90
    }
91
92
    /**
93
     * @param string            $class
94
     * @param string            $value
95
     * @param string|false|null $namespace
96
     *
97
     * @return string
98
     */
99 100
    public function renderConstant($class, $value, $namespace = null)
100
    {
101 100
        return $this->renderClass($this->renderProperty($class, strtoupper($value)), $namespace);
102
    }
103
104
    /**
105
     * @param string            $class
106
     * @param string[]          $arguments
107
     * @param string|false|null $namespace
108
     * @param bool              $semicolon
109
     * @param bool              $newLine
110
     *
111
     * @return string
112
     */
113 172
    public function renderObject(
114
        $class,
115
        array $arguments = [],
116
        $namespace = null,
117
        $semicolon = false,
118
        $newLine = false
119
    ) {
120 172
        return $this->renderCall(
121 172
            'new '.$this->renderClass($class, $namespace),
122 129
            $arguments,
123 129
            $semicolon,
124 129
            $newLine
125
        );
126
    }
127
128
    /**
129
     * @param string      $object
130
     * @param string|null $property
131
     *
132
     * @return string
133
     */
134 476
    public function renderProperty($object, $property = null)
135
    {
136 476
        if (!empty($property)) {
137 468
            $property = '.'.$property;
138
        }
139
140 476
        return $object.$property;
141
    }
142
143
    /**
144
     * @param string   $method
145
     * @param string[] $arguments
146
     * @param bool     $semicolon
147
     * @param bool     $newLine
148
     *
149
     * @return string
150
     */
151 88
    public function renderObjectCall(
152
        VariableAwareInterface $object,
153
        $method,
154
        array $arguments = [],
155
        $semicolon = false,
156
        $newLine = false
157
    ) {
158 88
        return $this->renderCall(
159 88
            $this->renderProperty($object->getVariable(), $method),
160 66
            $arguments,
161 66
            $semicolon,
162 66
            $newLine
163
        );
164
    }
165
166
    /**
167
     * @param string|null $method
168
     * @param string[]    $arguments
169
     * @param bool        $semicolon
170
     * @param bool        $newLine
171
     *
172
     * @return string
173
     */
174 404
    public function renderCall($method, array $arguments = [], $semicolon = false, $newLine = false)
175
    {
176 404
        return $this->renderCode(
177 404
            $method.$this->renderArguments($arguments),
178 303
            $semicolon,
179 303
            $newLine
180
        );
181
    }
182
183
    /**
184
     * @param string|null $code
185
     * @param string[]    $arguments
186
     * @param string|null $name
187
     * @param bool        $semicolon
188
     * @param bool        $newLine
189
     *
190
     * @return string
191
     */
192 136
    public function renderClosure(
193
        $code = null,
194
        array $arguments = [],
195
        $name = null,
196
        $semicolon = false,
197
        $newLine = false
198
    ) {
199 136
        $separator = $this->renderSeparator();
200
201 136
        if (null !== $name) {
202 72
            $name = ' '.$name;
203
        }
204
205 136
        return $this->renderCode($this->renderLines([
206 136
            'function'.$name.$separator.$this->renderArguments($arguments).$separator.'{',
207 136
            $this->renderIndentation($code),
208 136
            '}',
209 136
        ], !empty($code), $newLine && !$semicolon), $semicolon, $newLine && $semicolon);
210
    }
211
212
    /**
213
     * @param string $declaration
214
     * @param bool   $semicolon
215
     * @param bool   $newLine
216
     *
217
     * @return string
218
     */
219 204
    public function renderObjectAssignment(
220
        VariableAwareInterface $object,
221
        $declaration,
222
        $semicolon = false,
223
        $newLine = false
224
    ) {
225 204
        return $this->renderAssignment($object->getVariable(), $declaration, $semicolon, $newLine);
226
    }
227
228
    /**
229
     * @param string      $declaration
230
     * @param string|null $propertyPath
231
     * @param bool        $semicolon
232
     * @param bool        $newLine
233
     *
234
     * @return string
235
     */
236 48
    public function renderContainerAssignment(
237
        VariableAwareInterface $root,
238
        $declaration,
239
        $propertyPath = null,
240
        VariableAwareInterface $object = null,
241
        $semicolon = true,
242
        $newLine = true
243
    ) {
244 48
        return $this->renderAssignment(
245 48
            $this->renderContainerVariable($root, $propertyPath, $object),
246 36
            $declaration,
247 36
            $semicolon,
248 36
            $newLine
249
        );
250
    }
251
252
    /**
253
     * @param string|null $propertyPath
254
     *
255
     * @return string
256
     */
257 64
    public function renderContainerVariable(
258
        VariableAwareInterface $root,
259
        $propertyPath = null,
260
        VariableAwareInterface $object = null
261
    ) {
262 64
        $variable = $root->getVariable().'_container';
263
264 64
        if (null !== $propertyPath) {
265 24
            $variable = $this->renderProperty($variable, $propertyPath);
266
        }
267
268 64
        if (null !== $object) {
269 24
            $variable = $this->renderProperty($variable, $object->getVariable());
270
        }
271
272 64
        return $variable;
273
    }
274
275
    /**
276
     * @param string $variable
277
     * @param string $declaration
278
     * @param bool   $semicolon
279
     * @param bool   $newLine
280
     *
281
     * @return string
282
     */
283 328
    public function renderAssignment($variable, $declaration, $semicolon = false, $newLine = false)
284
    {
285 328
        $separator = $this->renderSeparator();
286
287 328
        return $this->renderCode($variable.$separator.'='.$separator.$declaration, $semicolon, $newLine);
288
    }
289
290
    /**
291
     * @param string      $statement
292
     * @param string      $code
293
     * @param string|null $condition
294
     * @param string|null $next
295
     * @param bool        $newLine
296
     *
297
     * @return string
298
     */
299 56
    public function renderStatement($statement, $code, $condition = null, $next = null, $newLine = true)
300
    {
301 56
        $separator = $this->renderSeparator();
302 56
        $statement .= $separator;
303
304 56
        if (!empty($condition)) {
305 48
            $statement .= $this->renderArguments([$condition]).$separator;
306
        }
307
308 56
        if (!empty($next)) {
309 28
            $next = $separator.$next;
310
        }
311
312 56
        return $this->renderLines([
313 56
            $statement.'{',
314 56
            $this->renderIndentation($code),
315 56
            '}'.$next,
316 56
        ], true, $newLine);
317
    }
318
319
    /**
320
     * @param string $code
321
     * @param bool   $semicolon
322
     * @param bool   $newLine
323
     *
324
     * @return string
325
     */
326 664
    public function renderCode($code, $semicolon = true, $newLine = true)
327
    {
328 664
        if ($semicolon) {
329 252
            $code .= ';';
330
        }
331
332 664
        return $this->renderLine($code, $newLine);
333
    }
334
335
    /**
336
     * @param string|null $code
337
     *
338
     * @return string
339
     */
340 320
    public function renderIndentation($code = null)
341
    {
342 320
        if ($this->debug && !empty($code)) {
343 84
            $indentation = str_repeat(' ', $this->indentationStep);
344 84
            $code = $indentation.str_replace("\n", "\n".$indentation, $code);
345
        }
346
347 320
        return (string) $code;
348
    }
349
350
    /**
351
     * @param string[] $codes
352
     * @param bool     $newLine
353
     * @param bool     $eolLine
354
     *
355
     * @return string
356
     */
357 344
    public function renderLines(array $codes, $newLine = true, $eolLine = true)
358
    {
359 344
        $result = '';
360 344
        $count = count($codes);
361
362 344
        for ($index = 0; $index < $count; ++$index) {
363 336
            $result .= $this->renderLine($codes[$index], $newLine && $index !== $count - 1);
364
        }
365
366 344
        return $this->renderLine($result, $eolLine);
367
    }
368
369
    /**
370
     * @param string|null $code
371
     * @param bool        $newLine
372
     *
373
     * @return string
374
     */
375 864
    public function renderLine($code = null, $newLine = true)
376
    {
377 864
        if ($newLine && !empty($code) && $this->debug) {
378 184
            $code .= "\n";
379
        }
380
381 864
        return (string) $code;
382
    }
383
384
    /**
385
     * @param string $argument
386
     *
387
     * @return string
388
     */
389 280
    public function renderEscape($argument)
390
    {
391 280
        return json_encode($argument, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
392
    }
393
394
    /**
395
     * @return string
396
     */
397 712
    public function renderSeparator()
398
    {
399 712
        return $this->debug ? ' ' : '';
400
    }
401
402
    /**
403
     * @param string[] $arguments
404
     *
405
     * @return string
406
     */
407 476
    private function renderArguments(array $arguments)
408
    {
409 476
        return '('.implode(','.$this->renderSeparator(), $arguments).')';
410
    }
411
}
412