Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 45e7788

Browse files
committed
feat: Add ClassDiagramDumper for YAML output of class diagrams
1 parent 8affea9 commit 45e7788

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer;
5+
6+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\AbstractClass_;
7+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Class_;
8+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Enum_;
9+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Interface_;
10+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Node;
11+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Composition;
12+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Dependency;
13+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Inheritance;
14+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Realization;
15+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Relationship;
16+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\TraitUsage;
17+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Trait_;
18+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\RenderOptions\RenderOptions;
19+
20+
class ClassDiagramDumper
21+
{
22+
public function __construct(private ClassDiagram $diagram)
23+
{
24+
}
25+
26+
public function toYaml(?RenderOptions $options = null): string
27+
{
28+
$options = $options ?? RenderOptions::default();
29+
30+
[$nodes, $relationships] = $this->extract($options);
31+
32+
$output = "nodes:\n";
33+
foreach ($nodes as $node) {
34+
$output .= " - type: " . $this->nodeType($node) . "\n";
35+
$output .= " name: " . $node->nodeName() . "\n";
36+
}
37+
38+
$output .= "relationships:\n";
39+
foreach ($relationships as $relationship) {
40+
$output .= " - type: " . $this->relationshipType($relationship) . "\n";
41+
$output .= " from: " . $relationship->from->nodeName() . "\n";
42+
$output .= " to: " . $relationship->to->nodeName() . "\n";
43+
}
44+
45+
return $output;
46+
}
47+
48+
/**
49+
* @return array{0: array<int, Node>, 1: array<int, Relationship>}
50+
*/
51+
private function extract(RenderOptions $options): array
52+
{
53+
$ref = new \ReflectionClass($this->diagram);
54+
55+
$nodesProp = $ref->getProperty('nodes');
56+
$nodesProp->setAccessible(true);
57+
$nodes = $nodesProp->getValue($this->diagram);
58+
59+
$relationshipsProp = $ref->getProperty('relationships');
60+
$relationshipsProp->setAccessible(true);
61+
$relationships = $relationshipsProp->getValue($this->diagram);
62+
63+
// Apply the same filtering/sorting policy as render()
64+
$nodes = $nodes->filter($options)->sort()->getAll();
65+
$relationships = $relationships->filter($options)->sort()->getAll();
66+
67+
return [$nodes, $relationships];
68+
}
69+
70+
private function nodeType(Node $node): string
71+
{
72+
return match (true) {
73+
$node instanceof AbstractClass_ => 'AbstractClass',
74+
$node instanceof Interface_ => 'Interface',
75+
$node instanceof Trait_ => 'Trait',
76+
$node instanceof Enum_ => 'Enum',
77+
$node instanceof Class_ => 'Class',
78+
default => 'Unknown',
79+
};
80+
}
81+
82+
private function relationshipType(Relationship $relationship): string
83+
{
84+
return match (true) {
85+
$relationship instanceof Inheritance => 'inheritance',
86+
$relationship instanceof Realization => 'realization',
87+
$relationship instanceof Dependency => 'dependency',
88+
$relationship instanceof Composition => 'composition',
89+
$relationship instanceof TraitUsage => 'traitUsage',
90+
default => 'unknown',
91+
};
92+
}
93+
}
94+

tests/ClassDiagramRenderer/ClassDiagramBuilderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PhpParser\PhpVersion;
1010
use PHPUnit\Framework\TestCase;
1111
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\ClassDiagramBuilder;
12+
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\ClassDiagramDumper;
1213
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\NodeParser;
1314
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\RenderOptions\RenderOptions;
1415

@@ -26,6 +27,16 @@ protected function setUp(): void
2627
$this->nodeParser = new NodeParser($this->parser, $this->nodeFinder);
2728
$this->classDigagramBuilder = new ClassDiagramBuilder($this->nodeParser);
2829
}
30+
31+
public function testDump(): void
32+
{
33+
$path = __DIR__ . '/../data/Project';
34+
35+
$classDiagram = $this->classDigagramBuilder
36+
->build($path);
37+
$dumper = new ClassDiagramDumper($classDiagram);
38+
echo $dumper->toYaml();
39+
}
2940

3041
public function testBuildFromSampleProject(): void
3142
{

0 commit comments

Comments
 (0)