Completed
Pull Request — master (#32)
by Brent
08:17
created

StateConfig::resolveTransition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
3
namespace Spatie\ModelStates;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Spatie\ModelStates\Exceptions\InvalidConfig;
7
8
class StateConfig
9
{
10
    public string $field;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
11
12
    /** @var string|\Spatie\ModelStates\State */
13
    public $stateClass;
14
15
    /** @var string[] */
16
    public array $allowedTransitions = [];
17
18
    public ?string $defaultStateClass = null;
19
20
    public function __construct(string $field, string $stateClass)
21
    {
22
        if (! is_subclass_of($stateClass, State::class)) {
23
            throw InvalidConfig::doesNotExtendState($stateClass);
24
        }
25
26
        $this->field = $field;
27
28
        $this->stateClass = $stateClass;
29
    }
30
31
    public function default(string $defaultStateClass): StateConfig
32
    {
33
        $this->defaultStateClass = $defaultStateClass;
34
35
        return $this;
36
    }
37
38
    /**
39
     * @param string|array $from
40
     * @param string $to
41
     * @param string|null $transition
42
     *
43
     * @return \Spatie\ModelStates\StateConfig
44
     */
45
    public function allowTransition($from, string $to, string $transition = null): StateConfig
46
    {
47
        if (is_array($from)) {
48
            foreach ($from as $fromState) {
49
                $this->allowTransition($fromState, $to, $transition);
50
            }
51
52
            return $this;
53
        }
54
55
        if (! is_subclass_of($from, $this->stateClass)) {
56
            throw InvalidConfig::doesNotExtendBaseClass($from, $this->stateClass);
57
        }
58
59
        if (! is_subclass_of($to, $this->stateClass)) {
60
            throw InvalidConfig::doesNotExtendBaseClass($to, $this->stateClass);
61
        }
62
63
        if ($transition && ! is_subclass_of($transition, Transition::class)) {
64
            throw InvalidConfig::doesNotExtendTransition($transition);
65
        }
66
67
        $this->allowedTransitions[$this->createTransitionKey($from, $to)] = $transition;
68
69
        return $this;
70
    }
71
72
    public function allowTransitions(array $transitions): StateConfig
73
    {
74
        foreach ($transitions as $transition) {
75
            $this->allowTransition($transition[0], $transition[1], $transition[2] ?? null);
76
        }
77
78
        return $this;
79
    }
80
81
    public function transitionableStates(string $fromClass): array
82
    {
83
        $transitionableStates = [];
84
85
        foreach ($this->allowedTransitions as $allowedTransition => $value) {
86
            [$from, $to] = explode('-', $allowedTransition);
87
88
            if ($from !== $fromClass) {
89
                continue;
90
            }
91
92
            $transitionableStates[] = $to::getMorphClass();
93
        }
94
95
        return $transitionableStates;
96
    }
97
98
    /**
99
     * @param string $from
100
     * @param string $to
101
     *
102
     * @return string|\Spatie\ModelStates\Transition|null
103
     */
104
    public function resolveTransition(Model $model, string $from, string $to)
105
    {
106
        $transitionKey = $this->createTransitionKey($from, $to);
107
108
        if (! array_key_exists($transitionKey, $this->allowedTransitions)) {
109
            return;
110
        }
111
112
        return $this->allowedTransitions[$transitionKey]
113
            ?? new DefaultTransition(
114
                $model,
115
                $this->field,
116
                $this->stateClass::make($to, $model)
117
            );
118
    }
119
120
    private function createTransitionKey(string $from, string $to): string
121
    {
122
        return "{$from}-{$to}";
123
    }
124
}
125