Completed
Push — master ( 47f9d7...a7d6eb )
by Freek
01:50 queued 10s
created

src/Models/StoredEvent.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 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
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($event->queue ?? config('event-projector.queue')));
0 ignored issues
show
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...
96
            });
97
    }
98
99
    public static function store(ShouldBeStored $event, string $uuid = null): void
100
    {
101
        static::storeMany([$event], $uuid);
102
    }
103
}
104