1414use InvalidArgumentException ;
1515use Symfony \Component \Workflow \Definition ;
1616use Symfony \Component \Workflow \Marking ;
17+ use Symfony \Component \Workflow \Metadata \MetadataStoreInterface ;
18+ use Symfony \Component \Workflow \Transition ;
1719
1820/**
1921 * PlantUmlDumper dumps a workflow as a PlantUML file.
@@ -63,13 +65,13 @@ public function __construct(string $transitionType = null)
6365 public function dump (Definition $ definition , Marking $ marking = null , array $ options = []): string
6466 {
6567 $ options = array_replace_recursive (self ::DEFAULT_OPTIONS , $ options );
66- $ code = $ this ->initialize ($ options );
68+
69+ $ workflowMetadata = $ definition ->getMetadataStore ();
70+
71+ $ code = $ this ->initialize ($ options , $ definition );
72+
6773 foreach ($ definition ->getPlaces () as $ place ) {
68- $ placeEscaped = $ this ->escape ($ place );
69- $ code [] =
70- "state $ placeEscaped " .
71- ($ definition ->getInitialPlace () === $ place ? ' ' .self ::INITIAL : '' ).
72- ($ marking && $ marking ->has ($ place ) ? ' ' .self ::MARKED : '' );
74+ $ code [] = $ this ->getState ($ place , $ definition , $ marking );
7375 }
7476 if ($ this ->isWorkflowTransitionType ()) {
7577 foreach ($ definition ->getTransitions () as $ transition ) {
@@ -83,18 +85,34 @@ public function dump(Definition $definition, Marking $marking = null, array $opt
8385 $ fromEscaped = $ this ->escape ($ from );
8486 foreach ($ transition ->getTos () as $ to ) {
8587 $ toEscaped = $ this ->escape ($ to );
88+
89+ $ transitionEscapedWithStyle = $ this ->getTransitionEscapedWithStyle ($ workflowMetadata , $ transition , $ transitionEscaped );
90+
91+ $ arrowColor = $ workflowMetadata ->getMetadata ('arrow_color ' , $ transition );
92+
93+ $ transitionColor = '' ;
94+ if (null !== $ arrowColor ) {
95+ $ transitionColor = $ this ->getTransitionColor ($ arrowColor ) ?? '' ;
96+ }
97+
8698 if ($ this ->isWorkflowTransitionType ()) {
99+ $ transitionLabel = '' ;
100+ // Add label only if it has a style
101+ if ($ transitionEscapedWithStyle != $ transitionEscaped ) {
102+ $ transitionLabel = ": $ transitionEscapedWithStyle " ;
103+ }
104+
87105 $ lines = [
88- "$ fromEscaped --> $ transitionEscaped " ,
89- "$ transitionEscaped --> $ toEscaped " ,
106+ "$ fromEscaped - $ {transitionColor} -> $ { transitionEscaped} $ {transitionLabel} " ,
107+ "$ transitionEscaped - $ {transitionColor} -> $ { toEscaped} $ {transitionLabel} " ,
90108 ];
91109 foreach ($ lines as $ line ) {
92110 if (!\in_array ($ line , $ code )) {
93111 $ code [] = $ line ;
94112 }
95113 }
96114 } else {
97- $ code [] = "$ fromEscaped --> $ toEscaped: $ transitionEscaped " ;
115+ $ code [] = "$ fromEscaped - $ {transitionColor} -> $ toEscaped: $ transitionEscapedWithStyle " ;
98116 }
99117 }
100118 }
@@ -126,15 +144,28 @@ private function getLines(array $code): string
126144 return implode (PHP_EOL , $ code );
127145 }
128146
129- private function initialize (array $ options ): array
147+ private function initialize (array $ options, Definition $ definition ): array
130148 {
149+ $ workflowMetadata = $ definition ->getMetadataStore ();
150+
131151 $ code = [];
132152 if (isset ($ options ['title ' ])) {
133153 $ code [] = "title {$ options ['title ' ]}" ;
134154 }
135155 if (isset ($ options ['name ' ])) {
136156 $ code [] = "title {$ options ['name ' ]}" ;
137157 }
158+
159+ // Add style from nodes
160+ foreach ($ definition ->getPlaces () as $ place ) {
161+ $ backgroundColor = $ workflowMetadata ->getMetadata ('bg_color ' , $ place );
162+ if (null !== $ backgroundColor ) {
163+ $ key = 'BackgroundColor<< ' .$ this ->getColorId ($ backgroundColor ).'>> ' ;
164+
165+ $ options ['skinparams ' ]['state ' ][$ key ] = $ backgroundColor ;
166+ }
167+ }
168+
138169 if (isset ($ options ['skinparams ' ]) && \is_array ($ options ['skinparams ' ])) {
139170 foreach ($ options ['skinparams ' ] as $ skinparamKey => $ skinparamValue ) {
140171 if (!$ this ->isWorkflowTransitionType () && 'agent ' === $ skinparamKey ) {
@@ -160,4 +191,62 @@ private function escape(string $string): string
160191 // It's not possible to escape property double quote, so let's remove it
161192 return '" ' .str_replace ('" ' , '' , $ string ).'" ' ;
162193 }
194+
195+ private function getState (string $ place , Definition $ definition , Marking $ marking = null ): string
196+ {
197+ $ workflowMetadata = $ definition ->getMetadataStore ();
198+
199+ $ placeEscaped = $ this ->escape ($ place );
200+
201+ $ output = "state $ placeEscaped " .
202+ ($ definition ->getInitialPlace () === $ place ? ' ' .self ::INITIAL : '' ).
203+ ($ marking && $ marking ->has ($ place ) ? ' ' .self ::MARKED : '' );
204+
205+ $ backgroundColor = $ workflowMetadata ->getMetadata ('bg_color ' , $ place );
206+ if (null !== $ backgroundColor ) {
207+ $ output .= ' << ' .$ this ->getColorId ($ backgroundColor ).'>> ' ;
208+ }
209+
210+ $ description = $ workflowMetadata ->getMetadata ('description ' , $ place );
211+ if (null !== $ description ) {
212+ $ output .= ' as ' .$ place .
213+ PHP_EOL .
214+ $ place .' : ' .$ description ;
215+ }
216+
217+ return $ output ;
218+ }
219+
220+ private function getTransitionEscapedWithStyle (MetadataStoreInterface $ workflowMetadata , Transition $ transition , string $ to ): string
221+ {
222+ $ to = $ workflowMetadata ->getMetadata ('label ' , $ transition ) ?? $ to ;
223+
224+ $ color = $ workflowMetadata ->getMetadata ('color ' , $ transition ) ?? null ;
225+
226+ if (null !== $ color ) {
227+ $ to = sprintf (
228+ '<font color=%1$s>%2$s</font> ' ,
229+ $ color ,
230+ $ to
231+ );
232+ }
233+
234+ return $ this ->escape ($ to );
235+ }
236+
237+ private function getTransitionColor (string $ color ): string
238+ {
239+ // PUML format requires that color in transition have to be prefixed with “#”.
240+ if ('# ' !== substr ($ color , 0 , 1 )) {
241+ $ color = '# ' .$ color ;
242+ }
243+
244+ return sprintf ('[%s] ' , $ color );
245+ }
246+
247+ private function getColorId (string $ color ): string
248+ {
249+ // Remove “#“ from start of the color name so it can be used as an identifier.
250+ return ltrim ($ color , '# ' );
251+ }
163252}
0 commit comments