我有一个带有多个托管文件上传的自定义模块。
$form['attachments'] = [
'#type' => 'managed_file',
'#multiple' => true,
'#upload_validators' => [
'file_validate_extensions' => ['jpg docx pdf xlsx jpeg png gif'],
'file_validate_size' => [10485760],
],
];
当上传一个大于 10MB 的文件时,它会通过 AJAX 给出正确的错误,即文件不能大于 10MB。开箱即用。
如何限制可以通过此表单上传的所有文件的总 MB?
例如:3MB 的 3 个文件 = 正常 3MB 的 4 个文件 = 错误。
发生这种情况时,我设法显示了一条消息
public function validateForm(array &$form, FormStateInterface $form_state) {
$max_size = 10485760;
$total_size = 0;
$triggered_element = $form_state->getTriggeringElement();
if($triggered_element['#name'] == 'attachments_upload_button') {
$fids = (array) $form_state->getValue('attachments', []);
if(!empty($fids)) {
$files = File::loadMultiple($fids);
foreach ($files as $key => $uploadedFile) {
$total_size += $uploadedFile->getSize();
if($total_size > $max_size) {
$form_state->setErrorByName('attachments', $this->t('The total maximum size of your file sizes can not be more than 10MB.'));
$form_state->set('attachments',array_pop($fids));
return;
}
}
}
}
}
但我似乎无法删除最后上传的文件。它仍然存在,并在表单提交时提交。消息的一部分,代码不阻止提交表单。
我希望从 form_state 以及 tmp 服务器文件夹中删除所有文件总数 > 10M 的最后提交的文件。理想情况下,通过 AJAX 不会丢失字段输入。
我找不到解决方案。提前致谢。
我怎样才能通过ajax实现这一点。
好吧,事实证明这并不难。使用上传验证器可以添加变量。所以我将 $form_state 作为变量添加到自定义上传验证器。
$form['attachments'] = [
'#type' => 'managed_file',
'#multiple' => true,
'#upload_validators' => [
'file_validate_extensions' => ['jpg docx pdf xlsx jpeg png gif'],
'file_validate_size' => [10485760],
'size_max_upload' => [$form_state],
],
];
并写了一个自定义验证器函数
/**
* Validate maximum size upload.
*
* @param \Drupal\file\FileInterface $file
* File object.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state object.
*
* @return array
* Errors array.
*/
function size_max_upload(File $file, &$form_state) {
$errors = [];
$max_size = 10485760;
$total_size = $file->getSize();
$triggered_element = $form_state->getTriggeringElement();
if($triggered_element['#name'] == 'attachments_upload_button') {
$fids = (array) $form_state->getValue('attachments', []);
if(!empty($fids)) {
$files = File::loadMultiple($fids);
foreach ($files as $key => $uploadedFile) {
$total_size += $uploadedFile->getSize();
if($total_size > $max_size) {
$errors[] = t("The total maximum size of your file sizes can not be more than 10MB.");
break;
}
}
}
}
return $errors;
}