Completed
Push — master ( f40c1b...a796d5 )
by Ievgen
02:13
created

Railway::performStep()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7.7999

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 6
nop 3
dl 0
loc 29
ccs 12
cts 19
cp 0.6316
crap 7.7999
rs 8.439
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
    protected $stepsQueue;
24
    /**
25
     * Accumulator of passed steps, while running railway
26
     *
27
     * @var array
28
     */
29
    protected $signaturesPipeline = [];
30
31 1
    public function __construct()
32
    {
33 1
        $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 1
    }
35
36
    /**
37
     *
38
     * @param AbstractStep $stepObject
39
     * @param array $opt
40
     * @return $this
41
     */
42 1
    public function rawStep(AbstractStep $stepObject, $opt = []) : Railway
43
    {
44 1
        $this->stepsQueue->attach($stepObject, $opt);
45 1
        return $this;
46
    }
47
48 1
    public function step(callable $callable, $opt = []) : Railway
49
    {
50 1
        $name = $opt['name'] ?? null;
51 1
        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 1
    public function runWithParams($params)
78
    {
79
        // a bit hardcoded, but let it be :)
80 1
        $params['__errors'] = [];
81
82 1
        $track = self::TRACK_SUCCESS;
83 1
        foreach ($this->stepsQueue as $step) {
84
            /** @var $step AbstractStep */
85 1
            $track = $this->performStep($step, $params, $track);
86
        }
87 1
        return new Result($params, $track, $this->signaturesPipeline);
88
    }
89
90
    /**
91
     * @throws \Exception
92
     */
93 1
    protected function performStep($step, &$params, $track)
94
    {
95 1
        $nextTrack = $track;
96 1
        $stepResult = $step($params, $track);
97
98 1
        if (!$step->isSkipped()) {
99 1
            if (isValidResponse($stepResult)) {
100 1
                $type = $stepResult['type'];
101 1
                if (isOk($type)) {
102 1
                    $nextTrack = self::TRACK_SUCCESS;
103 1
                    $appendParams = $stepResult['appendParams'] ?? [];
104 1
                    $params = array_merge($params, $appendParams);
105
                } elseif (isError($type)) {
106
                    $nextTrack = self::TRACK_FAILURE;
107
                    $appendError = $stepResult['appendError'] ?? [];
108
                    if($appendError) {
109
                        $params['__errors'] = $params['__errors'] + $appendError;
110
                    }
111
                }
112
113 1
                $this->signaturesPipeline[] = $step->signature();
114
            } else {
115
                $actualResult = var_export($stepResult, true);
116
                throw new \Exception("Step returned incorrectly formatted result: {$actualResult}");
117
            }
118
        }
119
120 1
        return $nextTrack;
121
    }
122
}
123