1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Cauditor\Analyzers; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* @author Matthias Mullie <[email protected]> |
7
|
|
|
* @copyright Copyright (c) 2016, Matthias Mullie. All rights reserved. |
8
|
|
|
* @license LICENSE MIT |
9
|
|
|
*/ |
10
|
|
View Code Duplication |
class Converter |
|
|
|
|
11
|
|
|
{ |
12
|
|
|
/** |
13
|
|
|
* Project-wide totals. |
14
|
|
|
* |
15
|
|
|
* @var array |
16
|
|
|
*/ |
17
|
|
|
protected $totals = array(); |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Processes XML node by node, extracts the relevant metrics & writes them |
21
|
|
|
* piecemeal to a JSON file. |
22
|
|
|
* |
23
|
|
|
* @param XMLReader $reader XML document to read from. |
24
|
|
|
* |
25
|
|
|
* @return string |
26
|
|
|
*/ |
27
|
|
|
public function convert(XMLReader $reader) |
28
|
|
|
{ |
29
|
|
|
$reader->readNext('metrics'); |
30
|
|
|
|
31
|
|
|
$this->totals = array(); |
32
|
|
|
$packages = $this->convertPackages($reader); |
33
|
|
|
|
34
|
|
|
$data = array( |
35
|
|
|
'loc' => $reader->getAttribute('eloc'), |
36
|
|
|
'noc' => $reader->getAttribute('noc'), |
37
|
|
|
'nom' => $reader->getAttribute('nom'), |
38
|
|
|
) + $this->totals; |
39
|
|
|
|
40
|
|
|
$json = json_encode($data); |
41
|
|
|
// data will be stored as json, but we need to inject children, so |
42
|
|
|
// don't write the closing `]` & `}` yet |
43
|
|
|
return substr($json, 0, -1).',"children":['.$packages.']}'; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
protected function convertPackages(XMLReader $reader) |
47
|
|
|
{ |
48
|
|
|
$i = 0; |
49
|
|
|
$content = ''; |
50
|
|
|
while ($reader->readNext('package', 'metrics')) { |
51
|
|
|
$data = array('name' => $reader->getAttribute('name')); |
52
|
|
|
|
53
|
|
|
$this->addToTotals($data); |
54
|
|
|
|
55
|
|
|
$json = json_encode($data); |
56
|
|
|
// add `,` between multiple nodes |
57
|
|
|
$json = $i++ === 0 ? $json : ','.$json; |
58
|
|
|
// data will be stored as json, but we need to fetch children, so |
59
|
|
|
// don't write the closing `]` & `}` yet |
60
|
|
|
$content .= substr($json, 0, -1).',"children":['.$this->convertClasses($reader).']}'; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
return $content; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
protected function convertClasses(XMLReader $reader) |
67
|
|
|
{ |
68
|
|
|
$i = 0; |
69
|
|
|
$content = ''; |
70
|
|
|
while ($reader->readNext('class', 'package')) { |
71
|
|
|
$data = array( |
72
|
|
|
'name' => $reader->getAttribute('name'), |
73
|
|
|
'loc' => (int) $reader->getAttribute('eloc'), |
74
|
|
|
'ca' => (int) $reader->getAttribute('ca'), |
75
|
|
|
'ce' => (int) $reader->getAttribute('ce'), |
76
|
|
|
'i' => (float) number_format((int) $reader->getAttribute('ce') / (((int) $reader->getAttribute('ce') + (int) $reader->getAttribute('ca')) ?: 1), 2), |
77
|
|
|
'dit' => (int) $reader->getAttribute('dit'), |
78
|
|
|
); |
79
|
|
|
|
80
|
|
|
$this->addToTotals($data); |
81
|
|
|
|
82
|
|
|
$json = json_encode($data); |
83
|
|
|
// add `,` between multiple nodes |
84
|
|
|
$json = $i++ === 0 ? $json : ','.$json; |
85
|
|
|
// data will be stored as json, but we need to fetch children, so |
86
|
|
|
// don't write the closing `]` & `}` yet |
87
|
|
|
$content .= substr($json, 0, -1).',"children":['.$this->convertMethods($reader).']}'; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return $content; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
protected function convertMethods(XMLReader $reader) |
94
|
|
|
{ |
95
|
|
|
$i = 0; |
96
|
|
|
$content = ''; |
97
|
|
|
while ($reader->readNext('method', 'class')) { |
98
|
|
|
$data = array( |
99
|
|
|
'name' => $reader->getAttribute('name'), |
100
|
|
|
'loc' => (int) $reader->getAttribute('eloc'), |
101
|
|
|
'ccn' => (int) $reader->getAttribute('ccn2'), |
102
|
|
|
'npath' => (int) $reader->getAttribute('npath'), |
103
|
|
|
'he' => (float) number_format($reader->getAttribute('he'), 2), |
104
|
|
|
'hi' => (float) number_format($reader->getAttribute('hi'), 2), |
105
|
|
|
'mi' => (float) number_format($reader->getAttribute('mi'), 2), |
106
|
|
|
); |
107
|
|
|
|
108
|
|
|
$this->addToTotals($data); |
109
|
|
|
|
110
|
|
|
$json = json_encode($data); |
111
|
|
|
// add `,` between multiple nodes |
112
|
|
|
$json = $i++ === 0 ? $json : ','.$json; |
113
|
|
|
|
114
|
|
|
$content .= $json; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $content; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
protected function addToTotals(array $data) |
121
|
|
|
{ |
122
|
|
|
// don't need these, obviously... |
123
|
|
|
unset($data['name'], $data['loc']); |
124
|
|
|
|
125
|
|
|
foreach ($data as $metric => $value) { |
126
|
|
|
if (!isset($this->totals[$metric])) { |
127
|
|
|
$this->totals[$metric] = 0; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
$this->totals[$metric] += $value; |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.