DiffOutputFilter   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 117
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B filter() 0 20 6
A getFilesWithAddedCode() 0 8 2
B getTouchedFilesAndLines() 0 24 6
A getDiffsWithAddedCode() 0 15 5
1
<?php
2
namespace Finder\Logic\Output\Filter;
3
4
use SebastianBergmann\Diff\Line;
5
6
/**
7
 * Limit AnalysisResult data by only the files and their lines touched by
8
 * the diff. For example: if the diff only touches a "costumer.php" file
9
 * at lines 10 and 11, the AnalysisResult will only return issues found on
10
 * that file and at those lines of code. All other issues will be ignored.
11
 */
12
class DiffOutputFilter implements OutputFilterInterface
13
{
14
    /**
15
     * Root path to which the diff file paths are relative.
16
     *
17
     * @var string root path.
18
     */
19
    protected $root;
20
21
    /**
22
     * An array of Diff objects.
23
     *
24
     * @var SebastianBergmann\Diff\Diff[] array of diff objects.
25
     */
26
    protected $diffs;
27
28
    /**
29
     * Constructor.
30
     *
31
     * @param string                        $root  root path.
32
     * @param SebastianBergmann\Diff\Diff[] $diffs array of diff objects.
33
     */
34
    public function __construct($root, array $diffs)
35
    {
36
        $this->root = $root;
37
        $this->diffs = $diffs;
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43
    public function filter($data)
44
    {
45
        $filteredData = [];
46
47
        foreach ($this->getTouchedFilesAndLines() as $fileName => $lines) {
48
            if (!isset($data[$fileName])) {
49
                continue;
50
            }
51
            foreach ($lines as $line) {
52
                if (!isset($data[$fileName][$line])) {
53
                    continue;
54
                }
55
                if (!isset($filteredData[$fileName])) {
56
                    $filteredData[$fileName] = [];
57
                }
58
                $filteredData[$fileName][$line] = $data[$fileName][$line];
59
            }
60
        }
61
        return $filteredData;
62
    }
63
64
    /**
65
     * Files touched by the diff and that received at least one new line of code.
66
     *
67
     * @return string[] files paths.
68
     */
69
    public function getFilesWithAddedCode()
70
    {
71
        $files = [];
72
        foreach ($this->getDiffsWithAddedCode() as $fileDiff) {
73
            $files[] = $this->root . DIRECTORY_SEPARATOR . substr($fileDiff->getTo(), 2);
74
        }
75
        return $files;
76
    }
77
78
    /**
79
     * Gets the list of files and lines touched by the diff.
80
     *
81
     * @return array where the key is the file path and its values the lines.
82
     */
83
    protected function getTouchedFilesAndLines()
84
    {
85
        $resultFilter = [];
86
        foreach ($this->getDiffsWithAddedCode() as $fileDiff) {
87
            $file = $this->root . DIRECTORY_SEPARATOR . substr($fileDiff->getTo(), 2);
88
            $lines = [];
89
            foreach ($fileDiff->getChunks() as $chunkDiff) {
90
                $counter = -1;
91
                foreach ($chunkDiff->getLines() as $lineDiff) {
92
                    if ($lineDiff->getType() == Line::REMOVED) {
93
                        continue;
94
                    }
95
                    $counter++;
96
97
                    // Only display results for touched lines
98
                    if ($lineDiff->getType() == Line::ADDED) {
99
                        $lines[] = $chunkDiff->getStart() + $counter;
100
                    }
101
                }
102
            }
103
            $resultFilter[$file] = $lines;
104
        }
105
        return $resultFilter;
106
    }
107
108
    /**
109
     * Search for diffs where at least one line of code was added.
110
     *
111
     * @return SebastianBergmann\Diff\Diff[] diffs adding code.
112
     */
113
    protected function getDiffsWithAddedCode()
114
    {
115
        $diffs = [];
116
        foreach ($this->diffs as $fileDiff) {
117
            foreach ($fileDiff->getChunks() as $chunkDiff) {
118
                foreach ($chunkDiff->getLines() as $lineDiff) {
119
                    if ($lineDiff->getType() == Line::ADDED) {
120
                        $diffs[] = $fileDiff;
121
                        break 2;
122
                    }
123
                }
124
            }
125
        }
126
        return $diffs;
127
    }
128
}
129