Completed
Push — master ( 492fa4...2ed89a )
by Tom
21s queued 13s
created

ActivityLogger::tap()   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 2
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 Illuminate\Support\Traits\Macroable;
8
use Illuminate\Contracts\Config\Repository;
9
use Spatie\Activitylog\Exceptions\CouldNotLogActivity;
10
use Spatie\Activitylog\Contracts\Activity as ActivityContract;
11
12
class ActivityLogger
13
{
14
    use Macroable;
15
16
    /** @var \Illuminate\Auth\AuthManager */
17
    protected $auth;
18
19
    protected $defaultLogName = '';
20
21
    /** @var string */
22
    protected $authDriver;
23
24
    /** @var \Spatie\Activitylog\ActivityLogStatus */
25
    protected $logStatus;
26
27
    /** @var \Spatie\Activitylog\Contracts\Activity */
28
    protected $activity;
29
30
    public function __construct(AuthManager $auth, Repository $config, ActivityLogStatus $logStatus)
31
    {
32
        $this->auth = $auth;
33
34
        $this->authDriver = $config['activitylog']['default_auth_driver'] ?? $auth->getDefaultDriver();
35
36
        $this->defaultLogName = $config['activitylog']['default_log_name'];
37
38
        $this->logStatus = $logStatus;
39
    }
40
41
    public function setLogStatus(ActivityLogStatus $logStatus)
42
    {
43
        $this->logStatus = $logStatus;
44
45
        return $this;
46
    }
47
48
    public function performedOn(Model $model)
49
    {
50
        $this->getActivity()->subject()->associate($model);
51
52
        return $this;
53
    }
54
55
    public function on(Model $model)
56
    {
57
        return $this->performedOn($model);
58
    }
59
60
    public function causedBy($modelOrId)
61
    {
62
        if ($modelOrId === null) {
63
            return $this;
64
        }
65
66
        $model = $this->normalizeCauser($modelOrId);
67
68
        $this->getActivity()->causer()->associate($model);
69
70
        return $this;
71
    }
72
73
    public function by($modelOrId)
74
    {
75
        return $this->causedBy($modelOrId);
76
    }
77
78
    public function withProperties($properties)
79
    {
80
        $this->getActivity()->properties = collect($properties);
0 ignored issues
show
Bug introduced by
Accessing properties on the interface Spatie\Activitylog\Contracts\Activity 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...
81
82
        return $this;
83
    }
84
85
    public function withProperty(string $key, $value)
86
    {
87
        $this->getActivity()->properties = $this->getActivity()->properties->put($key, $value);
0 ignored issues
show
Bug introduced by
Accessing properties on the interface Spatie\Activitylog\Contracts\Activity 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...
88
89
        return $this;
90
    }
91
92
    public function useLog(string $logName)
93
    {
94
        $this->getActivity()->log_name = $logName;
0 ignored issues
show
Bug introduced by
Accessing log_name on the interface Spatie\Activitylog\Contracts\Activity 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...
95
96
        return $this;
97
    }
98
99
    public function inLog(string $logName)
100
    {
101
        return $this->useLog($logName);
102
    }
103
104
    public function tap(callable $callback, string $eventName = null)
105
    {
106
        call_user_func($callback, $this->getActivity(), $eventName);
107
108
        return $this;
109
    }
110
111
    public function enableLogging()
112
    {
113
        $this->logStatus->enable();
114
115
        return $this;
116
    }
117
118
    public function disableLogging()
119
    {
120
        $this->logStatus->disable();
121
122
        return $this;
123
    }
124
125
    public function log(string $description)
126
    {
127
        if ($this->logStatus->disabled()) {
128
            return;
129
        }
130
131
        $activity = $this->activity;
132
133
        $activity->description = $this->replacePlaceholders($description, $activity);
0 ignored issues
show
Bug introduced by
Accessing description on the interface Spatie\Activitylog\Contracts\Activity 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...
134
135
        $activity->save();
136
137
        $this->activity = null;
138
139
        return $activity;
140
    }
141
142
    protected function normalizeCauser($modelOrId): Model
143
    {
144
        if ($modelOrId instanceof Model) {
145
            return $modelOrId;
146
        }
147
148
        $model = $this->auth->guard($this->authDriver)->getProvider()->retrieveById($modelOrId);
149
150
        if ($model) {
151
            return $model;
152
        }
153
154
        throw CouldNotLogActivity::couldNotDetermineUser($modelOrId);
155
    }
156
157
    protected function replacePlaceholders(string $description, ActivityContract $activity): string
158
    {
159
        return preg_replace_callback('/:[a-z0-9._-]+/i', function ($match) use ($activity) {
160
            $match = $match[0];
161
162
            $attribute = (string) string($match)->between(':', '.');
163
164
            if (! in_array($attribute, ['subject', 'causer', 'properties'])) {
165
                return $match;
166
            }
167
168
            $propertyName = substr($match, strpos($match, '.') + 1);
169
170
            $attributeValue = $activity->$attribute;
171
172
            if (is_null($attributeValue)) {
173
                return $match;
174
            }
175
176
            $attributeValue = $attributeValue->toArray();
177
178
            return array_get($attributeValue, $propertyName, $match);
179
        }, $description);
180
    }
181
182
    protected function getActivity(): ActivityContract
183
    {
184
        if (! $this->activity instanceof ActivityContract) {
185
            $this->activity = ActivitylogServiceProvider::getActivityModelInstance();
186
            $this
187
                ->useLog($this->defaultLogName)
188
                ->withProperties([])
189
                ->causedBy($this->auth->guard($this->authDriver)->user());
190
        }
191
192
        return $this->activity;
193
    }
194
}
195