Completed
Push — master ( e354e8...92f8f2 )
by Freek
01:23
created

ActivityLogger::enableLogging()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\Activitylog;
4
5
use Illuminate\Auth\AuthManager;
6
use Illuminate\Database\Eloquent\Model;
7
use Spatie\Activitylog\Models\Activity;
8
use Illuminate\Support\Traits\Macroable;
9
use Illuminate\Contracts\Config\Repository;
10
use Spatie\Activitylog\Exceptions\CouldNotLogActivity;
11
12
class ActivityLogger
13
{
14
    use Macroable;
15
16
    /** @var \Illuminate\Auth\AuthManager */
17
    protected $auth;
18
19
    protected $logName = '';
20
21
    /** @var bool */
22
    protected $logEnabled;
23
24
    /** @var \Illuminate\Database\Eloquent\Model */
25
    protected $performedOn;
26
27
    /** @var \Illuminate\Database\Eloquent\Model */
28
    protected $causedBy;
29
30
    /** @var \Illuminate\Support\Collection */
31
    protected $properties;
32
33
    /** @var string */
34
    protected $authDriver;
35
36
    public function __construct(AuthManager $auth, Repository $config)
37
    {
38
        $this->auth = $auth;
39
40
        $this->properties = collect();
41
42
        $this->authDriver = $config['activitylog']['default_auth_driver'] ?? $auth->getDefaultDriver();
43
44 View Code Duplication
        if (starts_with(app()->version(), '5.1')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
            $this->causedBy = $auth->driver($this->authDriver)->user();
0 ignored issues
show
Bug introduced by
The method driver() does not exist on Illuminate\Auth\AuthManager. Did you maybe mean createSessionDriver()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
46
        } else {
47
            $this->causedBy = $auth->guard($this->authDriver)->user();
48
        }
49
50
        $this->logName = $config['activitylog']['default_log_name'];
51
52
        $this->logEnabled = $config['activitylog']['enabled'] ?? true;
53
    }
54
55
    public function performedOn(Model $model)
56
    {
57
        $this->performedOn = $model;
58
59
        return $this;
60
    }
61
62
    public function on(Model $model)
63
    {
64
        return $this->performedOn($model);
65
    }
66
67
    /**
68
     * @param \Illuminate\Database\Eloquent\Model|int|string $modelOrId
69
     *
70
     * @return $this
71
     */
72
    public function causedBy($modelOrId)
73
    {
74
        $model = $this->normalizeCauser($modelOrId);
75
76
        $this->causedBy = $model;
77
78
        return $this;
79
    }
80
81
    public function by($modelOrId)
82
    {
83
        return $this->causedBy($modelOrId);
84
    }
85
86
    /**
87
     * @param array|\Illuminate\Support\Collection $properties
88
     *
89
     * @return $this
90
     */
91
    public function withProperties($properties)
92
    {
93
        $this->properties = collect($properties);
94
95
        return $this;
96
    }
97
98
    /**
99
     * @param string $key
100
     * @param mixed $value
101
     *
102
     * @return $this
103
     */
104
    public function withProperty(string $key, $value)
105
    {
106
        $this->properties->put($key, $value);
107
108
        return $this;
109
    }
110
111
    public function useLog(string $logName)
112
    {
113
        $this->logName = $logName;
114
115
        return $this;
116
    }
117
118
    public function inLog(string $logName)
119
    {
120
        return $this->useLog($logName);
121
    }
122
123
    public function disableLogging()
124
    {
125
        $this->logEnabled = false;
126
127
        return $this;
128
    }
129
130
    public function enableLogging()
131
    {
132
        $this->logEnabled = true;
133
134
        return $this;
135
    }
136
137
    /**
138
     * @param string $description
139
     *
140
     * @return null|mixed
141
     */
142
    public function log(string $description)
143
    {
144
        if (! $this->logEnabled) {
145
            return;
146
        }
147
148
        $activity = ActivitylogServiceProvider::getActivityModelInstance();
149
150
        if ($this->performedOn) {
151
            $activity->subject()->associate($this->performedOn);
152
        }
153
154
        if ($this->causedBy) {
155
            $activity->causer()->associate($this->causedBy);
156
        }
157
158
        $activity->properties = $this->properties;
159
160
        $activity->description = $this->replacePlaceholders($description, $activity);
161
162
        $activity->log_name = $this->logName;
163
164
        $activity->save();
165
166
        return $activity;
167
    }
168
169
    /**
170
     * @param \Illuminate\Database\Eloquent\Model|int|string $modelOrId
171
     *
172
     * @throws \Spatie\Activitylog\Exceptions\CouldNotLogActivity
173
     *
174
     * @return \Illuminate\Database\Eloquent\Model
175
     */
176
    protected function normalizeCauser($modelOrId): Model
177
    {
178
        if ($modelOrId instanceof Model) {
179
            return $modelOrId;
180
        }
181
182 View Code Duplication
        if (starts_with(app()->version(), '5.1')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
            $model = $this->auth->driver($this->authDriver)->getProvider()->retrieveById($modelOrId);
0 ignored issues
show
Bug introduced by
The method driver() does not exist on Illuminate\Auth\AuthManager. Did you maybe mean createSessionDriver()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
184
        } else {
185
            $model = $this->auth->guard($this->authDriver)->getProvider()->retrieveById($modelOrId);
186
        }
187
188
        if ($model) {
189
            return $model;
190
        }
191
192
        throw CouldNotLogActivity::couldNotDetermineUser($modelOrId);
193
    }
194
195
    protected function replacePlaceholders(string $description, Activity $activity): string
196
    {
197
        return preg_replace_callback('/:[a-z0-9._-]+/i', function ($match) use ($activity) {
198
            $match = $match[0];
199
200
            $attribute = (string) string($match)->between(':', '.');
201
202
            if (! in_array($attribute, ['subject', 'causer', 'properties'])) {
203
                return $match;
204
            }
205
206
            $propertyName = substr($match, strpos($match, '.') + 1);
207
208
            $attributeValue = $activity->$attribute;
209
210
            if (is_null($attributeValue)) {
211
                return $match;
212
            }
213
214
            $attributeValue = $attributeValue->toArray();
215
216
            return array_get($attributeValue, $propertyName, $match);
217
        }, $description);
218
    }
219
}
220