Completed
Pull Request — master (#1)
by Fabrice
06:06
created

FlowAbstract::interruptNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of NodalFlow.
5
 *     (c) Fabrice de Stefanis / https://github.com/fab2s/NodalFlow
6
 * This source file is licensed under the MIT license which you will
7
 * find in the LICENSE file or at https://opensource.org/licenses/MIT
8
 */
9
10
namespace fab2s\NodalFlow\Flows;
11
12
use fab2s\NodalFlow\NodalFlowException;
13
use fab2s\NodalFlow\Nodes\NodeInterface;
14
15
/**
16
 * Abstract Class FlowAbstract
17
 */
18
abstract class FlowAbstract implements FlowInterface
19
{
20
    use FlowIdTrait;
21
22
    /**
23
     * The parent Flow, only set when branched
24
     *
25
     * @var FlowInterface
26
     */
27
    public $parent;
28
29
    /**
30
     * Current Flow Status
31
     *
32
     * @var FlowStatusInterface
33
     */
34
    protected $flowStatus;
35
36
    /**
37
     * The underlying node structure
38
     *
39
     * @var NodeInterface[]
40
     */
41
    protected $nodes = [];
42
43
    /**
44
     * @var FlowMapInterface
45
     */
46
    protected $flowMap;
47
48
    /**
49
     * Continue flag
50
     *
51
     * @var bool
52
     */
53
    protected $continue = false;
54
55
    /**
56
     * Break Flag
57
     *
58
     * @var bool
59
     */
60
    protected $break = false;
61
62
    /**
63
     * Progress modulo to apply
64
     * Set to x if you want to trigger
65
     * progress every x iterations in flow
66
     *
67
     * @var int
68
     */
69
    protected $progressMod = 1024;
70
71
    /**
72
     * @var string|bool
73
     */
74
    protected $interruptNodeId;
75
76
    /**
77
     * Get the stats array with latest Node stats
78
     *
79
     * @return array
80
     */
81
    public function getStats()
82
    {
83
        return $this->flowMap->getStats();
84
    }
85
86
    /**
87
     * Get the stats array with latest Node stats
88
     *
89
     * @return FlowMapInterface
90
     */
91
    public function getFlowMap()
92
    {
93
        return $this->flowMap;
94
    }
95
96
    /**
97
     * Get the Node array
98
     *
99
     * @return NodeInterface[]
100
     */
101
    public function getNodes()
102
    {
103
        return $this->nodes;
104
    }
105
106
    /**
107
     * Get/Generate Node Map
108
     *
109
     * @return array
110
     */
111
    public function getNodeMap()
112
    {
113
        return $this->flowMap->getNodeMap();
114
    }
115
116
    /**
117
     * Get current $progressMod
118
     *
119
     * @return int
120
     */
121
    public function getProgressMod()
122
    {
123
        return $this->progressMod;
124
    }
125
126
    /**
127
     * The Flow status can either indicate be:
128
     *      - clean (isClean()): everything went well
129
     *      - dirty (isDirty()): one Node broke the flow
130
     *      - exception (isException()): an exception was raised during the flow
131
     *
132
     * @return FlowStatusInterface
133
     */
134
    public function getFlowStatus()
135
    {
136
        return $this->flowStatus;
137
    }
138
139
    /**
140
     * getId() alias for backward compatibility
141
     *
142
     * @deprecated use `getId` instead
143
     *
144
     * @return string
145
     */
146
    public function getFlowId()
147
    {
148
        return $this->getId();
149
    }
150
151
    /**
152
     * Set parent Flow, happens only when branched
153
     *
154
     * @param FlowInterface $flow
155
     *
156
     * @return $this
157
     */
158
    public function setParent(FlowInterface $flow)
159
    {
160
        $this->parent = $flow;
161
162
        return $this;
163
    }
164
165
    /**
166
     * Get eventual parent Flow
167
     *
168
     * @return FlowInterface
169
     */
170
    public function getParent()
171
    {
172
        return $this->parent;
173
    }
174
175
    /**
176
     * Tells if this flow has a parent
177
     *
178
     * @return bool
179
     */
180
    public function hasParent()
181
    {
182
        return !empty($this->parent);
183
    }
184
185
    /**
186
     * Define the progress modulo, Progress Callback will be
187
     * triggered upon each iteration in the flow modulo $progressMod
188
     *
189
     * @param int $progressMod
190
     *
191
     * @return $this
192
     */
193
    public function setProgressMod($progressMod)
194
    {
195
        $this->progressMod = max(1, (int) $progressMod);
196
197
        return $this;
198
    }
199
200
    /**
201
     * @param string                    $interruptType
202
     * @param InterrupterInterface|null $flowInterrupt
203
     *
204
     * @throws NodalFlowException
205
     *
206
     * @return $this
207
     */
208
    public function interruptFlow($interruptType, InterrupterInterface $flowInterrupt = null)
209
    {
210
        switch ($interruptType) {
211
            case InterrupterInterface::TYPE_CONTINUE:
212
                $this->continue = true;
213
                $this->flowMap->incrementFlow('num_continue');
214
                break;
215
            case InterrupterInterface::TYPE_BREAK:
216
                $this->flowStatus = new FlowStatus(FlowStatus::FLOW_DIRTY);
217
                $this->break      = true;
218
                $this->flowMap->incrementFlow('num_break');
219
                break;
220
            default:
221
                throw new NodalFlowException('FlowInterrupt Type missing');
222
        }
223
224
        if ($flowInterrupt) {
225
            $flowInterrupt->setType($interruptType)->propagate($this);
226
        }
227
228
        return $this;
229
    }
230
231
    /**
232
     * Used to set the eventual Node Target of an Interrupt signal
233
     * set to :
234
     * - A node hash to target
235
     * - true to interrupt every upstream nodes
236
     *     in this Flow
237
     * - false to only interrupt up to the first
238
     *     upstream Traversable in this Flow
239
     *
240
     * @param string|bool $interruptNodeId
241
     *
242
     * @return $this
243
     */
244
    public function setInterruptNodeId($interruptNodeId)
245
    {
246
        $this->interruptNodeId = $interruptNodeId;
247
248
        return $this;
249
    }
250
251
    /**
252
     * @param NodeInterface $node
253
     *
254
     * @return bool
255
     */
256
    protected function interruptNode(NodeInterface $node)
257
    {
258
        // if we have an interruptNodeId, bubble up until we match a node
259
        // else stop propagation
260
        return $this->interruptNodeId ? $this->interruptNodeId !== $node->getId() : false;
261
    }
262
}
263