Completed
Pull Request — master (#170)
by
unknown
01:31
created

StoredEvent   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

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

9 Methods

Rating   Name   Duplication   Size   Complexity  
A createForEvent() 0 13 1
A getEventAttribute() 0 13 2
A scopeStartingFrom() 0 4 1
A scopeEndingTo() 0 8 2
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 Exception;
6
use Carbon\Carbon;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Builder;
9
use Spatie\EventProjector\ShouldBeStored;
10
use Spatie\EventProjector\Facades\Projectionist;
11
use Spatie\SchemalessAttributes\SchemalessAttributes;
12
use Spatie\EventProjector\Exceptions\InvalidStoredEvent;
13
use Spatie\EventProjector\EventSerializers\EventSerializer;
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 scopeEndingTo(Builder $query, ?int $storedEventId)
60
    {
61
        if ($storedEventId === null) {
62
            return $query;
63
        }
64
65
        return $query->where('id', '<=', $storedEventId);
66
    }
67
68
    public function scopeUuid(Builder $query, string $uuid): void
69
    {
70
        $query->where('aggregate_uuid', $uuid);
71
    }
72
73
    public function getMetaDataAttribute(): SchemalessAttributes
74
    {
75
        return SchemalessAttributes::createForModel($this, 'meta_data');
76
    }
77
78
    public function scopeWithMetaDataAttributes(): Builder
79
    {
80
        return SchemalessAttributes::scopeWithSchemalessAttributes('meta_data');
81
    }
82
83
    public static function storeMany(array $events, string $uuid = null): void
84
    {
85
        collect($events)
86
            ->map(function (ShouldBeStored $domainEvent) use ($uuid) {
87
                $storedEvent = static::createForEvent($domainEvent, $uuid);
88
89
                return [$domainEvent, $storedEvent];
90
            })
91
            ->eachSpread(function (ShouldBeStored $event, StoredEvent $storedEvent) {
92
                Projectionist::handleWithSyncProjectors($storedEvent);
93
94
                if (method_exists($event, 'tags')) {
95
                    $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...
96
                }
97
98
                $storedEventJob = call_user_func(
99
                    [config('event-projector.stored_event_job'), 'createForEvent'],
100
                    $storedEvent,
101
                    $tags ?? []
102
                );
103
104
                dispatch($storedEventJob->onQueue($event->queue ?? config('event-projector.queue')));
0 ignored issues
show
Bug introduced by
Accessing queue on the interface Spatie\EventProjector\ShouldBeStored suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
105
            });
106
    }
107
108
    public static function store(ShouldBeStored $event, string $uuid = null): void
109
    {
110
        static::storeMany([$event], $uuid);
111
    }
112
}
113