Passed
Push — master ( 3c2796...b074c7 )
by Satoshi
02:28
created

UmlFormatter::getGroupedClasses()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer\Detector\GraphFormatter;
5
6
use DependencyAnalyzer\DependencyGraph;
7
use DependencyAnalyzer\Detector\RuleViolationDetector\Component;
8
use DependencyAnalyzer\Patterns\QualifiedNamePattern;
9
10
class UmlFormatter
11
{
12
    /**
13
     * @var DependencyGraph
14
     */
15
    protected $graph;
16
17
    /**
18
     * @var array
19
     */
20
    protected $ruleDefinition;
21
22
    /**
23
     * @var Component[]
24
     */
25
    protected $components = [];
26
27
    protected $groupedClasses = [];
28
29
    /**
30
     * @var QualifiedNamePattern
31
     */
32
    protected $excludeDefinition;
33
34
    public function __construct(DependencyGraph $graph, array $ruleDefinition = [])
35
    {
36
        $this->graph = $graph;
37
        $this->ruleDefinition = $ruleDefinition;
38
39
        if (isset($ruleDefinition['namespace'])) {
40
            foreach ($ruleDefinition['namespace'] as $componentName => $componentDefinition) {
41
                $this->components[] = new Component($componentName, new QualifiedNamePattern($componentDefinition));
42
            }
43
        }
44
        if (isset($ruleDefinition['exclude'])) {
45
            $this->excludeDefinition = new QualifiedNamePattern($ruleDefinition['exclude']);
46
        }
47
        if (isset($ruleDefinition['group'])) {
48
            foreach ($ruleDefinition['group'] as $groupName => $groupDefinition) {
49
                $this->graph = $this->graph->groupByPattern($groupName, new QualifiedNamePattern($groupDefinition));
50
            }
51
        }
52
53
        $this->groupedClasses = $this->getGroupedClasses($this->graph, $this->components);
54
    }
55
56
    public function format()
57
    {
58
        $output = '@startuml' . PHP_EOL;
59
60
        foreach ($this->components as $component) {
61
            $output .= "namespace {$component->getName()} {" . PHP_EOL;
62
63
            foreach ($this->graph->getClasses() as $class) {
64
                if ($component->isBelongedTo($class->getId())) {
65
                    if (!$this->isExcludeClass($class->getId())) {
66
                        $output .= "class {$class->getId()} {" . PHP_EOL;
67
                        $output .= '}' . PHP_EOL;
68
                    }
69
                }
70
            }
71
72
            $output .= '}' . PHP_EOL;
73
        }
74
75
        foreach ($this->graph->getClasses() as $class) {
76
            if ($this->isExcludeClass($class->getId())) {
77
                continue;
78
            }
79
80
            foreach ($this->components as $component) {
81
                if ($component->isBelongedTo($class->getId())) {
82
                    continue 2;
83
                }
84
            }
85
86
            $output .= "class {$class->getId()} {" . PHP_EOL;
87
            $output .= '}' . PHP_EOL;
88
        }
89
90
//        foreach ($this->groupedClasses as $componentName => $classes) {
91
//            if ($componentName !== '') {
92
//                $output .= "namespace {$componentName} {" . PHP_EOL;
93
//            }
94
//
95
//            foreach ($classes as $class) {
96
//                if (!$this->isExcludeClass($class)) {
97
//                    $output .= "class {$class} {" . PHP_EOL;
98
//                    $output .= '}' . PHP_EOL;
99
//                }
100
//            }
101
//
102
//            if ($componentName !== '') {
103
//                $output .= '}' . PHP_EOL;
104
//            }
105
//        }
106
107
        foreach ($this->graph->getDependencyArrows() as $edge) {
108
            $depender = $edge->getVertexStart();
109
            $dependee = $edge->getVertexEnd();
110
111
            if ($this->isExcludeClass($depender->getId()) || $this->isExcludeClass($dependee->getId())) {
112
                continue;
113
            }
114
            $output .= "{$this->searchGroupedClasses($depender->getId())} --> {$this->searchGroupedClasses($dependee->getId())}" . PHP_EOL;
115
        }
116
117
        $output .= '@enduml';
118
119
        return $output;
120
    }
121
122
    protected function isExcludeClass(string $className)
123
    {
124
        if ($this->excludeDefinition) {
125
            return $this->excludeDefinition->isMatch($className);
126
        }
127
128
        return false;
129
    }
130
131
    protected function getGroupedClasses(DependencyGraph $graph, array $components): array
132
    {
133
        $classNames = [];
134
        foreach ($graph->getClasses() as $class) {
135
            $key = $this->getBelongToComponent($class->getId(), $components);
136
            $classNames[$key][] = $class->getId();
137
//            $classNames[] = $class->getId();
138
        }
139
//        sort($classNames);
140
141
        return $classNames;
142
    }
143
144
    protected function getBelongToComponent(string $className, array $components): string
145
    {
146
        foreach ($components as $component) {
147
            if ($component->isBelongedTo($className)) {
148
                return $component->getName();
149
            }
150
        }
151
152
        return '';
153
    }
154
155
    protected function searchGroupedClasses(string $needle)
156
    {
157
        foreach ($this->groupedClasses as $componentName => $classes) {
158
            if ($componentName === '') {
159
                continue;
160
            }
161
162
            foreach ($classes as $class) {
163
                if ($class === $needle) {
164
                    return "{$componentName}.$needle";
165
                }
166
            }
167
        }
168
169
        return $needle;
170
    }
171
}
172