0

我有一个带有多个托管文件上传的自定义模块。

        $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;
}
4

0 回答 0