Passed
Pull Request — master (#777)
by Mark van den
11:22 queued 07:43
created

LogsActivity::shouldLogEvent()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 6
eloc 9
c 2
b 1
f 0
nc 5
nop 1
dl 0
loc 20
ccs 8
cts 8
cp 1
crap 6
rs 9.2222
1
<?php
2
3
namespace Spatie\Activitylog\Traits;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Relations\MorphMany;
7
use Illuminate\Database\Eloquent\SoftDeletes;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\Collection;
10
use Spatie\Activitylog\ActivityLogger;
11
use Spatie\Activitylog\ActivitylogServiceProvider;
12
use Spatie\Activitylog\ActivityLogStatus;
13
14
trait LogsActivity
15
{
16
    use DetectsChanges;
17
18
    protected $enableLoggingModelsEvents = true;
19 216
20
    protected static function bootLogsActivity()
21
    {
22
        static::eventsToBeRecorded()->each(function ($eventName) {
23 212
            return static::$eventName(function (Model $model) use ($eventName) {
24 12
                if (! $model->shouldLogEvent($eventName)) {
25
                    return;
26
                }
27 208
28
                $description = $model->getDescriptionForEvent($eventName);
29 208
30
                $logName = $model->getLogNameToUse($eventName);
31 208
32
                if ($description == '') {
33
                    return;
34
                }
35 208
36
                $attrs = $model->attributeValuesToBeLogged($eventName);
37 208
38 4
                if ($model->isLogEmpty($attrs) && ! $model->shouldSubmitEmptyLogs()) {
39
                    return;
40
                }
41 208
42 208
                $logger = app(ActivityLogger::class)
43 208
                    ->useLog($logName)
0 ignored issues
show
Bug introduced by
It seems like $logName can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $logName of Spatie\Activitylog\ActivityLogger::useLog() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

43
                    ->useLog(/** @scrutinizer ignore-type */ $logName)
Loading history...
44 208
                    ->performedOn($model)
45
                    ->withProperties($attrs);
46 208
47 8
                if (method_exists($model, 'tapActivity')) {
48
                    $logger->tap([$model, 'tapActivity'], $eventName);
49
                }
50 208
51 216
                $logger->log($description);
0 ignored issues
show
Bug introduced by
It seems like $description can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $description of Spatie\Activitylog\ActivityLogger::log() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
                $logger->log(/** @scrutinizer ignore-type */ $description);
Loading history...
52 216
            });
53 216
        });
54
    }
55 72
56
    public function shouldSubmitEmptyLogs(): bool
57 72
    {
58
        return ! isset(static::$submitEmptyLogs) ? true : static::$submitEmptyLogs;
59
    }
60 208
61
    public function isLogEmpty($attrs): bool
62 208
    {
63
        return empty($attrs['attributes'] ?? []) && empty($attrs['old'] ?? []);
64
    }
65 12
66
    public function disableLogging()
67 12
    {
68
        $this->enableLoggingModelsEvents = false;
69 12
70
        return $this;
71
    }
72 4
73
    public function enableLogging()
74 4
    {
75
        $this->enableLoggingModelsEvents = true;
76 4
77
        return $this;
78
    }
79 28
80
    public function activities(): MorphMany
81 28
    {
82
        return $this->morphMany(ActivitylogServiceProvider::determineActivityModel(), 'subject');
0 ignored issues
show
Bug introduced by
It seems like morphMany() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
        return $this->/** @scrutinizer ignore-call */ morphMany(ActivitylogServiceProvider::determineActivityModel(), 'subject');
Loading history...
83
    }
84 204
85
    public function getDescriptionForEvent(string $eventName): string
86 204
    {
87
        return $eventName;
88
    }
89 204
90
    public function getLogNameToUse(string $eventName = ''): string
91 204
    {
92 4
        if (isset(static::$logName)) {
93
            return static::$logName;
94
        }
95 200
96
        return config('activitylog.default_log_name');
97
    }
98
99
    /*
100
     * Get the event names that should be recorded.
101 216
     */
102
    protected static function eventsToBeRecorded(): Collection
103 216
    {
104
        if (isset(static::$recordEvents)) {
105
            return collect(static::$recordEvents);
106
        }
107 216
108 216
        $events = collect([
109
            'created',
110
            'updated',
111
            'deleted',
112
        ]);
113 216
114 76
        if (collect(class_uses_recursive(static::class))->contains(SoftDeletes::class)) {
115
            $events->push('restored');
116
        }
117 216
118
        return $events;
119
    }
120 208
121
    public function attributesToBeIgnored(): array
122 208
    {
123 208
        if (! isset(static::$ignoreChangedAttributes)) {
124
            return [];
125
        }
126
127
        return static::$ignoreChangedAttributes;
128
    }
129 212
130
    protected function shouldLogEvent(string $eventName): bool
131 212
    {
132 8
        $logStatus = app(ActivityLogStatus::class);
133
134
        if (! $this->enableLoggingModelsEvents || $logStatus->disabled()) {
135 208
            return false;
136 24
        }
137
138
        if (! in_array($eventName, ['created', 'updated'])) {
139 208
            return true;
140 4
        }
141 4
142
        if (Arr::has($this->getDirty(), 'deleted_at')) {
0 ignored issues
show
Bug introduced by
It seems like getDirty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

142
        if (Arr::has($this->/** @scrutinizer ignore-call */ getDirty(), 'deleted_at')) {
Loading history...
143
            if ($this->getDirty()['deleted_at'] === null) {
144
                return false;
145
            }
146 208
        }
147
148
        //do not log update event if only ignored attributes are changed
149
        return (bool) count(Arr::except($this->getDirty(), $this->attributesToBeIgnored()));
150
    }
151
}
152