Completed
Push — master ( 6aa47e...cf79b7 )
by Ievgen
05:38
created

Railway::performStep()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.0729

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 5
nop 3
dl 0
loc 22
ccs 12
cts 14
cp 0.8571
crap 5.0729
rs 8.6737
c 0
b 0
f 0
1
<?php
2
namespace einfach\operation;
3
4
use function einfach\operation\response\isError;
5
use function einfach\operation\response\isOk;
6
use function einfach\operation\response\isValidResponse;
7
use const einfach\operation\response\RESPONSE_TYPE_ERROR;
8
use const einfach\operation\response\RESPONSE_TYPE_OK;
9
use einfach\operation\step\Step;
10
use einfach\operation\step\Failure;
11
use einfach\operation\step\AbstractStep;
12
use einfach\operation\step\Always;
13
use einfach\operation\step\TryCatch;
14
15
class Railway
16
{
17
    const TRACK_SUCCESS = 'success_track';
18
    const TRACK_FAILURE = 'failure_track';
19
20
    /**
21
     * @var \SplQueue
22
     */
23
    public $stepsQueue;
24
    /**
25
     * Accumulator of passed steps, while running railway
26
     *
27
     * @var array
28
     */
29
    protected $signaturesPipeline = [];
30
31 6
    public function __construct()
32
    {
33 6
        $this->stepsQueue = new \SplObjectStorage();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \SplObjectStorage() of type object<SplObjectStorage> is incompatible with the declared type object<SplQueue> of property $stepsQueue.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
34 6
    }
35
36
    /**
37
     *
38
     * @param AbstractStep $stepObject
39
     * @param array        $opt
40
     * @return $this
41
     */
42 6
    public function rawStep(AbstractStep $stepObject, $opt = []) : Railway
43
    {
44 6
        $this->stepsQueue->attach($stepObject, $opt);
45 6
        return $this;
46
    }
47
48 6
    public function step(callable $callable, $opt = []) : Railway
49
    {
50 6
        $name = $opt['name'] ?? null;
51 6
        return $this->rawStep(new Step($callable, $name), $opt);
52
    }
53
54
    public function always(callable $callable, $opt = []) : Railway
55
    {
56
        $name = $opt['name'] ?? null;
57
        return $this->rawStep(new Always($callable, $name), $opt);
58
    }
59
60
    public function failure(callable $callable, $opt = []) : Railway
61
    {
62
        $name = $opt['name'] ?? null;
63
        return $this->rawStep(new Failure($callable, $name), $opt);
64
    }
65
66
    public function tryCatch(callable $callable, $opt = []) : Railway
67
    {
68
        $name = $opt['name'] ?? null;
69
        return $this->rawStep(new TryCatch($callable, $name), $opt);
70
    }
71
72
    /**
73
     * @param $params
74
     * @return Result
75
     * @throws \Exception
76
     */
77 6
    public function runWithParams($params)
78
    {
79
        // a bit hardcoded, but let it be :)
80 6
        $params['__errors'] = [];
81
82 6
        $track = self::TRACK_SUCCESS;
83 6
        foreach ($this->stepsQueue as $step) {
84
            /**
85
 * @var $step AbstractStep
86
*/
87 6
            $track = $this->performStep($step, $params, $track);
88
        }
89 5
        return new Result($params, $track, $this->signaturesPipeline);
90
    }
91
92
    /**
93
     * @throws \Exception
94
     */
95 6
    protected function performStep($step, &$params, $track)
96
    {
97 6
        $nextTrack = $track;
98 6
        $stepResult = $step($params, $track);
99
100 5
        if (!$step->isSkipped()) {
101 5
            if (isValidResponse($stepResult)) {
102 5
                if (isOk($stepResult)) {
103 4
                    $nextTrack = self::TRACK_SUCCESS;
104 1
                } elseif (isError($stepResult)) {
105 1
                    $nextTrack = self::TRACK_FAILURE;
106
                }
107 5
                $params = $stepResult['params'];
108 5
                $this->signaturesPipeline[] = $step->signature();
109
            } else {
110
                $actualResult = var_export($stepResult, true);
111
                throw new \Exception("Step returned incorrectly formatted result: {$actualResult}");
112
            }
113
        }
114
115 5
        return $nextTrack;
116
    }
117
}
118