17
17
use Drupal \Core \Render \RenderContext ;
18
18
use Drupal \Core \Render \RendererInterface ;
19
19
use Drupal \Core \Session \AccountProxyInterface ;
20
+ use Drupal \Core \StringTranslation \ByteSizeMarkup ;
20
21
use Drupal \Core \StringTranslation \StringTranslationTrait ;
21
22
use Drupal \Core \Utility \Token ;
22
23
use Drupal \file \FileInterface ;
24
+ use Drupal \file \Validation \FileValidatorInterface ;
23
25
use Drupal \graphql \GraphQL \Response \FileUploadResponse ;
24
26
use Symfony \Component \EventDispatcher \EventDispatcherInterface ;
25
27
use Symfony \Component \HttpFoundation \File \UploadedFile ;
@@ -111,6 +113,13 @@ class FileUpload {
111
113
*/
112
114
protected $ imageFactory ;
113
115
116
+ /**
117
+ * The file validator service.
118
+ *
119
+ * @var \Drupal\file\Validation\FileValidatorInterface
120
+ */
121
+ protected FileValidatorInterface $ fileValidator ;
122
+
114
123
/**
115
124
* Constructor.
116
125
*/
@@ -126,6 +135,7 @@ public function __construct(
126
135
RendererInterface $ renderer ,
127
136
EventDispatcherInterface $ eventDispatcher ,
128
137
ImageFactory $ image_factory ,
138
+ FileValidatorInterface $ file_validator ,
129
139
) {
130
140
/** @var \Drupal\file\FileStorageInterface $file_storage */
131
141
$ file_storage = $ entityTypeManager ->getStorage ('file ' );
@@ -140,6 +150,7 @@ public function __construct(
140
150
$ this ->renderer = $ renderer ;
141
151
$ this ->eventDispatcher = $ eventDispatcher ;
142
152
$ this ->imageFactory = $ image_factory ;
153
+ $ this ->fileValidator = $ file_validator ;
143
154
}
144
155
145
156
/**
@@ -193,10 +204,7 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
193
204
switch ($ uploaded_file ->getError ()) {
194
205
case UPLOAD_ERR_INI_SIZE :
195
206
case UPLOAD_ERR_FORM_SIZE :
196
- // @todo Drupal 10.1 compatibility, needs to be converted to
197
- // ByteSizeMarkup later.
198
- // @phpstan-ignore-next-line
199
- $ maxUploadSize = format_size ($ this ->getMaxUploadSize ($ settings ));
207
+ $ maxUploadSize = ByteSizeMarkup::create ($ this ->getMaxUploadSize ($ settings ));
200
208
$ response ->addViolation ($ this ->t ('The file @file could not be saved because it exceeds @maxsize, the maximum allowed size for uploads. ' , [
201
209
'@file ' => $ uploaded_file ->getClientOriginalName (),
202
210
'@maxsize ' => $ maxUploadSize ,
@@ -248,8 +256,8 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
248
256
249
257
$ temp_file_path = $ uploaded_file ->getRealPath ();
250
258
251
- // Drupal 10.2 compatibility: use the deprecated constant for now.
252
- // @phpstan-ignore-next-line
259
+ // Drupal 10.3 compatibility: use the deprecated constant for now.
260
+ // @phpstan-ignore-next-line as it is deprecated in D12.
253
261
$ file_uri = $ this ->fileSystem ->getDestinationFilename ($ file_uri , FileSystemInterface::EXISTS_RENAME );
254
262
255
263
// Lock based on the prepared file URI.
@@ -272,11 +280,17 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
272
280
// before it is saved.
273
281
$ file ->setSize (@filesize ($ temp_file_path ));
274
282
275
- // Validate against file_validate() first with the temporary path.
276
- // @todo Drupal 10.1 compatibility, needs to be converted to file validate
277
- // service later.
278
- // @phpstan-ignore-next-line
279
- $ errors = file_validate ($ file , $ validators );
283
+ // Validate against fileValidator first with the temporary path.
284
+ /** @var \Symfony\Component\Validator\ConstraintViolationListInterface $file_validate_errors */
285
+ $ file_validate_errors = $ this ->fileValidator ->validate ($ file , $ validators );
286
+ $ errors = [];
287
+ if (count ($ file_validate_errors ) > 0 ) {
288
+ foreach ($ file_validate_errors as $ violation ) {
289
+ $ errors [] = $ violation ->getMessage ();
290
+ }
291
+ }
292
+
293
+ // Validate Image resolution.
280
294
$ maxResolution = $ settings ['max_resolution ' ] ?? 0 ;
281
295
$ minResolution = $ settings ['min_resolution ' ] ?? 0 ;
282
296
if (!empty ($ maxResolution ) || !empty ($ minResolution )) {
@@ -287,14 +301,13 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
287
301
$ response ->addViolations ($ errors );
288
302
return $ response ;
289
303
}
290
-
291
304
$ file ->setFileUri ($ file_uri );
292
305
// Move the file to the correct location after validation. Use
293
306
// FileSystemInterface::EXISTS_ERROR as the file location has already been
294
307
// determined above in FileSystem::getDestinationFilename().
295
308
try {
296
- // Drupal 10.2 compatibility: use the deprecated constant for now.
297
- // @phpstan-ignore-next-line
309
+ // Drupal 10.3 compatibility: use the deprecated constant for now.
310
+ // @phpstan-ignore-next-line as it is deprecated in D12.
298
311
$ this ->fileSystem ->move ($ temp_file_path , $ file_uri , FileSystemInterface::EXISTS_ERROR );
299
312
}
300
313
catch (FileException $ e ) {
@@ -315,7 +328,6 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi
315
328
}
316
329
317
330
$ file ->save ();
318
-
319
331
$ response ->setFileEntity ($ file );
320
332
return $ response ;
321
333
}
@@ -487,12 +499,12 @@ protected function validateFileImageResolution(FileInterface $file, $maximum_dim
487
499
protected function prepareFilename (string $ filename , array &$ validators ): string {
488
500
// Don't rename if 'allow_insecure_uploads' evaluates to TRUE.
489
501
if (!$ this ->systemFileConfig ->get ('allow_insecure_uploads ' )) {
490
- if (!empty ($ validators ['file_validate_extensions ' ][0 ])) {
491
- // If there is a file_validate_extensions validator and a list of
492
- // valid extensions, munge the filename to protect against possible
493
- // malicious extension hiding within an unknown file type. For example,
494
- // "filename.html.foo".
495
- $ event = new FileUploadSanitizeNameEvent ($ filename , $ validators ['file_validate_extensions ' ][0 ]);
502
+ if (!empty ($ validators ['FileExtension ' ][' extensions ' ])) {
503
+ // If there is a fileValidator service to validate FileExtension and
504
+ // a list of valid extensions, munge the filename to protect against
505
+ // possible malicious extension hiding within an unknown file type.
506
+ // For example, "filename.html.foo".
507
+ $ event = new FileUploadSanitizeNameEvent ($ filename , $ validators ['FileExtension ' ][' extensions ' ]);
496
508
$ this ->eventDispatcher ->dispatch ($ event );
497
509
$ filename = $ event ->getFilename ();
498
510
}
@@ -502,33 +514,30 @@ protected function prepareFilename(string $filename, array &$validators): string
502
514
// and filename._php.txt, respectively).
503
515
if (preg_match (FileSystemInterface::INSECURE_EXTENSION_REGEX , $ filename )) {
504
516
// If the file will be rejected anyway due to a disallowed extension, it
505
- // should not be renamed; rather, we'll let file_validate_extensions()
506
- // reject it below.
517
+ // should not be renamed; rather, we'll let fileValidator service
518
+ // to validate FileExtension reject it below.
507
519
$ passes_validation = FALSE ;
508
- if (!empty ($ validators ['file_validate_extensions ' ][0 ])) {
520
+ if (!empty ($ validators ['FileExtension ' ][' extensions ' ])) {
509
521
/** @var \Drupal\file\FileInterface $file */
510
522
$ file = $ this ->fileStorage ->create ([]);
511
523
$ file ->setFilename ($ filename );
512
- // @todo Drupal 10.1 compatibility, needs to be converted to file
513
- // validator service later.
514
- // @phpstan-ignore-next-line
515
- $ passes_validation = empty (file_validate_extensions ($ file , $ validators ['file_validate_extensions ' ][0 ]));
524
+ $ passes_validation = count ($ this ->fileValidator ->validate ($ file , $ validators ['FileExtension ' ]['extensions ' ]));
516
525
}
517
- if (empty ($ validators ['file_validate_extensions ' ][0 ]) || $ passes_validation ) {
526
+ if (empty ($ validators ['FileExtension ' ][' extensions ' ]) || ( $ passes_validation > 0 ) ) {
518
527
if ((substr ($ filename , -4 ) != '.txt ' )) {
519
528
// The destination filename will also later be used to create the
520
529
// URI.
521
530
$ filename .= '.txt ' ;
522
531
}
523
532
524
- $ event = new FileUploadSanitizeNameEvent ($ filename , $ validators ['file_validate_extensions ' ][0 ] ?? '' );
533
+ $ event = new FileUploadSanitizeNameEvent ($ filename , $ validators ['FileExtension ' ][' extensions ' ] ?? '' );
525
534
$ this ->eventDispatcher ->dispatch ($ event );
526
535
$ filename = $ event ->getFilename ();
527
536
528
537
// The .txt extension may not be in the allowed list of extensions. We
529
538
// have to add it here or else the file upload will fail.
530
- if (!empty ($ validators ['file_validate_extensions ' ][0 ])) {
531
- $ validators ['file_validate_extensions ' ][0 ] .= ' txt ' ;
539
+ if (!empty ($ validators ['FileExtension ' ][' extensions ' ])) {
540
+ $ validators ['FileExtension ' ][' extensions ' ] .= ' txt ' ;
532
541
}
533
542
}
534
543
}
@@ -579,7 +588,7 @@ protected function getUploadLocation(array $settings): string {
579
588
protected function getUploadValidators (array $ settings ): array {
580
589
$ validators = [
581
590
// Add in our check of the file name length.
582
- 'file_validate_name_length ' => [],
591
+ 'FileNameLength ' => [],
583
592
];
584
593
585
594
// Cap the upload size according to the PHP limit.
@@ -589,11 +598,11 @@ protected function getUploadValidators(array $settings): array {
589
598
}
590
599
591
600
// There is always a file size limit due to the PHP server limit.
592
- $ validators ['file_validate_size ' ] = [$ max_filesize ];
601
+ $ validators ['FileSizeLimit ' ] = [' fileLimit ' => $ max_filesize ];
593
602
594
603
// Add the extension check if necessary.
595
604
if (!empty ($ settings ['file_extensions ' ])) {
596
- $ validators ['file_validate_extensions ' ] = [$ settings ['file_extensions ' ]];
605
+ $ validators ['FileExtension ' ] = [' extensions ' => $ settings ['file_extensions ' ]];
597
606
}
598
607
599
608
return $ validators ;
0 commit comments