1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author @jayS-de <[email protected]> |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Commercetools\Core\Helper\State; |
7
|
|
|
|
8
|
|
|
use Commercetools\Core\Client; |
9
|
|
|
use Commercetools\Core\Model\Common\Context; |
10
|
|
|
use Commercetools\Core\Helper\State\Renderer\NodeRenderer; |
11
|
|
|
use Commercetools\Core\Helper\State\Renderer\TransitionRenderer; |
12
|
|
|
use Commercetools\Core\Model\State\StateCollection; |
13
|
|
|
use Commercetools\Core\Request\States\StateQueryRequest; |
14
|
|
|
|
15
|
|
|
class Renderer |
16
|
|
|
{ |
17
|
|
|
/** @var array Colors for drawing dwh states */ |
18
|
|
|
public static $colors = array( |
19
|
|
|
'#2266aa', |
20
|
|
|
'#228866', |
21
|
|
|
'#775533', |
22
|
|
|
'#333311', |
23
|
|
|
'#881122', |
24
|
|
|
'#662266', |
25
|
|
|
'#00212E', |
26
|
|
|
'#42002E', |
27
|
|
|
'#422100', |
28
|
|
|
'#000B11', |
29
|
|
|
'#5A0011', |
30
|
|
|
'#5A0B00' |
31
|
|
|
); |
32
|
|
|
|
33
|
|
|
/** @var array $eventColors colors for drawing the events */ |
34
|
|
|
protected $eventColors = array( |
35
|
|
|
'manual' => '#00AA00', // color for manually executable event |
36
|
|
|
'timeout' => '#AAAAAA', // color for timeout event |
37
|
|
|
'statewasset' => '#0000AA', // color for other events |
38
|
|
|
'default' => '#222222', // color for other events |
39
|
|
|
); |
40
|
|
|
|
41
|
|
|
/** @var string $defaultFontColor default font color for state nodes */ |
42
|
|
|
protected $defaultFontColor = ''; |
43
|
|
|
/** @var string $defaultBorderColor default border color for state nodes */ |
44
|
|
|
protected $defaultBorderColor = ''; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var array $nodeRenderers contains the renderers for the state nodes. |
48
|
|
|
* |
49
|
|
|
* They can be set by setNodeRendererByStateName(). If no renderer is set the default renderer |
50
|
|
|
* Bob_StateMachine_Renderer_Node_DefaultRenderer will be used. |
51
|
|
|
*/ |
52
|
|
|
protected $nodeRenderers = array(); |
53
|
|
|
|
54
|
|
|
protected $transitionRenderers = array(); |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @return array |
58
|
|
|
*/ |
59
|
|
|
public function getEventColors() |
60
|
|
|
{ |
61
|
|
|
return $this->eventColors; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param array $eventColors |
66
|
|
|
*/ |
67
|
|
|
public function setEventColors($eventColors) |
68
|
|
|
{ |
69
|
|
|
$this->eventColors = $eventColors; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @return string |
74
|
|
|
*/ |
75
|
|
|
public function getDefaultFontColor() |
76
|
|
|
{ |
77
|
|
|
return $this->defaultFontColor; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @param string $defaultFontColor |
82
|
|
|
*/ |
83
|
|
|
public function setDefaultFontColor($defaultFontColor) |
84
|
|
|
{ |
85
|
|
|
$this->defaultFontColor = $defaultFontColor; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @return string |
90
|
|
|
*/ |
91
|
|
|
public function getDefaultBorderColor() |
92
|
|
|
{ |
93
|
|
|
return $this->defaultBorderColor; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @param string $defaultBorderColor |
98
|
|
|
*/ |
99
|
|
|
public function setDefaultBorderColor($defaultBorderColor) |
100
|
|
|
{ |
101
|
|
|
$this->defaultBorderColor = $defaultBorderColor; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @return array |
106
|
|
|
*/ |
107
|
|
|
public function getNodeRenderers() |
108
|
|
|
{ |
109
|
|
|
return $this->nodeRenderers; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @param array $nodeRenderers |
114
|
|
|
*/ |
115
|
|
|
public function setNodeRenderers($nodeRenderers) |
116
|
|
|
{ |
117
|
|
|
$this->nodeRenderers = $nodeRenderers; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @return array |
122
|
|
|
*/ |
123
|
|
|
public function getTransitionRenderers() |
124
|
|
|
{ |
125
|
|
|
return $this->transitionRenderers; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param array $transitionRenderers |
130
|
|
|
*/ |
131
|
|
|
public function setTransitionRenderers($transitionRenderers) |
132
|
|
|
{ |
133
|
|
|
$this->transitionRenderers = $transitionRenderers; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Is there a state node renderer for the given state name? |
138
|
|
|
* |
139
|
|
|
* @param $stateName |
140
|
|
|
* @return bool |
141
|
|
|
*/ |
142
|
|
|
public function hasNodeRendererByStateName($stateName) |
143
|
|
|
{ |
144
|
|
|
return isset($this->nodeRenderers[$stateName]); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Get the renderer for the given state name. |
149
|
|
|
* |
150
|
|
|
* If no renderer was set the default renderer Bob_StateMachine_Renderer_Node_DefaultRenderer() is returned |
151
|
|
|
* |
152
|
|
|
* @param $stateName |
153
|
|
|
* @return NodeRenderer |
154
|
|
|
*/ |
155
|
|
|
public function getNodeRendererByStateName($stateName) |
156
|
|
|
{ |
157
|
|
|
if (isset($this->nodeRenderers[$stateName])) { |
158
|
|
|
return $this->nodeRenderers[$stateName]; |
159
|
|
|
} |
160
|
|
|
return new NodeRenderer(); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
public function getTransitionRendererByStateName($stateName) |
164
|
|
|
{ |
165
|
|
|
if (isset($this->transitionRenderers[$stateName])) { |
166
|
|
|
return $this->transitionRenderers[$stateName]; |
167
|
|
|
} |
168
|
|
|
return new TransitionRenderer(); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Renders a dot graph into an svg |
173
|
|
|
* |
174
|
|
|
* @param string $dotString The dot graph that is fed into the |
175
|
|
|
* @return string|bool the resulting SVG |
176
|
|
|
*/ |
177
|
|
|
public function runDot($dotString) |
178
|
|
|
{ |
179
|
|
|
$descriptorSpec = array( |
180
|
|
|
0 => array("pipe", "r"), // stdin |
181
|
|
|
1 => array("pipe", "w"), // stdout |
182
|
|
|
2 => array("pipe", "a") // stderr |
183
|
|
|
); |
184
|
|
|
|
185
|
|
|
$process = proc_open('dot -Tsvg', $descriptorSpec, $pipes); |
186
|
|
|
|
187
|
|
|
if (is_resource($process)) { |
188
|
|
|
fwrite($pipes[0], $dotString); |
189
|
|
|
fclose($pipes[0]); |
190
|
|
|
|
191
|
|
|
$svg = stream_get_contents($pipes[1]); |
192
|
|
|
fclose($pipes[1]); |
193
|
|
|
|
194
|
|
|
proc_close($process); |
195
|
|
|
$svg = explode('<svg ', $svg); |
196
|
|
|
|
197
|
|
|
// has it worked out? |
198
|
|
|
if (count($svg) < 2) { |
199
|
|
|
return false; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
return '<svg ' . $svg[1]; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
return false; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Creates a dot graph for a process |
210
|
|
|
* |
211
|
|
|
* @param StateCollection $stateCollection |
212
|
|
|
* @return string A dot graph |
213
|
|
|
*/ |
214
|
|
|
public function renderDot(StateCollection $stateCollection) |
215
|
|
|
{ |
216
|
|
|
// define the graph |
217
|
|
|
$graph = 'digraph ' . 'test' |
218
|
|
|
. ' { dpi="56";compound="true";fontname="Arial";margin="";nodesep="0.6";rankdir="TD";ranksep="0.4";' |
219
|
|
|
. PHP_EOL; |
220
|
|
|
|
221
|
|
|
// add all states to the graph |
222
|
|
View Code Duplication |
foreach ($stateCollection as $state) { |
|
|
|
|
223
|
|
|
$nodeRenderer = $this->getNodeRendererByStateName($state->getKey()); |
224
|
|
|
$graph .= ' ' . $nodeRenderer->render($state); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
// add all transitions to the graph |
228
|
|
View Code Duplication |
foreach ($stateCollection as $state) { |
|
|
|
|
229
|
|
|
$nodeRenderer = $this->getTransitionRendererByStateName($state->getKey()); |
230
|
|
|
$graph .= ' ' . $nodeRenderer->render($state); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
$graph .= '}' . PHP_EOL; |
234
|
|
|
|
235
|
|
|
|
236
|
|
|
return $graph; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @param Client $client |
241
|
|
|
* @param Context $context |
242
|
|
|
* @return string |
243
|
|
|
*/ |
244
|
|
|
public static function run(Client $client, Context $context = null) |
245
|
|
|
{ |
246
|
|
|
$renderer = new static(); |
247
|
|
|
$request = new StateQueryRequest($context); |
248
|
|
|
$request->expand('transitions[*]'); |
249
|
|
|
|
250
|
|
|
$states = $client->execute($request)->toObject(); |
251
|
|
|
|
252
|
|
|
$dotString = $renderer->renderDot($states); |
253
|
|
|
return $renderer->runDot($dotString); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.