Completed
Pull Request — master (#108)
by Brent
19:52 queued 18:46
created

StateConfig   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
wmc 18
lcom 2
cbo 2
dl 0
loc 120
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\ModelStates;
4
5
use Spatie\ModelStates\Exceptions\InvalidConfig;
6
7
class StateConfig
8
{
9
    public string $modelClass;
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...
10
11
    public string $fieldName;
12
13
    public string $baseStateClass;
14
15
    public ?string $defaultStateClass = null;
16
17
    /** @var string[] */
18
    public array $allowedTransitions = [];
19
20
    public function __construct(
21
        string $modelClass,
22
        string $fieldName,
23
        string $baseStateClass
24
    ) {
25
        $this->fieldName = $fieldName;
26
        $this->modelClass = $modelClass;
27
        $this->baseStateClass = $baseStateClass;
28
    }
29
30
    public function default(string $defaultStateClass): StateConfig
31
    {
32
        $this->defaultStateClass = $defaultStateClass;
33
34
        return $this;
35
    }
36
37
    public function allowTransition($from, string $to, string $transition = null): StateConfig
38
    {
39
        if (is_array($from)) {
40
            foreach ($from as $fromState) {
41
                $this->allowTransition($fromState, $to, $transition);
42
            }
43
44
            return $this;
45
        }
46
47
        if (! is_subclass_of($from, $this->baseStateClass)) {
48
            throw InvalidConfig::doesNotExtendBaseClass($from, $this->baseStateClass);
49
        }
50
51
        if (! is_subclass_of($to, $this->baseStateClass)) {
52
            throw InvalidConfig::doesNotExtendBaseClass($to, $this->baseStateClass);
53
        }
54
55
        if ($transition && ! is_subclass_of($transition, Transition::class)) {
56
            throw InvalidConfig::doesNotExtendTransition($transition);
57
        }
58
59
        $this->allowedTransitions[$this->createTransitionKey($from, $to)] = $transition;
60
61
        return $this;
62
    }
63
64
    public function allowTransitions(array $transitions): StateConfig
65
    {
66
        foreach ($transitions as $transition) {
67
            $this->allowTransition($transition[0], $transition[1], $transition[2] ?? null);
68
        }
69
70
        return $this;
71
    }
72
73
    public function isTransitionAllowed(string $fromMorphClass, string $toMorphClass): bool
74
    {
75
        $transitionKey = $this->createTransitionKey($fromMorphClass, $toMorphClass);
76
77
        return array_key_exists($transitionKey, $this->allowedTransitions);
78
    }
79
80
    public function transitionableStates(string $fromMorphClass): array
81
    {
82
        $transitionableStates = [];
83
84
        foreach ($this->allowedTransitions as $allowedTransition => $value) {
85
            [$transitionFromMorphClass, $transitionToMorphClass] = explode('-', $allowedTransition);
86
87
            if ($transitionFromMorphClass !== $fromMorphClass) {
88
                continue;
89
            }
90
91
            $transitionableStates[] = $transitionToMorphClass;
92
        }
93
94
        return $transitionableStates;
95
    }
96
97
    private function createTransitionKey(string $from, string $to): string
98
    {
99
        if (is_subclass_of($from, $this->baseStateClass)) {
100
            $from = $from::getMorphClass();
101
        }
102
103
        if (is_subclass_of($to, $this->baseStateClass)) {
104
            $to = $to::getMorphClass();
105
        }
106
107
        return "{$from}-{$to}";
108
    }
109
}
110