Completed
Push — symfony-console-application ( 3187e2...c3ee2a )
by Luis
10:39
created

ClassGraphElements::extractFrom()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 12
nc 8
nop 2
1
<?php
2
/**
3
 * PHP version 7.1
4
 *
5
 * This source file is subject to the license that is bundled with this package in the file LICENSE.
6
 */
7
8
namespace PhUml\Graphviz;
9
10
use PhUml\Code\ClassDefinition;
11
use PhUml\Code\Structure;
12
use PhUml\Code\Variable;
13
14
class ClassGraphElements
15
{
16
    /** @var HasDotRepresentation[] */
17
    private $dotElements = [];
18
19
    /** @var bool[] */
20
    private $associations = [];
21
22
    /** @var bool */
23
    private $createAssociations;
24
25
    /** @var NodeLabelBuilder */
26
    private $labelBuilder;
27
28
    /** @var Structure */
29
    private $structure;
30
31
    public function __construct(bool $createAssociations, NodeLabelBuilder $labelBuilder)
32
    {
33
        $this->createAssociations = $createAssociations;
34
        $this->labelBuilder = $labelBuilder;
35
    }
36
37
    /**
38
     * @return HasDotRepresentation[]
39
     */
40
    public function extractFrom(ClassDefinition $class, Structure $structure): array
41
    {
42
        $this->dotElements = [];
43
        $this->associations = [];
44
        $this->structure = $structure;
45
46
        if ($this->createAssociations) {
47
            $this->addElementsForAttributes($class);
48
            $this->addElementsForParameters($class);
49
        }
50
51
        $this->dotElements[] = new Node($class, $this->labelBuilder->labelForClass($class));
52
53
        if ($class->hasParent()) {
54
            $this->dotElements[] = Edge::inheritance($class->extends, $class);
55
        }
56
57
        foreach ($class->implements as $interface) {
58
            $this->dotElements[] = Edge::implementation($interface, $class);
59
        }
60
61
        return $this->dotElements;
62
    }
63
64
    /** @return HasDotRepresentation[] */
65
    private function addElementsForAttributes(ClassDefinition $class): void
66
    {
67
        /** @var \PhUml\Code\Attribute $attribute */
68
        foreach ($class->attributes as $attribute) {
69
            $this->addAssociationForVariable($class, $attribute);
70
        }
71
    }
72
73
    /** @return HasDotRepresentation[] */
74
    private function addElementsForParameters(ClassDefinition $class): void
75
    {
76
        if (!$class->hasConstructor()) {
77
            return;
78
        }
79
        foreach ($class->constructorParameters() as $parameter) {
80
            $this->addAssociationForVariable($class, $parameter);
81
        }
82
    }
83
84
    private function addAssociationForVariable(ClassDefinition $class, Variable $attribute): void
85
    {
86
        if ($this->needAssociation($attribute)) {
87
            $this->dotElements[] = Edge::association(
88
                $this->structure->get((string)$attribute->type),
89
                $class
90
            );
91
            $this->associations[strtolower($attribute->type)] = true;
92
        }
93
    }
94
95
    private function needAssociation(Variable $attribute): bool
96
    {
97
        return $attribute->hasType() && !$attribute->isBuiltIn() && !$this->isAssociationResolved($attribute->type);
98
    }
99
100
    private function isAssociationResolved(string $type): bool
101
    {
102
        return array_key_exists(strtolower($type), $this->associations);
103
    }
104
}
105