Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Validation\Rules;
4
 
5
use Illuminate\Contracts\Validation\DataAwareRule;
6
use Illuminate\Contracts\Validation\Rule;
7
use Illuminate\Contracts\Validation\ValidatorAwareRule;
8
use Illuminate\Support\Arr;
9
use Illuminate\Support\Facades\Validator;
10
use Illuminate\Support\Traits\Conditionable;
11
use Illuminate\Support\Traits\Macroable;
12
use InvalidArgumentException;
13
 
14
class File implements Rule, DataAwareRule, ValidatorAwareRule
15
{
16
    use Conditionable;
17
    use Macroable;
18
 
19
    /**
20
     * The MIME types that the given file should match. This array may also contain file extensions.
21
     *
22
     * @var array
23
     */
24
    protected $allowedMimetypes = [];
25
 
26
    /**
27
     * The minimum size in kilobytes that the file can be.
28
     *
29
     * @var null|int
30
     */
31
    protected $minimumFileSize = null;
32
 
33
    /**
34
     * The maximum size in kilobytes that the file can be.
35
     *
36
     * @var null|int
37
     */
38
    protected $maximumFileSize = null;
39
 
40
    /**
41
     * An array of custom rules that will be merged into the validation rules.
42
     *
43
     * @var array
44
     */
45
    protected $customRules = [];
46
 
47
    /**
48
     * The error message after validation, if any.
49
     *
50
     * @var array
51
     */
52
    protected $messages = [];
53
 
54
    /**
55
     * The data under validation.
56
     *
57
     * @var array
58
     */
59
    protected $data;
60
 
61
    /**
62
     * The validator performing the validation.
63
     *
64
     * @var \Illuminate\Validation\Validator
65
     */
66
    protected $validator;
67
 
68
    /**
69
     * The callback that will generate the "default" version of the file rule.
70
     *
71
     * @var string|array|callable|null
72
     */
73
    public static $defaultCallback;
74
 
75
    /**
76
     * Set the default callback to be used for determining the file default rules.
77
     *
78
     * If no arguments are passed, the default file rule configuration will be returned.
79
     *
80
     * @param  static|callable|null  $callback
81
     * @return static|null
82
     */
83
    public static function defaults($callback = null)
84
    {
85
        if (is_null($callback)) {
86
            return static::default();
87
        }
88
 
89
        if (! is_callable($callback) && ! $callback instanceof static) {
90
            throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);
91
        }
92
 
93
        static::$defaultCallback = $callback;
94
    }
95
 
96
    /**
97
     * Get the default configuration of the file rule.
98
     *
99
     * @return static
100
     */
101
    public static function default()
102
    {
103
        $file = is_callable(static::$defaultCallback)
104
            ? call_user_func(static::$defaultCallback)
105
            : static::$defaultCallback;
106
 
107
        return $file instanceof Rule ? $file : new self();
108
    }
109
 
110
    /**
111
     * Limit the uploaded file to only image types.
112
     *
113
     * @return ImageFile
114
     */
115
    public static function image()
116
    {
117
        return new ImageFile();
118
    }
119
 
120
    /**
121
     * Limit the uploaded file to the given MIME types or file extensions.
122
     *
123
     * @param  string|array<int, string>  $mimetypes
124
     * @return static
125
     */
126
    public static function types($mimetypes)
127
    {
128
        return tap(new static(), fn ($file) => $file->allowedMimetypes = (array) $mimetypes);
129
    }
130
 
131
    /**
132
     * Indicate that the uploaded file should be exactly a certain size in kilobytes.
133
     *
134
     * @param  int  $kilobytes
135
     * @return $this
136
     */
137
    public function size($kilobytes)
138
    {
139
        $this->minimumFileSize = $kilobytes;
140
        $this->maximumFileSize = $kilobytes;
141
 
142
        return $this;
143
    }
144
 
145
    /**
146
     * Indicate that the uploaded file should be between a minimum and maximum size in kilobytes.
147
     *
148
     * @param  int  $minKilobytes
149
     * @param  int  $maxKilobytes
150
     * @return $this
151
     */
152
    public function between($minKilobytes, $maxKilobytes)
153
    {
154
        $this->minimumFileSize = $minKilobytes;
155
        $this->maximumFileSize = $maxKilobytes;
156
 
157
        return $this;
158
    }
159
 
160
    /**
161
     * Indicate that the uploaded file should be no less than the given number of kilobytes.
162
     *
163
     * @param  int  $kilobytes
164
     * @return $this
165
     */
166
    public function min($kilobytes)
167
    {
168
        $this->minimumFileSize = $kilobytes;
169
 
170
        return $this;
171
    }
172
 
173
    /**
174
     * Indicate that the uploaded file should be no more than the given number of kilobytes.
175
     *
176
     * @param  int  $kilobytes
177
     * @return $this
178
     */
179
    public function max($kilobytes)
180
    {
181
        $this->maximumFileSize = $kilobytes;
182
 
183
        return $this;
184
    }
185
 
186
    /**
187
     * Specify additional validation rules that should be merged with the default rules during validation.
188
     *
189
     * @param  string|array  $rules
190
     * @return $this
191
     */
192
    public function rules($rules)
193
    {
194
        $this->customRules = array_merge($this->customRules, Arr::wrap($rules));
195
 
196
        return $this;
197
    }
198
 
199
    /**
200
     * Determine if the validation rule passes.
201
     *
202
     * @param  string  $attribute
203
     * @param  mixed  $value
204
     * @return bool
205
     */
206
    public function passes($attribute, $value)
207
    {
208
        $this->messages = [];
209
 
210
        $validator = Validator::make(
211
            $this->data,
212
            [$attribute => $this->buildValidationRules()],
213
            $this->validator->customMessages,
214
            $this->validator->customAttributes
215
        );
216
 
217
        if ($validator->fails()) {
218
            return $this->fail($validator->messages()->all());
219
        }
220
 
221
        return true;
222
    }
223
 
224
    /**
225
     * Build the array of underlying validation rules based on the current state.
226
     *
227
     * @return array
228
     */
229
    protected function buildValidationRules()
230
    {
231
        $rules = ['file'];
232
 
233
        $rules = array_merge($rules, $this->buildMimetypes());
234
 
235
        $rules[] = match (true) {
236
            is_null($this->minimumFileSize) && is_null($this->maximumFileSize) => null,
237
            is_null($this->maximumFileSize) => "min:{$this->minimumFileSize}",
238
            is_null($this->minimumFileSize) => "max:{$this->maximumFileSize}",
239
            $this->minimumFileSize !== $this->maximumFileSize => "between:{$this->minimumFileSize},{$this->maximumFileSize}",
240
            default => "size:{$this->minimumFileSize}",
241
        };
242
 
243
        return array_merge(array_filter($rules), $this->customRules);
244
    }
245
 
246
    /**
247
     * Separate the given mimetypes from extensions and return an array of correct rules to validate against.
248
     *
249
     * @return array
250
     */
251
    protected function buildMimetypes()
252
    {
253
        if (count($this->allowedMimetypes) === 0) {
254
            return [];
255
        }
256
 
257
        $rules = [];
258
 
259
        $mimetypes = array_filter(
260
            $this->allowedMimetypes,
261
            fn ($type) => str_contains($type, '/')
262
        );
263
 
264
        $mimes = array_diff($this->allowedMimetypes, $mimetypes);
265
 
266
        if (count($mimetypes) > 0) {
267
            $rules[] = 'mimetypes:'.implode(',', $mimetypes);
268
        }
269
 
270
        if (count($mimes) > 0) {
271
            $rules[] = 'mimes:'.implode(',', $mimes);
272
        }
273
 
274
        return $rules;
275
    }
276
 
277
    /**
278
     * Adds the given failures, and return false.
279
     *
280
     * @param  array|string  $messages
281
     * @return bool
282
     */
283
    protected function fail($messages)
284
    {
285
        $messages = collect(Arr::wrap($messages))->map(function ($message) {
286
            return $this->validator->getTranslator()->get($message);
287
        })->all();
288
 
289
        $this->messages = array_merge($this->messages, $messages);
290
 
291
        return false;
292
    }
293
 
294
    /**
295
     * Get the validation error message.
296
     *
297
     * @return array
298
     */
299
    public function message()
300
    {
301
        return $this->messages;
302
    }
303
 
304
    /**
305
     * Set the current validator.
306
     *
307
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
308
     * @return $this
309
     */
310
    public function setValidator($validator)
311
    {
312
        $this->validator = $validator;
313
 
314
        return $this;
315
    }
316
 
317
    /**
318
     * Set the current data under validation.
319
     *
320
     * @param  array  $data
321
     * @return $this
322
     */
323
    public function setData($data)
324
    {
325
        $this->data = $data;
326
 
327
        return $this;
328
    }
329
}