diff --git a/core/modules/file/file.module b/core/modules/file/file.module index fb2f3484b7..c41613c415 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -930,6 +930,7 @@ function _file_save_upload_single(\SplFileInfo $file_info, $form_field_name, $va // Check for file upload errors and return FALSE for this file if a lower // level system error occurred. For a complete list of errors: // See http://php.net/manual/features.file-upload.errors.php. + $error_to_log = NULL; switch ($file_info->getError()) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: @@ -941,6 +942,21 @@ function _file_save_upload_single(\SplFileInfo $file_info, $form_field_name, $va \Drupal::messenger()->addError(t('The file %file could not be saved because the upload did not complete.', ['%file' => $original_file_name])); return FALSE; + case UPLOAD_ERR_NO_TMP_DIR: + \Drupal::messenger() + ->addError(t('The file %file could not be saved because the server is missing a temporary folder.', ['%file' => $original_file_name])); + return FALSE; + + case UPLOAD_ERR_CANT_WRITE: + \Drupal::messenger() + ->addError(t('The file %file could not be saved because the server is unable to write to disk.', ['%file' => $original_file_name])); + return FALSE; + + case UPLOAD_ERR_EXTENSION: + \Drupal::messenger() + ->addError(t('The file %file could not be saved because a PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.', ['%file' => $original_file_name])); + return FALSE; + case UPLOAD_ERR_OK: // Final check that this is a valid upload, if it isn't, use the // default error handler. @@ -950,9 +966,19 @@ function _file_save_upload_single(\SplFileInfo $file_info, $form_field_name, $va default: // Unknown error - \Drupal::messenger()->addError(t('The file %file could not be saved. An unknown error has occurred.', ['%file' => $original_file_name])); - return FALSE; - + $error_to_log = 'The file ' . $file_info->getFilename() . ' could not be saved. An unknown error has occurred.'; + break; + } + if (isset($error_to_log)) { + // Use trigger_error() here so that the error will be reported to the + // screen depending on the site's error reporting level. + trigger_error($error_to_log, E_USER_ERROR); + // Unconditionally display an error message to the end user. This is a + // generic message since the errors that trigger this represent + // server-level problems that end users should not know about (and cannot + // fix by attempting the upload again). + \Drupal::messenger()->addError(t('The file %file could not be saved. An unknown error has occurred.', ['%file' => $original_file_name])); + return FALSE; } // Build a list of allowed extensions. diff --git a/core/modules/file/tests/src/Kernel/FileModuleTest.php b/core/modules/file/tests/src/Kernel/FileModuleTest.php index de15467832..c12727ca0b 100644 --- a/core/modules/file/tests/src/Kernel/FileModuleTest.php +++ b/core/modules/file/tests/src/Kernel/FileModuleTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\file\Kernel; -use Drupal\Component\Utility\Environment; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\KernelTests\KernelTestBase; use Symfony\Component\HttpFoundation\File\UploadedFile; @@ -22,16 +21,53 @@ class FileModuleTest extends KernelTestBase { /** * Tests file size upload errors. * - * @throws \Drupal\Core\Entity\EntityStorageException + * @dataProvider providerFileSaveUploadSingle */ - public function testFileSaveUploadSingleErrorFormSize() { + public function testFileSaveUploadSingle($error, $message) { $file_name = $this->randomMachineName(); $file_info = $this->createMock(UploadedFile::class); - $file_info->expects($this->once())->method('getError')->willReturn(UPLOAD_ERR_FORM_SIZE); + $file_info->expects($this->once())->method('getError')->willReturn($error); $file_info->expects($this->once())->method('getClientOriginalName')->willReturn($file_name); $this->assertFalse(\_file_save_upload_single($file_info, 'name')); - $expected_message = new TranslatableMarkup('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', ['%file' => $file_name, '%maxsize' => format_size(Environment::getUploadMaxSize())]); + $expected_message = new TranslatableMarkup(sprintf($message, $file_name)); $this->assertEquals($expected_message, \Drupal::messenger()->all()['error'][0]); } + /** + * Data provider for testFileSaveUploadSingle. + */ + public function providerFileSaveUploadSingle() { + return [ + [ + UPLOAD_ERR_INI_SIZE, + 'The file %s could not be saved because it exceeds 100 MB, the maximum allowed size for uploads.', + ], + [ + UPLOAD_ERR_FORM_SIZE, + 'The file %s could not be saved because it exceeds 100 MB, the maximum allowed size for uploads.', + ], + [ + UPLOAD_ERR_PARTIAL, + 'The file %s could not be saved because the upload did not complete.', + ], + [ + UPLOAD_ERR_NO_FILE, + 'The file %s could not be saved because the upload did not complete.', + ], + [ + UPLOAD_ERR_NO_TMP_DIR, + 'The file %s could not be saved because the server is missing a temporary folder.', + ], + [ + UPLOAD_ERR_CANT_WRITE, + 'The file %s could not be saved because the server is unable to write to disk.', + ], + [ + UPLOAD_ERR_EXTENSION, + 'The file %s could not be saved because a PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.', + ], + ]; + + } + }