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 Padosoft\Uploadable; |
||
4 | |||
5 | use DB; |
||
6 | use Illuminate\Database\Eloquent\Model; |
||
7 | use Illuminate\Http\UploadedFile; |
||
8 | use Illuminate\Support\Facades\Log; |
||
9 | use Illuminate\Support\Facades\Storage; |
||
10 | use Illuminate\Support\Facades\URL; |
||
11 | use Padosoft\Uploadable\Events\UploadDeleteExecuted; |
||
12 | use Padosoft\Uploadable\Events\UploadExecuted; |
||
13 | |||
14 | /** |
||
15 | * Class Uploadable |
||
16 | * Auto upload and save files on save/create/delete model. |
||
17 | * @package Padosoft\Uploadable |
||
18 | */ |
||
19 | trait Uploadable |
||
20 | { |
||
21 | /** @var UploadOptions */ |
||
22 | protected $uploadOptions; |
||
23 | |||
24 | /** |
||
25 | * Determine if the model or given attribute(s) have been modified. |
||
26 | * Implemented in \Illuminate\Database\Eloquent\Model |
||
27 | * |
||
28 | * @param array|string|null $attributes = null |
||
29 | * |
||
30 | * @return bool |
||
31 | */ |
||
32 | abstract public function isDirty($attributes = null); |
||
33 | |||
34 | /** |
||
35 | * Get the model's original attribute values. |
||
36 | * Implemented in \Illuminate\Database\Eloquent\Model |
||
37 | * |
||
38 | * @param string|null $key = null |
||
39 | * @param mixed $default = null |
||
40 | * |
||
41 | * @return mixed|array |
||
42 | */ |
||
43 | abstract public function getOriginal($key = null, $default = null); |
||
44 | |||
45 | /** |
||
46 | * Boot the trait. |
||
47 | */ |
||
48 | public static function bootUploadable() |
||
49 | { |
||
50 | self::bindCreateEvents(); |
||
51 | self::bindSaveEvents(); |
||
52 | self::bindUpdateEvents(); |
||
53 | self::bindDeleteEvents(); |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * Bind create model events. |
||
58 | */ |
||
59 | protected static function bindCreateEvents() |
||
60 | { |
||
61 | static::creating(function ($model) { |
||
62 | $model->uploadOptions = $model->getUploadOptionsOrDefault(); |
||
63 | $model->guardAgainstInvalidUploadOptions(); |
||
64 | }); |
||
65 | } |
||
66 | |||
67 | /** |
||
68 | * Bind save model events. |
||
69 | */ |
||
70 | protected static function bindSaveEvents() |
||
71 | { |
||
72 | static::saved(function (Model $model) { |
||
73 | $model->uploadFiles(); |
||
74 | }); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Bind update model events. |
||
79 | */ |
||
80 | protected static function bindUpdateEvents() |
||
81 | { |
||
82 | static::updating(function (Model $model) { |
||
83 | //check if there is old files to delete |
||
84 | $model->checkIfNeedToDeleteOldFiles(); |
||
85 | }); |
||
86 | } |
||
87 | |||
88 | /** |
||
89 | * Bind delete model events. |
||
90 | */ |
||
91 | protected static function bindDeleteEvents() |
||
92 | { |
||
93 | static::deleting(function (Model $model) { |
||
94 | $model->uploadOptions = $model->getUploadOptionsOrDefault(); |
||
95 | $model->guardAgainstInvalidUploadOptions(); |
||
96 | //check if there is old files to delete |
||
97 | $model->checkIfNeedToDeleteOldFiles(); |
||
98 | }); |
||
99 | |||
100 | static::deleted(function (Model $model) { |
||
101 | $model->deleteUploadedFiles(); |
||
102 | }); |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * Retrive a specifice UploadOptions for this model, or return default UploadOptions |
||
107 | * @return UploadOptions |
||
108 | */ |
||
109 | public function getUploadOptionsOrDefault() : UploadOptions |
||
110 | { |
||
111 | if ($this->uploadOptions) { |
||
112 | return $this->uploadOptions; |
||
113 | } |
||
114 | |||
115 | if (method_exists($this, 'getUploadOptions')) { |
||
116 | $method = 'getUploadOptions'; |
||
117 | $this->uploadOptions = $this->{$method}(); |
||
118 | } else { |
||
119 | $this->uploadOptions = UploadOptions::create()->getUploadOptionsDefault() |
||
120 | ->setUploadBasePath('upload/' . $this->getTable()); |
||
0 ignored issues
–
show
|
|||
121 | } |
||
122 | |||
123 | return $this->uploadOptions; |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * This function will throw an exception when any of the options is missing or invalid. |
||
128 | * @throws InvalidOption |
||
129 | */ |
||
130 | public function guardAgainstInvalidUploadOptions() |
||
131 | { |
||
132 | if (!is_array($this->uploadOptions->uploads) || count($this->uploadOptions->uploads)<1) { |
||
133 | throw InvalidOption::missingUploadFields(); |
||
134 | } |
||
135 | if ($this->uploadOptions->uploadBasePath === null || $this->uploadOptions->uploadBasePath == '') { |
||
136 | throw InvalidOption::missingUploadBasePath(); |
||
137 | } |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Handle file upload. |
||
142 | */ |
||
143 | public function uploadFiles() |
||
144 | { |
||
145 | //invalid model |
||
146 | if ($this->id < 1) { |
||
0 ignored issues
–
show
The property
id 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;
![]() |
|||
147 | return; |
||
148 | } |
||
149 | |||
150 | //loop for every upload model attributes and do upload if has a file in request |
||
151 | foreach ($this->getUploadsAttributesSafe() as $uploadField) { |
||
152 | |||
153 | $this->uploadFile($uploadField); |
||
154 | } |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Upload a file releted to a passed attribute name |
||
159 | * @param string $uploadField |
||
160 | */ |
||
161 | public function uploadFile(string $uploadField) |
||
162 | { |
||
163 | //check if there is a valid file in request for current attribute |
||
164 | if (!isValidCurrentRequestUploadFile($uploadField, |
||
165 | $this->getUploadOptionsOrDefault()->uploadsMimeType) |
||
166 | ) { |
||
167 | return; |
||
168 | } |
||
169 | |||
170 | //retrive the uploaded file |
||
171 | $uploadedFile = getCurrentRequestFileSafe($uploadField); |
||
172 | if ($uploadedFile === null) { |
||
173 | return; |
||
174 | } |
||
175 | |||
176 | //calcolate new file name and set it to model attribute |
||
177 | $this->generateNewUploadFileNameAndSetAttribute($uploadField); |
||
178 | |||
179 | //do the work |
||
180 | $newName = $this->doUpload($uploadedFile, $uploadField); |
||
0 ignored issues
–
show
It seems like
$uploadedFile defined by getCurrentRequestFileSafe($uploadField) on line 171 can also be of type array ; however, Padosoft\Uploadable\Uploadable::doUpload() does only seem to accept object<Illuminate\Http\UploadedFile> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
181 | |||
182 | //save on db (not call model save because invoke event and entering in loop) |
||
183 | $this->updateDb($uploadField, $newName); |
||
184 | |||
185 | event(new UploadExecuted($uploadField, $this)); |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Get an UploadedFile, generate new name, and save it in destination path. |
||
190 | * Return empty string if it fails, otherwise return the saved file name. |
||
191 | * @param UploadedFile $uploadedFile |
||
192 | * @param string $uploadAttribute |
||
193 | * @return string |
||
194 | */ |
||
195 | public function doUpload(UploadedFile $uploadedFile, $uploadAttribute) : string |
||
196 | { |
||
197 | if (!$uploadAttribute) { |
||
198 | return ''; |
||
199 | } |
||
200 | |||
201 | //get file name by attribute |
||
202 | $newName = $this->{$uploadAttribute}; |
||
203 | |||
204 | //get upload path to store (method create dir if not exists and return '' if it failed) |
||
205 | $pathToStore = $this->getUploadFileBasePath($uploadAttribute); |
||
206 | |||
207 | //delete if file already exists |
||
208 | $newFile = njoin($pathToStore, $newName); |
||
209 | if($this->getUploadOptionsOrDefault()->storage->exists($newFile)){ |
||
210 | $this->getUploadOptionsOrDefault()->storage->delete($newFile); |
||
211 | } |
||
212 | |||
213 | //move file to destination folder |
||
214 | try { |
||
215 | //$targetFile = $uploadedFile->move($pathToStore, $newName); |
||
216 | $targetFile = $this->getUploadOptionsOrDefault()->storage->putFileAs( |
||
217 | $pathToStore, $uploadedFile, $newName |
||
218 | ); |
||
219 | |||
220 | } catch (\Exception $e) { |
||
221 | $targetFile = null; |
||
222 | Log::warning('Error in doUpload() when try to move ' . $newName . ' to folder: ' . $pathToStore . PHP_EOL . $e->getMessage() . PHP_EOL . $e->getTraceAsString()); |
||
223 | } |
||
224 | |||
225 | return $targetFile ? $newName : ''; |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * Check request for valid files and server for correct paths defined in model |
||
230 | * @return bool |
||
231 | */ |
||
232 | public function requestHasValidFilesAndCorrectPaths() : bool |
||
233 | { |
||
234 | //current request has not uploaded files |
||
235 | if (!currentRequestHasFiles()) { |
||
236 | return false; |
||
237 | } |
||
238 | |||
239 | //ensure that all upload path are ok or create it. |
||
240 | if (!$this->checkOrCreateAllUploadBasePaths()) { |
||
241 | return false; |
||
242 | } |
||
243 | |||
244 | return true; |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Generate a new file name for uploaded file. |
||
249 | * Return empty string if uploadedFile is null, otherwise return the new file name.. |
||
250 | * @param UploadedFile $uploadedFile |
||
251 | * @return string |
||
252 | * @internal param string $uploadField |
||
253 | */ |
||
254 | public function generateNewUploadFileName(UploadedFile $uploadedFile) : string |
||
255 | { |
||
256 | if (!$this->id && $this->getUploadOptionsOrDefault()->appendModelIdSuffixInUploadedFileName) { |
||
257 | return ''; |
||
258 | } |
||
259 | |||
260 | //check if file need a new name |
||
261 | $newName = $this->calcolateNewUploadFileName($uploadedFile); |
||
262 | if ($newName != '') { |
||
263 | return $newName; |
||
264 | } |
||
265 | |||
266 | //no new file name, return original file name |
||
267 | return $uploadedFile->getFilename(); |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * Check if file need a new name and return it, otherwise return empty string. |
||
272 | * @param UploadedFile $uploadedFile |
||
273 | * @return string |
||
274 | */ |
||
275 | public function calcolateNewUploadFileName(UploadedFile $uploadedFile) : string |
||
276 | { |
||
277 | if (!$this->getUploadOptionsOrDefault()->appendModelIdSuffixInUploadedFileName) { |
||
278 | return ''; |
||
279 | } |
||
280 | |||
281 | //retrive original file name and extension |
||
282 | $filenameWithoutExtension = getUploadedFilenameWithoutExtension($uploadedFile); |
||
283 | $ext = $uploadedFile->getClientOriginalExtension(); |
||
284 | |||
285 | $newName = $filenameWithoutExtension . $this->getUploadOptionsOrDefault()->uploadFileNameSuffixSeparator . $this->id . '.' . $ext; |
||
286 | return sanitize_filename($newName); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * delete all Uploaded Files |
||
291 | */ |
||
292 | public function deleteUploadedFiles() |
||
293 | { |
||
294 | //loop for every upload model attributes |
||
295 | foreach ($this->getUploadOptionsOrDefault()->uploads as $uploadField) { |
||
296 | $this->deleteUploadedFile($uploadField); |
||
297 | } |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Delete upload file related to passed attribute name |
||
302 | * @param string $uploadField |
||
303 | */ |
||
304 | public function deleteUploadedFile(string $uploadField) |
||
305 | { |
||
306 | if (!$uploadField) { |
||
307 | return; |
||
308 | } |
||
309 | |||
310 | if (!$this->{$uploadField}) { |
||
311 | return; |
||
312 | } |
||
313 | |||
314 | //retrive correct upload storage path for current attribute |
||
315 | $uploadFieldPath = $this->getUploadFileBasePath($uploadField); |
||
316 | |||
317 | //unlink file |
||
318 | $path = njoin($uploadFieldPath, $this->{$uploadField}); |
||
319 | if(!$this->getUploadOptionsOrDefault()->storage->delete($path)){ |
||
320 | Log::error('Error when Uploadable.deleteUploadedFile() try to delete file:'.$path); |
||
321 | } |
||
322 | |||
323 | //reset model attribute and update db field |
||
324 | $this->setBlanckAttributeAndDB($uploadField); |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * Reset model attribute and update db field |
||
329 | * @param string $uploadField |
||
330 | */ |
||
331 | public function setBlanckAttributeAndDB(string $uploadField) |
||
332 | { |
||
333 | if (!$uploadField) { |
||
334 | return; |
||
335 | } |
||
336 | |||
337 | //old value |
||
338 | $old = $this->{$uploadField}; |
||
339 | |||
340 | //set to black attribute |
||
341 | $this->{$uploadField} = ''; |
||
342 | |||
343 | //save on db (not call model save because invoke event and entering in loop) |
||
344 | $this->updateDb($uploadField, ''); |
||
345 | |||
346 | event(new UploadDeleteExecuted($uploadField, $old, $this)); |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * Return true If All Upload atrributes Are Empty or |
||
351 | * if the uploads array is not set. |
||
352 | * @return bool |
||
353 | */ |
||
354 | public function checkIfAllUploadFieldsAreEmpty() : bool |
||
355 | { |
||
356 | foreach ($this->getUploadsAttributesSafe() as $uploadField) { |
||
357 | //for performance if one attribute has value exit false |
||
358 | if ($uploadField && $this->{$uploadField}) { |
||
359 | return false; |
||
360 | } |
||
361 | } |
||
362 | |||
363 | return true; |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Check all attributes upload path, and try to create dir if not already exists. |
||
368 | * Return false if it fails to create all founded dirs. |
||
369 | * @return bool |
||
370 | */ |
||
371 | public function checkOrCreateAllUploadBasePaths() : bool |
||
372 | { |
||
373 | foreach ($this->getUploadsAttributesSafe() as $uploadField) { |
||
374 | if (!$this->checkOrCreateUploadBasePath($uploadField)) { |
||
375 | return false; |
||
376 | } |
||
377 | } |
||
378 | |||
379 | return true; |
||
380 | } |
||
381 | |||
382 | /** |
||
383 | * Check uploads property and return a uploads class field |
||
384 | * or empty array if somethings wrong. |
||
385 | * @return array |
||
386 | */ |
||
387 | public function getUploadsAttributesSafe() : array |
||
388 | { |
||
389 | if (!is_array($this->getUploadOptionsOrDefault()->uploads)) { |
||
390 | return []; |
||
391 | } |
||
392 | |||
393 | return $this->getUploadOptionsOrDefault()->uploads; |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * Check attribute upload path, and try to create dir if not already exists. |
||
398 | * Return false if it fails to create the dir. |
||
399 | * @param string $uploadField |
||
400 | * @return bool |
||
401 | */ |
||
402 | public function checkOrCreateUploadBasePath(string $uploadField) : bool |
||
403 | { |
||
404 | /* |
||
405 | $uploadFieldPath = $this->getUploadFileBasePath($uploadField); |
||
406 | |||
407 | return $uploadFieldPath == '' ? '' : DirHelper::checkDirExistOrCreate($uploadFieldPath, |
||
408 | $this->getUploadOptionsOrDefault()->uploadCreateDirModeMask); |
||
409 | */ |
||
410 | //Laravel storage (Local, FTP, S3) seems that you can simply write |
||
411 | // to a path and not worry whether directory exists or not. |
||
412 | |||
413 | return true; |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * Return the upload path for the passed attribute and try to create it if not exists. |
||
418 | * Returns empty string if dir if not exists and fails to create it. |
||
419 | * @param string $uploadField |
||
420 | * @return string |
||
421 | */ |
||
422 | public function getUploadFileBasePath(string $uploadField) : string |
||
423 | { |
||
424 | //default model upload path |
||
425 | $uploadFieldPath = canonicalize($this->getUploadOptionsOrDefault()->uploadBasePath); |
||
426 | |||
427 | //overwrite if there is specific path for the field |
||
428 | $specificPath = $this->getUploadFileBasePathSpecific($uploadField); |
||
429 | if ($specificPath != '') { |
||
430 | $uploadFieldPath = $specificPath; |
||
431 | } |
||
432 | |||
433 | //check if exists or try to create dir |
||
434 | //Laravel storage (Local, FTP, S3) seems that you can simply write |
||
435 | // to a path and not worry whether directory exists or not. |
||
436 | /* |
||
437 | if (!DirHelper::checkDirExistOrCreate($uploadFieldPath, |
||
438 | $this->getUploadOptionsOrDefault()->uploadCreateDirModeMask) |
||
439 | ) { |
||
440 | return ''; |
||
441 | }*/ |
||
442 | |||
443 | return $uploadFieldPath; |
||
444 | } |
||
445 | |||
446 | /** |
||
447 | * Return the specific upload path (by uploadPaths prop) for the passed attribute if exists, |
||
448 | * otherwise return empty string. |
||
449 | * If uploadPaths for this field is relative, a public_path was appended. |
||
450 | * @param string $uploadField |
||
451 | * @return string |
||
452 | */ |
||
453 | public function getUploadFileBasePathSpecific(string $uploadField) : string |
||
454 | { |
||
455 | //check if there is a specified upload path for this field |
||
456 | if (!$this->hasUploadPathSpecifiedForThisField($uploadField)) { |
||
457 | return ''; |
||
458 | } |
||
459 | |||
460 | $path = $this->getUploadOptionsOrDefault()->uploadPaths[$uploadField]; |
||
461 | |||
462 | //if path is relative, nothing to do because all is relative to storage disk root path |
||
463 | |||
464 | return canonicalize($path); |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Check if there is a specified upload path setted for this field |
||
469 | * @param string $uploadField |
||
470 | * @return bool |
||
471 | */ |
||
472 | public function hasUploadPathSpecifiedForThisField(string $uploadField) : bool |
||
473 | { |
||
474 | return !(empty($this->getUploadOptionsOrDefault()->uploadPaths) |
||
475 | || count($this->getUploadOptionsOrDefault()->uploadPaths) < 1 |
||
476 | || !array_key_exists($uploadField, $this->getUploadOptionsOrDefault()->uploadPaths) |
||
477 | ); |
||
478 | } |
||
479 | |||
480 | /** |
||
481 | * Return the full (path+filename) upload abs path for the passed attribute. |
||
482 | * Returns empty string if dir if not exists. |
||
483 | * @param string $uploadField |
||
484 | * @return string |
||
485 | */ |
||
486 | public |
||
487 | function getUploadFileFullPath( |
||
488 | string $uploadField |
||
489 | ) : string |
||
490 | { |
||
491 | $uploadFieldPath = $this->getUploadFileBasePath($uploadField); |
||
492 | $uploadFieldPath = canonicalize($this->getUploadOptionsOrDefault()->storage->path(addFinalSlash($uploadFieldPath) . $this->{$uploadField})); |
||
493 | |||
494 | if ($this->isSlashOrEmptyDir($uploadFieldPath)) { |
||
495 | return ''; |
||
496 | } |
||
497 | |||
498 | return $uploadFieldPath; |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * Return the full url (base url + filename) for the passed attribute. |
||
503 | * Returns empty string if dir if not exists. |
||
504 | * Ex.: http://localhost/laravel/public/upload/news/pippo.jpg |
||
505 | * @param string $uploadField |
||
506 | * @return string |
||
507 | */ |
||
508 | View Code Duplication | public |
|
509 | function getUploadFileUrl( |
||
510 | string $uploadField |
||
511 | ) : string |
||
512 | { |
||
513 | $url = addFinalSlash($this->getUploadFileBasePath($uploadField)). $this->{$uploadField}; |
||
514 | |||
515 | return $url == '' ? '' : $this->getUploadOptionsOrDefault()->storage->url($url); |
||
516 | } |
||
517 | |||
518 | /** |
||
519 | * get a path and remove public_path. |
||
520 | * @param string $path |
||
521 | * @return string |
||
522 | */ |
||
523 | public |
||
524 | function removePublicPath( |
||
525 | string $path |
||
526 | ) : string |
||
527 | { |
||
528 | if ($path == '') { |
||
529 | return ''; |
||
530 | } |
||
531 | $len = strpos($path, DIRECTORY_SEPARATOR); |
||
532 | if ($len === false) { |
||
533 | return ''; |
||
534 | } |
||
535 | $path = substr($path, 0, $len); |
||
536 | if ($this->isSlashOrEmptyDir($path)) { |
||
537 | return ''; |
||
538 | } |
||
539 | |||
540 | return $path; |
||
541 | } |
||
542 | |||
543 | /** |
||
544 | * Return the base url (without filename) for the passed attribute. |
||
545 | * Returns empty string if dir if not exists. |
||
546 | * Ex.: http://localhost/laravel/public/upload/ |
||
547 | * @param string $uploadField |
||
548 | * @return string |
||
549 | */ |
||
550 | View Code Duplication | public |
|
551 | function getUploadFileBaseUrl( |
||
552 | string $uploadField |
||
553 | ) : string |
||
554 | { |
||
555 | $uploadFieldPath = $this->getUploadFileBasePath($uploadField); |
||
556 | /*dump($uploadFieldPath); |
||
557 | $uploadFieldPath = canonicalize(addFinalSlash($this->removePublicPath($uploadFieldPath)));*/ |
||
558 | |||
559 | if ($this->isSlashOrEmptyDir($uploadFieldPath)) { |
||
560 | return ''; |
||
561 | } |
||
562 | |||
563 | return addFinalSlash($this->getUploadOptionsOrDefault()->storage->url($uploadFieldPath)); |
||
564 | } |
||
565 | |||
566 | /** |
||
567 | * Calcolate the new name for ALL uploaded files and set relative upload attributes |
||
568 | */ |
||
569 | public |
||
570 | function generateAllNewUploadFileNameAndSetAttribute() |
||
571 | { |
||
572 | foreach ($this->getUploadsAttributesSafe() as $uploadField) { |
||
573 | $this->generateNewUploadFileNameAndSetAttribute($uploadField); |
||
574 | } |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * Calcolate the new name for uploaded file relative to passed attribute name and set the upload attribute |
||
579 | * @param string $uploadField |
||
580 | */ |
||
581 | public |
||
582 | function generateNewUploadFileNameAndSetAttribute( |
||
583 | string $uploadField |
||
584 | ) { |
||
585 | if (!trim($uploadField)) { |
||
586 | return; |
||
587 | } |
||
588 | |||
589 | //generate new file name |
||
590 | $uploadedFile = getCurrentRequestFileSafe($uploadField); |
||
591 | if ($uploadedFile === null) { |
||
592 | return; |
||
593 | } |
||
594 | $newName = $this->generateNewUploadFileName($uploadedFile); |
||
0 ignored issues
–
show
It seems like
$uploadedFile defined by getCurrentRequestFileSafe($uploadField) on line 590 can also be of type array ; however, Padosoft\Uploadable\Uplo...rateNewUploadFileName() does only seem to accept object<Illuminate\Http\UploadedFile> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
595 | if ($newName == '') { |
||
596 | return; |
||
597 | } |
||
598 | |||
599 | //set attribute |
||
600 | $this->{$uploadField} = $newName; |
||
601 | } |
||
602 | |||
603 | /** |
||
604 | * @param string $uploadField |
||
605 | * @param string $newName |
||
606 | */ |
||
607 | public |
||
608 | function updateDb( |
||
609 | string $uploadField, |
||
610 | string $newName |
||
611 | ) { |
||
612 | if ($this->id < 1) { |
||
613 | return; |
||
614 | } |
||
615 | DB::table($this->getTable()) |
||
0 ignored issues
–
show
It seems like
getTable() 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 ![]() |
|||
616 | ->where('id', $this->id) |
||
617 | ->update([$uploadField => $newName]); |
||
618 | } |
||
619 | |||
620 | /** |
||
621 | * @param string $path |
||
622 | * @return bool |
||
623 | */ |
||
624 | public |
||
625 | function isSlashOrEmptyDir( |
||
626 | string $path |
||
627 | ):bool |
||
628 | { |
||
629 | return isNullOrEmpty($path) || $path == '\/' || $path == DIRECTORY_SEPARATOR; |
||
630 | } |
||
631 | |||
632 | /** |
||
633 | * Check if all uploadedFields are changed, so there is an old value |
||
634 | * for attribute and if true try to unlink old file. |
||
635 | */ |
||
636 | public |
||
637 | function checkIfNeedToDeleteOldFiles() |
||
638 | { |
||
639 | foreach ($this->getUploadsAttributesSafe() as $uploadField) { |
||
640 | $this->checkIfNeedToDeleteOldFile($uploadField); |
||
641 | } |
||
642 | } |
||
643 | |||
644 | /** |
||
645 | * Check if $uploadField are changed, so there is an old value |
||
646 | * for $uploadField attribute and if true try to unlink old file. |
||
647 | * @param string $uploadField |
||
648 | */ |
||
649 | public |
||
650 | function checkIfNeedToDeleteOldFile( |
||
651 | string $uploadField |
||
652 | ) { |
||
653 | if (isNullOrEmpty($uploadField) |
||
654 | || !$this->isDirty($uploadField) |
||
655 | || ($this->{$uploadField} == $this->getOriginal($uploadField)) |
||
656 | || isNullOrEmpty($this->getOriginal($uploadField)) |
||
657 | ) { |
||
658 | return; |
||
659 | } |
||
660 | |||
661 | $oldValue = $this->getOriginal($uploadField); |
||
662 | |||
663 | $this->getUploadOptionsOrDefault()->storage->delete(njoin($this->getUploadFileBasePath($uploadField), $oldValue)); |
||
664 | } |
||
665 | } |
||
666 |
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.