Verified Commit e3930ea5 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #59750 by quietone, larowlan, mikeryan, quicksketch, sreynen, kleinmp,...

Issue #59750 by quietone, larowlan, mikeryan, quicksketch, sreynen, kleinmp, kim.pepper, Bèr Kessels, chx, S3b0uN3t, ravi.shankar, mrddthi, webchick, neclimdul, Lendude: Required flag on file forms breaks on validation

(cherry picked from commit a5b44e8f)
parent bcf1477d
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -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;
  }

}
+6 −0
Original line number Diff line number Diff line
@@ -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'
+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;
  }

}
+22 −0
Original line number Diff line number Diff line
@@ -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!');
  }

}
+0 −1
Original line number Diff line number Diff line
@@ -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' => [],