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

HandleRepeatableUploads::uploadRepeatableFiles()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 3
dl 0
loc 2
rs 10
c 0
b 0
f 0
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 ?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(): ?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)->toArray();
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)->toArray();
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;
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)) {
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