Passed
Pull Request — 1.x (#12)
by
unknown
14:08
created

MermaidRenderer   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 46
c 1
b 0
f 0
dl 0
loc 83
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
B render() 0 76 11
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Schema\Renderer\MermaidRenderer;
6
7
use Cycle\ORM\Relation;
8
use Cycle\ORM\SchemaInterface;
9
use Cycle\Schema\Renderer\MermaidRenderer\Entity\EntityArrow;
10
use Cycle\Schema\Renderer\MermaidRenderer\Entity\EntityTable;
11
use Cycle\Schema\Renderer\MermaidRenderer\Exception\RelationNotFoundException;
12
use Cycle\Schema\Renderer\MermaidRenderer\Schema\ClassDiagram;
13
use Cycle\Schema\Renderer\SchemaRenderer;
14
15
final class MermaidRenderer implements SchemaRenderer
16
{
17
    private const METHOD_FORMAT = '%s: %s';
18
19
    /**
20
     * @throws RelationNotFoundException
21
     */
22
    public function render(array $schema): string
23
    {
24
        $class = new ClassDiagram();
25
        $relationMapper = new RelationMapper();
26
27
        foreach ($schema as $key => $value) {
28
            if (!isset($value[SchemaInterface::COLUMNS])) {
29
                continue;
30
            }
31
32
            $role = $value[SchemaInterface::ROLE] ?? $key;
33
34
            // to avoid mermaid class error (user:credentials)
35
            if (str_contains($role, ':')) {
36
                $role = $key;
37
            }
38
39
            $table = new EntityTable($role);
40
            $arrow = new EntityArrow();
41
42
            foreach ($value[SchemaInterface::COLUMNS] as $column) {
43
                $table->addRow($value[SchemaInterface::TYPECAST][$column] ?? 'string', $column);
44
            }
45
46
            foreach ($value[SchemaInterface::RELATIONS] ?? [] as $relationKey => $relation) {
47
                if (!isset($relation[Relation::TARGET], $relation[Relation::SCHEMA])) {
48
                    continue;
49
                }
50
51
                $target = $relation[Relation::TARGET];
52
                $throughEntity = $relation[Relation::SCHEMA][Relation::THROUGH_ENTITY] ?? null;
53
                $isNullable = $relation[Relation::SCHEMA][Relation::NULLABLE] ?? false;
54
55
                $mappedRelation = $relationMapper->mapWithNode($relation[Relation::TYPE], $isNullable);
56
57
                switch ($relation[Relation::TYPE]) {
58
                    case Relation::MANY_TO_MANY:
59
                        $table->addMethod($relationKey, sprintf(self::METHOD_FORMAT, $mappedRelation[0], $target));
60
61
                        // tag --* post : posts
62
                        $arrow->addArrow($role, $target, $relationKey, $mappedRelation[1]);
63
                        // postTag ..> tag : tag.posts
64
                        $arrow->addArrow($throughEntity, $role, "$role.$relationKey", '..>');
0 ignored issues
show
Bug introduced by
It seems like $throughEntity can also be of type null; however, parameter $parent of Cycle\Schema\Renderer\Me...EntityArrow::addArrow() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
                        $arrow->addArrow(/** @scrutinizer ignore-type */ $throughEntity, $role, "$role.$relationKey", '..>');
Loading history...
65
                        // postTag ..> post : tag.posts
66
                        $arrow->addArrow($throughEntity, $target, "$role.$relationKey", '..>');
67
                        break;
68
                    case Relation::EMBEDDED:
69
                        // explode string like user:credentials
70
                        $methodTarget = explode(':', $target);
71
                        $table->addMethod(
72
                            $methodTarget[1] ?? $target,
73
                            sprintf(self::METHOD_FORMAT, $mappedRelation[0], $relationKey)
74
                        );
75
76
                        $arrowTarget = str_replace(':', '&#58', $target);
77
                        $arrow->addArrow($role, $relationKey, $arrowTarget, $mappedRelation[1]);
78
                        break;
79
                    default:
80
                        $table->addMethod($relationKey, sprintf(self::METHOD_FORMAT, $mappedRelation[0], $target));
81
                        $arrow->addArrow($role, $target, $relationKey, $mappedRelation[1]);
82
                }
83
            }
84
85
            foreach ($value[SchemaInterface::CHILDREN] ?? [] as $children) {
86
                $arrow->addArrow($role, $children, 'STI', '--|>');
87
            }
88
89
            if (isset($value[SchemaInterface::PARENT])) {
90
                $arrow->addArrow($value[SchemaInterface::PARENT], $role, 'JTI', '--|>');
91
            }
92
93
            $class->addEntity($table);
94
            $class->addEntity($arrow);
95
        }
96
97
        return (string)$class;
98
    }
99
}
100