Skip to content
Snippets Groups Projects
Verified Commit a5b44e8f 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
parent a30c59d4
No related branches found
No related tags found
37 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!54479.5.x SF update,!5014Issue #3071143: Table Render Array Example Is Incorrect,!4868Issue #1428520: Improve menu parent link selection,!4289Issue #1344552 by marcingy, Niklas Fiekas, Ravi.J, aleevas, Eduardo Morales...,!4114Issue #2707291: Disable body-level scrolling when a dialog is open as a modal,!4100Issue #3249600: Add support for PHP 8.1 Enums as allowed values for list_* data types,!3630Issue #2815301 by Chi, DanielVeza, kostyashupenko, smustgrave: Allow to create...,!3600Issue #3344629: Passing null to parameter #1 ($haystack) of type string is deprecated,!3291Issue #3336463: Rewrite rules for gzipped CSS and JavaScript aggregates never match,!3102Issue #3164428 by DonAtt, longwave, sahil.goyal, Anchal_gupta, alexpott: Use...,!2853#3274419 Makes BaseFieldOverride inherit the internal property from the base field.,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2074Issue #2707689: NodeForm::actions() checks for delete access on new entities,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1484Exposed filters get values from URL when Ajax is on,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1254Issue #3238915: Refactor (if feasible) uses of the jQuery ready function to use VanillaJS,!1162Issue #3100350: Unable to save '/' root path alias,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!957Added throwing of InvalidPluginDefinitionException from getDefinition().,!925Issue #2339235: Remove taxonomy hard dependency on node module,!877Issue #2708101: Default value for link text is not saved,!873Issue #2875228: Site install not using batch API service,!872Draft: Issue #3221319: Race condition when creating menu links and editing content deletes menu links,!844Resolve #3036010 "Updaters",!712Issue #2909128: Autocomplete intermittent on Chrome Android,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer
......@@ -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;
}
}
......@@ -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'
<?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;
}
}
......@@ -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!');
}
}
......@@ -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' => [],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment