From a5b44e8f740c6fc5f50fba1289962176293c52ee Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 3 Oct 2022 20:21:47 +0100 Subject: [PATCH] =?UTF-8?q?Issue=20#59750=20by=20quietone,=20larowlan,=20m?= =?UTF-8?q?ikeryan,=20quicksketch,=20sreynen,=20kleinmp,=20kim.pepper,=20B?= =?UTF-8?q?=C3=A8r=20Kessels,=20chx,=20S3b0uN3t,=20ravi.shankar,=20mrddthi?= =?UTF-8?q?,=20webchick,=20neclimdul,=20Lendude:=20Required=20flag=20on=20?= =?UTF-8?q?file=20forms=20breaks=20on=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/lib/Drupal/Core/Render/Element/File.php | 26 +++++++++++++++++ .../tests/file_test/file_test.routing.yml | 6 ++++ .../src/Form/FileRequiredTestForm.php | 28 +++++++++++++++++++ .../tests/src/Functional/SaveUploadTest.php | 22 +++++++++++++++ .../system/src/Form/ThemeSettingsForm.php | 1 - 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php diff --git a/core/lib/Drupal/Core/Render/Element/File.php b/core/lib/Drupal/Core/Render/Element/File.php index c909b926deaf..315817319862 100644 --- a/core/lib/Drupal/Core/Render/Element/File.php +++ b/core/lib/Drupal/Core/Render/Element/File.php @@ -15,6 +15,10 @@ * - #multiple: A Boolean indicating whether multiple files may be uploaded. * - #size: The size of the file input element in characters. * + * The value of this form element will always be an array of + * \Symfony\Component\HttpFoundation\File\UploadedFile objects, regardless of + * whether #multiple is TRUE or FALSE + * * @FormElement("file") */ class File extends FormElement { @@ -36,6 +40,9 @@ public function getInfo() { ], '#theme' => 'input__file', '#theme_wrappers' => ['form_element'], + '#value_callback' => [ + [$class, 'valueCallback'], + ], ]; } @@ -72,4 +79,23 @@ public static function preRenderFile($element) { return $element; } + /** + * {@inheritdoc} + */ + public static function valueCallback(&$element, $input, FormStateInterface $form_state) { + if ($input === FALSE) { + return NULL; + } + $parents = $element['#parents']; + $element_name = array_shift($parents); + $uploaded_files = \Drupal::request()->files->get('files', []); + $uploaded_file = $uploaded_files[$element_name] ?? NULL; + if ($uploaded_file) { + // Cast this to an array so that the structure is consistent regardless of + // whether #value is set or not. + return (array) $uploaded_file; + } + return NULL; + } + } diff --git a/core/modules/file/tests/file_test/file_test.routing.yml b/core/modules/file/tests/file_test/file_test.routing.yml index 0505615a4e5a..20af642f92a5 100644 --- a/core/modules/file/tests/file_test/file_test.routing.yml +++ b/core/modules/file/tests/file_test/file_test.routing.yml @@ -10,3 +10,9 @@ file.save_upload_from_form_test: _form: '\Drupal\file_test\Form\FileTestSaveUploadFromForm' requirements: _access: 'TRUE' +file.required_test: + path: '/file-test/upload_required' + defaults: + _form: '\Drupal\file_test\Form\FileRequiredTestForm' + requirements: + _access: 'TRUE' diff --git a/core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php b/core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php new file mode 100644 index 000000000000..c6dca9b0f689 --- /dev/null +++ b/core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php @@ -0,0 +1,28 @@ +<?php + +namespace Drupal\file_test\Form; + +use Drupal\Core\Form\FormStateInterface; + +/** + * File required test form class. + */ +class FileRequiredTestForm extends FileTestForm { + + /** + * {@inheritdoc} + */ + public function getFormId() { + return '_file_required_test_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $form = parent::buildForm($form, $form_state); + $form['file_test_upload']['#required'] = TRUE; + return $form; + } + +} diff --git a/core/modules/file/tests/src/Functional/SaveUploadTest.php b/core/modules/file/tests/src/Functional/SaveUploadTest.php index 3fa9f3d8f76f..4a70d2d1c5a6 100644 --- a/core/modules/file/tests/src/Functional/SaveUploadTest.php +++ b/core/modules/file/tests/src/Functional/SaveUploadTest.php @@ -732,4 +732,26 @@ public function testInvalidUtf8FilenameUpload() { $this->assertFileDoesNotExist('temporary://' . $filename); } + /** + * Tests the file_save_upload() function when the field is required. + */ + public function testRequired() { + // Reset the hook counters to get rid of the 'load' we just called. + file_test_reset(); + + // Confirm the field is required. + $this->drupalGet('file-test/upload_required'); + $this->submitForm([], 'Submit'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseContains('field is required'); + + // Confirm that uploading another file works. + $image = current($this->drupalGetTestFiles('image')); + $edit = ['files[file_test_upload]' => \Drupal::service('file_system')->realpath($image->uri)]; + $this->drupalGet('file-test/upload_required'); + $this->submitForm($edit, 'Submit'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseContains('You WIN!'); + } + } diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php index 00d6b28c71e9..3d044f5c28cc 100644 --- a/core/modules/system/src/Form/ThemeSettingsForm.php +++ b/core/modules/system/src/Form/ThemeSettingsForm.php @@ -234,7 +234,6 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = $form['logo']['settings']['logo_upload'] = [ '#type' => 'file', '#title' => $this->t('Upload logo image'), - '#maxlength' => 40, '#description' => $this->t("If you don't have direct file access to the server, use this field to upload your logo."), '#upload_validators' => [ 'file_validate_is_image' => [], -- GitLab