Completed
Push — master ( 33591a...530541 )
by Freek
09:49
created

SnapshotFactory::guardAgainstInvalidSnapshot()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
namespace Spatie\EventProjector\Snapshots;
4
5
use Exception;
6
use Spatie\EventProjector\EventProjectionist;
7
use Illuminate\Contracts\Filesystem\Filesystem;
8
use Spatie\EventProjector\Exceptions\CouldNotCreateSnapshot;
9
use Spatie\EventProjector\Models\StoredEvent;
10
11
class SnapshotFactory
12
{
13
    /** @var \Spatie\EventProjector\EventProjectionist */
14
    protected $eventProjectionist;
15
16
    /** @var \Spatie\EventProjector\Snapshots\Filesystem */
17
    protected $disk;
18
19
    /** @var array */
20
    protected $config;
21
22
    public function __construct(EventProjectionist $eventProjectionist, Filesystem $disk, array $config)
23
    {
24
        $this->eventProjectionist = $eventProjectionist;
25
26
        $this->disk = $disk;
0 ignored issues
show
Documentation Bug introduced by
It seems like $disk of type object<Illuminate\Contra...\Filesystem\Filesystem> is incompatible with the declared type object<Spatie\EventProje...r\Snapshots\Filesystem> of property $disk.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
27
28
        $this->config = $config;
29
    }
30
31
    public function createForProjector(Snapshottable $projector, string $name = ''): Snapshot
32
    {
33
        $lastEventId = $projector->getLastProcessedEventId();
34
35
        $projectorName = str_replace('\\', '+', $projector->getName());
36
37
        $fileName = "Snapshot---{$projectorName}---{$lastEventId}---{$name}.txt";
38
39
        $snapshot = new Snapshot(
40
            $this->eventProjectionist,
41
            $this->config,
42
            $this->disk,
43
            $fileName
44
        );
45
46
        try {
47
            $projector->writeToSnapshot($snapshot);
48
        } catch (Exception $exception) {
49
            $this->attemptToDeleteSnapshot($snapshot);
50
51
            throw CouldNotCreateSnapshot::projectorThrewExceptionDuringWritingToSnapshot($projector, $exception);
52
        }
53
54
        if (!$this->disk->exists($fileName)) {
55
            throw CouldNotCreateSnapshot::projectorDidNotWriteAnythingToSnapshot($projector);
56
        }
57
58
        $this->guardAgainstInvalidSnapshot($snapshot);
59
60
        return $snapshot;
61
    }
62
63
    public function createForFile(Filesystem $disk, string $fileName): Snapshot
64
    {
65
        return new Snapshot(
66
            $this->eventProjectionist,
67
            $this->config,
68
            $disk,
69
            $fileName);
70
    }
71
72
    protected function guardAgainstInvalidSnapshot(Snapshot $snapshot)
73
    {
74
        $newStoredEvents = $this->config['stored_event_model']::after($snapshot->lastProcessedEventId())->get();
75
76
        $newEventsHandledByProjectorOfSnapshot = $newStoredEvents
77
            ->filter(function (StoredEvent $storedEvent) use ($snapshot) {
78
                return $snapshot->projector()->handlesEvent($storedEvent->event);
79
        });
80
81
        if (! $newEventsHandledByProjectorOfSnapshot->isEmpty())
82
        {
83
            $this->attemptToDeleteSnapshot($snapshot);
84
85
            throw CouldNotCreateSnapshot::newEventsStoredDuringSnapshotCreation($snapshot, $newEventsHandledByProjectorOfSnapshot);
86
        }
87
    }
88
89
    protected function attemptToDeleteSnapshot(Snapshot $snapshot)
90
    {
91
        try {
92
            $snapshot->delete();
93
        } catch (Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
94
        }
95
    }
96
}
97