This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace Cviebrock\EloquentLoggable; |
||
2 | |||
3 | use Cviebrock\EloquentLoggable\Models\Change; |
||
4 | use Illuminate\Contracts\Events\Dispatcher; |
||
5 | use Illuminate\Foundation\Auth\User as Authenticatable; |
||
6 | |||
7 | |||
8 | class LoggableObserver |
||
9 | { |
||
10 | |||
11 | /** |
||
12 | * @var mixed |
||
13 | */ |
||
14 | private $userId; |
||
15 | |||
16 | /** |
||
17 | * @var \Illuminate\Contracts\Events\Dispatcher |
||
18 | */ |
||
19 | private $events; |
||
20 | |||
21 | /** |
||
22 | * LoggableObserver constructor. |
||
23 | * |
||
24 | * @param \Illuminate\Foundation\Auth\User $user |
||
25 | * @param \Illuminate\Contracts\Events\Dispatcher $events |
||
26 | */ |
||
27 | public function __construct(Authenticatable $user, Dispatcher $events) |
||
28 | { |
||
29 | $this->userId = $user->getKey(); |
||
30 | $this->events = $events; |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * Log a created model. |
||
35 | * |
||
36 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
37 | * |
||
38 | * @return void |
||
39 | */ |
||
40 | public function created(Loggable $model): void |
||
41 | { |
||
42 | $data = $this->buildDataToLog('create', $model); |
||
43 | |||
44 | Change::create($data); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Log an updated model. |
||
49 | * |
||
50 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
51 | * |
||
52 | * @return void |
||
53 | */ |
||
54 | public function updated(Loggable $model): void |
||
55 | { |
||
56 | $data = $this->buildDataToLog('update', $model); |
||
57 | |||
58 | foreach ($this->getLoggableAttributes($model) as $change) { |
||
59 | |||
60 | $data['attribute'] = $change['attribute']; |
||
61 | $data['old_value'] = $change['old_value']; |
||
62 | $data['new_value'] = $change['new_value']; |
||
63 | |||
64 | Change::create($data); |
||
65 | } |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Log a deleted model. |
||
70 | * |
||
71 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
72 | * |
||
73 | * @return void |
||
74 | */ |
||
75 | public function deleted(Loggable $model): void |
||
76 | { |
||
77 | $data = $this->buildDataToLog('delete', $model); |
||
78 | |||
79 | Change::create($data); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Log a restored model. |
||
84 | * |
||
85 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
86 | * |
||
87 | * @return void |
||
88 | */ |
||
89 | public function restored(Loggable $model): void |
||
90 | { |
||
91 | $data = $this->buildDataToLog('restore', $model); |
||
92 | |||
93 | Change::create($data); |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * Build up the array of data to log. |
||
98 | * |
||
99 | * @param string $type |
||
100 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
101 | * |
||
102 | * @return array |
||
103 | */ |
||
104 | protected function buildDataToLog(string $type, Loggable $model): array |
||
105 | { |
||
106 | $data = [ |
||
107 | 'change_type' => $type, |
||
108 | 'user_id' => $this->userId, |
||
109 | 'model_type' => get_class($model), |
||
110 | 'model_id' => $model->getKey(), |
||
0 ignored issues
–
show
|
|||
111 | ]; |
||
112 | |||
113 | $data['change_set'] = $this->generateChangeSet($data); |
||
114 | |||
115 | return $data; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Return a "unique" hash to identify sets of changes. |
||
120 | * |
||
121 | * @param array $data |
||
122 | * |
||
123 | * @return string |
||
124 | */ |
||
125 | protected function generateChangeSet(array $data): string |
||
126 | { |
||
127 | return substr(md5(serialize($data)), 0, 8) . '.' . microtime(true); |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Return an array of old and new values that should be logged. |
||
132 | * |
||
133 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
134 | * |
||
135 | * @return array |
||
136 | */ |
||
137 | private function getLoggableAttributes(Loggable $model): array |
||
138 | { |
||
139 | // Get the list of all the changed attributes |
||
140 | $attributes = $model->getDirty(); |
||
0 ignored issues
–
show
It seems like
getDirty() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
141 | |||
142 | // The list of timestamp attributes to filter out |
||
143 | $timestamps = $this->getTimestampAttributes($model); |
||
144 | |||
145 | // If the model has a defined list of attributes to log, |
||
146 | // use that and filter the timestamp list accordingly |
||
147 | if ($only = $model->getLoggableAttributes()) { |
||
148 | $attributes = array_only($attributes, $only); |
||
149 | $timestamps = array_diff($timestamps, $only); |
||
150 | } |
||
151 | |||
152 | // Finally, filter out any unloggable attributes, |
||
153 | // and any remaining unloggable timestamp attributes |
||
154 | if ($except = $model->getUnloggableAttributes()) { |
||
155 | $attributes = array_except($attributes, array_merge($except, $timestamps)); |
||
156 | } |
||
157 | |||
158 | // Get a list of attributes to be obfuscated |
||
159 | $hidden = $model->getHidden(); |
||
0 ignored issues
–
show
It seems like
getHidden() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
160 | |||
161 | return array_map( |
||
162 | function($attribute, $value) use ($model, $hidden) { |
||
163 | if (in_array($attribute, $hidden, null)) { |
||
164 | return [ |
||
165 | 'attribute' => $attribute, |
||
166 | 'old_value' => '** HIDDEN **', |
||
167 | 'new_value' => '** HIDDEN **', |
||
168 | ]; |
||
169 | } |
||
170 | |||
171 | return [ |
||
172 | 'attribute' => $attribute, |
||
173 | 'old_value' => $model->getOriginal($attribute), |
||
0 ignored issues
–
show
It seems like
getOriginal() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
174 | 'new_value' => $value, |
||
175 | ]; |
||
176 | }, |
||
177 | array_keys($attributes), $attributes |
||
178 | ); |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * Get the timestamp attributes on the model that are normally not logged. |
||
183 | * |
||
184 | * @param \Cviebrock\EloquentLoggable\Loggable|\Illuminate\Database\Eloquent\Model $model |
||
185 | * |
||
186 | * @return array |
||
187 | */ |
||
188 | private function getTimestampAttributes(Loggable $model): array |
||
189 | { |
||
190 | if (!$model->usesTimestamps()) { |
||
0 ignored issues
–
show
It seems like
usesTimestamps() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
191 | return []; |
||
192 | } |
||
193 | |||
194 | $attributes = [ |
||
195 | $model->getCreatedAtColumn(), |
||
0 ignored issues
–
show
It seems like
getCreatedAtColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
196 | $model->getUpdatedAtColumn(), |
||
0 ignored issues
–
show
It seems like
getUpdatedAtColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
197 | ]; |
||
198 | if (method_exists($model, 'getDeletedAtColumn')) { |
||
199 | $attributes[] = $model->getDeletedAtColumn(); |
||
0 ignored issues
–
show
It seems like
getDeletedAtColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
200 | } |
||
201 | |||
202 | return $attributes; |
||
203 | } |
||
204 | |||
205 | } |
||
206 |
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idable
provides a methodequalsId
that in turn relies on the methodgetId()
. If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()
as an abstract method to the trait will make sure it is available.