PhpFileFormatter   F
last analyzed

Complexity

Total Complexity 71

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 106
c 1
b 0
f 0
dl 0
loc 141
ccs 102
cts 102
cp 1
rs 2.7199
wmc 71

4 Methods

Rating   Name   Duplication   Size   Complexity  
A formatValue() 0 6 1
D getColor() 0 69 61
A replaceSpecialCharacters() 0 6 1
B loadFile() 0 44 8

How to fix   Complexity   

Complex Class

Complex classes like PhpFileFormatter 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 PhpFileFormatter, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Scheb\Tombstone\Analyzer\Report\Html\Renderer;
6
7
/*
8
 * Based on code from PHP_CodeCoverage
9
 * https://github.com/sebastianbergmann/php-code-coverage
10
 *
11
 * Copyright (c) 2009-2015, Sebastian Bergmann <[email protected]>.
12
 * All rights reserved.
13
 */
14
class PhpFileFormatter
15
{
16
    private const COLOR_HTML = 'html';
17
    private const COLOR_COMMENT = 'comment';
18
    private const COLOR_KEYWORD = 'keyword';
19
    private const COLOR_STRING = 'string';
20
    private const COLOR_DEFAULT = 'default';
21
22 1
    public static function loadFile(string $file): array
23
    {
24 1
        $buffer = file_get_contents($file);
25 1
        $tokens = token_get_all($buffer);
26 1
        $result = [''];
27 1
        $i = 0;
28 1
        $fileEndsWithNewLine = "\n" === substr($buffer, -1);
29 1
        unset($buffer);
30
31 1
        foreach ($tokens as $token) {
32
            // Handle plain string tokens
33 1
            if (is_string($token)) {
34 1
                $result[$i] .= self::formatValue($token, self::COLOR_KEYWORD);
35 1
                continue;
36
            }
37
38 1
            [$tokenType, $value] = $token;
39
40
            // Handle new lines
41 1
            if ("\n" === $value) {
42 1
                $result[++$i] = '';
43 1
                continue;
44
            }
45
46 1
            $value = self::replaceSpecialCharacters($value);
47 1
            $lines = explode("\n", $value);
48 1
            foreach ($lines as $lineNumber => $lineValue) {
49 1
                $lineValue = trim($lineValue);
50
51 1
                if ('' !== $lineValue) {
52 1
                    $result[$i] .= self::formatValue($lineValue, self::getColor($tokenType));
53
                }
54
55 1
                if (isset($lines[$lineNumber + 1])) {
56 1
                    $result[++$i] = '';
57
                }
58
            }
59
        }
60
61 1
        if ($fileEndsWithNewLine) {
62 1
            unset($result[count($result) - 1]);
63
        }
64
65 1
        return $result;
66
    }
67
68 1
    private static function replaceSpecialCharacters(string $value): string
69
    {
70 1
        return str_replace(
71 1
            ["\t", ' '],
72 1
            ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'],
73 1
            htmlspecialchars($value, ENT_COMPAT)
74
        );
75
    }
76
77 1
    private static function formatValue(string $value, string $color): string
78
    {
79 1
        return sprintf(
80 1
            '<span class="%s">%s</span>',
81 1
            $color,
82 1
            $value
83
        );
84
    }
85
86 1
    private static function getColor(int $token): string
87
    {
88
        switch ($token) {
89 1
            case T_INLINE_HTML:
90 1
                return self::COLOR_HTML;
91 1
            case T_COMMENT:
92 1
            case T_DOC_COMMENT:
93 1
                return self::COLOR_COMMENT;
94 1
            case T_ABSTRACT:
95 1
            case T_ARRAY:
96 1
            case T_AS:
97 1
            case T_BREAK:
98 1
            case T_CALLABLE:
99 1
            case T_CASE:
100 1
            case T_CATCH:
101 1
            case T_CLASS:
102 1
            case T_CLONE:
103 1
            case T_CONTINUE:
104 1
            case T_DEFAULT:
105 1
            case T_ECHO:
106 1
            case T_ELSE:
107 1
            case T_ELSEIF:
108 1
            case T_EMPTY:
109 1
            case T_ENDDECLARE:
110 1
            case T_ENDFOR:
111 1
            case T_ENDFOREACH:
112 1
            case T_ENDIF:
113 1
            case T_ENDSWITCH:
114 1
            case T_ENDWHILE:
115 1
            case T_EXIT:
116 1
            case T_EXTENDS:
117 1
            case T_FINAL:
118 1
            case T_FINALLY:
119 1
            case T_FOREACH:
120 1
            case T_FUNCTION:
121 1
            case T_GLOBAL:
122 1
            case T_IF:
123 1
            case T_IMPLEMENTS:
124 1
            case T_INCLUDE:
125 1
            case T_INCLUDE_ONCE:
126 1
            case T_INSTANCEOF:
127 1
            case T_INSTEADOF:
128 1
            case T_INTERFACE:
129 1
            case T_ISSET:
130 1
            case T_LOGICAL_AND:
131 1
            case T_LOGICAL_OR:
132 1
            case T_LOGICAL_XOR:
133 1
            case T_NAMESPACE:
134 1
            case T_NEW:
135 1
            case T_PRIVATE:
136 1
            case T_PROTECTED:
137 1
            case T_PUBLIC:
138 1
            case T_REQUIRE:
139 1
            case T_REQUIRE_ONCE:
140 1
            case T_RETURN:
141 1
            case T_STATIC:
142 1
            case T_THROW:
143 1
            case T_TRAIT:
144 1
            case T_TRY:
145 1
            case T_UNSET:
146 1
            case T_USE:
147 1
            case T_VAR:
148 1
            case T_WHILE:
149 1
            case T_YIELD:
150 1
                return self::COLOR_KEYWORD;
151 1
            case T_CONSTANT_ENCAPSED_STRING:
152 1
                return self::COLOR_STRING;
153
            default:
154 1
                return self::COLOR_DEFAULT;
155
        }
156
    }
157
}
158