Completed
Push — master ( 00f04e...1d93d6 )
by Freek
03:46
created

ReplayCommand::selectProjectors()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.568
c 0
b 0
f 0
cc 4
nc 3
nop 1
1
<?php
2
3
namespace Spatie\EventSourcing\Console;
4
5
use Exception;
6
use Illuminate\Console\Command;
7
use Illuminate\Support\Collection;
8
use Spatie\EventSourcing\Projectionist;
9
use Spatie\EventSourcing\StoredEventRepository;
10
11
class ReplayCommand extends Command
12
{
13
    protected $signature = 'event-sourcing:replay {projector?*}
14
                            {--from=0 : Replay events starting from this event number}
15
                            {--stored-event-model= : Replay events from this store}';
16
17
    protected $description = 'Replay stored events';
18
19
    protected Projectionist $projectionist;
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...
20
21
    public function __construct(Projectionist $projectionist)
22
    {
23
        parent::__construct();
24
25
        $this->projectionist = $projectionist;
26
    }
27
28
    public function handle(): void
29
    {
30
        $projectors = $this->selectProjectors($this->argument('projector'));
31
32
        if (is_null($projectors)) {
33
            $this->warn('No events replayed!');
34
35
            return;
36
        }
37
38
        $this->replay($projectors, $this->option('from'));
39
    }
40
41
    public function selectProjectors(array $projectorClassNames): ?Collection
42
    {
43
        if (count($projectorClassNames ?? []) === 0) {
44
            if (! $confirmed = $this->confirm('Are you sure you want to replay events to all projectors?', true)) {
45
                return null;
46
            }
47
48
            return $this->projectionist->getProjectors();
49
        }
50
51
        return collect($projectorClassNames)
52
            ->map(fn(string $projectorName) => ltrim($projectorName, '\\'))
53
            ->map(function (string $projectorName) {
54
                if (! $projector = $this->projectionist->getProjector($projectorName)) {
55
                    throw new Exception("Projector {$projectorName} not found. Did you register it?");
56
                }
57
58
                return $projector;
59
            });
60
    }
61
62
    public function replay(Collection $projectors, int $startingFrom): void
63
    {
64
        $repository = app(StoredEventRepository::class);
65
        $events = $repository->retrieveAllStartingFrom($startingFrom);
66
        $replayCount = $events->count();
67
68
        if ($replayCount === 0) {
69
            $this->warn('There are no events to replay');
70
71
            return;
72
        }
73
74
        $this->comment("Replaying {$replayCount} events...");
75
76
        $bar = $this->output->createProgressBar($events->count());
77
        $onEventReplayed = function () use ($bar) {
78
            $bar->advance();
79
        };
80
81
        $this->projectionist->replay($projectors, $startingFrom, $onEventReplayed);
82
83
        $bar->finish();
84
85
        $this->emptyLine(2);
86
        $this->comment('All done!');
87
    }
88
89
    private function emptyLine(int $amount = 1): void
90
    {
91
        foreach (range(1, $amount) as $i) {
92
            $this->line('');
93
        }
94
    }
95
}
96