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 |
||
2 | |||
3 | namespace Spatie\BinaryUuid; |
||
4 | |||
5 | use Ramsey\Uuid\Uuid; |
||
6 | use Illuminate\Database\Eloquent\Model; |
||
7 | |||
8 | trait HasBinaryUuid |
||
9 | { |
||
10 | protected static function bootHasBinaryUuid() |
||
11 | { |
||
12 | static::creating(function (Model $model) { |
||
13 | if ($model->{$model->getKeyName()}) { |
||
14 | return; |
||
15 | } |
||
16 | |||
17 | $model->{$model->getKeyName()} = static::encodeUuid(static::generateUuid()); |
||
18 | }); |
||
19 | } |
||
20 | |||
21 | public static function scopeWithUuid(Builder $builder, $uuid, $field = null): Builder |
||
22 | { |
||
23 | if ($field) { |
||
24 | return static::scopeWithUuidRelation($builder, $uuid, $field); |
||
25 | } |
||
26 | |||
27 | if ($uuid instanceof Uuid) { |
||
28 | $uuid = (string) $uuid; |
||
29 | } |
||
30 | |||
31 | $uuid = (array) $uuid; |
||
32 | |||
33 | return $builder->whereKey(array_map(function (string $modelUuid) { |
||
34 | return static::encodeUuid($modelUuid); |
||
35 | }, $uuid)); |
||
36 | } |
||
37 | |||
38 | public static function scopeWithUuidRelation(Builder $builder, $uuid, string $field): Builder |
||
39 | { |
||
40 | if ($uuid instanceof Uuid) { |
||
41 | $uuid = (string) $uuid; |
||
42 | } |
||
43 | |||
44 | $uuid = (array) $uuid; |
||
45 | |||
46 | return $builder->whereIn($field, array_map(function (string $modelUuid) { |
||
0 ignored issues
–
show
|
|||
47 | return static::encodeUuid($modelUuid); |
||
48 | }, $uuid)); |
||
49 | } |
||
50 | |||
51 | public static function generateUuid() : string |
||
52 | { |
||
53 | return Uuid::uuid1(); |
||
54 | } |
||
55 | |||
56 | public static function encodeUuid($uuid): string |
||
57 | { |
||
58 | if (! Uuid::isValid($uuid)) { |
||
59 | return $uuid; |
||
60 | } |
||
61 | |||
62 | if (! $uuid instanceof Uuid) { |
||
63 | $uuid = Uuid::fromString($uuid); |
||
64 | } |
||
65 | |||
66 | return $uuid->getBytes(); |
||
67 | } |
||
68 | |||
69 | public static function decodeUuid(string $binaryUuid): string |
||
70 | { |
||
71 | if (Uuid::isValid($binaryUuid)) { |
||
72 | return $binaryUuid; |
||
73 | } |
||
74 | |||
75 | return Uuid::fromBytes($binaryUuid)->toString(); |
||
76 | } |
||
77 | |||
78 | public function toArray() |
||
79 | { |
||
80 | $uuidAttributes = $this->getUuidAttributes(); |
||
81 | |||
82 | $array = parent::toArray(); |
||
83 | |||
84 | if (! $this->exists || ! is_array($uuidAttributes)) { |
||
85 | return $array; |
||
86 | } |
||
87 | |||
88 | foreach ($uuidAttributes as $attributeKey) { |
||
89 | if (! array_key_exists($attributeKey, $array)) { |
||
90 | continue; |
||
91 | } |
||
92 | $uuidKey = $this->getRelatedBinaryKeyName($attributeKey); |
||
93 | $array[$attributeKey] = $this->{$uuidKey}; |
||
94 | } |
||
95 | |||
96 | return $array; |
||
97 | } |
||
98 | |||
99 | public function getRelatedBinaryKeyName($attribute): string |
||
100 | { |
||
101 | $suffix = $this->getUuidSuffix(); |
||
102 | |||
103 | return preg_match('/(?:uu)?id/i', $attribute) ? "{$attribute}{$suffix}" : $attribute; |
||
104 | } |
||
105 | |||
106 | public function getAttribute($key) |
||
107 | { |
||
108 | $uuidKey = $this->uuidTextAttribute($key); |
||
109 | |||
110 | if ($uuidKey && $this->{$uuidKey} !== null) { |
||
111 | return static::decodeUuid($this->{$uuidKey}); |
||
112 | } |
||
113 | |||
114 | return parent::getAttribute($key); |
||
115 | } |
||
116 | |||
117 | public function setAttribute($key, $value) |
||
118 | { |
||
119 | if ($this->uuidTextAttribute($key)) { |
||
120 | $value = static::encodeUuid($value); |
||
121 | } |
||
122 | |||
123 | return parent::setAttribute($key, $value); |
||
124 | } |
||
125 | |||
126 | protected function getUuidSuffix() |
||
127 | { |
||
128 | return (property_exists($this, 'uuidSuffix')) ? $this->uuidSuffix : '_text'; |
||
129 | } |
||
130 | |||
131 | protected function uuidTextAttribute($key) |
||
132 | { |
||
133 | $uuidAttributes = $this->getUuidAttributes(); |
||
134 | $suffix = $this->getUuidSuffix(); |
||
135 | $offset = -(strlen($suffix)); |
||
136 | |||
137 | if (substr($key, $offset) == $suffix && in_array(($uuidKey = substr($key, 0, $offset)), $uuidAttributes)) { |
||
138 | return $uuidKey; |
||
139 | } |
||
140 | |||
141 | return false; |
||
142 | } |
||
143 | |||
144 | public function getUuidAttributes() |
||
145 | { |
||
146 | $uuidAttributes = []; |
||
147 | |||
148 | if (property_exists($this, 'uuids') && is_array($this->uuids)) { |
||
149 | $uuidAttributes = array_merge($uuidAttributes, $this->uuids); |
||
150 | } |
||
151 | |||
152 | // non composite primary keys will return a string so casting required |
||
153 | $key = (array) $this->getKeyName(); |
||
154 | |||
155 | $uuidAttributes = array_unique(array_merge($uuidAttributes, $key)); |
||
156 | |||
157 | return $uuidAttributes; |
||
158 | } |
||
159 | |||
160 | public function getUuidTextAttribute(): ?string |
||
161 | { |
||
162 | $key = $this->getKeyName(); |
||
163 | |||
164 | if (! $this->exists || is_array($key)) { |
||
165 | return null; |
||
166 | } |
||
167 | |||
168 | return static::decodeUuid($this->{$key}); |
||
169 | } |
||
170 | |||
171 | public function setUuidTextAttribute(string $uuid) |
||
172 | { |
||
173 | $key = $this->getKeyName(); |
||
174 | |||
175 | if (is_array($key)) { |
||
176 | return; |
||
177 | } |
||
178 | |||
179 | $this->{$key} = static::encodeUuid($uuid); |
||
180 | } |
||
181 | |||
182 | public function getQueueableId() |
||
183 | { |
||
184 | return base64_encode($this->{$this->getKeyName()}); |
||
185 | } |
||
186 | |||
187 | public function newQueryForRestoration($id) |
||
188 | { |
||
189 | return $this->newQueryWithoutScopes()->whereKey(base64_decode($id)); |
||
0 ignored issues
–
show
It seems like
newQueryWithoutScopes() 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 ![]() |
|||
190 | } |
||
191 | |||
192 | public function newEloquentBuilder($query) |
||
193 | { |
||
194 | return new Builder($query); |
||
195 | } |
||
196 | |||
197 | public function getRouteKeyName() |
||
198 | { |
||
199 | $suffix = $this->getUuidSuffix(); |
||
200 | |||
201 | return "uuid{$suffix}"; |
||
202 | } |
||
203 | |||
204 | public function getKeyName() |
||
205 | { |
||
206 | return 'uuid'; |
||
207 | } |
||
208 | |||
209 | public function getIncrementing() |
||
210 | { |
||
211 | return false; |
||
212 | } |
||
213 | |||
214 | public function resolveRouteBinding($value) |
||
215 | { |
||
216 | return $this->withUuid($value)->first(); |
||
217 | } |
||
218 | } |
||
219 |
If you implement
__call
and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.This is often the case, when
__call
is implemented by a parent class and only the child class knows which methods exist: