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.',
+ ],
+ ];
+
+ }
+
}