Completed
Push — master ( 778435...d8b9d0 )
by Freek
01:25
created

ActivityLogger::setLogStatus()   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 1
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 \Illuminate\Database\Eloquent\Model */
22
    protected $performedOn;
23
24
    /** @var \Illuminate\Database\Eloquent\Model */
25
    protected $causedBy;
26
27
    /** @var \Illuminate\Support\Collection */
28
    protected $properties;
29
30
    /** @var string */
31
    protected $authDriver;
32
33
    /** @var \Spatie\Activitylog\ActivityLogStatus */
34
    protected $logStatus;
35
36
    public function __construct(AuthManager $auth, Repository $config, ActivityLogStatus $logStatus)
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;
0 ignored issues
show
Bug introduced by
The property logEnabled does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
53
54
        $this->logStatus = $logStatus;
55
    }
56
57
    public function setLogStatus(ActivityLogStatus $logStatus)
58
    {
59
        $this->logStatus = $logStatus;
60
61
        return $this;
62
    }
63
64
    public function performedOn(Model $model)
65
    {
66
        $this->performedOn = $model;
67
68
        return $this;
69
    }
70
71
    public function on(Model $model)
72
    {
73
        return $this->performedOn($model);
74
    }
75
76
    /**
77
     * @param \Illuminate\Database\Eloquent\Model|int|string $modelOrId
78
     *
79
     * @return $this
80
     */
81
    public function causedBy($modelOrId)
82
    {
83
        $model = $this->normalizeCauser($modelOrId);
84
85
        $this->causedBy = $model;
86
87
        return $this;
88
    }
89
90
    public function by($modelOrId)
91
    {
92
        return $this->causedBy($modelOrId);
93
    }
94
95
    /**
96
     * @param array|\Illuminate\Support\Collection $properties
97
     *
98
     * @return $this
99
     */
100
    public function withProperties($properties)
101
    {
102
        $this->properties = collect($properties);
103
104
        return $this;
105
    }
106
107
    /**
108
     * @param string $key
109
     * @param mixed $value
110
     *
111
     * @return $this
112
     */
113
    public function withProperty(string $key, $value)
114
    {
115
        $this->properties->put($key, $value);
116
117
        return $this;
118
    }
119
120
    public function useLog(string $logName)
121
    {
122
        $this->logName = $logName;
123
124
        return $this;
125
    }
126
127
    public function inLog(string $logName)
128
    {
129
        return $this->useLog($logName);
130
    }
131
132
    public function enableLogging()
133
    {
134
        $this->logStatus->enable();
135
136
        return $this;
137
    }
138
139
    public function disableLogging()
140
    {
141
        $this->logStatus->disable();
142
143
        return $this;
144
    }
145
146
    /**
147
     * @param string $description
148
     *
149
     * @return null|mixed
150
     */
151
    public function log(string $description)
152
    {
153
        if ($this->logStatus->disabled()) {
154
            return;
155
        }
156
157
        $activity = ActivitylogServiceProvider::getActivityModelInstance();
158
159
        if ($this->performedOn) {
160
            $activity->subject()->associate($this->performedOn);
161
        }
162
163
        if ($this->causedBy) {
164
            $activity->causer()->associate($this->causedBy);
165
        }
166
167
        $activity->properties = $this->properties;
168
169
        $activity->description = $this->replacePlaceholders($description, $activity);
170
171
        $activity->log_name = $this->logName;
172
173
        $activity->save();
174
175
        return $activity;
176
    }
177
178
    /**
179
     * @param \Illuminate\Database\Eloquent\Model|int|string $modelOrId
180
     *
181
     * @throws \Spatie\Activitylog\Exceptions\CouldNotLogActivity
182
     *
183
     * @return \Illuminate\Database\Eloquent\Model
184
     */
185
    protected function normalizeCauser($modelOrId): Model
186
    {
187
        if ($modelOrId instanceof Model) {
188
            return $modelOrId;
189
        }
190
191 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...
192
            $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...
193
        } else {
194
            $model = $this->auth->guard($this->authDriver)->getProvider()->retrieveById($modelOrId);
195
        }
196
197
        if ($model) {
198
            return $model;
199
        }
200
201
        throw CouldNotLogActivity::couldNotDetermineUser($modelOrId);
202
    }
203
204
    protected function replacePlaceholders(string $description, Activity $activity): string
205
    {
206
        return preg_replace_callback('/:[a-z0-9._-]+/i', function ($match) use ($activity) {
207
            $match = $match[0];
208
209
            $attribute = (string) string($match)->between(':', '.');
210
211
            if (! in_array($attribute, ['subject', 'causer', 'properties'])) {
212
                return $match;
213
            }
214
215
            $propertyName = substr($match, strpos($match, '.') + 1);
216
217
            $attributeValue = $activity->$attribute;
218
219
            if (is_null($attributeValue)) {
220
                return $match;
221
            }
222
223
            $attributeValue = $attributeValue->toArray();
224
225
            return array_get($attributeValue, $propertyName, $match);
226
        }, $description);
227
    }
228
}
229