Completed
Push — master ( ddc20e...61f12d )
by Fabrice
03:08
created

NodeAbstract::getCarrier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\Nodes;
11
12
use fab2s\NodalFlow\Flows\FlowInterface;
13
use fab2s\NodalFlow\NodalFlowException;
14
15
/**
16
 * abstract Class NodeAbstract
17
 */
18
abstract class NodeAbstract implements NodeInterface
19
{
20
    /**
21
     * The carrying Flow
22
     *
23
     * @var FlowInterface
24
     */
25
    public $carrier;
26
27
    /**
28
     * Indicate if this Node is traversable
29
     *
30
     * @var bool
31
     */
32
    protected $isATraversable;
33
34
    /**
35
     * Indicate if this Node is returning a value
36
     *
37
     * @var bool
38
     */
39
    protected $isAReturningVal;
40
41
    /**
42
     * Indicate if this Node is a Flow (Branch)
43
     *
44
     * @var bool
45
     */
46
    protected $isAFlow;
47
48
    /**
49
     * Instantiate a Node
50
     */
51
    public function __construct()
52
    {
53
        $this->enforceIsATraversable();
54
    }
55
56
    /**
57
     * Indicate if this Node is Traversable
58
     *
59
     * @return bool
60
     */
61
    public function isTraversable()
62
    {
63
        return (bool) $this->isATraversable;
64
    }
65
66
    /**
67
     * Indicate if this Node is a Flow (Branch)
68
     *
69
     * @return bool true if this node instanceof FlowInterface
70
     */
71
    public function isFlow()
72
    {
73
        return (bool) $this->isAFlow;
74
    }
75
76
    /**
77
     * Indicate if this Node is returning a value
78
     *
79
     * @return bool true if this node is expected to return
80
     *              something to pass on next node as param.
81
     *              If nothing is returned, the previously
82
     *              returned value will be use as param
83
     *              for next nodes.
84
     */
85
    public function isReturningVal()
86
    {
87
        return (bool) $this->isAReturningVal;
88
    }
89
90
    /**
91
     * Set carrying Flow
92
     *
93
     * @param FlowInterface $flow
94
     *
95
     * @return $this
96
     */
97
    public function setCarrier(FlowInterface $flow)
98
    {
99
        $this->carrier = $flow;
100
101
        return $this;
102
    }
103
104
    /**
105
     * Get carrying Flow
106
     *
107
     * @return FlowInterface
108
     */
109
    public function getCarrier()
110
    {
111
        return $this->carrier;
112
    }
113
114
    /**
115
     * Get this Node's hash, must be deterministic and unique
116
     *
117
     * Caching the result would save a bit of resources
118
     * but would require to implement `__clone()` to
119
     * make sure we reset the hash should a node be cloned.
120
     * Doing this would add the burden to actual Node
121
     * implementation to trigger `parent::_clone()`
122
     * which is not ideal and impossible to guaranty.
123
     * Now since this method is not used in the actual
124
     * flow execution loop, but only when an interruption
125
     * is raised, it's not a performance issue.
126
     *
127
     * @return string
128
     */
129
    public function getNodeHash()
130
    {
131
        return \sha1(\spl_object_hash($this));
132
    }
133
134
    /**
135
     * Make sure this Node is consistent
136
     *
137
     * @throws NodalFlowException
138
     *
139
     * @return $this
140
     */
141
    protected function enforceIsATraversable()
142
    {
143
        if ($this->isFlow()) {
144
            if ($this->isATraversable) {
145
                throw new NodalFlowException('Cannot Traverse a Branch');
146
            }
147
148
            return $this;
149
        }
150
151
        if ($this->isATraversable) {
152
            if (!($this instanceof TraversableNodeInterface)) {
153
                throw new NodalFlowException('Cannot Traverse a Node that does not implement TraversableNodeInterface');
154
            }
155
156
            return $this;
157
        }
158
159
        if (!($this instanceof ExecNodeInterface)) {
160
            throw new NodalFlowException('Cannot Exec a Node that does not implement ExecNodeInterface');
161
        }
162
163
        return $this;
164
    }
165
}
166