Completed
Pull Request — master (#403)
by
unknown
01:49
created

Reporter::getTrend()   B

Complexity

Conditions 9
Paths 19

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 19
nop 4
dl 0
loc 48
rs 7.5789
c 0
b 0
f 0
1
<?php
2
namespace Hal\Report\Html;
3
4
use Hal\Application\Config\Config;
5
use Hal\Component\Output\Output;
6
use Hal\Metric\Consolidated;
7
use Hal\Metric\Metrics;
8
use Hal\Report\ReporterInterface;
9
10
/**
11
 * This class takes care about the global report in HTML of consolidated metrics.
12
 */
13
class Reporter implements ReporterInterface
14
{
15
    /** @var Config */
16
    private $config;
17
18
    /** @var Output */
19
    private $output;
20
21
    /**
22
     * @param Config $config
23
     * @param Output $output
24
     */
25
    public function __construct(Config $config, Output $output)
26
    {
27
        $this->config = $config;
28
        $this->output = $output;
29
    }
30
31
    /**
32
     * {@inheritDoc}
33
     */
34
    public function generate(Metrics $metrics)
35
    {
36
        $logDir = $this->config->get('report-html');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $logDir is correct as $this->config->get('report-html') (which targets Hal\Application\Config\Config::get()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
37
        if (!$logDir) {
38
            return;
39
        }
40
41
        $consolidated = new Consolidated($metrics);
42
43
        $files = glob($logDir . '/js/history-*.json');
44
        natsort($files);
45
        $history = array_map(static function ($filename) {
46
            return json_decode(file_get_contents($filename));
47
        }, $files);
48
49
        foreach (['js', 'css', 'images', 'fonts'] as $subFolder) {
50
            $folder = $logDir . '/' . $subFolder;
51
            if (!file_exists($folder)) {
52
                mkdir($folder, 0755, true);
53
            }
54
            recurse_copy(__DIR__ . '/template/' . $subFolder, $folder);
55
        }
56
57
        // render dynamic pages
58
        $this->renderPage(__DIR__ . '/template/index.php', $logDir . '/index.html', $consolidated, $history);
59
        $this->renderPage(__DIR__ . '/template/loc.php', $logDir . '/loc.html', $consolidated, $history);
60
        $this->renderPage(__DIR__ . '/template/relations.php', $logDir . '/relations.html', $consolidated, $history);
61
        $this->renderPage(__DIR__ . '/template/coupling.php', $logDir . '/coupling.html', $consolidated, $history);
62
        $this->renderPage(__DIR__ . '/template/all.php', $logDir . '/all.html', $consolidated, $history);
63
        $this->renderPage(__DIR__ . '/template/oop.php', $logDir . '/oop.html', $consolidated, $history);
64
        $this->renderPage(__DIR__ . '/template/complexity.php', $logDir . '/complexity.html', $consolidated, $history);
65
        $this->renderPage(__DIR__ . '/template/panel.php', $logDir . '/panel.html', $consolidated, $history);
66
        $this->renderPage(__DIR__ . '/template/violations.php', $logDir . '/violations.html', $consolidated, $history);
67
        $this->renderPage(__DIR__ . '/template/packages.php', $logDir . '/packages.html', $consolidated, $history);
68
        $this->renderPage(__DIR__ . '/template/package_relations.php', $logDir . '/package_relations.html', $consolidated, $history);
69
        if ($this->config->has('git')) {
70
            $this->renderPage(__DIR__ . '/template/git.php', $logDir . '/git.html', $consolidated, $history);
71
        }
72
        $this->renderPage(__DIR__ . '/template/junit.php', $logDir . '/junit.html', $consolidated, $history);
73
74
        $today = (object)['avg' => $consolidated->getAvg(), 'sum' => $consolidated->getSum()];
75
        $encodedToday = json_encode($today, JSON_PRETTY_PRINT);
76
        $next = count($history) + 1;
77
        file_put_contents(sprintf('%s/js/history-%d.json', $logDir, $next), $encodedToday);
78
        file_put_contents(sprintf('%s/js/latest.json', $logDir), $encodedToday);
79
80
        file_put_contents(
81
            $logDir . '/js/classes.js',
82
            'var classes = ' . json_encode($consolidated->getClasses(), JSON_PRETTY_PRINT)
83
        );
84
85
        $this->output->writeln(sprintf('HTML report generated in "%s" directory', $logDir));
86
    }
87
88
    /**
89
     * @param $source
90
     * @param $destination
91
     * @param Consolidated $consolidated
92
     * @param $history
93
     * @return $this
94
     */
95
    public function renderPage($source, $destination, Consolidated $consolidated, $history)
96
    {
97
        $this->sum = $sum = $consolidated->getSum();
0 ignored issues
show
Bug introduced by
The property sum does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
98
        $this->avg = $avg = $consolidated->getAvg();
0 ignored issues
show
Bug introduced by
The property avg does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
99
        $this->classes = $classes = $consolidated->getClasses();
0 ignored issues
show
Bug introduced by
The property classes does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
100
        $this->files = $files = $consolidated->getFiles();
0 ignored issues
show
Bug introduced by
The property files does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
101
        $this->project = $project = $consolidated->getProject();
0 ignored issues
show
Bug introduced by
The property project does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
102
        $this->packages = $packages = $consolidated->getPackages();
0 ignored issues
show
Bug introduced by
The property packages does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
103
        $config = $this->config;
104
        $this->history = $history;
0 ignored issues
show
Bug introduced by
The property history does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
105
106
        ob_start();
107
        require $source;
108
        $content = ob_get_clean();
109
        file_put_contents($destination, $content);
110
        return $this;
111
    }
112
113
    /**
114
     * @param $type
115
     * @param $key
116
     * @param bool $lowIsBetter
117
     * @param bool $highIsBetter
118
     * @return string
119
     */
120
    protected function getTrend($type, $key, $lowIsBetter = false, $highIsBetter = false)
121
    {
122
        $svg = [
123
            'gt' => '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
124
    <path d="M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z"/>
125
    <path d="M0 0h24v24H0z" fill="none"/>
126
</svg>',
127
            'eq' => '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
128
    <path d="M22 12l-4-4v3H3v2h15v3z"/>
129
    <path d="M0 0h24v24H0z" fill="none"/>
130
</svg>',
131
            'lt' => '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
132
    <path d="M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z"/>
133
    <path d="M0 0h24v24H0z" fill="none"/>
134
</svg>',
135
        ];
136
        $last = end($this->history);
137
        if (!isset($last->$type->$key)) {
138
            return '';
139
        }
140
141
        $oldValue = $last->$type->$key;
142
        $newValue = isset($this->$type->$key) ? $this->$type->$key : 0;
143
144
        $diff = $newValue - $oldValue;
145
        $goodOrBad = 'neutral';
146
        if ($newValue > $oldValue) {
147
            $r = 'gt';
148
            $diff = '+' . $diff;
149
            $goodOrBad = $lowIsBetter ? 'bad' : $goodOrBad;
150
            $goodOrBad = $highIsBetter ? 'good' : $goodOrBad;
151
        } elseif ($newValue < $oldValue) {
152
            $r = 'lt';
153
            $goodOrBad = $lowIsBetter ? 'good' : $goodOrBad;
154
            $goodOrBad = $highIsBetter ? 'bad' : $goodOrBad;
155
        } else {
156
            $r = 'eq';
157
        }
158
159
        return sprintf(
160
            '<span title="Last value: %s" class="progress progress-%s progress-%s">%s %s</span>',
161
            $oldValue,
162
            $goodOrBad,
163
            $r,
164
            $diff,
165
            $svg[$r]
166
        );
167
    }
168
}
169