Completed
Push — master ( 0e291a...511168 )
by Ievgen
05:31
created

Railway::performStep()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 21
nc 5
nop 4
dl 0
loc 30
ccs 0
cts 20
cp 0
crap 30
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
    public function __construct()
26
    {
27
        $this->stepsQueue = new \SplQueue();
28
    }
29
30
    /**
31
     *
32
     * @param AbstractStep $stepObject
33
     * @param array $opt
34
     * @return $this
35
     */
36
    public function rawStep(AbstractStep $stepObject, $opt = []) : Railway
0 ignored issues
show
Unused Code introduced by
The parameter $opt is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
37
    {
38
        $this->stepsQueue->enqueue($stepObject);
39
        return $this;
40
    }
41
42
    public function step(callable $callable, $opt = []) : Railway
43
    {
44
        return $this->rawStep(new Step($callable, $opt['name']), $opt);
45
    }
46
47
    public function always(callable $callable, $opt = []) : Railway
48
    {
49
        return $this->rawStep(new Always($callable, $opt['name']), $opt);
50
    }
51
52
    public function failure(callable $callable, $opt = []) : Railway
53
    {
54
        return $this->rawStep(new Failure($callable, $opt['name']), $opt);
55
    }
56
57
    public function tryCatch(callable $callable, $opt = []) : Railway
58
    {
59
        return $this->rawStep(new TryCatch($callable, $opt['name']), $opt);
60
    }
61
62
    /**
63
     * @param $params
64
     * @return Result
65
     * @throws \Exception
66
     */
67
    public function runWithParams($params)
68
    {
69
        // a bit hardcoded, but let it be :)
70
        $params['errors'] = [];
71
        $signaturesPipeline = [];
72
73
        $track = self::TRACK_SUCCESS;
74
        foreach ($this->stepsQueue as $step) {
75
            /** @var $step AbstractStep */
76
            $track = $this->performStep($step, $params, $track, $signaturesPipeline);
77
        }
78
        return new Result($params, $track, $signaturesPipeline);
79
    }
80
81
    /**
82
     * @param $params
83
     * @param $step
84
     * @return string
85
     * @throws \Exception
86
     */
87
    protected function performStep($step, &$params, $track, &$signaturesPipeline)
88
    {
89
        $newTrack = $track;
90
        $stepResult = $step($params, $track);
91
92
        if (!$step->isSkipped()) {
93
            if (isValidResponse($stepResult)) {
94
                $type = $stepResult['type'];
95
                if (isOk($type)) {
96
                    $newTrack = self::TRACK_SUCCESS;
97
                    $appendParams = $stepResult['appendParams'] ?? [];
98
                    $params = array_merge($params, $appendParams);
99
                } elseif (isError($type)) {
100
                    $newTrack = self::TRACK_FAILURE;
101
                    $appendError = [$stepResult['appendError']] ?? [];
102
                    // TODO: Fix errors merge
103
                    print_r($params['errors']);
104
                    print_r($appendError);
105
                    $params['errors'] = $params['errors'] + $appendError;
106
                }
107
108
                $signaturesPipeline[] = $this->getStepClassName($step);
109
            } else {
110
                $actualResult = var_export($stepResult, true);
111
                throw new \Exception("Step returned incorrectly formatted result: {$actualResult}");
112
            }
113
        }
114
115
        return $newTrack;
116
    }
117
118
    protected function getStepClassName(AbstractStep $step) : string
119
    {
120
        $className = (new \ReflectionClass($step))->getShortName();
121
        return sprintf("%-10s", $className) . " | " . $step->functionName();
122
    }
123
}
124