From 08c0efdfb38bd99c12f68132641007335e063988 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Tue, 2 Apr 2024 09:18:32 +0100 Subject: [PATCH] Issue #3432882 by kim.pepper, Satane, andypost, alexpott, longwave: Removed deprecated code in File module (core/module/file) --- core/.phpstan-baseline.php | 5 - .../Controller/CKEditor5ImageController.php | 2 +- core/modules/file/file.api.php | 4 +- core/modules/file/file.module | 374 +----------------- core/modules/file/src/Element/ManagedFile.php | 10 +- .../src/Plugin/Field/FieldType/FileItem.php | 3 +- .../rest/resource/FileUploadResource.php | 63 +-- .../file/src/Upload/FileUploadHandler.php | 139 +------ .../file/src/Upload/FormUploadedFile.php | 42 -- .../file/src/Upload/UploadedFileInterface.php | 44 --- .../file/src/Validation/FileValidator.php | 48 +-- .../src/Functional/SaveUploadFormTest.php | 2 +- .../tests/src/Kernel/FileSaveUploadTest.php | 70 ---- .../src/Kernel/FileUploadHandlerTest.php | 41 +- .../tests/src/Kernel/LegacyFileModuleTest.php | 50 --- .../tests/src/Kernel/LegacyFileThemeTest.php | 48 --- .../tests/src/Kernel/LegacyValidateTest.php | 59 --- .../tests/src/Kernel/LegacyValidatorTest.php | 255 ------------ .../Upload/LegacyFileUploadHandlerTest.php | 39 -- .../Kernel/Validation/FileValidatorTest.php | 16 +- 20 files changed, 33 insertions(+), 1281 deletions(-) delete mode 100644 core/modules/file/tests/src/Kernel/FileSaveUploadTest.php delete mode 100644 core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php delete mode 100644 core/modules/file/tests/src/Kernel/LegacyFileThemeTest.php delete mode 100644 core/modules/file/tests/src/Kernel/LegacyValidateTest.php delete mode 100644 core/modules/file/tests/src/Kernel/LegacyValidatorTest.php delete mode 100644 core/modules/file/tests/src/Kernel/Upload/LegacyFileUploadHandlerTest.php diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 96be90402611..65d4b5c62420 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -826,11 +826,6 @@ 'count' => 1, 'path' => __DIR__ . '/modules/file/file.module', ]; -$ignoreErrors[] = [ - 'message' => '#^Variable \\$message might not be defined\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/modules/file/file.module', -]; $ignoreErrors[] = [ 'message' => '#^Variable \\$rows in empty\\(\\) always exists and is not falsy\\.$#', 'count' => 1, diff --git a/core/modules/ckeditor5/src/Controller/CKEditor5ImageController.php b/core/modules/ckeditor5/src/Controller/CKEditor5ImageController.php index 43f4d9b44cfc..733d60866b3c 100644 --- a/core/modules/ckeditor5/src/Controller/CKEditor5ImageController.php +++ b/core/modules/ckeditor5/src/Controller/CKEditor5ImageController.php @@ -149,7 +149,7 @@ public function upload(Request $request): Response { try { $uploadedFile = new FormUploadedFile($upload); - $uploadResult = $this->fileUploadHandler->handleFileUpload($uploadedFile, $validators, $destination, FileSystemInterface::EXISTS_RENAME, FALSE); + $uploadResult = $this->fileUploadHandler->handleFileUpload($uploadedFile, $validators, $destination, FileSystemInterface::EXISTS_RENAME); if ($uploadResult->hasViolations()) { throw new UnprocessableEntityHttpException((string) $uploadResult->getViolations()); } diff --git a/core/modules/file/file.api.php b/core/modules/file/file.api.php index fa86532f7c48..f0e2eff6430f 100644 --- a/core/modules/file/file.api.php +++ b/core/modules/file/file.api.php @@ -27,8 +27,8 @@ * '#type' => 'file', * '#title' => $this->t('Upload file'), * '#upload_validators' => [ - * 'file_validate_extensions' => [ - * 'png gif jpg', + * 'FileExtension' => [ + * 'extensions' => 'png gif jpg', * ], * ], * ]; diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 525c8b15d5c4..184221455d32 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -68,289 +68,6 @@ function file_field_widget_info_alter(array &$info) { $info['uri']['field_types'][] = 'file_uri'; } -/** - * Checks that a file meets the criteria specified by the validators. - * - * After executing the validator callbacks specified hook_file_validate() will - * also be called to allow other modules to report errors about the file. - * - * @param \Drupal\file\FileInterface $file - * A file entity. - * @param array $validators - * (optional) An associative array of callback functions used to validate - * the file. The keys are function names and the values arrays of callback - * parameters which will be passed in after the file entity. The functions - * should return an array of error messages; an empty array indicates that - * the file passed validation. The callback functions will be called in the - * order specified in the array, then the hook hook_file_validate() - * will be invoked so other modules can validate the new file. - * - * @return array - * An array containing validation error messages. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - */ -function file_validate(FileInterface $file, $validators = []) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $violations = \Drupal::service('file.validator')->validate($file, $validators); - $errors = []; - foreach ($violations as $violation) { - $errors[] = $violation->getMessage(); - } - return $errors; -} - -/** - * Checks for files with names longer than can be stored in the database. - * - * @param \Drupal\file\FileInterface $file - * A file entity. - * - * @return array - * An empty array if the file name length is smaller than the limit or an - * array containing an error message if it's not or is empty. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - */ -function file_validate_name_length(FileInterface $file) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $errors = []; - - if (!$file->getFilename()) { - $errors[] = t("The file's name is empty. Enter a name for the file."); - } - if (strlen($file->getFilename()) > 240) { - $errors[] = t("The file's name exceeds the 240 characters limit. Rename the file and try again."); - } - return $errors; -} - -/** - * Checks that the filename ends with an allowed extension. - * - * @param \Drupal\file\FileInterface $file - * A file entity. - * @param string $extensions - * A string with a space separated list of allowed extensions. - * - * @return array - * An empty array if the file extension is allowed or an array containing an - * error message if it's not. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - * @see hook_file_validate() - */ -function file_validate_extensions(FileInterface $file, $extensions) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $errors = []; - - $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote($extensions)) . ')$/i'; - // Filename may differ from the basename, for instance in case files migrated - // from D7 file entities. Because of that new files are saved temporarily with - // a generated file name, without the original extension, we will use the - // generated filename property for extension validation only in case of - // temporary files; and use the file system file name in case of permanent - // files. - $subject = $file->isTemporary() ? $file->getFilename() : $file->getFileUri(); - if (!preg_match($regex, $subject)) { - $errors[] = t('Only files with the following extensions are allowed: %files-allowed.', ['%files-allowed' => $extensions]); - } - return $errors; -} - -/** - * Checks that the file's size is below certain limits. - * - * @param \Drupal\file\FileInterface $file - * A file entity. - * @param int $file_limit - * (optional) The maximum file size in bytes. Zero (the default) indicates - * that no limit should be enforced. - * @param int $user_limit - * (optional) The maximum number of bytes the user is allowed. Zero (the - * default) indicates that no limit should be enforced. - * - * @return array - * An empty array if the file size is below limits or an array containing an - * error message if it's not. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - * @see hook_file_validate() - */ -function file_validate_size(FileInterface $file, $file_limit = 0, $user_limit = 0) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $user = \Drupal::currentUser(); - $errors = []; - - if ($file_limit && $file->getSize() > $file_limit) { - $errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', [ - '%filesize' => ByteSizeMarkup::create($file->getSize()), - '%maxsize' => ByteSizeMarkup::create($file_limit), - ]); - } - - // Save a query by only calling spaceUsed() when a limit is provided. - if ($user_limit && (\Drupal::entityTypeManager()->getStorage('file')->spaceUsed($user->id()) + $file->getSize()) > $user_limit) { - $errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', [ - '%filesize' => ByteSizeMarkup::create($file->getSize()), - '%quota' => ByteSizeMarkup::create($user_limit), - ]); - } - - return $errors; -} - -/** - * Checks that the file is recognized as a valid image. - * - * @param \Drupal\file\FileInterface $file - * A file entity. - * - * @return array - * An empty array if the file is a valid image or an array containing an error - * message if it's not. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - * @see hook_file_validate() - */ -function file_validate_is_image(FileInterface $file) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $errors = []; - - $image_factory = \Drupal::service('image.factory'); - $image = $image_factory->get($file->getFileUri()); - if (!$image->isValid()) { - $supported_extensions = $image_factory->getSupportedExtensions(); - $errors[] = t('The image file is invalid or the image type is not allowed. Allowed types: %types', ['%types' => implode(', ', $supported_extensions)]); - } - - return $errors; -} - -/** - * Verifies that image dimensions are within the specified maximum and minimum. - * - * Non-image files will be ignored. If an image toolkit is available the image - * will be scaled to fit within the desired maximum dimensions. - * - * @param \Drupal\file\FileInterface $file - * A file entity. This function may resize the file affecting its size. - * @param string|int $maximum_dimensions - * (optional) A string in the form WIDTHxHEIGHT; for example, '640x480' or - * '85x85'. If an image toolkit is installed, the image will be resized down - * to these dimensions. A value of zero (the default) indicates no restriction - * on size, so no resizing will be attempted. - * @param string|int $minimum_dimensions - * (optional) A string in the form WIDTHxHEIGHT. This will check that the - * image meets a minimum size. A value of zero (the default) indicates that - * there is no restriction on size. - * - * @return array - * An empty array if the file meets the specified dimensions, was resized - * successfully to meet those requirements or is not an image. If the image - * does not meet the requirements or an attempt to resize it fails, an array - * containing the error message will be returned. - * - * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the - * 'file.validator' service instead. - * - * @see https://www.drupal.org/node/3363700 - * @see hook_file_validate() - */ -function file_validate_image_resolution(FileInterface $file, $maximum_dimensions = 0, $minimum_dimensions = 0) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $errors = []; - - // Check first that the file is an image. - $image_factory = \Drupal::service('image.factory'); - $image = $image_factory->get($file->getFileUri()); - - if ($image->isValid()) { - $scaling = FALSE; - if ($maximum_dimensions) { - // Check that it is smaller than the given dimensions. - [$width, $height] = explode('x', $maximum_dimensions); - if ($image->getWidth() > $width || $image->getHeight() > $height) { - // Try to resize the image to fit the dimensions. - if ($image->scale($width, $height)) { - $scaling = TRUE; - $image->save(); - // Update the file size now that the image has been resized. - $file->setSize($image->getFileSize()); - if (!empty($width) && !empty($height)) { - $message = t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels. The new dimensions of the resized image are %new_widthx%new_height pixels.', - [ - '%dimensions' => $maximum_dimensions, - '%new_width' => $image->getWidth(), - '%new_height' => $image->getHeight(), - ]); - } - elseif (empty($width)) { - $message = t('The image was resized to fit within the maximum allowed height of %height pixels. The new dimensions of the resized image are %new_widthx%new_height pixels.', - [ - '%height' => $height, - '%new_width' => $image->getWidth(), - '%new_height' => $image->getHeight(), - ]); - } - elseif (empty($height)) { - $message = t('The image was resized to fit within the maximum allowed width of %width pixels. The new dimensions of the resized image are %new_widthx%new_height pixels.', - [ - '%width' => $width, - '%new_width' => $image->getWidth(), - '%new_height' => $image->getHeight(), - ]); - } - \Drupal::messenger()->addStatus($message); - } - else { - $errors[] = t('The image exceeds the maximum allowed dimensions and an attempt to resize it failed.'); - } - } - } - - if ($minimum_dimensions) { - // Check that it is larger than the given dimensions. - [$width, $height] = explode('x', $minimum_dimensions); - if ($image->getWidth() < $width || $image->getHeight() < $height) { - if ($scaling) { - $errors[] = t('The resized image is too small. The minimum dimensions are %dimensions pixels and after resizing, the image size will be %widthx%height pixels.', - [ - '%dimensions' => $minimum_dimensions, - '%width' => $image->getWidth(), - '%height' => $image->getHeight(), - ]); - } - else { - $errors[] = t('The image is too small. The minimum dimensions are %dimensions pixels and the image size is %widthx%height pixels.', - [ - '%dimensions' => $minimum_dimensions, - '%width' => $image->getWidth(), - '%height' => $image->getHeight(), - ]); - } - } - } - } - - return $errors; -} - /** * Examines a file entity and returns appropriate content headers for download. * @@ -589,7 +306,7 @@ function _file_save_upload_from_form(array $element, FormStateInterface $form_st * If the array is empty, it will be set up to call file_validate_extensions() * with a safe list of extensions, as follows: "jpg jpeg gif png txt doc * xls pdf ppt pps odt ods odp". To allow all extensions, you must explicitly - * set this array to ['file_validate_extensions' => '']. (Beware: this is not + * set this array to ['FileExtension' => []]. (Beware: this is not * safe and should only be allowed for trusted users, if at all.) * @param string|false $destination * (optional) A string containing the URI that the file should be copied to. @@ -661,7 +378,7 @@ function file_save_upload($form_field_name, $validators = [], $destination = FAL continue; } $form_uploaded_file = new FormUploadedFile($uploaded_file); - $result = $file_upload_handler->handleFileUpload($form_uploaded_file, $validators, $destination, $replace, FALSE); + $result = $file_upload_handler->handleFileUpload($form_uploaded_file, $validators, $destination, $replace); if ($result->hasViolations()) { $errors = []; foreach ($result->getViolations() as $violation) { @@ -725,33 +442,6 @@ function file_save_upload($form_field_name, $validators = [], $destination = FAL return isset($delta) ? $files[$delta] : $files; } -/** - * Determines the preferred upload progress implementation. - * - * @return string|false - * A string indicating which upload progress system is available. Either "apc" - * or "uploadprogress". If neither are available, returns FALSE. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * extension_loaded('uploadprogress') instead. - * - * @see https://www.drupal.org/node/3397577 - */ -function file_progress_implementation() { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use extension_loaded(\'uploadprogress\') instead. See https://www.drupal.org/node/3397577', E_USER_DEPRECATED); - static $implementation; - if (!isset($implementation)) { - $implementation = FALSE; - - // We prefer the PECL extension uploadprogress because it supports multiple - // simultaneous uploads. APCu only supports one at a time. - if (extension_loaded('uploadprogress')) { - $implementation = 'uploadprogress'; - } - } - return $implementation; -} - /** * Implements hook_ENTITY_TYPE_predelete() for file entities. */ @@ -1239,32 +929,18 @@ function template_preprocess_file_upload_help(&$variables) { $descriptions[] = \Drupal::translation()->formatPlural($cardinality, 'One file only.', 'Maximum @count files.'); } } - if (isset($upload_validators['file_validate_size'])) { - @trigger_error('\'file_validate_size\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileSizeLimit\' constraint instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $descriptions[] = t('@size limit.', ['@size' => ByteSizeMarkup::create($upload_validators['file_validate_size'][0])]); - } + if (isset($upload_validators['FileSizeLimit'])) { $descriptions[] = t('@size limit.', ['@size' => ByteSizeMarkup::create($upload_validators['FileSizeLimit']['fileLimit'])]); } - if (isset($upload_validators['file_validate_extensions'])) { - @trigger_error('\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $descriptions[] = t('Allowed types: @extensions.', ['@extensions' => $upload_validators['file_validate_extensions'][0]]); - } if (isset($upload_validators['FileExtension'])) { $descriptions[] = t('Allowed types: @extensions.', ['@extensions' => $upload_validators['FileExtension']['extensions']]); } - if (isset($upload_validators['file_validate_image_resolution']) || isset($upload_validators['FileImageDimensions'])) { - if (isset($upload_validators['file_validate_image_resolution'])) { - @trigger_error('\'file_validate_image_resolution\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileImageDimensions\' constraint instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $max = $upload_validators['file_validate_image_resolution'][0]; - $min = $upload_validators['file_validate_image_resolution'][1]; - } - else { - $max = $upload_validators['FileImageDimensions']['maxDimensions']; - $min = $upload_validators['FileImageDimensions']['minDimensions']; - } + if (isset($upload_validators['FileImageDimensions'])) { + $max = $upload_validators['FileImageDimensions']['maxDimensions']; + $min = $upload_validators['FileImageDimensions']['minDimensions']; if ($min && $max && $min == $max) { $descriptions[] = t('Images must be exactly <strong>@size</strong> pixels.', ['@size' => $max]); } @@ -1285,44 +961,6 @@ function template_preprocess_file_upload_help(&$variables) { $variables['descriptions'] = $descriptions; } -/** - * Gets a class for the icon for a MIME type. - * - * @param string $mime_type - * A MIME type. - * - * @return string - * A class associated with the file. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\IconMimeTypes::getIconClass() instead. - * - * @see https://www.drupal.org/node/3411269 - */ -function file_icon_class($mime_type) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getIconClass() instead. See https://www.drupal.org/node/3411269', E_USER_DEPRECATED); - return IconMimeTypes::getIconClass($mime_type); -} - -/** - * Determines the generic icon MIME package based on a file's MIME type. - * - * @param string $mime_type - * A MIME type. - * - * @return string|false - * The generic icon MIME package expected for this file. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\IconMimeTypes::getGenericMimeType() instead. - * - * @see https://www.drupal.org/node/3411269 - */ -function file_icon_map($mime_type) { - @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getGenericMimeType() instead. See https://www.drupal.org/node/3411269', E_USER_DEPRECATED); - return IconMimeTypes::getGenericMimeType($mime_type); -} - /** * Retrieves a list of references to a file. * diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php index 5cc5c43805a7..2d076bfa6819 100644 --- a/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -358,14 +358,8 @@ public static function processManagedFile(&$element, FormStateInterface $form_st } // Add the extension list to the page as JavaScript settings. - if (isset($element['#upload_validators']['file_validate_extensions'][0]) || isset($element['#upload_validators']['FileExtension']['extensions'])) { - if (isset($element['#upload_validators']['file_validate_extensions'][0])) { - @trigger_error('\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $allowed_extensions = $element['#upload_validators']['file_validate_extensions'][0]; - } - else { - $allowed_extensions = $element['#upload_validators']['FileExtension']['extensions']; - } + if (isset($element['#upload_validators']['FileExtension']['extensions'])) { + $allowed_extensions = $element['#upload_validators']['FileExtension']['extensions']; $extension_list = implode(',', array_filter(explode(' ', $allowed_extensions))); $element['upload']['#attached']['drupalSettings']['file']['elements']['#' . $id] = $extension_list; } diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php index d9fe46ec600c..604960c0c263 100644 --- a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php @@ -238,7 +238,8 @@ public static function validateDirectory($element, FormStateInterface $form_stat * * This doubles as a convenience clean-up function and a validation routine. * Commas are allowed by the end-user, but ultimately the value will be stored - * as a space-separated list for compatibility with file_validate_extensions(). + * as a space-separated list for compatibility with the 'FileExtension' + * constraint. */ public static function validateExtensions($element, FormStateInterface $form_state) { if (!empty($element['#value'])) { diff --git a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php index 1206acc77a29..2d010922c460 100644 --- a/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php +++ b/core/modules/file/src/Plugin/rest/resource/FileUploadResource.php @@ -63,32 +63,6 @@ class FileUploadResource extends ResourceBase { validate as resourceValidate; } - /** - * The regex used to extract the filename from the content disposition header. - * - * @var string - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Upload\ContentDispositionFilenameParser::REQUEST_HEADER_FILENAME_REGEX - * instead. - * - * @see https://www.drupal.org/node/3380380 - */ - const REQUEST_HEADER_FILENAME_REGEX = '@\bfilename(?<star>\*?)=\"(?<filename>.+)\"@'; - - /** - * The amount of bytes to read in each iteration when streaming file data. - * - * @var int - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Upload\InputStreamFileWriterInterface::DEFAULT_BYTES_TO_READ - * instead. - * - * @see https://www.drupal.org/node/3380607 - */ - const BYTES_TO_READ = 8192; - /** * The file system service. * @@ -193,12 +167,12 @@ class FileUploadResource extends ResourceBase { * The system file configuration. * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher * The event dispatcher service. - * @param \Drupal\file\Validation\FileValidatorInterface|null $file_validator + * @param \Drupal\file\Validation\FileValidatorInterface $file_validator * The file validator service. - * @param \Drupal\file\Upload\InputStreamFileWriterInterface|null $input_stream_file_writer + * @param \Drupal\file\Upload\InputStreamFileWriterInterface $input_stream_file_writer * The input stream file writer. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, $serializer_formats, LoggerInterface $logger, FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, AccountInterface $current_user, $mime_type_guesser, Token $token, LockBackendInterface $lock, Config $system_file_config, EventDispatcherInterface $event_dispatcher, FileValidatorInterface $file_validator = NULL, InputStreamFileWriterInterface $input_stream_file_writer = NULL) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, $serializer_formats, LoggerInterface $logger, FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, AccountInterface $current_user, $mime_type_guesser, Token $token, LockBackendInterface $lock, Config $system_file_config, EventDispatcherInterface $event_dispatcher, FileValidatorInterface $file_validator, InputStreamFileWriterInterface $input_stream_file_writer) { parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); $this->fileSystem = $file_system; $this->entityTypeManager = $entity_type_manager; @@ -209,15 +183,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->lock = $lock; $this->systemFileConfig = $system_file_config; $this->eventDispatcher = $event_dispatcher; - if (!$file_validator) { - @trigger_error('Calling ' . __METHOD__ . '() without the $file_validator argument is deprecated in drupal:10.2.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $file_validator = \Drupal::service('file.validator'); - } $this->fileValidator = $file_validator; - if (!$input_stream_file_writer) { - @trigger_error('Calling ' . __METHOD__ . '() without the $input_stream_file_writer argument is deprecated in drupal:10.3.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3380607', E_USER_DEPRECATED); - $input_stream_file_writer = \Drupal::service('file.input_stream_file_writer'); - } $this->inputStreamFileWriter = $input_stream_file_writer; } @@ -396,29 +362,6 @@ protected function streamUploadData(): string { return $temp_file_path; } - /** - * Validates and extracts the filename from the Content-Disposition header. - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - * - * @return string - * The filename extracted from the header. - * - * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - * Thrown when the 'Content-Disposition' request header is invalid. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Upload\ContentDispositionFilenameParser::parseFilename() - * instead. - * - * @see https://www.drupal.org/node/3380380 - */ - protected function validateAndParseContentDispositionHeader(Request $request) { - @trigger_error('Calling ' . __METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\Upload\ContentDispositionFilenameParser::parseFilename() instead. See https://www.drupal.org/node/3380380', E_USER_DEPRECATED); - return ContentDispositionFilenameParser::parseFilename($request); - } - /** * Validates and loads a field definition instance. * diff --git a/core/modules/file/src/Upload/FileUploadHandler.php b/core/modules/file/src/Upload/FileUploadHandler.php index 6313960fdfac..402017e75926 100644 --- a/core/modules/file/src/Upload/FileUploadHandler.php +++ b/core/modules/file/src/Upload/FileUploadHandler.php @@ -14,18 +14,9 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface; use Drupal\file\Entity\File; -use Drupal\file\FileInterface; use Drupal\file\FileRepositoryInterface; use Drupal\file\Validation\FileValidatorInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\HttpFoundation\File\Exception\CannotWriteFileException; -use Symfony\Component\HttpFoundation\File\Exception\ExtensionFileException; -use Symfony\Component\HttpFoundation\File\Exception\FileException; -use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException; -use Symfony\Component\HttpFoundation\File\Exception\IniSizeFileException; -use Symfony\Component\HttpFoundation\File\Exception\NoFileException; -use Symfony\Component\HttpFoundation\File\Exception\NoTmpDirFileException; -use Symfony\Component\HttpFoundation\File\Exception\PartialFileException; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Mime\MimeTypeGuesserInterface; @@ -119,11 +110,11 @@ class FileUploadHandler { * The current user. * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack * The request stack. - * @param \Drupal\file\FileRepositoryInterface|null $fileRepository + * @param \Drupal\file\FileRepositoryInterface $fileRepository * The file repository. - * @param \Drupal\file\Validation\FileValidatorInterface|null $file_validator + * @param \Drupal\file\Validation\FileValidatorInterface $file_validator * The file validator. - * @param \Drupal\Core\Lock\LockBackendInterface|null $lock + * @param \Drupal\Core\Lock\LockBackendInterface $lock * The lock. */ public function __construct( @@ -134,9 +125,9 @@ public function __construct( MimeTypeGuesserInterface $mimeTypeGuesser, AccountInterface $currentUser, RequestStack $requestStack, - FileRepositoryInterface $fileRepository = NULL, - FileValidatorInterface $file_validator = NULL, - protected ?LockBackendInterface $lock = NULL, + FileRepositoryInterface $fileRepository, + FileValidatorInterface $file_validator, + protected LockBackendInterface $lock, ) { $this->fileSystem = $fileSystem; $this->entityTypeManager = $entityTypeManager; @@ -145,20 +136,8 @@ public function __construct( $this->mimeTypeGuesser = $mimeTypeGuesser; $this->currentUser = $currentUser; $this->requestStack = $requestStack; - if ($fileRepository === NULL) { - @trigger_error('Calling ' . __METHOD__ . ' without the $fileRepository argument is deprecated in drupal:10.1.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3346839', E_USER_DEPRECATED); - $fileRepository = \Drupal::service('file.repository'); - } $this->fileRepository = $fileRepository; - if (!$file_validator) { - @trigger_error('Calling ' . __METHOD__ . '() without the $file_validator argument is deprecated in drupal:10.2.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - $file_validator = \Drupal::service('file.validator'); - } $this->fileValidator = $file_validator; - if (!$this->lock) { - @trigger_error('Calling ' . __METHOD__ . '() without the $lock argument is deprecated in drupal:10.3.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3389017', E_USER_DEPRECATED); - $this->lock = \Drupal::service('lock'); - } } /** @@ -176,8 +155,6 @@ public function __construct( * - FileSystemInterface::EXISTS_RENAME - Append _{incrementing number} * until the filename is unique. * - FileSystemInterface::EXISTS_ERROR - Throw an exception. - * @param bool $throw - * (optional) Whether to throw an exception if the file is invalid. * * @return \Drupal\file\Upload\FileUploadResult * The created file entity. @@ -193,46 +170,8 @@ public function __construct( * @throws \Drupal\Core\Lock\LockAcquiringException * Thrown when a lock cannot be acquired. */ - public function handleFileUpload(UploadedFileInterface $uploadedFile, array $validators = [], string $destination = 'temporary://', int $replace = FileSystemInterface::EXISTS_REPLACE, bool $throw = TRUE): FileUploadResult { + public function handleFileUpload(UploadedFileInterface $uploadedFile, array $validators = [], string $destination = 'temporary://', int $replace = FileSystemInterface::EXISTS_REPLACE): FileUploadResult { $originalName = $uploadedFile->getClientOriginalName(); - // @phpstan-ignore-next-line - if ($throw && !$uploadedFile->isValid()) { - @trigger_error('Calling ' . __METHOD__ . '() with the $throw argument as TRUE is deprecated in drupal:10.3.0 and will be removed in drupal:11.0.0. Use \Drupal\file\Upload\FileUploadResult::getViolations() instead. See https://www.drupal.org/node/3375456', E_USER_DEPRECATED); - // @phpstan-ignore-next-line - switch ($uploadedFile->getError()) { - case \UPLOAD_ERR_INI_SIZE: - // @phpstan-ignore-next-line - throw new IniSizeFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_FORM_SIZE: - // @phpstan-ignore-next-line - throw new FormSizeFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_PARTIAL: - // @phpstan-ignore-next-line - throw new PartialFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_NO_FILE: - // @phpstan-ignore-next-line - throw new NoFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_CANT_WRITE: - // @phpstan-ignore-next-line - throw new CannotWriteFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_NO_TMP_DIR: - // @phpstan-ignore-next-line - throw new NoTmpDirFileException($uploadedFile->getErrorMessage()); - - case \UPLOAD_ERR_EXTENSION: - // @phpstan-ignore-next-line - throw new ExtensionFileException($uploadedFile->getErrorMessage()); - - } - // @phpstan-ignore-next-line - throw new FileException($uploadedFile->getErrorMessage()); - } - $extensions = $this->handleExtensionValidation($validators); // Assert that the destination contains a valid stream. @@ -295,20 +234,6 @@ public function handleFileUpload(UploadedFileInterface $uploadedFile, array $val return $result; } - if ($throw) { - $errors = []; - foreach ($violations as $violation) { - $errors[] = $violation->getMessage(); - } - if (!empty($errors)) { - throw new FileValidationException( - 'File validation failed', - $filename, - $errors - ); - } - } - $file->setFileUri($destinationFilename); if (!$this->moveUploadedFile($uploadedFile, $file->getFileUri())) { @@ -343,18 +268,6 @@ public function handleFileUpload(UploadedFileInterface $uploadedFile, array $val // We can now validate the file object itself before it's saved. $violations = $file->validate(); - if ($throw) { - foreach ($violations as $violation) { - $errors[] = $violation->getMessage(); - } - if (!empty($errors)) { - throw new FileValidationException( - 'File validation failed', - $filename, - $errors - ); - } - } if (count($violations) > 0) { $result->addViolations($violations); @@ -416,25 +329,6 @@ protected function moveUploadedFile(UploadedFileInterface $uploadedFile, string * The space delimited list of allowed file extensions. */ protected function handleExtensionValidation(array &$validators): string { - // Handle legacy extension validation. - if (isset($validators['file_validate_extensions'])) { - @trigger_error( - '\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700', - E_USER_DEPRECATED - ); - // Empty string means all extensions are allowed so we should remove the - // validator. - if (\is_string($validators['file_validate_extensions']) && empty($validators['file_validate_extensions'])) { - unset($validators['file_validate_extensions']); - return ''; - } - // The deprecated 'file_validate_extensions' has configuration, so that - // should be used. - $validators['FileExtension']['extensions'] = $validators['file_validate_extensions'][0]; - unset($validators['file_validate_extensions']); - return $validators['FileExtension']['extensions']; - } - // No validator was provided, so add one using the default list. // Build a default non-munged safe list for // \Drupal\system\EventSubscriber\SecurityFileUploadEventSubscriber::sanitizeName(). @@ -455,25 +349,6 @@ protected function handleExtensionValidation(array &$validators): string { return $validators['FileExtension']['extensions']; } - /** - * Loads the first File entity found with the specified URI. - * - * @param string $uri - * The file URI. - * - * @return \Drupal\file\FileInterface|null - * The first file with the matched URI if found, NULL otherwise. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. - * Use \Drupal\file\FileRepositoryInterface::loadByUri(). - * - * @see https://www.drupal.org/node/3409326 - */ - protected function loadByUri(string $uri): ?FileInterface { - @trigger_error('FileUploadHandler::loadByUri() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\FileRepositoryInterface::loadByUri(). See https://www.drupal.org/node/3409326', E_USER_DEPRECATED); - return $this->fileRepository->loadByUri($uri); - } - /** * Generates a lock ID based on the file URI. */ diff --git a/core/modules/file/src/Upload/FormUploadedFile.php b/core/modules/file/src/Upload/FormUploadedFile.php index 7ae45b7721ee..b26a7e01eb20 100644 --- a/core/modules/file/src/Upload/FormUploadedFile.php +++ b/core/modules/file/src/Upload/FormUploadedFile.php @@ -33,48 +33,6 @@ public function getClientOriginalName(): string { return $this->uploadedFile->getClientOriginalName(); } - /** - * {@inheritdoc} - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * - * @see https://www.drupal.org/node/3375456 - */ - public function isValid(): bool { - @trigger_error(__METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\Validation\UploadedFileValidatorInterface::validate() instead. See https://www.drupal.org/node/3375456', E_USER_DEPRECATED); - return $this->uploadedFile->isValid(); - } - - /** - * {@inheritdoc} - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * - * @see https://www.drupal.org/node/3375456 - */ - public function getErrorMessage(): string { - @trigger_error(__METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\Validation\UploadedFileValidatorInterface::validate() instead. See https://www.drupal.org/node/3375456', E_USER_DEPRECATED); - return $this->uploadedFile->getErrorMessage(); - } - - /** - * {@inheritdoc} - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * - * @see https://www.drupal.org/node/3375456 - */ - public function getError(): int { - @trigger_error(__METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\Validation\UploadedFileValidatorInterface::validate() instead. See https://www.drupal.org/node/3375456', E_USER_DEPRECATED); - return $this->uploadedFile->getError(); - } - /** * {@inheritdoc} */ diff --git a/core/modules/file/src/Upload/UploadedFileInterface.php b/core/modules/file/src/Upload/UploadedFileInterface.php index c601e0e9a604..dabb67970b50 100644 --- a/core/modules/file/src/Upload/UploadedFileInterface.php +++ b/core/modules/file/src/Upload/UploadedFileInterface.php @@ -18,50 +18,6 @@ interface UploadedFileInterface { */ public function getClientOriginalName(): string; - /** - * Returns whether the file was uploaded successfully. - * - * @return bool - * TRUE if the file has been uploaded with HTTP and no error occurred. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * @see https://www.drupal.org/node/3375456 - */ - public function isValid(): bool; - - /** - * Returns an informative upload error message. - * - * @return string - * The error message regarding a failed upload. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * - * @see https://www.drupal.org/node/3375456 - */ - public function getErrorMessage(): string; - - /** - * Returns the upload error code. - * - * If the upload was successful, the constant UPLOAD_ERR_OK is returned. - * Otherwise, one of the other UPLOAD_ERR_XXX constants is returned. - * - * @return int - * The upload error code. - * - * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use - * \Drupal\file\Validation\UploadedFileValidatorInterface::validate() - * instead. - * - * @see https://www.drupal.org/node/3375456 - */ - public function getError(): int; - /** * Gets file size. * diff --git a/core/modules/file/src/Validation/FileValidator.php b/core/modules/file/src/Validation/FileValidator.php index 4e517e531ad8..c649f219be59 100644 --- a/core/modules/file/src/Validation/FileValidator.php +++ b/core/modules/file/src/Validation/FileValidator.php @@ -2,13 +2,9 @@ namespace Drupal\file\Validation; -use Drupal\Component\Plugin\Exception\PluginNotFoundException; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Validation\ConstraintManager; -use Drupal\Core\Validation\DrupalTranslator; use Drupal\file\FileInterface; -use Symfony\Component\Validator\ConstraintViolation; -use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -42,52 +38,16 @@ public function __construct( */ public function validate(FileInterface $file, array $validators): ConstraintViolationListInterface { $constraints = []; - $errors = []; foreach ($validators as $validator => $options) { - if (function_exists($validator)) { - @trigger_error('Support for file validation function ' . $validator . '() is deprecated in drupal:10.2.0 and will be removed in drupal:11.0.0. Use Symfony Constraints instead. See https://www.drupal.org/node/3363700', E_USER_DEPRECATED); - if (!is_array($options)) { - $options = [$options]; - } - array_unshift($options, $file); - // Call the validation function. - // Options are a list of function args. - $errors = array_merge($errors, call_user_func_array($validator, $options)); - } - else { - // Create the constraint. - // Options are an associative array of constraint properties and values. - try { - $constraints[] = $this->constraintManager->create($validator, $options); - } - catch (PluginNotFoundException) { - @trigger_error(sprintf('Passing invalid constraint plugin ID "%s" in the list of $validators to Drupal\file\Validation\FileValidator::validate() is deprecated in drupal:10.2.0 and will throw an exception in drupal:11.0.0. See https://www.drupal.org/node/3363700', $validator), E_USER_DEPRECATED); - } - } - } - - // Call legacy hook implementations. - $errors = array_merge($errors, $this->moduleHandler->invokeAllDeprecated('Use file validation events instead. See https://www.drupal.org/node/3363700', 'file_validate', [$file])); - - $violations = new ConstraintViolationList(); - - // Convert legacy errors to violations. - $translator = new DrupalTranslator(); - foreach ($errors as $error) { - $violation = new ConstraintViolation($translator->trans($error), - $error, - [], - $file, - '', - NULL - ); - $violations->add($violation); + // Create the constraint. + // Options are an associative array of constraint properties and values. + $constraints[] = $this->constraintManager->create($validator, $options); } // Get the typed data. $fileTypedData = $file->getTypedData(); - $violations->addAll($this->validator->validate($fileTypedData, $constraints)); + $violations = $this->validator->validate($fileTypedData, $constraints); $this->eventDispatcher->dispatch(new FileValidationEvent($file, $violations)); diff --git a/core/modules/file/tests/src/Functional/SaveUploadFormTest.php b/core/modules/file/tests/src/Functional/SaveUploadFormTest.php index 612396bdfbb4..63a8641d851b 100644 --- a/core/modules/file/tests/src/Functional/SaveUploadFormTest.php +++ b/core/modules/file/tests/src/Functional/SaveUploadFormTest.php @@ -372,7 +372,7 @@ public function testHandleFileMunge() { // Check that the correct hooks were called. $this->assertFileHooksCalled(['validate', 'insert']); - // Ensure that setting $validators['file_validate_extensions'] = [''] + // Ensure that setting $validators['FileExtension'] = ['extensions' => NULL] // rejects all files. // Reset the hook counters. file_test_reset(); diff --git a/core/modules/file/tests/src/Kernel/FileSaveUploadTest.php b/core/modules/file/tests/src/Kernel/FileSaveUploadTest.php deleted file mode 100644 index d512a0f74272..000000000000 --- a/core/modules/file/tests/src/Kernel/FileSaveUploadTest.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace Drupal\Tests\file\Kernel; - -use Drupal\Core\Messenger\MessengerInterface; -use Drupal\KernelTests\KernelTestBase; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Tests file_save_upload(). - * - * @group file - * @group legacy - */ -class FileSaveUploadTest extends KernelTestBase { - - /** - * {@inheritdoc} - */ - protected static $modules = [ - 'file', - 'file_test', - 'file_validator_test', - 'user', - ]; - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - \file_put_contents('test.bbb', 'test'); - - parent::setUp(); - $request = new Request(); - $request->files->set('files', [ - 'file' => new UploadedFile( - path: 'test.bbb', - originalName: 'test.bbb', - mimeType: 'text/plain', - error: \UPLOAD_ERR_OK, - test: TRUE - ), - ]); - - $requestStack = new RequestStack(); - $requestStack->push($request); - - $this->container->set('request_stack', $requestStack); - } - - /** - * Tests file_save_upload() with empty extensions. - */ - public function testFileSaveUploadEmptyExtensions(): void { - // Allow all extensions. - $validators = ['file_validate_extensions' => '']; - $this->expectDeprecation('\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700'); - $files = file_save_upload('file', $validators); - $this->assertCount(1, $files); - $file = $files[0]; - // @todo work out why move_uploaded_file() is failing. - $this->assertFalse($file); - $messages = \Drupal::messenger()->messagesByType(MessengerInterface::TYPE_ERROR); - $this->assertNotEmpty($messages); - $this->assertEquals('File upload error. Could not move uploaded file.', $messages[0]); - } - -} diff --git a/core/modules/file/tests/src/Kernel/FileUploadHandlerTest.php b/core/modules/file/tests/src/Kernel/FileUploadHandlerTest.php index 5410552c9c29..edd56b6a349a 100644 --- a/core/modules/file/tests/src/Kernel/FileUploadHandlerTest.php +++ b/core/modules/file/tests/src/Kernel/FileUploadHandlerTest.php @@ -7,7 +7,6 @@ use Drupal\file\Upload\FileUploadHandler; use Drupal\file\Upload\UploadedFileInterface; use Drupal\KernelTests\KernelTestBase; -use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Tests the file upload handler. @@ -34,44 +33,6 @@ protected function setUp(): void { $this->fileUploadHandler = $this->container->get('file.upload_handler'); } - /** - * Tests the legacy extension support. - * - * @group legacy - */ - public function testLegacyExtensions(): void { - $filename = $this->randomMachineName() . '.txt'; - $uploadedFile = $this->createMock(UploadedFileInterface::class); - $uploadedFile->expects($this->once()) - ->method('getClientOriginalName') - ->willReturn($filename); - $uploadedFile->expects($this->once())->method('isValid')->willReturn(TRUE); - - // Throw an exception in mimeTypeGuesser to return early from the method. - $mimeTypeGuesser = $this->createMock(MimeTypeGuesserInterface::class); - $mimeTypeGuesser->expects($this->once())->method('guessMimeType') - ->willThrowException(new \RuntimeException('Expected exception')); - - $fileUploadHandler = new FileUploadHandler( - fileSystem: $this->container->get('file_system'), - entityTypeManager: $this->container->get('entity_type.manager'), - streamWrapperManager: $this->container->get('stream_wrapper_manager'), - eventDispatcher: $this->container->get('event_dispatcher'), - mimeTypeGuesser: $mimeTypeGuesser, - currentUser: $this->container->get('current_user'), - requestStack: $this->container->get('request_stack'), - fileRepository: $this->container->get('file.repository'), - file_validator: $this->container->get('file.validator'), - ); - - $this->expectException(\Exception::class); - $this->expectDeprecation('\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700'); - $fileUploadHandler->handleFileUpload($uploadedFile, ['file_validate_extensions' => ['txt']]); - - $subscriber = $this->container->get('file_validation_sanitization_subscriber'); - $this->assertEquals(['txt'], $subscriber->getAllowedExtensions()); - } - /** * Test the lock acquire exception. */ @@ -100,7 +61,7 @@ public function testLockAcquireException(): void { $this->expectException(LockAcquiringException::class); $this->expectExceptionMessage(sprintf('File "temporary://%s" is already locked for writing.', $file_name)); - $fileUploadHandler->handleFileUpload(uploadedFile: $file_info, throw: FALSE); + $fileUploadHandler->handleFileUpload(uploadedFile: $file_info); } } diff --git a/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php b/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php deleted file mode 100644 index 1239a570c801..000000000000 --- a/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\file\Kernel; - -use Drupal\KernelTests\KernelTestBase; - -// cspell:ignore msword - -/** - * Tests file module deprecations. - * - * @group legacy - * @group file - */ -class LegacyFileModuleTest extends KernelTestBase { - - /** - * {@inheritdoc} - */ - protected static $modules = ['file']; - - /** - * @covers ::file_progress_implementation - */ - public function testFileProgressDeprecation() { - $this->expectDeprecation('file_progress_implementation() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use extension_loaded(\'uploadprogress\') instead. See https://www.drupal.org/node/3397577'); - $this->assertFalse(\file_progress_implementation()); - } - - /** - * @covers ::file_icon_map - */ - public function testFileIconMapDeprecation(): void { - $this->expectDeprecation('file_icon_map() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getGenericMimeType() instead. See https://www.drupal.org/node/3411269'); - $mimeType = \file_icon_map('application/msword'); - $this->assertEquals('x-office-document', $mimeType); - } - - /** - * @covers ::file_icon_class - */ - public function testFileIconClassDeprecation(): void { - $this->expectDeprecation('file_icon_class() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getIconClass() instead. See https://www.drupal.org/node/3411269'); - $iconClass = \file_icon_class('image/jpeg'); - $this->assertEquals('image', $iconClass); - } - -} diff --git a/core/modules/file/tests/src/Kernel/LegacyFileThemeTest.php b/core/modules/file/tests/src/Kernel/LegacyFileThemeTest.php deleted file mode 100644 index 257a85df8e57..000000000000 --- a/core/modules/file/tests/src/Kernel/LegacyFileThemeTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -namespace Drupal\Tests\file\Kernel; - -use Drupal\KernelTests\KernelTestBase; - -/** - * Tests legacy deprecated functions in file.module. - * - * @group file - * @group legacy - */ -class LegacyFileThemeTest extends KernelTestBase { - - /** - * {@inheritdoc} - */ - protected static $modules = ['file']; - - /** - * @covers ::template_preprocess_file_upload_help - */ - public function testTemplatePreprocessFileUploadHelp(): void { - $variables['description'] = 'foo'; - $variables['cardinality'] = 1; - $variables['upload_validators'] = [ - 'file_validate_size' => [1000], - 'file_validate_extensions' => ['txt'], - 'file_validate_image_resolution' => ['100x100', '50x50'], - ]; - - $this->expectDeprecation('\'file_validate_size\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileSizeLimit\' constraint instead. See https://www.drupal.org/node/3363700'); - $this->expectDeprecation('\'file_validate_extensions\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileExtension\' constraint instead. See https://www.drupal.org/node/3363700'); - $this->expectDeprecation('\'file_validate_image_resolution\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'FileImageDimensions\' constraint instead. See https://www.drupal.org/node/3363700'); - - template_preprocess_file_upload_help($variables); - - $this->assertCount(5, $variables['descriptions']); - - $descriptions = $variables['descriptions']; - $this->assertEquals('foo', $descriptions[0]); - $this->assertEquals('One file only.', $descriptions[1]); - $this->assertEquals('1000 bytes limit.', $descriptions[2]); - $this->assertEquals('Allowed types: txt.', $descriptions[3]); - $this->assertEquals('Images must be larger than 50x50 pixels. Images larger than 100x100 pixels will be resized.', $descriptions[4]); - } - -} diff --git a/core/modules/file/tests/src/Kernel/LegacyValidateTest.php b/core/modules/file/tests/src/Kernel/LegacyValidateTest.php deleted file mode 100644 index 1317803603c7..000000000000 --- a/core/modules/file/tests/src/Kernel/LegacyValidateTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -namespace Drupal\Tests\file\Kernel; - -/** - * Tests the file_validate() function. - * - * @group file - * @group legacy - */ -class LegacyValidateTest extends FileManagedUnitTestBase { - - /** - * Tests that the validators passed into are checked. - */ - public function testCallerValidation() { - $file = $this->createFile(); - - // Empty validators. - $this->expectDeprecation('file_validate() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $this->assertEquals([], file_validate($file, []), 'Validating an empty array works successfully.'); - $this->assertFileHooksCalled([]); - - // Use the file_test.module's test validator to ensure that passing tests - // return correctly. - file_test_reset(); - file_test_set_return('validate', []); - $passing = ['file_test_validator' => [[]]]; - $this->assertEquals([], file_validate($file, $passing), 'Validating passes.'); - $this->assertFileHooksCalled([]); - - // Now test for failures in validators passed in and by hook_validate. - file_test_reset(); - $failing = ['file_test_validator' => [['Failed', 'Badly']]]; - $this->assertEquals(['Failed', 'Badly'], file_validate($file, $failing), 'Validating returns errors.'); - $this->assertFileHooksCalled([]); - } - - /** - * Tests hard-coded security check in file_validate(). - */ - public function testInsecureExtensions() { - $file = $this->createFile('test.php', 'Invalid PHP'); - - // Test that file_validate() will check for insecure extensions by default. - $this->expectDeprecation('file_validate() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate($file, []); - $this->assertEquals('For security reasons, your upload has been rejected.', $errors[0]); - $this->assertFileHooksCalled([]); - file_test_reset(); - - // Test that the 'allow_insecure_uploads' is respected. - $this->config('system.file')->set('allow_insecure_uploads', TRUE)->save(); - $errors = file_validate($file, []); - $this->assertEmpty($errors); - $this->assertFileHooksCalled([]); - } - -} diff --git a/core/modules/file/tests/src/Kernel/LegacyValidatorTest.php b/core/modules/file/tests/src/Kernel/LegacyValidatorTest.php deleted file mode 100644 index 20c27fe2d8b0..000000000000 --- a/core/modules/file/tests/src/Kernel/LegacyValidatorTest.php +++ /dev/null @@ -1,255 +0,0 @@ -<?php - -namespace Drupal\Tests\file\Kernel; - -use Drupal\file\Entity\File; - -/** - * Tests the functions used to validate uploaded files. - * - * @group file - * @group legacy - */ -class LegacyValidatorTest extends FileManagedUnitTestBase { - - /** - * An image file. - * - * @var \Drupal\file\FileInterface - */ - protected $image; - - /** - * A file which is not an image. - * - * @var \Drupal\file\Entity\File - */ - protected $nonImage; - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - parent::setUp(); - - $this->image = File::create(); - $this->image->setFileUri('core/misc/druplicon.png'); - /** @var \Drupal\Core\File\FileSystemInterface $file_system */ - $file_system = \Drupal::service('file_system'); - $this->image->setFilename($file_system->basename($this->image->getFileUri())); - $this->image->setSize(@filesize($this->image->getFileUri())); - - $this->nonImage = File::create(); - $this->nonImage->setFileUri('core/assets/vendor/jquery/jquery.min.js'); - $this->nonImage->setFilename($file_system->basename($this->nonImage->getFileUri())); - } - - /** - * Tests the file_validate_extensions() function. - */ - public function testFileValidateExtensions() { - $file = File::create(['filename' => 'asdf.txt']); - $this->expectDeprecation('file_validate_extensions() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate_extensions($file, 'asdf txt pork'); - $this->assertCount(0, $errors, 'Valid extension accepted.'); - - $file->setFilename('asdf.txt'); - $errors = file_validate_extensions($file, 'exe png'); - $this->assertCount(1, $errors, 'Invalid extension blocked.'); - } - - /** - * Tests the file_validate_extensions() function. - * - * @param array $file_properties - * The properties of the file being validated. - * @param string[] $extensions - * An array of the allowed file extensions. - * @param string[] $expected_errors - * The expected error messages as string. - * - * @dataProvider providerTestFileValidateExtensionsOnUri - */ - public function testFileValidateExtensionsOnUri(array $file_properties, array $extensions, array $expected_errors) { - $file = File::create($file_properties); - $this->expectDeprecation('file_validate_extensions() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $actual_errors = file_validate_extensions($file, implode(' ', $extensions)); - $actual_errors_as_string = array_map(function ($error_message) { - return (string) $error_message; - }, $actual_errors); - $this->assertEquals($expected_errors, $actual_errors_as_string); - } - - /** - * Data provider for ::testFileValidateExtensionsOnUri. - * - * @return array[][] - * The test cases. - */ - public static function providerTestFileValidateExtensionsOnUri(): array { - $temporary_txt_file_properties = [ - 'filename' => 'asdf.txt', - 'uri' => 'temporary://asdf', - 'status' => 0, - ]; - $permanent_txt_file_properties = [ - 'filename' => 'asdf.txt', - 'uri' => 'public://asdf_0.txt', - 'status' => 1, - ]; - $permanent_png_file_properties = [ - 'filename' => 'The Druplicon', - 'uri' => 'public://druplicon.png', - 'status' => 1, - ]; - return [ - 'Temporary txt validated with "asdf", "txt", "pork"' => [ - 'File properties' => $temporary_txt_file_properties, - 'Allowed_extensions' => ['asdf', 'txt', 'pork'], - 'Expected errors' => [], - ], - 'Temporary txt validated with "exe" and "png"' => [ - 'File properties' => $temporary_txt_file_properties, - 'Allowed_extensions' => ['exe', 'png'], - 'Expected errors' => [ - 'Only files with the following extensions are allowed: <em class="placeholder">exe png</em>.', - ], - ], - 'Permanent txt validated with "asdf", "txt", "pork"' => [ - 'File properties' => $permanent_txt_file_properties, - 'Allowed_extensions' => ['asdf', 'txt', 'pork'], - 'Expected errors' => [], - ], - 'Permanent txt validated with "exe" and "png"' => [ - 'File properties' => $permanent_txt_file_properties, - 'Allowed_extensions' => ['exe', 'png'], - 'Expected errors' => [ - 'Only files with the following extensions are allowed: <em class="placeholder">exe png</em>.', - ], - ], - 'Permanent png validated with "png", "gif", "jpg", "jpeg"' => [ - 'File properties' => $permanent_png_file_properties, - 'Allowed_extensions' => ['png', 'gif', 'jpg', 'jpeg'], - 'Expected errors' => [], - ], - 'Permanent png validated with "exe" and "txt"' => [ - 'File properties' => $permanent_png_file_properties, - 'Allowed_extensions' => ['exe', 'txt'], - 'Expected errors' => [ - 'Only files with the following extensions are allowed: <em class="placeholder">exe txt</em>.', - ], - ], - ]; - } - - /** - * This ensures a specific file is actually an image. - */ - public function testFileValidateIsImage() { - $this->assertFileExists($this->image->getFileUri()); - $this->expectDeprecation('file_validate_is_image() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate_is_image($this->image); - $this->assertCount(0, $errors, 'No error reported for our image file.'); - - $this->assertFileExists($this->nonImage->getFileUri()); - $errors = file_validate_is_image($this->nonImage); - $this->assertCount(1, $errors, 'An error reported for our non-image file.'); - } - - /** - * This ensures the dimensions of a specific file is within bounds. - * - * The image will be resized if it's too large. - */ - public function testFileValidateImageResolution() { - // Non-images. - $this->expectDeprecation('file_validate_image_resolution() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate_image_resolution($this->nonImage); - $this->assertCount(0, $errors, 'Should not get any errors for a non-image file.'); - $errors = file_validate_image_resolution($this->nonImage, '50x50', '100x100'); - $this->assertCount(0, $errors, 'Do not check the dimensions on non files.'); - - // Minimum size. - $errors = file_validate_image_resolution($this->image); - $this->assertCount(0, $errors, 'No errors for an image when there is no minimum or maximum dimensions.'); - $errors = file_validate_image_resolution($this->image, 0, '200x1'); - $this->assertCount(1, $errors, 'Got an error for an image that was not wide enough.'); - $errors = file_validate_image_resolution($this->image, 0, '1x200'); - $this->assertCount(1, $errors, 'Got an error for an image that was not tall enough.'); - $errors = file_validate_image_resolution($this->image, 0, '200x200'); - $this->assertCount(1, $errors, 'Small images report an error.'); - - // Maximum size. - if ($this->container->get('image.factory')->getToolkitId()) { - // Copy the image so that the original doesn't get resized. - copy('core/misc/druplicon.png', 'temporary://druplicon.png'); - $this->image->setFileUri('temporary://druplicon.png'); - - $errors = file_validate_image_resolution($this->image, '10x5'); - $this->assertCount(0, $errors, 'No errors should be reported when an oversized image can be scaled down.'); - - $image = $this->container->get('image.factory')->get($this->image->getFileUri()); - // Verify that the image was scaled to the correct width and height. - $this->assertLessThanOrEqual(10, $image->getWidth()); - $this->assertLessThanOrEqual(5, $image->getHeight()); - // Verify that the file size has been updated after resizing. - $this->assertEquals($this->image->getSize(), $image->getFileSize()); - - // Once again, now with negative width and height to force an error. - copy('core/misc/druplicon.png', 'temporary://druplicon.png'); - $this->image->setFileUri('temporary://druplicon.png'); - $errors = file_validate_image_resolution($this->image, '-10x-5'); - $this->assertCount(1, $errors, 'An error reported for an oversized image that can not be scaled down.'); - - \Drupal::service('file_system')->unlink('temporary://druplicon.png'); - } - else { - // TODO: should check that the error is returned if no toolkit is available. - $errors = file_validate_image_resolution($this->image, '5x10'); - $this->assertCount(1, $errors, 'Oversize images that cannot be scaled get an error.'); - } - } - - /** - * This will ensure the filename length is valid. - */ - public function testFileValidateNameLength() { - // Create a new file entity. - $file = File::create(); - - // Add a filename with an allowed length and test it. - $file->setFilename(str_repeat('x', 240)); - $this->assertEquals(240, strlen($file->getFilename())); - $this->expectDeprecation('file_validate_name_length() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate_name_length($file); - $this->assertCount(0, $errors, 'No errors reported for 240 length filename.'); - - // Add a filename with a length too long and test it. - $file->setFilename(str_repeat('x', 241)); - $errors = file_validate_name_length($file); - $this->assertCount(1, $errors, 'An error reported for 241 length filename.'); - - // Add a filename with an empty string and test it. - $file->setFilename(''); - $errors = file_validate_name_length($file); - $this->assertCount(1, $errors, 'An error reported for 0 length filename.'); - } - - /** - * Tests file_validate_size(). - */ - public function testFileValidateSize() { - // Create a file with a size of 1000 bytes, and quotas of only 1 byte. - $file = File::create(['filesize' => 1000]); - $this->expectDeprecation('file_validate_size() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use the \'file.validator\' service instead. See https://www.drupal.org/node/3363700'); - $errors = file_validate_size($file, 0, 0); - $this->assertCount(0, $errors, 'No limits means no errors.'); - $errors = file_validate_size($file, 1, 0); - $this->assertCount(1, $errors, 'Error for the file being over the limit.'); - $errors = file_validate_size($file, 0, 1); - $this->assertCount(1, $errors, 'Error for the user being over their limit.'); - $errors = file_validate_size($file, 1, 1); - $this->assertCount(2, $errors, 'Errors for both the file and their limit.'); - } - -} diff --git a/core/modules/file/tests/src/Kernel/Upload/LegacyFileUploadHandlerTest.php b/core/modules/file/tests/src/Kernel/Upload/LegacyFileUploadHandlerTest.php deleted file mode 100644 index 3ca6d2b623f8..000000000000 --- a/core/modules/file/tests/src/Kernel/Upload/LegacyFileUploadHandlerTest.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -namespace Drupal\Tests\file\Kernel\Upload; - -use Drupal\file\Upload\UploadedFileInterface; -use Drupal\KernelTests\KernelTestBase; -use Symfony\Component\HttpFoundation\File\Exception\FileException; - -/** - * Provides tests for legacy file upload handler code. - * - * @group file - * @group legacy - * @coversDefaultClass \Drupal\file\Upload\FileUploadHandler - */ -class LegacyFileUploadHandlerTest extends KernelTestBase { - - /** - * {@inheritdoc} - */ - protected static $modules = ['file']; - - /** - * @covers ::handleFileUpload - */ - public function testThrow(): void { - $fileUploadHandler = $this->container->get('file.upload_handler'); - - $uploadedFile = $this->createMock(UploadedFileInterface::class); - $uploadedFile->expects($this->once()) - ->method('isValid') - ->willReturn(FALSE); - - $this->expectDeprecation('Calling Drupal\file\Upload\FileUploadHandler::handleFileUpload() with the $throw argument as TRUE is deprecated in drupal:10.3.0 and will be removed in drupal:11.0.0. Use \Drupal\file\Upload\FileUploadResult::getViolations() instead. See https://www.drupal.org/node/3375456'); - $this->expectException(FileException::class); - $result = $fileUploadHandler->handleFileUpload(uploadedFile: $uploadedFile, throw: TRUE); - } - -} diff --git a/core/modules/file/tests/src/Kernel/Validation/FileValidatorTest.php b/core/modules/file/tests/src/Kernel/Validation/FileValidatorTest.php index a990cae8cd24..4effd1ac0c5d 100644 --- a/core/modules/file/tests/src/Kernel/Validation/FileValidatorTest.php +++ b/core/modules/file/tests/src/Kernel/Validation/FileValidatorTest.php @@ -24,40 +24,32 @@ class FileValidatorTest extends FileValidatorTestBase { /** * Tests the validator. - * - * @group legacy */ public function testValidate(): void { - // Use a mix of legacy functions and plugin IDs to test both work. + // Use plugin IDs to test they work. // Each Constraint has its own tests under // core/modules/file/tests/src/Kernel/Plugin/Validation/Constraint. - // Also check that arbitrary strings can be used. $validators = [ - 'file_validate_name_length' => [], 'FileNameLength' => [], - 'foo' => [], ]; file_test_reset(); - $this->expectDeprecation('Support for file validation function file_validate_name_length() is deprecated in drupal:10.2.0 and will be removed in drupal:11.0.0. Use Symfony Constraints instead. See https://www.drupal.org/node/3363700'); $violations = $this->validator->validate($this->file, $validators); $this->assertCount(0, $violations); $this->assertCount(1, file_test_get_calls('validate')); - $this->expectDeprecation('Passing invalid constraint plugin ID "foo" in the list of $validators to Drupal\file\Validation\FileValidator::validate() is deprecated in drupal:10.2.0 and will throw an exception in drupal:11.0.0. See https://www.drupal.org/node/3363700'); file_test_reset(); $this->file->set('filename', ''); $violations = $this->validator->validate($this->file, $validators); - $this->assertCount(2, $violations); - $this->assertEquals($violations[0]->getMessage(), $violations[1]->getMessage(), 'Message names are equal'); + $this->assertCount(1, $violations); + $this->assertEquals($violations[0]->getMessage(), $violations[0]->getMessage(), 'Message names are equal'); $this->assertCount(1, file_test_get_calls('validate')); file_test_reset(); $this->file->set('filename', $this->randomMachineName(241)); $violations = $this->validator->validate($this->file, $validators); - $this->assertCount(2, $violations); + $this->assertCount(1, $violations); $this->assertEquals("The file's name exceeds the 240 characters limit. Rename the file and try again.", $violations[0]->getMessage()); - $this->assertEquals("The file's name exceeds the 240 characters limit. Rename the file and try again.", $violations[1]->getMessage()); $this->assertCount(1, file_test_get_calls('validate')); } -- GitLab