Completed
Pull Request — master (#137)
by Sebastian
04:40
created

StoredEvent   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 89
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A createForEvent() 0 13 1
A getEventAttribute() 0 13 2
A scopeStartingFrom() 0 4 1
A scopeUuid() 0 4 1
A getMetaDataAttribute() 0 4 1
A scopeWithMetaDataAttributes() 0 4 1
A storeMany() 0 24 2
A store() 0 4 1
1
<?php
2
3
namespace Spatie\EventProjector\Models;
4
5
use Carbon\Carbon;
6
use Exception;
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Database\Eloquent\Model;
9
use Spatie\EventProjector\EventSerializers\EventSerializer;
10
use Spatie\EventProjector\Exceptions\InvalidStoredEvent;
11
use Spatie\EventProjector\Facades\Projectionist;
12
use Spatie\EventProjector\ShouldBeStored;
13
use Spatie\SchemalessAttributes\SchemalessAttributes;
14
15
class StoredEvent extends Model
16
{
17
    public $guarded = [];
18
19
    public $timestamps = false;
20
21
    public $casts = [
22
        'event_properties' => 'array',
23
        'meta_data' => 'array',
24
    ];
25
26
    public static function createForEvent(ShouldBeStored $event, string $uuid = null): StoredEvent
27
    {
28
        $storedEvent = new static();
29
        $storedEvent->aggregate_uuid = $uuid;
30
        $storedEvent->event_class = get_class($event);
31
        $storedEvent->attributes['event_properties'] = app(EventSerializer::class)->serialize(clone $event);
32
        $storedEvent->meta_data = [];
33
        $storedEvent->created_at = Carbon::now();
34
35
        $storedEvent->save();
36
37
        return $storedEvent;
38
    }
39
40
    public function getEventAttribute(): ShouldBeStored
41
    {
42
        try {
43
            $event = app(EventSerializer::class)->deserialize(
44
                $this->event_class,
45
                $this->getOriginal('event_properties')
46
            );
47
        } catch (Exception $exception) {
48
            throw InvalidStoredEvent::couldNotUnserializeEvent($this, $exception);
49
        }
50
51
        return $event;
52
    }
53
54
    public function scopeStartingFrom(Builder $query, int $storedEventId): void
55
    {
56
        $query->where('id', '>=', $storedEventId);
57
    }
58
59
    public function scopeUuid(Builder $query, string $uuid): void
60
    {
61
        $query->where('aggregate_uuid', $uuid);
62
    }
63
64
    public function getMetaDataAttribute(): SchemalessAttributes
65
    {
66
        return SchemalessAttributes::createForModel($this, 'meta_data');
67
    }
68
69
    public function scopeWithMetaDataAttributes(): Builder
70
    {
71
        return SchemalessAttributes::scopeWithSchemalessAttributes('meta_data');
72
    }
73
74
    public static function storeMany(array $events, string $uuid = null): void
75
    {
76
        collect($events)
77
            ->map(function (ShouldBeStored $domainEvent) use ($uuid) {
78
                $storedEvent = static::createForEvent($domainEvent, $uuid);
79
80
                return [$domainEvent, $storedEvent];
81
            })
82
            ->eachSpread(function (ShouldBeStored $event, StoredEvent $storedEvent) {
83
                Projectionist::handleWithSyncProjectors($storedEvent);
84
85
                if (method_exists($event, 'tags')) {
86
                    $tags = $event->tags();
0 ignored issues
show
Bug introduced by
The method tags() does not seem to exist on object<Spatie\EventProjector\ShouldBeStored>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87
                }
88
89
                $storedEventJob = call_user_func(
90
                    [config('event-projector.stored_event_job'), 'createForEvent'],
91
                    $storedEvent,
92
                    $tags ?? []
93
                );
94
95
                dispatch($storedEventJob->onQueue(config('event-projector.queue')));
96
            });
97
    }
98
99
    public static function store(ShouldBeStored $event, string $uuid = null): void
100
    {
101
        static::storeMany([$event], $uuid);
102
    }
103
}
104