diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php index 6bd7031..1e42eed 100644 --- a/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -292,19 +292,21 @@ public static function processManagedFile(&$element, FormStateInterface $form_st // validation runs before submit handlers and prevents handling these // files in a submit handler. $values = NestedArray::getValue($form_state->getValues(), $element['#parents']); - foreach ($values['fids'] as $key => $fid) { - if (isset($values['file_' . $fid]) && $values['file_' . $fid]['selected']) { - // If it's a temporary file we can safely remove it immediately, otherwise - // it's up to the implementing module to remove usages of files to have them - // removed. - if ($element['#files'][$fid] && $element['#files'][$fid]->isTemporary()) { - $element['#files'][$fid]->delete(); + if (isset($values['fids'])) { + foreach ($values['fids'] as $key => $fid) { + if (isset($values['file_' . $fid]) && $values['file_' . $fid]['selected']) { + // If it's a temporary file we can safely remove it immediately, otherwise + // it's up to the implementing module to remove usages of files to have them + // removed. + if ($element['#files'][$fid] && $element['#files'][$fid]->isTemporary()) { + $element['#files'][$fid]->delete(); + } + unset($element['#files'][$fid]); + unset($values['fids'][$key]); } - unset($element['#files'][$fid]); - unset($values['fids'][$key]); } + NestedArray::setValue($form_state->getValues(), $element['#parents'], $values); } - NestedArray::setValue($form_state->getValues(), $element['#parents'], $values); foreach ($element['#files'] as $delta => $file) { $file_link = [ diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php index 7c24aab..97e2be9 100644 --- a/core/modules/file/src/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php @@ -419,4 +419,48 @@ function testWidgetValidation() { $this->assertNoRaw($error_message, t('Validation error removed when file with correct extension uploaded (JSMode=%type).', array('%type' => $type))); } } + + /** + * Tests removal of excess files when too many files were uploaded. + */ + function testExcessFileRemoval() { + $node_storage = $this->container->get('entity.manager')->getStorage('node'); + $type_name = 'article'; + $field_name = strtolower($this->randomMachineName()); + $cardinality = 3; + $this->createFileField($field_name, 'node', $type_name, ['cardinality' => $cardinality]); + + $test_file = $this->getTestFile('text'); + $upload_files = [$test_file, $test_file]; + + foreach (array('nojs', 'js') as $type) { + // Try to upload multiple files, but fewer than the maximum. + $nid = $this->uploadNodeFiles($upload_files, $field_name, $type_name); + $node_storage->resetCache([$nid]); + $node = $node_storage->load($nid); + $this->assertEqual(count($node->{$field_name}), count($upload_files), 'Node was successfully saved with mulitple files.'); + + // Try to upload more files than allowed on revision. + $this->uploadNodeFiles($upload_files, $field_name, $nid, 1); + $args = ['%field' => $field_name, '@count' => $cardinality]; + $this->assertRaw(t('%field: this field cannot hold more than @count values.', $args), 'Node with file displays too many files error.'); + $this->assertFieldByXpath('//input[@type="submit"]', t('Remove selected'), 'Node with file displays the "Remove selected" button.'); + + // Locate the last checkbox + $last_fid = $this->getLastFileId(); + $edit = [$field_name . '[2][file_' . $last_fid . '][selected]' => TRUE]; + + switch ($type) { + case 'nojs': + $this->drupalPostForm(NULL, $edit, t('Remove selected')); + break; + case 'js': + $button = $this->xpath('//input[@type="submit" and @value="' . t('Remove selected') . '"]'); + $this->drupalPostAjaxForm(NULL, $edit, array((string) $button[0]['name'] => (string) $button[0]['value'])); + break; + } + $this->assertNoRaw(t('%field: this field cannot hold more than @count values.', $args), 'Excess files were succesfully removed'); + } + } + }