Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Test Setup Failed
Pull Request — main (#5725)
by Pedro
25:49 queued 10:59
created

deleteRepeatableRelationFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\Uploaders\Support\Traits;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
6
use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\Pivot;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Facades\Log;
11
use Illuminate\Support\Facades\Storage;
12
use Illuminate\Support\Str;
13
14
/**
15
 * @codeCoverageIgnore
16
 */
17
trait HandleRepeatableUploads
18
{
19
    public bool $handleRepeatableFiles = false;
20
21
    public null|string $repeatableContainerName = null;
22
23
    /*******************************
24
     * Setters - fluently configure the uploader
25
     *******************************/
26
    public function repeats(string $repeatableContainerName): self
27
    {
28
        $this->handleRepeatableFiles = true;
29
30
        $this->repeatableContainerName = $repeatableContainerName;
31
32
        return $this;
33
    }
34
35
    /*******************************
36
     * Getters
37
     *******************************/
38
    public function getRepeatableContainerName(): null|string
39
    {
40
        return $this->repeatableContainerName;
41
    }
42
43
    /*******************************
44
     * Default implementation methods
45
     *******************************/
46
    protected function uploadRepeatableFiles($values, $previousValues, $entry = null)
47
    {
48
    }
49
50
    protected function handleRepeatableFiles(Model $entry): Model
51
    {
52
        $values = collect(CRUD::getRequest()->get($this->getRepeatableContainerName()));
0 ignored issues
show
Bug introduced by
The method getRequest() does not exist on Backpack\CRUD\app\Librar...udPanel\CrudPanelFacade. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
        $values = collect(CRUD::/** @scrutinizer ignore-call */ getRequest()->get($this->getRepeatableContainerName()));
Loading history...
53
        $files = collect(CRUD::getRequest()->file($this->getRepeatableContainerName()));
54
55
        $value = $this->mergeValuesRecursive($values, $files);
56
57
        if ($this->isRelationship()) {
0 ignored issues
show
Bug introduced by
It seems like isRelationship() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

57
        if ($this->/** @scrutinizer ignore-call */ isRelationship()) {
Loading history...
58
            if ($value->isEmpty()) {
59
                return $entry;
60
            }
61
62
            return $this->processRelationshipRepeatableUploaders($entry);
63
        }
64
65
        $processedEntryValues = $this->processRepeatableUploads($entry, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $values of Backpack\CRUD\app\Librar...cessRepeatableUploads() does only seem to accept Illuminate\Support\Collection, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
        $processedEntryValues = $this->processRepeatableUploads($entry, /** @scrutinizer ignore-type */ $value);
Loading history...
66
67
        if ($this->isFake()) {
0 ignored issues
show
Bug introduced by
It seems like isFake() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

67
        if ($this->/** @scrutinizer ignore-call */ isFake()) {
Loading history...
68
            $fakeValues = $entry->{$this->getFakeAttribute()} ?? [];
0 ignored issues
show
Bug introduced by
It seems like getFakeAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
            $fakeValues = $entry->{$this->/** @scrutinizer ignore-call */ getFakeAttribute()} ?? [];
Loading history...
69
70
            if (is_string($fakeValues)) {
71
                $fakeValues = json_decode($fakeValues, true);
72
            }
73
74
            $fakeValues[$this->getRepeatableContainerName()] = empty($processedEntryValues)
75
                                                        ? null
76
                                                        : (isset($entry->getCasts()[$this->getFakeAttribute()])
77
                                                            ? $processedEntryValues
78
                                                            : json_encode($processedEntryValues));
79
80
            $entry->{$this->getFakeAttribute()} = isset($entry->getCasts()[$this->getFakeAttribute()])
81
                                                            ? $fakeValues
82
                                                            : json_encode($fakeValues);
83
84
            return $entry;
85
        }
86
87
        $entry->{$this->getRepeatableContainerName()} = empty($processedEntryValues)
88
                                                        ? null
89
                                                        : (isset($entry->getCasts()[$this->getRepeatableContainerName()])
90
                                                            ? $processedEntryValues
91
                                                            : json_encode($processedEntryValues));
92
93
        return $entry;
94
    }
95
96
    private function processRelationshipRepeatableUploaders(Model $entry)
97
    {
98
        foreach (app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName()) as $uploader) {
99
            $entry = $uploader->uploadRelationshipFiles($entry);
100
        }
101
102
        return $entry;
103
    }
104
105
    protected function uploadRelationshipFiles(Model $entry): Model
106
    {
107
        $entryValue = $this->getFilesFromEntry($entry);
108
109
        if ($this->handleMultipleFiles && is_string($entryValue)) {
110
            try {
111
                $entryValue = json_decode($entryValue, true);
112
            } catch (\Exception) {
113
                return $entry;
114
            }
115
        }
116
117
        if ($this->hasDeletedFiles($entryValue)) {
0 ignored issues
show
Bug introduced by
It seems like hasDeletedFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        if ($this->/** @scrutinizer ignore-call */ hasDeletedFiles($entryValue)) {
Loading history...
118
            $entry->{$this->getAttributeName()} = $this->uploadFiles($entry, false);
0 ignored issues
show
Bug introduced by
It seems like uploadFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            /** @scrutinizer ignore-call */ 
119
            $entry->{$this->getAttributeName()} = $this->uploadFiles($entry, false);
Loading history...
Bug introduced by
It seems like getAttributeName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            $entry->{$this->/** @scrutinizer ignore-call */ getAttributeName()} = $this->uploadFiles($entry, false);
Loading history...
119
            $this->updatedPreviousFiles = $this->getEntryAttributeValue($entry);
0 ignored issues
show
Bug Best Practice introduced by
The property updatedPreviousFiles does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
120
        }
121
122
        if ($this->shouldKeepPreviousValueUnchanged($entry, $entryValue)) {
0 ignored issues
show
Bug introduced by
It seems like shouldKeepPreviousValueUnchanged() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
        if ($this->/** @scrutinizer ignore-call */ shouldKeepPreviousValueUnchanged($entry, $entryValue)) {
Loading history...
123
            $entry->{$this->getAttributeName()} = $this->updatedPreviousFiles ?? $this->getEntryOriginalValue($entry);
124
125
            return $entry;
126
        }
127
128
        if ($this->shouldUploadFiles($entryValue)) {
0 ignored issues
show
Bug introduced by
It seems like shouldUploadFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

128
        if ($this->/** @scrutinizer ignore-call */ shouldUploadFiles($entryValue)) {
Loading history...
129
            $entry->{$this->getAttributeName()} = $this->uploadFiles($entry, $entryValue);
130
        }
131
132
        return $entry;
133
    }
134
135
    protected function getFilesFromEntry(Model $entry)
136
    {
137
        return $entry->getAttribute($this->getAttributeName());
138
    }
139
140
    protected function getEntryAttributeValue(Model $entry)
141
    {
142
        return $entry->{$this->getAttributeName()};
143
    }
144
145
    protected function getEntryOriginalValue(Model $entry)
146
    {
147
        return $entry->getOriginal($this->getAttributeName());
148
    }
149
150
    protected function processRepeatableUploads(Model $entry, Collection $values): Collection
151
    {
152
        foreach (app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName()) as $uploader) {
153
            $uploadedValues = $uploader->uploadRepeatableFiles($values->pluck($uploader->getAttributeName())->toArray(), $this->getPreviousRepeatableValues($entry, $uploader));
154
155
            $values = $values->map(function ($item, $key) use ($uploadedValues, $uploader) {
156
                $item[$uploader->getAttributeName()] = $uploadedValues[$key] ?? null;
157
158
                return $item;
159
            });
160
        }
161
162
        return $values->toArray();
163
    }
164
165
    private function retrieveRepeatableFiles(Model $entry): Model
166
    {
167
        if ($this->isRelationship) {
168
            return $this->retrieveRepeatableRelationFiles($entry);
169
        }
170
171
        $repeatableUploaders = app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName());
172
173
        if ($this->attachedToFakeField) {
174
            $values = $entry->{$this->attachedToFakeField};
175
176
            $values = is_string($values) ? json_decode($values, true) : $values;
177
178
            $values[$this->getAttributeName()] = isset($values[$this->getAttributeName()]) ? $this->getValueWithoutPath($values[$this->getAttributeName()]) : null;
0 ignored issues
show
Bug introduced by
It seems like getValueWithoutPath() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

178
            $values[$this->getAttributeName()] = isset($values[$this->getAttributeName()]) ? $this->/** @scrutinizer ignore-call */ getValueWithoutPath($values[$this->getAttributeName()]) : null;
Loading history...
179
            $entry->{$this->attachedToFakeField} = isset($entry->getCasts()[$this->attachedToFakeField]) ? $values : json_encode($values);
180
181
            return $entry;
182
        }
183
184
        $values = $entry->{$this->getRepeatableContainerName()};
185
        $values = is_string($values) ? json_decode($values, true) : $values;
186
        $values = array_map(function ($item) use ($repeatableUploaders) {
187
            foreach ($repeatableUploaders as $upload) {
188
                $item[$upload->getAttributeName()] = $this->getValuesWithPathStripped($item, $upload);
189
            }
190
191
            return $item;
192
        }, $values ?? []);
193
194
        $entry->{$this->getRepeatableContainerName()} = $values;
195
196
        return $entry;
197
    }
198
199
    private function retrieveRepeatableRelationFiles(Model $entry)
200
    {
201
        switch($this->getRepeatableRelationType()) {
202
            case 'BelongsToMany':
203
            case 'MorphToMany':
204
                $pivotClass = app('crud')->getModel()->{$this->getUploaderSubfield()['baseEntity']}()->getPivotClass();
205
                $pivotFieldName = 'pivot_'.$this->getAttributeName();
206
                $connectedEntry = new $pivotClass([$this->getAttributeName() => $entry->$pivotFieldName]);
207
                $entry->{$pivotFieldName} = $this->retrieveFiles($connectedEntry)->{$this->getAttributeName()};
0 ignored issues
show
Bug introduced by
It seems like retrieveFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

207
                $entry->{$pivotFieldName} = $this->/** @scrutinizer ignore-call */ retrieveFiles($connectedEntry)->{$this->getAttributeName()};
Loading history...
208
209
                break;
210
            default:
211
                $entry = $this->retrieveFiles($entry);
212
        }
213
214
        return $entry;
215
    }
216
217
    private function getRepeatableRelationType()
218
    {
219
        return $this->getUploaderField()->getAttributes()['relation_type'];
220
    }
221
222
    private function getUploaderField()
223
    {
224
        return app('crud')->field($this->getRepeatableContainerName());
225
    }
226
227
    private function getUploaderSubfield()
228
    {
229
        return collect($this->getUploaderFieldSubfields())->where('name', '===', $this->getName())->first();
0 ignored issues
show
Bug introduced by
It seems like getName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

229
        return collect($this->getUploaderFieldSubfields())->where('name', '===', $this->/** @scrutinizer ignore-call */ getName())->first();
Loading history...
230
    }
231
232
    private function getUploaderFieldSubfields()
233
    {
234
        return $this->getUploaderField()->getAttributes()['subfields'];
235
    }
236
237
    private function deleteRepeatableFiles(Model $entry): void
238
    {
239
        if ($this->isRelationship) {
240
            $this->deleteRelationshipFiles($entry);
241
242
            return;
243
        }
244
245
        if ($this->attachedToFakeField) {
246
            $repeatableValues = $entry->{$this->attachedToFakeField}[$this->getRepeatableContainerName()] ?? null;
247
            $repeatableValues = is_string($repeatableValues) ? json_decode($repeatableValues, true) : $repeatableValues;
248
            $repeatableValues = collect($repeatableValues);
249
        }
250
251
        $repeatableValues ??= collect($entry->{$this->getRepeatableContainerName()});
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $repeatableValues does not seem to be defined for all execution paths leading up to this point.
Loading history...
252
253
        foreach (app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName()) as $upload) {
254
            if (! $upload->shouldDeleteFiles()) {
255
                continue;
256
            }
257
            $values = $repeatableValues->pluck($upload->getName())->toArray();
258
            foreach ($values as $value) {
259
                if (! $value) {
260
                    continue;
261
                }
262
263
                if (is_array($value)) {
264
                    foreach ($value as $subvalue) {
265
                        Storage::disk($upload->getDisk())->delete($upload->getPath().$subvalue);
266
                    }
267
268
                    continue;
269
                }
270
271
                Storage::disk($upload->getDisk())->delete($upload->getPath().$value);
272
            }
273
        }
274
    }
275
    /*******************************
276
     * Helper methods
277
     *******************************/
278
279
    /**
280
     * Given two multidimensional arrays/collections, merge them recursively.
281
     */
282
    protected function mergeValuesRecursive(array|Collection $array1, array|Collection $array2): array|Collection
283
    {
284
        $merged = $array1;
285
        foreach ($array2 as $key => &$value) {
286
            if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
287
                $merged[$key] = $this->mergeValuesRecursive($merged[$key], $value);
288
            } else {
289
                $merged[$key] = $value;
290
            }
291
        }
292
293
        return $merged;
294
    }
295
296
    /**
297
     * Repeatable items send `_order_` parameter in the request.
298
     * This holds the order of the items in the repeatable container.
299
     */
300
    protected function getFileOrderFromRequest(): array
301
    {
302
        $items = CRUD::getRequest()->input('_order_'.$this->getRepeatableContainerName()) ?? [];
303
304
        array_walk($items, function (&$key, $value) {
305
            $requestValue = $key[$this->getName()] ?? null;
306
            $key = $this->handleMultipleFiles ? (is_string($requestValue) ? explode(',', $requestValue) : $requestValue) : $requestValue;
307
        });
308
309
        return $items;
310
    }
311
312
    private function getPreviousRepeatableValues(Model $entry, UploaderInterface $uploader): array
313
    {
314
        $previousValues = $entry->getOriginal($uploader->getRepeatableContainerName());
315
316
        if (! is_array($previousValues)) {
317
            $previousValues = json_decode($previousValues, true);
318
        }
319
320
        if (! empty($previousValues)) {
321
            $previousValues = array_column($previousValues, $uploader->getName());
322
        }
323
324
        return $previousValues ?? [];
325
    }
326
327
    private function getValuesWithPathStripped(array|string|null $item, UploaderInterface $uploader)
328
    {
329
        $uploadedValues = $item[$uploader->getName()] ?? null;
330
        if (is_array($uploadedValues)) {
331
            return array_map(function ($value) use ($uploader) {
332
                return $uploader->getValueWithoutPath($value);
0 ignored issues
show
Bug introduced by
The method getValueWithoutPath() does not exist on Backpack\CRUD\app\Librar...faces\UploaderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Backpack\CRUD\app\Librar...faces\UploaderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

332
                return $uploader->/** @scrutinizer ignore-call */ getValueWithoutPath($value);
Loading history...
333
            }, $uploadedValues);
334
        }
335
336
        return isset($uploadedValues) ? $uploader->getValueWithoutPath($uploadedValues) : null;
337
    }
338
339
    private function deleteRelationshipFiles(Model $entry): void
340
    {
341
        if (! is_a($entry, Pivot::class, true) &&
342
            ! $entry->relationLoaded($this->getRepeatableContainerName()) &&
343
            method_exists($entry, $this->getRepeatableContainerName())
0 ignored issues
show
Bug introduced by
It seems like $this->getRepeatableContainerName() can also be of type null; however, parameter $method of method_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

343
            method_exists($entry, /** @scrutinizer ignore-type */ $this->getRepeatableContainerName())
Loading history...
344
        ) {
345
            $entry->loadMissing($this->getRepeatableContainerName());
346
        }
347
348
        foreach (app('UploadersRepository')->getRepeatableUploadersFor($this->getRepeatableContainerName()) as $uploader) {
349
            if ($uploader->shouldDeleteFiles()) {
350
                $uploader->deleteRepeatableRelationFiles($entry);
351
            }
352
        }
353
    }
354
355
    protected function deleteRepeatableRelationFiles(Model $entry)
356
    {
357
        match ($this->getRepeatableRelationType()) {
358
            'BelongsToMany', 'MorphToMany' => $this->deletePivotFiles($entry),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->deletePivotFiles($entry) targeting Backpack\CRUD\app\Librar...ads::deletePivotFiles() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
359
            default => $this->deleteRelatedFiles($entry),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->deleteRelatedFiles($entry) targeting Backpack\CRUD\app\Librar...s::deleteRelatedFiles() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
360
        };
361
    }
362
363
    private function deleteRelatedFiles(Model $entry)
364
    {
365
        if (get_class($entry) === get_class(app('crud')->model)) {
0 ignored issues
show
Bug introduced by
app('crud')->model of type string is incompatible with the type object expected by parameter $object of get_class(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

365
        if (get_class($entry) === get_class(/** @scrutinizer ignore-type */ app('crud')->model)) {
Loading history...
366
            $relatedEntries = $entry->{$this->getRepeatableContainerName()} ?? [];
367
        }
368
369
        if (! is_a($relatedEntries ?? '', Collection::class, true)) {
370
            $relatedEntries = ! empty($relatedEntries) ? [$relatedEntries] : [$entry];
371
        }
372
373
        foreach ($relatedEntries as $relatedEntry) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $relatedEntries does not seem to be defined for all execution paths leading up to this point.
Loading history...
374
            $this->deleteFiles($relatedEntry);
0 ignored issues
show
Bug introduced by
The method deleteFiles() does not exist on Backpack\CRUD\app\Librar...HandleRepeatableUploads. Did you maybe mean deletePivotFiles()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

374
            $this->/** @scrutinizer ignore-call */ 
375
                   deleteFiles($relatedEntry);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
375
        }
376
    }
377
378
    protected function deletePivotFiles(Pivot|Model $entry)
379
    {
380
        if (! is_a($entry, Pivot::class, true)) {
381
            $pivots = $entry->{$this->getRepeatableContainerName()};
382
            foreach ($pivots as $pivot) {
383
                $this->deletePivotModelFiles($pivot);
384
            }
385
386
            return;
387
        }
388
389
        $pivotAttributes = $entry->getAttributes();
390
        $connectedPivot = $entry->pivotParent->{$this->getRepeatableContainerName()}->where(function ($item) use ($pivotAttributes) {
391
            $itemPivotAttributes = $item->pivot->only(array_keys($pivotAttributes));
392
393
            return $itemPivotAttributes === $pivotAttributes;
394
        })->first();
395
396
        if (! $connectedPivot) {
397
            return;
398
        }
399
400
        $this->deletePivotModelFiles($connectedPivot);
401
    }
402
403
    private function deletePivotModelFiles(Pivot|Model $entry)
404
    {
405
        $files = $entry->getOriginal()['pivot_'.$this->getAttributeName()];
406
407
        if (! $files) {
408
            return;
409
        }
410
411
        if ($this->handleMultipleFiles && is_string($files)) {
412
            try {
413
                $files = json_decode($files, true);
414
            } catch (\Exception) {
415
                Log::error('Could not parse files for deletion pivot entry with key: '.$entry->getKey().' and uploader: '.$this->getName());
416
417
                return;
418
            }
419
        }
420
421
        if (is_array($files)) {
422
            foreach ($files as $value) {
423
                $value = Str::start($value, $this->getPath());
0 ignored issues
show
Bug introduced by
It seems like getPath() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

423
                $value = Str::start($value, $this->/** @scrutinizer ignore-call */ getPath());
Loading history...
424
                Storage::disk($this->getDisk())->delete($value);
0 ignored issues
show
Bug introduced by
It seems like getDisk() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

424
                Storage::disk($this->/** @scrutinizer ignore-call */ getDisk())->delete($value);
Loading history...
425
            }
426
427
            return;
428
        }
429
430
        $value = Str::start($files, $this->getPath());
431
        Storage::disk($this->getDisk())->delete($value);
432
    }
433
}
434