Passed
Push — master ( 7fa476...2eca2e )
by Fabrice
03:09 queued 57s
created

ProgressBarSubscriber::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of YaEtl
5
 *     (c) Fabrice de Stefanis / https://github.com/fab2s/YaEtl
6
 * This source file is licensed under the MIT license which you will
7
 * find in the LICENSE file or at https://opensource.org/licenses/MIT
8
 */
9
10
namespace fab2s\YaEtl\Events;
11
12
use fab2s\NodalFlow\Events\FlowEvent;
13
use fab2s\NodalFlow\Events\FlowEventInterface;
14
use fab2s\NodalFlow\Flows\FlowInterface;
15
use fab2s\YaEtl\YaEtl;
16
use ReflectionException;
17
use Symfony\Component\Console\Helper\ProgressBar;
18
use Symfony\Component\Console\Output\ConsoleOutput;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
21
22
/**
23
 * Class ProgressBarSubscriber
24
 */
25
class ProgressBarSubscriber implements EventSubscriberInterface
26
{
27
    /**
28
     * The Laravel output object, extracted from the command object
29
     *
30
     * @var OutputInterface
31
     */
32
    protected $output;
33
34
    /**
35
     * The number of records
36
     *
37
     * @var int|null
38
     */
39
    protected $numRecords;
40
41
    /**
42
     * Progress modulo, should be aligned with YaEtl's one
43
     *
44
     * @var int
45
     */
46
    protected $progressMod = 1024;
47
48
    /**
49
     * @var ProgressBar
50
     */
51
    protected $progressBar;
52
53
    /**
54
     * ProgressBarSubscriber constructor.
55
     *
56
     * @param YaEtl|null $flow
57
     *
58
     * @throws ReflectionException
59
     */
60
    public function __construct(YaEtl $flow = null)
61
    {
62
        if ($flow !== null) {
63
            // auto register
64
            $this->registerFlow($flow);
65
        }
66
    }
67
68
    /**
69
     * @param YaEtl $flow
70
     *
71
     * @throws ReflectionException
72
     *
73
     * @return static
74
     */
75
    public function registerFlow(YaEtl $flow): self
76
    {
77
        $flow->getDispatcher()->addSubscriber($this);
78
79
        return $this;
80
    }
81
82
    /**
83
     * @return OutputInterface
84
     */
85
    public function getOutput()
86
    {
87
        if (!isset($this->output)) {
88
            $this->output = new ConsoleOutput;
89
        }
90
91
        return $this->output;
92
    }
93
94
    /**
95
     * @param OutputInterface $output
96
     *
97
     * @return static
98
     */
99
    public function setOutput(OutputInterface $output): self
100
    {
101
        $this->output = $output;
102
103
        return $this;
104
    }
105
106
    /**
107
     * Set progress modulo
108
     *
109
     * @param int $progressMod
110
     *
111
     * @return static
112
     */
113
    public function setProgressMod(int $progressMod): self
114
    {
115
        $this->progressMod = max(1, $progressMod);
116
117
        return $this;
118
    }
119
120
    /**
121
     * Set the total number of records prior to FLow execution
122
     *
123
     * @param int|null $numRecords
124
     *
125
     * @return static
126
     */
127
    public function setNumRecords(?int $numRecords): self
128
    {
129
        $this->numRecords = $numRecords;
130
131
        return $this;
132
    }
133
134
    /**
135
     * Triggered when a Flow starts
136
     *
137
     * @param FlowEventInterface $event
138
     */
139
    public function start(FlowEventInterface $event)
140
    {
141
        /** @var YaEtl $flow */
142
        $flow = $event->getFlow();
143
        $this->setProgressMod($flow->getProgressMod())
144
            ->getOutput()
145
            ->writeln('<info>[YaEtl] Start</info>');
146
        $this->progressBar = new ProgressBar($this->output);
147
        $this->progressBar->start($this->numRecords);
148
    }
149
150
    /**
151
     * Triggered when a Flow progresses,
152
     * e.g. exec once or generates once
153
     */
154
    public function progress()
155
    {
156
        $this->progressBar->advance($this->progressMod);
157
    }
158
159
    /**
160
     * Triggered when a Flow succeeds
161
     *
162
     * @param FlowEventInterface $event
163
     */
164
    public function success(FlowEventInterface $event)
165
    {
166
        $this->progressBar->finish();
167
        $this->output->writeln('');
168
        $flow       = $event->getFlow();
169
        $flowStatus = $flow->getFlowStatus();
170
        if ($flowStatus->isDirty()) {
171
            $this->output->writeln('<comment>[YaEtl] Dirty Success</comment>');
172
        } else {
173
            $this->output->writeln('<info>[YaEtl] Clean Success</info>');
174
        }
175
176
        $this->displayReport($flow);
177
    }
178
179
    /**
180
     * Triggered when a Flow fails
181
     *
182
     * @param FlowEventInterface $event
183
     */
184
    public function fail(FlowEventInterface $event)
185
    {
186
        $this->progressBar->finish();
187
        $this->output->writeln('');
188
        $this->output->writeln('<error>[YaEtl] Failed</error>');
189
        $this->displayReport($event->getFlow());
190
    }
191
192
    /**
193
     * @return array
194
     */
195
    public static function getSubscribedEvents(): array
196
    {
197
        return [
198
            FlowEvent::FLOW_START    => ['start', 0],
199
            FlowEvent::FLOW_PROGRESS => ['progress', 0],
200
            FlowEvent::FLOW_SUCCESS  => ['success', 0],
201
            FlowEvent::FLOW_FAIL     => ['fail', 0],
202
        ];
203
    }
204
205
    /**
206
     * @param FlowInterface $flow
207
     *
208
     * @return static
209
     */
210
    protected function displayReport(FlowInterface $flow): self
211
    {
212
        $flowStats = $flow->getStats();
213
        $this->output->writeln($flowStats['report']);
214
215
        return $this;
216
    }
217
}
218