-
Notifications
You must be signed in to change notification settings - Fork 924
Expand file tree
/
Copy pathMultipleFiles.php
More file actions
127 lines (103 loc) · 4.31 KB
/
MultipleFiles.php
File metadata and controls
127 lines (103 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
namespace Backpack\CRUD\app\Library\Uploaders;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Storage;
class MultipleFiles extends Uploader
{
public static function for(array $field, $configuration): UploaderInterface
{
return (new self($field, $configuration))->multiple();
}
public function uploadFiles(Model $entry, $value = null)
{
if ($value && isset($value[0]) && is_null($value[0])) {
$value = false;
}
$filesToDelete = $this->getFilesToDeleteFromRequest();
$value = $value ?? collect($value)->flatten()->toArray();
$previousFiles = $this->getPreviousFiles($entry) ?? [];
if (is_array($previousFiles) && empty($previousFiles[0] ?? [])) {
$previousFiles = [];
}
if (! is_array($previousFiles) && is_string($previousFiles)) {
$previousFiles = json_decode($previousFiles, true);
}
if ($filesToDelete) {
foreach ($previousFiles as $previousFile) {
if (in_array($previousFile, $filesToDelete)) {
Storage::disk($this->getDisk())->delete($previousFile);
$previousFiles = Arr::where($previousFiles, function ($value, $key) use ($previousFile) {
return $value != $previousFile;
});
}
}
}
if (! is_array($value)) {
$value = [];
}
foreach ($value as $file) {
if ($file && is_file($file)) {
$fileName = $this->getFileName($file);
$file->storeAs($this->getPath(), $fileName, $this->getDisk());
$previousFiles[] = $this->getPath().$fileName;
}
}
$previousFiles = array_values($previousFiles);
if (empty($previousFiles)) {
return null;
}
return isset($entry->getCasts()[$this->getName()]) || $this->isFake() ? $previousFiles : json_encode($previousFiles);
}
/** @codeCoverageIgnore */
public function uploadRepeatableFiles($files, $previousRepeatableValues, $entry = null)
{
$fileOrder = $this->getFileOrderFromRequest();
foreach ($files as $row => $files) {
foreach ($files ?? [] as $file) {
if ($file && is_file($file)) {
$fileName = $this->getFileName($file);
$file->storeAs($this->getPath(), $fileName, $this->getDisk());
$fileOrder[$row][] = $this->getPath().$fileName;
}
}
}
// create a temporary variable that we can unset keys
// everytime one is found. That way we avoid iterating
// already handled keys (notice we do a deep array copy)
$tempFileOrder = array_map(function ($item) {
return $item;
}, $fileOrder);
foreach ($previousRepeatableValues as $previousRow => $previousFiles) {
foreach ($previousFiles ?? [] as $key => $file) {
$previousFileInArray = array_filter($tempFileOrder, function ($items, $key) use ($file, $tempFileOrder) {
$found = array_search($file, $items ?? [], true);
if ($found !== false) {
Arr::forget($tempFileOrder, $key.'.'.$found);
return true;
}
return false;
}, ARRAY_FILTER_USE_BOTH);
if ($file && ! $previousFileInArray) {
Storage::disk($this->getDisk())->delete($file);
}
}
}
return $fileOrder;
}
public function hasDeletedFiles($value): bool
{
return empty($this->getFilesToDeleteFromRequest()) ? false : true;
}
public function getEntryAttributeValue(Model $entry)
{
$value = $entry->{$this->getAttributeName()};
return isset($entry->getCasts()[$this->getName()]) ? $value : json_encode($value);
}
private function getFilesToDeleteFromRequest(): array
{
return collect(CRUD::getRequest()->get('clear_'.$this->getNameForRequest()))->flatten()->toArray();
}
}