Phpcpd   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 81
rs 10
c 0
b 0
f 0
wmc 17

9 Methods

Rating   Name   Duplication   Size   Complexity  
A handleEndOfBlock() 0 12 5
A getErrorsOnLine() 0 8 2
A addFoundBlock() 0 5 1
A hasFileName() 0 3 1
A startOfBlock() 0 3 1
A getDescription() 0 3 1
A parseLines() 0 18 4
A __construct() 0 3 1
A handleNotFoundFile() 0 3 1
1
<?php
2
namespace exussum12\CoverageChecker\Loaders;
3
4
use exussum12\CoverageChecker\FileChecker;
5
6
class Phpcpd implements FileChecker
7
{
8
    protected $file;
9
10
    protected $duplicateCode = [];
11
12
    public function __construct($file)
13
    {
14
        $this->file = fopen($file, 'r');
15
    }
16
17
    public function parseLines(): array
18
    {
19
        $block = [];
20
        $this->duplicateCode = [];
21
        while (($line = fgets($this->file)) !== false) {
0 ignored issues
show
Bug introduced by
It seems like $this->file can also be of type boolean; however, parameter $handle of fgets() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

21
        while (($line = fgets(/** @scrutinizer ignore-type */ $this->file)) !== false) {
Loading history...
22
            if (!$this->hasFileName($line)) {
23
                continue;
24
            }
25
26
            if ($this->startOfBlock($line)) {
27
                $this->handleEndOfBlock($block);
28
                $block = [];
29
            }
30
31
            $block += $this->addFoundBlock($line);
32
        }
33
34
        return array_keys($this->duplicateCode);
35
    }
36
37
38
    public function getErrorsOnLine(string $file, int $lineNumber)
39
    {
40
        $errors = [];
41
        if (isset($this->duplicateCode[$file][$lineNumber])) {
42
            $errors = $this->duplicateCode[$file][$lineNumber];
43
        }
44
45
        return $errors;
46
    }
47
48
    public function handleNotFoundFile()
49
    {
50
        return true;
51
    }
52
53
    public static function getDescription(): string
54
    {
55
        return "Parses the text output from phpcpd (Copy Paste Detect)";
56
    }
57
58
    private function startOfBlock(string $line)
59
    {
60
        return preg_match('/^\s+-/', $line);
61
    }
62
63
    private function hasFileName(string $line)
64
    {
65
        return preg_match('/:\d+-\d+/', $line);
66
    }
67
68
    private function addFoundBlock(string $line)
69
    {
70
        $matches = [];
71
        preg_match('/\s+(?:- )?(?<fileName>.*?):(?<startLine>\d+)-(?<endLine>\d+)$/', $line, $matches);
72
        return [$matches['fileName'] => range($matches['startLine'], $matches['endLine'])];
73
    }
74
75
    private function handleEndOfBlock(array $block)
76
    {
77
        foreach ($block as $filename => $lines) {
78
            foreach ($lines as $lineNumber) {
79
                foreach ($block as $duplicate => $dupeLines) {
80
                    if ($filename == $duplicate) {
81
                        continue;
82
                    }
83
                    $start = reset($dupeLines);
84
                    $end = end($dupeLines);
85
                    $message = "Duplicate of " . $duplicate . ':' . $start . '-' . $end;
86
                    $this->duplicateCode[$filename][$lineNumber][] = $message;
87
                }
88
            }
89
        }
90
    }
91
}
92