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 Neurony\Url\Traits; |
||
4 | |||
5 | use Illuminate\Database\Eloquent\Model; |
||
6 | use Illuminate\Support\Str; |
||
7 | use Neurony\Url\Exceptions\SlugException; |
||
8 | use Neurony\Url\Options\SlugOptions; |
||
9 | |||
10 | trait HasSlug |
||
11 | { |
||
12 | /** |
||
13 | * The container for all the options necessary for this trait. |
||
14 | * Options can be viewed in the Neurony\Url\Options\SlugOptions file. |
||
15 | * |
||
16 | * @var SlugOptions |
||
17 | */ |
||
18 | protected $slugOptions; |
||
19 | |||
20 | /** |
||
21 | * Set the options for the HasSlug trait. |
||
22 | * |
||
23 | * @return SlugOptions |
||
24 | */ |
||
25 | abstract public function getSlugOptions(): SlugOptions; |
||
26 | |||
27 | /** |
||
28 | * Boot the trait. |
||
29 | * |
||
30 | * @return void |
||
31 | */ |
||
32 | public static function bootHasSlug(): void |
||
33 | { |
||
34 | static::creating(function (Model $model) { |
||
35 | $model->generateSlugOnCreate(); |
||
36 | }); |
||
37 | |||
38 | static::updating(function (Model $model) { |
||
39 | $model->generateSlugOnUpdate(); |
||
40 | }); |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * Handle setting the slug on model creation. |
||
45 | * |
||
46 | * @return void |
||
47 | * @throws SlugException |
||
48 | */ |
||
49 | protected function generateSlugOnCreate(): void |
||
50 | { |
||
51 | $this->initSlugOptions(); |
||
52 | |||
53 | if ($this->slugOptions->generateSlugOnCreate === false) { |
||
54 | return; |
||
55 | } |
||
56 | |||
57 | $this->generateSlug(); |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * Handle setting the slug on model update. |
||
62 | * |
||
63 | * @return void |
||
64 | * @throws SlugException |
||
65 | */ |
||
66 | protected function generateSlugOnUpdate(): void |
||
67 | { |
||
68 | $this->initSlugOptions(); |
||
69 | |||
70 | if ($this->slugOptions->generateSlugOnUpdate === false) { |
||
71 | return; |
||
72 | } |
||
73 | |||
74 | $this->generateSlug(); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * The logic for actually setting the slug. |
||
79 | * |
||
80 | * @return void |
||
81 | * @throws SlugException |
||
82 | */ |
||
83 | public function generateSlug(): void |
||
84 | { |
||
85 | $this->initSlugOptions(); |
||
86 | |||
87 | if ($this->slugHasBeenSupplied()) { |
||
88 | $slug = $this->generateNonUniqueSlug(); |
||
89 | |||
90 | if ($this->slugOptions->uniqueSlugs) { |
||
91 | $slug = $this->makeSlugUnique($slug); |
||
92 | } |
||
93 | |||
94 | $this->setAttribute($this->slugOptions->toField, $slug); |
||
0 ignored issues
–
show
|
|||
95 | } |
||
96 | } |
||
97 | |||
98 | /** |
||
99 | * Generate a non unique slug for this record. |
||
100 | * |
||
101 | * @return string |
||
102 | */ |
||
103 | protected function generateNonUniqueSlug(): string |
||
104 | { |
||
105 | if ($this->slugHasChanged()) { |
||
106 | $source = $this->getAttribute($this->slugOptions->toField); |
||
0 ignored issues
–
show
It seems like
getAttribute() 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 ![]() |
|||
107 | |||
108 | return Str::is('/', $source) ? $source : Str::slug($source); |
||
109 | } |
||
110 | |||
111 | $source = $this->getSlugSource(); |
||
112 | |||
113 | return Str::is('/', $source) ? $source : Str::slug( |
||
114 | $source, $this->slugOptions->slugSeparator, $this->slugOptions->slugLanguage |
||
115 | ); |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Make the given slug unique. |
||
120 | * |
||
121 | * @param string $slug |
||
122 | * @return string |
||
123 | */ |
||
124 | protected function makeSlugUnique(string $slug): string |
||
125 | { |
||
126 | $original = $slug; |
||
127 | $i = 1; |
||
128 | |||
129 | while ($this->slugAlreadyExists($slug) || $slug === '') { |
||
130 | $slug = $original.$this->slugOptions->slugSeparator.$i++; |
||
131 | } |
||
132 | |||
133 | return $slug; |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Check if the $fromField slug has been supplied. |
||
138 | * If not, then skip the entire slug generation. |
||
139 | * |
||
140 | * @return bool |
||
141 | */ |
||
142 | protected function slugHasBeenSupplied(): bool |
||
143 | { |
||
144 | if (is_array($this->slugOptions->fromField)) { |
||
145 | foreach ($this->slugOptions->fromField as $field) { |
||
146 | if ($this->getAttribute($field) !== null) { |
||
0 ignored issues
–
show
It seems like
getAttribute() 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 ![]() |
|||
147 | return true; |
||
148 | } |
||
149 | } |
||
150 | |||
151 | return false; |
||
152 | } |
||
153 | |||
154 | return $this->getAttribute($this->slugOptions->fromField) !== null; |
||
0 ignored issues
–
show
It seems like
getAttribute() 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 ![]() |
|||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Determine if a custom slug has been saved. |
||
159 | * |
||
160 | * @return bool |
||
161 | */ |
||
162 | protected function slugHasChanged(): bool |
||
163 | { |
||
164 | return |
||
165 | $this->getOriginal($this->slugOptions->toField) && |
||
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 ![]() |
|||
166 | $this->getOriginal($this->slugOptions->toField) != $this->getAttribute($this->slugOptions->toField); |
||
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 ![]() It seems like
getAttribute() 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 ![]() |
|||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Get the string that should be used as base for the slug. |
||
171 | * |
||
172 | * @return string |
||
173 | */ |
||
174 | protected function getSlugSource(): string |
||
175 | { |
||
176 | if (is_callable($this->slugOptions->fromField)) { |
||
177 | return call_user_func($this->slugOptions->fromField, $this); |
||
178 | } |
||
179 | |||
180 | return collect($this->slugOptions->fromField)->map(function ($field) { |
||
181 | return $this->getAttribute($field) ?: ''; |
||
0 ignored issues
–
show
It seems like
getAttribute() 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 ![]() |
|||
182 | })->implode($this->slugOptions->slugSeparator); |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Check if the given slug already exists on another record. |
||
187 | * |
||
188 | * @param string $slug |
||
189 | * @return bool |
||
190 | */ |
||
191 | protected function slugAlreadyExists(string $slug): bool |
||
192 | { |
||
193 | return (bool) static::withoutGlobalScopes()->where($this->slugOptions->toField, $slug) |
||
194 | ->where($this->getKeyName(), '!=', $this->getKey() ?: '0') |
||
0 ignored issues
–
show
It seems like
getKeyName() 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 ![]() It seems like
getKey() 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 ![]() |
|||
195 | ->first(); |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Both instantiate the slug options as well as validate their contents. |
||
200 | * |
||
201 | * @return void |
||
202 | * @throws SlugException |
||
203 | */ |
||
204 | protected function initSlugOptions(): void |
||
205 | { |
||
206 | if ($this->slugOptions === null) { |
||
207 | $this->slugOptions = $this->getSlugOptions(); |
||
208 | } |
||
209 | |||
210 | $this->validateSlugOptions(); |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Check if mandatory slug options have been properly set from the model. |
||
215 | * Check if $fromField and $toField have been set. |
||
216 | * |
||
217 | * @return void |
||
218 | * @throws SlugException |
||
219 | */ |
||
220 | protected function validateSlugOptions(): void |
||
221 | { |
||
222 | if (! $this->slugOptions->fromField) { |
||
223 | throw SlugException::mandatoryFromField(static::class); |
||
224 | } |
||
225 | |||
226 | if (! $this->slugOptions->toField) { |
||
227 | throw SlugException::mandatoryToField(static::class); |
||
228 | } |
||
229 | } |
||
230 | } |
||
231 |
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.