1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @link https://github.com/old-town/old-town-workflow |
4
|
|
|
* @author Malofeykin Andrey <[email protected]> |
5
|
|
|
*/ |
6
|
|
|
namespace OldTown\Workflow\Loader; |
7
|
|
|
|
8
|
|
|
use DOMElement; |
9
|
|
|
use OldTown\Workflow\Exception\InternalWorkflowException; |
10
|
|
|
use OldTown\Workflow\Exception\InvalidDescriptorException; |
11
|
|
|
use OldTown\Workflow\Exception\InvalidWorkflowDescriptorException; |
12
|
|
|
use OldTown\Workflow\Exception\InvalidWriteWorkflowException; |
13
|
|
|
use SplObjectStorage; |
14
|
|
|
use DOMDocument; |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class ConditionDescriptor |
19
|
|
|
* |
20
|
|
|
* @package OldTown\Workflow\Loader |
21
|
|
|
*/ |
22
|
|
|
class ConditionalResultDescriptor extends ResultDescriptor |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var ConditionsDescriptor[]|SplObjectStorage |
26
|
|
|
*/ |
27
|
|
|
protected $conditions; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @param $element |
31
|
|
|
*/ |
32
|
40 |
|
public function __construct(DOMElement $element = null) |
33
|
|
|
{ |
34
|
40 |
|
$this->conditions = new SplObjectStorage(); |
35
|
|
|
|
36
|
40 |
|
$this->flagNotExecuteInit = true; |
37
|
40 |
|
parent::__construct($element); |
38
|
40 |
|
$this->flagNotExecuteInit = false; |
39
|
|
|
|
40
|
40 |
|
if (null !== $element) { |
41
|
39 |
|
$this->init($element); |
42
|
39 |
|
} |
43
|
40 |
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param DOMElement $conditionalResult |
47
|
|
|
* |
48
|
|
|
* @return void |
49
|
|
|
*/ |
50
|
39 |
View Code Duplication |
protected function init(DOMElement $conditionalResult) |
|
|
|
|
51
|
|
|
{ |
52
|
39 |
|
parent::init($conditionalResult); |
53
|
|
|
|
54
|
39 |
|
$conditionNodes = XMLUtil::getChildElements($conditionalResult, 'conditions'); |
55
|
|
|
|
56
|
39 |
|
foreach ($conditionNodes as $condition) { |
57
|
27 |
|
$conditionDescriptor = DescriptorFactory::getFactory()->createConditionsDescriptor($condition); |
58
|
27 |
|
$conditionDescriptor->setParent($this); |
59
|
27 |
|
$this->conditions->attach($conditionDescriptor); |
60
|
39 |
|
} |
61
|
39 |
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @return ConditionsDescriptor[]|SplObjectStorage |
65
|
|
|
*/ |
66
|
28 |
|
public function getConditions() |
67
|
|
|
{ |
68
|
28 |
|
return $this->conditions; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* |
73
|
|
|
* |
74
|
|
|
* @return string |
75
|
|
|
* @throws InvalidWorkflowDescriptorException |
76
|
|
|
* @throws InternalWorkflowException |
77
|
|
|
* @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
78
|
|
|
*/ |
79
|
19 |
|
public function getDestination() |
80
|
|
|
{ |
81
|
|
|
/** @var WorkflowDescriptor $desc */ |
82
|
8 |
|
$desc = null; |
83
|
8 |
|
$sName = ''; |
84
|
|
|
|
85
|
|
|
//action |
86
|
8 |
|
$parent = $this->getParent(); |
87
|
8 |
|
if (!$parent instanceof AbstractDescriptor) { |
88
|
1 |
|
$errMsg = sprintf( |
89
|
1 |
|
'Родитель должен реализовывать %s', |
90
|
|
|
AbstractDescriptor::class |
91
|
1 |
|
); |
92
|
1 |
|
throw new InvalidWorkflowDescriptorException($errMsg); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
//step |
96
|
7 |
|
$actionDesc = $parent->getParent(); |
97
|
7 |
|
if (null !== $actionDesc) { |
98
|
4 |
|
$desc = $actionDesc->getParent(); |
99
|
4 |
|
} |
100
|
|
|
|
101
|
7 |
|
$join = $this->getJoin(); |
102
|
7 |
|
$split = $this->getSplit(); |
103
|
7 |
|
if (null !== $join && 0 !== $join) { |
104
|
1 |
|
$result = sprintf('join #%s', $join); |
105
|
1 |
|
return $result; |
106
|
19 |
|
} elseif (null !== $split && 0 !== $split) { |
107
|
2 |
|
$result = sprintf('split #%s', $split); |
108
|
2 |
|
return $result; |
109
|
|
|
} else { |
110
|
4 |
|
$step = $this->getStep(); |
111
|
4 |
|
if ($desc !== null) { |
112
|
|
|
/** @var WorkflowDescriptor $desc */ |
113
|
|
|
|
114
|
4 |
|
$stepDescriptor = $desc->getStep($step); |
115
|
|
|
|
116
|
4 |
|
if (!$stepDescriptor instanceof StepDescriptor) { |
117
|
1 |
|
$errMsg = sprintf( |
118
|
1 |
|
'Дескриптор шалаг должен реализовывать %s', |
119
|
|
|
StepDescriptor::class |
120
|
1 |
|
); |
121
|
1 |
|
throw new InvalidWorkflowDescriptorException($errMsg); |
122
|
|
|
} |
123
|
3 |
|
$sName = $stepDescriptor->getName(); |
124
|
3 |
|
} |
125
|
|
|
|
126
|
3 |
|
$result = sprintf('step #%s [%s]', $step, $sName); |
127
|
3 |
|
return $result; |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Валидация дескриптора |
134
|
|
|
* |
135
|
|
|
* @return void |
136
|
|
|
* @throws InvalidWorkflowDescriptorException |
137
|
|
|
* @throws InternalWorkflowException |
138
|
|
|
*/ |
139
|
16 |
|
public function validate() |
140
|
|
|
{ |
141
|
16 |
|
parent::validate(); |
142
|
|
|
|
143
|
16 |
|
$conditions = $this->getConditions(); |
144
|
16 |
|
if (0 === $conditions->count()) { |
145
|
2 |
|
$actionDescriptor = $this->getParent(); |
146
|
2 |
|
if (!$actionDescriptor instanceof ActionDescriptor) { |
147
|
1 |
|
$errMsg = sprintf( |
148
|
1 |
|
'Родитель должен реализовывать %s', |
149
|
|
|
ActionDescriptor::class |
150
|
1 |
|
); |
151
|
1 |
|
throw new InvalidWorkflowDescriptorException($errMsg); |
152
|
|
|
} |
153
|
|
|
|
154
|
1 |
|
$errMsg = sprintf( |
155
|
1 |
|
'Результат условия от %s к %s должны иметь по крайней мере одну условие', |
156
|
1 |
|
$actionDescriptor->getName(), |
157
|
1 |
|
$this->getDestination() |
158
|
1 |
|
); |
159
|
1 |
|
throw new InvalidWorkflowDescriptorException($errMsg); |
160
|
|
|
} |
161
|
|
|
|
162
|
14 |
|
ValidationHelper::validate($conditions); |
163
|
14 |
|
} |
164
|
|
|
|
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Создает DOMElement - эквивалентный состоянию дескриптора |
168
|
|
|
* |
169
|
|
|
* @param DOMDocument $dom |
170
|
|
|
* |
171
|
|
|
* @return DOMElement |
172
|
|
|
* @throws InvalidDescriptorException |
173
|
|
|
* @throws InvalidWriteWorkflowException |
174
|
|
|
*/ |
175
|
19 |
|
public function writeXml(DOMDocument $dom = null) |
176
|
|
|
{ |
177
|
19 |
|
if (null === $dom) { |
178
|
1 |
|
$errMsg = 'Не передан DOMDocument'; |
179
|
1 |
|
throw new InvalidWriteWorkflowException($errMsg); |
180
|
|
|
} |
181
|
|
|
|
182
|
18 |
|
$descriptor = $dom->createElement('result'); |
183
|
|
|
|
184
|
18 |
|
if ($this->hasId()) { |
185
|
2 |
|
$id = $this->getId(); |
186
|
2 |
|
$descriptor->setAttribute('id', $id); |
187
|
2 |
|
} |
188
|
|
|
|
189
|
18 |
|
$dueDate = $this->getDueDate(); |
190
|
18 |
View Code Duplication |
if (null !== $dueDate && is_string($dueDate) && strlen($dueDate) > 0) { |
|
|
|
|
191
|
2 |
|
$descriptor->setAttribute('due-date', $dueDate); |
192
|
2 |
|
} |
193
|
|
|
|
194
|
18 |
|
$oldStatus = $this->getOldStatus(); |
195
|
18 |
|
if (null === $oldStatus) { |
196
|
1 |
|
$errMsg = 'Некорректное значение для атрибута old-status'; |
197
|
1 |
|
throw new InvalidDescriptorException($errMsg); |
198
|
|
|
} |
199
|
17 |
|
$descriptor->setAttribute('old-status', $oldStatus); |
200
|
|
|
|
201
|
|
|
|
202
|
|
|
|
203
|
17 |
|
$join = $this->getJoin(); |
204
|
17 |
|
$split = $this->getSplit(); |
205
|
17 |
View Code Duplication |
if (null !== $join && 0 !== $join) { |
|
|
|
|
206
|
1 |
|
$descriptor->setAttribute('join', $join); |
207
|
17 |
|
} elseif (null !== $split && 0 !== $split) { |
208
|
12 |
|
$descriptor->setAttribute('split', $split); |
209
|
12 |
|
} else { |
210
|
4 |
|
$status = $this->getStatus(); |
211
|
4 |
|
if (null === $status) { |
212
|
1 |
|
$errMsg = 'Некорректное значение для атрибута status'; |
213
|
1 |
|
throw new InvalidDescriptorException($errMsg); |
214
|
|
|
} |
215
|
3 |
|
$descriptor->setAttribute('status', $status); |
216
|
|
|
|
217
|
3 |
|
$step = $this->getStep(); |
218
|
3 |
|
if (null === $step) { |
219
|
1 |
|
$errMsg = 'Некорректное значение для атрибута step'; |
220
|
1 |
|
throw new InvalidDescriptorException($errMsg); |
221
|
|
|
} |
222
|
2 |
|
$descriptor->setAttribute('step', $step); |
223
|
|
|
|
224
|
2 |
|
$owner = $this->getOwner(); |
225
|
2 |
|
if (null !== $owner && is_string($owner) && strlen($owner) > 0) { |
226
|
2 |
|
$descriptor->setAttribute('owner', $owner); |
227
|
2 |
|
} |
228
|
|
|
|
229
|
2 |
|
$displayName = $this->getDisplayName(); |
230
|
2 |
|
if (null !== $displayName && is_string($displayName) && strlen($displayName) > 0) { |
231
|
2 |
|
$descriptor->setAttribute('display-name', $displayName); |
232
|
2 |
|
} |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
|
236
|
15 |
|
foreach ($this->getConditions() as $condition) { |
237
|
13 |
|
$conditionElement = $condition->writeXml($dom); |
238
|
13 |
|
if ($conditionElement) { |
239
|
13 |
|
$descriptor->appendChild($conditionElement); |
240
|
13 |
|
} |
241
|
15 |
|
} |
242
|
|
|
|
243
|
15 |
|
$validators = $this->getValidators(); |
244
|
15 |
View Code Duplication |
if ($validators->count() > 0) { |
|
|
|
|
245
|
2 |
|
$validatorsDescriptor = $dom->createElement('validators'); |
246
|
2 |
|
$descriptor->appendChild($validatorsDescriptor); |
247
|
|
|
|
248
|
2 |
|
foreach ($validators as $validator) { |
249
|
2 |
|
$validatorElement = $validator->writeXml($dom); |
250
|
2 |
|
$validatorsDescriptor->appendChild($validatorElement); |
251
|
2 |
|
} |
252
|
2 |
|
} |
253
|
|
|
|
254
|
15 |
|
$preFunctionsElement = $this->printPreFunctions($dom); |
255
|
15 |
|
if (null !== $preFunctionsElement) { |
256
|
2 |
|
$descriptor->appendChild($preFunctionsElement); |
257
|
2 |
|
} |
258
|
|
|
|
259
|
15 |
|
$postFunctionsElement = $this->printPostFunctions($dom); |
260
|
15 |
|
if (null !== $postFunctionsElement) { |
261
|
13 |
|
$descriptor->appendChild($postFunctionsElement); |
262
|
13 |
|
} |
263
|
|
|
|
264
|
15 |
|
return $descriptor; |
265
|
|
|
} |
266
|
|
|
} |
267
|
|
|
|
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.