Completed
Push — master ( c75aba...5e0d33 )
by Sébastien
09:08
created

Debug::printCallbacks()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Sebdesign\SM\Commands;
4
5
use Illuminate\Console\Command;
6
use Symfony\Component\Console\Helper\TableSeparator;
7
8
class Debug extends Command
9
{
10
    /**
11
     * The name and signature of the console command.
12
     *
13
     * @var string
14
     */
15
    protected $signature = 'winzou:state-machine:debug {graph? : A state machine graph}';
16
17
    /**
18
     * The console command description.
19
     *
20
     * @var string
21
     */
22
    protected $description = 'Show states and transitions of state machine graphs';
23
24
    protected $config;
25
26
    /**
27
     * Create a new command instance.
28
     *
29
     * @param array $config
30
     */
31
    public function __construct(array $config)
32
    {
33
        parent::__construct();
34
35
        $this->config = $config;
36
    }
37
38
    /**
39
     * Execute the console command.
40
     *
41
     * @return mixed
42
     */
43
    public function handle()
44
    {
45
        if (empty($this->config)) {
46
            $this->error('There are no state machines configured.');
47
48
            return 1;
49
        }
50
51
        if (! $this->argument('graph')) {
52
            $this->askForGraph();
53
        }
54
55
        $graph = $this->argument('graph');
56
57
        if (! array_key_exists($graph, $this->config)) {
58
            $this->error('The provided state machine graph is not configured.');
59
60
            return 1;
61
        }
62
63
        $config = $this->config[$graph];
64
65
        $this->printStates($config['states']);
66
        $this->printTransitions($config['transitions']);
67
68
        if (isset($config['callbacks'])) {
69
            $this->printCallbacks($config['callbacks']);
70
        }
71
72
        return 0;
73
    }
74
75
    /**
76
     * Ask for a graph name if one was not provided as argument.
77
     */
78
    protected function askForGraph()
79
    {
80
        $choices = array_map(function ($name, $config) {
81
            return $name."\t(".$config['class'].' - '.$config['graph'].')';
82
        }, array_keys($this->config), $this->config);
83
84
        $choice = $this->choice('Which state machine would you like to know about?', $choices, 0);
85
86
        $choice = substr($choice, 0, strpos($choice, "\t"));
87
88
        $this->info('You have just selected: '.$choice);
89
90
        $this->input->setArgument('graph', $choice);
91
    }
92
93
    /**
94
     * Display the graph states on a table.
95
     *
96
     * @param array $states
97
     */
98
    protected function printStates(array $states)
99
    {
100
        $this->table(['Configured States:'], array_map(function ($state) {
101
            return [$state];
102
        }, $states));
103
    }
104
105
    /**
106
     * Display the graph transitions on a table.
107
     *
108
     * @param array $transitions
109
     */
110
    protected function printTransitions(array $transitions)
111
    {
112
        end($transitions);
113
114
        $lastTransition = key($transitions);
115
116
        reset($transitions);
117
118
        $rows = [];
119
120
        foreach ($transitions as $name => $transition) {
121
            $rows[] = [$name, implode("\n", $transition['from']), $transition['to']];
122
123
            if ($name !== $lastTransition) {
124
                $rows[] = new TableSeparator();
125
            }
126
        }
127
128
        $this->table(['Transition', 'From(s)', 'To'], $rows);
129
    }
130
131
    /**
132
     * Display the graph callbacks on a table.
133
     *
134
     * @param array $allCallbacks
135
     */
136
    protected function printCallbacks(array $allCallbacks)
137
    {
138
        foreach ($allCallbacks as $type => $callbacks) {
139
            $rows = [];
140
            foreach ($callbacks as $name => $callback) {
141
                $rows[] = [
142
                    $name,
143
                    $this->formatClause($callback, 'on'),
144
                    $this->formatCallable($callback['do']),
145
                    $this->formatClause($callback, 'args'),
146
                ];
147
            }
148
149
            $this->table([ucfirst($type). ' Callbacks', 'On', 'Do', 'Args'], $rows);
150
        }
151
    }
152
153
    protected function formatClause(array $callback, $clause)
154
    {
155
        if (isset($callback[$clause])) {
156
            return implode(PHP_EOL, (array) $callback[$clause]);
157
        }
158
    }
159
160
    /**
161
     * Format the callable.
162
     *
163
     * @param  callable $callable
164
     * @return string
165
     */
166
    protected function formatCallable($callable)
167
    {
168
        if (is_array($callable)) {
169
            return implode('@', $callable);
170
        }
171
172
        if ($callable instanceof \Closure) {
173
            return 'Closure';
174
        }
175
176
        return $callable;
177
    }
178
}
179