Loading core/lib/Drupal/Core/Render/Element/File.php +26 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -36,6 +40,9 @@ public function getInfo() { ], '#theme' => 'input__file', '#theme_wrappers' => ['form_element'], '#value_callback' => [ [$class, 'valueCallback'], ], ]; } Loading Loading @@ -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; } } core/modules/file/tests/file_test/file_test.routing.yml +6 −0 Original line number Diff line number Diff line Loading @@ -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' core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?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; } } core/modules/file/tests/src/Functional/SaveUploadTest.php +22 −0 Original line number Diff line number Diff line Loading @@ -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!'); } } core/modules/system/src/Form/ThemeSettingsForm.php +0 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,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' => [], Loading Loading
core/lib/Drupal/Core/Render/Element/File.php +26 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -36,6 +40,9 @@ public function getInfo() { ], '#theme' => 'input__file', '#theme_wrappers' => ['form_element'], '#value_callback' => [ [$class, 'valueCallback'], ], ]; } Loading Loading @@ -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; } }
core/modules/file/tests/file_test/file_test.routing.yml +6 −0 Original line number Diff line number Diff line Loading @@ -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'
core/modules/file/tests/file_test/src/Form/FileRequiredTestForm.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?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; } }
core/modules/file/tests/src/Functional/SaveUploadTest.php +22 −0 Original line number Diff line number Diff line Loading @@ -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!'); } }
core/modules/system/src/Form/ThemeSettingsForm.php +0 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,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' => [], Loading