Completed
Push — master ( cd56b1...82f5c2 )
by wen
02:47
created

File::getDefaultUploadPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Sco\Admin\Form\Elements;
4
5
use Illuminate\Http\UploadedFile;
6
use Illuminate\Support\Str;
7
use Storage;
8
use Validator;
9
10
class File extends NamedElement
11
{
12
    protected $type = 'file';
13
14
    protected $actionUrl;
15
16
    protected $multiSelect = false;
17
18
    protected $multiFile = true;
19
20
    protected $showFileList = true;
21
22
    protected $withCredentials = false;
23
24
    protected $maxFileSize;
25
26
    protected $fileUploadsLimit = 0;
27
28
    protected $fileExtensions;
29
30
    protected $listType = 'text';
31
32
    protected $disk;
33
34
    /**
35
     * @var string|\Closure|null
36
     */
37
    protected $uploadPath;
38
39
    /**
40
     * @var \Closure|null
41
     */
42
    protected $uploadFileNameRule;
43
44
    protected $uploadValidationRules = ['bail', 'file'];
45
46
    protected $uploadValidationMessages = [];
47
48
    public function getValue()
49
    {
50
        $value = parent::getValue();
51
        if (empty($value)) {
52
            return [];
53
        }
54
        return collect(explode(',', $value))->filter(function ($item) {
55
            return $this->existsFile($item);
56
        })->map(function ($item) {
57
            return $this->getFileInfo($item);
58
        });
59
    }
60
61
    public function getActionUrl()
62
    {
63
        if ($this->actionUrl) {
64
            return $this->actionUrl;
65
        }
66
        $model = app('admin.components')->get(get_class($this->getModel()));
67
68
        $params       = [
69
            'model' => $model->getName(),
70
            'field' => $this->getName(),
71
        ];
72
        $params['id'] = null;
73
        if ($this->getModel()->exists) {
74
            $params['id'] = $this->getModel()->getKey();
75
        }
76
        $params['_token'] = csrf_token();
77
78
        return route('admin.model.upload.file', $params);
79
    }
80
81
    public function setActionUrl($value)
82
    {
83
        $this->actionUrl = $value;
84
85
        return $this;
86
    }
87
88
    public function isMultiSelect()
89
    {
90
        return $this->multiSelect;
91
    }
92
93
    public function enableMultiSelect()
94
    {
95
        $this->multiSelect = true;
96
97
        return $this;
98
    }
99
100
    /**
101
     * Show file list
102
     *
103
     * @return $this
104
     */
105
    public function disableFileList()
106
    {
107
        $this->showFileList = false;
108
109
        return $this;
110
    }
111
112
    /**
113
     * Indicates whether or not cross-site Access-Control requests
114
     * should be made using credentials
115
     *
116
     * @return $this
117
     */
118
    public function withCredentials()
119
    {
120
        $this->withCredentials = true;
121
122
        return $this;
123
    }
124
125
    /**
126
     * The maximum size of an uploaded file in bytes
127
     * If didn't set maximum size, return maximum size as configured in php.ini.
128
     *
129
     * @return int
130
     */
131
    public function getMaxFileSize()
132
    {
133
        $size = UploadedFile::getMaxFilesize();
134
        if ($this->maxFileSize) {
135
            $size = $this->maxFileSize;
136
        }
137
        $this->addValidationRule('max:' . $size);
138
        return $size;
139
    }
140
141
    /**
142
     * The maximum size allowed for an uploaded file in bytes
143
     *
144
     * @param int $value
145
     *
146
     * @return $this
147
     */
148
    public function setMaxFileSize($value)
149
    {
150
        $this->maxFileSize = intval($value);
151
152
        return $this;
153
    }
154
155
    public function getFileExtensions()
156
    {
157
        $exts = $this->getDefaultExtensions();
158
        if ($this->fileExtensions) {
159
            $exts = $this->fileExtensions;
160
        }
161
        $this->addValidationRule('mimes:' . $exts);
162
        return $exts;
163
    }
164
165
    /**
166
     * A list of allowable extensions that can be uploaded.
167
     *
168
     * @param string $value
169
     *
170
     * @return $this
171
     */
172
    public function setFileExtensions($value)
173
    {
174
        $this->fileExtensions = $value;
175
176
        return $this;
177
    }
178
179
    protected function getDefaultExtensions()
180
    {
181
        return config('admin.upload.extensions.file');
182
    }
183
184
    public function getFileUploadsLimit()
185
    {
186
        return $this->fileUploadsLimit;
187
    }
188
189
    /**
190
     * The maximum number of files that can be uploaded.
191
     *
192
     * @param int $value
193
     *
194
     * @return $this
195
     */
196
    public function setFileUploadsLimit($value)
197
    {
198
        $this->fileUploadsLimit = intval($value);
199
200
        return $this;
201
    }
202
203
    public function getListType()
204
    {
205
        return $this->listType;
206
    }
207
208
    public function toArray()
209
    {
210
        return parent::toArray() + [
211
                'action'           => $this->getActionUrl(),
212
                'showFileList'     => $this->showFileList,
213
                'multiSelect'      => $this->isMultiSelect(),
214
                'maxFileSize'      => $this->getMaxFileSize(),
215
                'fileUploadsLimit' => $this->getFileUploadsLimit(),
216
                'fileExtensions'   => $this->getFileExtensions(),
217
                'listType'         => $this->getListType(),
218
            ];
219
    }
220
221
    public function getDisk()
222
    {
223
        if ($this->disk) {
224
            return $this->disk;
225
        }
226
227
        return config('admin.upload.disk', 'public');
228
    }
229
230
    public function setDisk($value)
231
    {
232
        $this->disk = $value;
233
234
        return $this;
235
    }
236
237
    protected function getDefaultUploadPath(UploadedFile $file)
0 ignored issues
show
Unused Code introduced by
The parameter $file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
238
    {
239
        return config('admin.upload.directory', 'admin/uploads');
240
    }
241
242
    public function getUploadPath(UploadedFile $file)
243
    {
244
        if (!($path = $this->uploadPath)) {
245
            $path = $this->getDefaultUploadPath($file);
246
        }
247
        if (is_callable($path)) {
248
            return call_user_func($path, $file);
249
        }
250
251
        return $path;
252
    }
253
254
    /**
255
     * The path of file save
256
     *
257
     * @param string|\Closure $value
258
     *
259
     * @return $this
260
     */
261
    public function setUploadPath($value)
262
    {
263
        $this->uploadPath = $value;
264
265
        return $this;
266
    }
267
268
    public function getUploadFileName(UploadedFile $file)
269
    {
270
        if (is_callable($this->uploadFileNameRule)) {
271
            return call_user_func($this->uploadFileNameRule, $file);
272
        }
273
274
        return $this->getDefaultFileName($file);
275
    }
276
277
    protected function getDefaultFileName(UploadedFile $file)
278
    {
279
        $hash = Str::random(40);
280
        return $hash . '.' . $file->guessExtension();
281
    }
282
283
    public function setUploadFileNameRule(\Closure $value)
284
    {
285
        $this->uploadFileNameRule = $value;
286
287
        return $this;
288
    }
289
290
    public function saveFile(UploadedFile $file)
291
    {
292
        Validator::validate(
293
            [$this->getName() => $file],
294
            $this->getUploadValidationRules(),
295
            $this->getUploadValidationMessages(),
296
            $this->getUploadValidationTitles()
297
        );
298
299
        $path = $file->storeAs(
300
            $this->getUploadPath($file),
301
            $this->getUploadFileName($file),
302
            $this->getDisk()
303
        );
304
305
        return $this->getFileInfo($path);
306
    }
307
308
    protected function prepareValue($value)
309
    {
310
        if (empty($value) || !is_array($value)) {
311
            return '';
312
        }
313
        return collect($value)->implode('path', ',');
314
    }
315
316
    protected function existsFile($path)
317
    {
318
        return Storage::disk($this->getDisk())->exists($path);
319
    }
320
321
    protected function getFileUrl($path)
322
    {
323
        return Storage::disk($this->getDisk())->url($path);
324
    }
325
326
    protected function getFileInfo($path)
327
    {
328
        return [
329
            'name' => substr($path, strrpos($path, '/') + 1),
330
            'path' => $path,
331
            'url' => $this->getFileUrl($path),
332
        ];
333
    }
334
335
    public function addValidationRule($rule, $message = null)
336
    {
337
        $uploadRules = ['image', 'mimes', 'size', 'dimensions', 'max', 'min', 'between'];
338
        list($name,) = explode(':', $rule, 2);
339
        if (in_array($name, $uploadRules)) {
340
            return $this->addUploadValidationRule($rule, $message);
341
        }
342
343
        return parent::addValidationRule($rule, $message);
344
    }
345
346
    public function addUploadValidationRule($rule, $message = null)
347
    {
348
        $this->uploadValidationRules[] = $rule;
349
350
        if (is_null($message)) {
351
            return $this;
352
        }
353
        return $this->addUploadValidationMessage($rule, $message);
354
    }
355
356 View Code Duplication
    public function addUploadValidationMessage($rule, $message)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
357
    {
358
        if (($pos = strpos($rule, ':')) !== false) {
359
            $rule = substr($rule, 0, $pos);
360
        }
361
362
        $this->uploadValidationMessages[$this->getName() . '.' . $rule] = $message;
363
364
        return $this;
365
    }
366
367
    public function getUploadValidationRules()
368
    {
369
        return [$this->getName() => $this->uploadValidationRules];
370
    }
371
372
    public function getUploadValidationMessages()
373
    {
374
        return $this->uploadValidationMessages;
375
    }
376
377
    public function getUploadValidationTitles()
378
    {
379
        return $this->getValidationTitles();
380
    }
381
}
382