简介
我正在使用:
- Symfony v6.3.3
- OneUpUploaderBundle v4.0.1
- UPPY(通过Yarn)
"@uppy/core": "^3.3.1"
"@uppy/dashboard": "^3.4.2"
"@uppy/golden-retriever": "^3.1.0"
"@uppy/locales": "^3.2.3"
"@uppy/xhr-upload": "^3.3.1"
在撰写本文时,还没有正式的OneUpUploaderBundle
与UPPY
集成。幸运的是,OneUpUploaderBundle
的开发人员具有前瞻性思维,并添加了support for a custom Uploader!
所以我选择实施它。
实现
首先,我选择使用Blueimp jQuery File Uploader设置上传,因为它是由bundle支持的。
成功后,我转移到设置上传与UPPY
和Custom uploader
。
对于我的CustomUploader
,我选择了BlueimpController
-从一堆其他上传器的捆绑支持。
目前上传工程与自定义上传(为UPPY)。
问题
出于安全原因,我不允许上传extension
* 与其mime type
不对应 * 的文件。我用UploadValidationListener
中的Symfony检查此(在服务器上,收到文件后)。在这种情况下,我需要向用户显示错误,但不知道如何将其传递给UPPY Dashboard
。
现状是:文件上传成功,但这样的文件不会被保留-因为它没有通过验证。如果没有消息,用户会想知道:幻影文件在哪里,因为他们看到他们上传成功!
代码
下面是UPPY
设置方式
'use strict';
import Translator from 'bazinga-translator';
import Uppy from '@uppy/core';
import Dashboard from '@uppy/dashboard';
import GoldenRetriever from '@uppy/golden-retriever';
import XHR from '@uppy/xhr-upload';
import '@uppy/core/dist/style.css';
import '@uppy/dashboard/dist/style.css';
import en_US from "@uppy/locales/lib/en_US";
const js_data = document.querySelector('#js-data');
let data_allowed_file_types_str = js_data.dataset.allowedFileTypes;
const data_allowed_file_types = data_allowed_file_types_str.split('|');
const data_allowed_file_size_min = js_data.dataset.allowedFileSizeMin;
const data_allowed_file_size_max = js_data.dataset.allowedFileSizeMax;
const data_upload_endpoint = js_data.dataset.uploadEndpoint;
const uppy = new Uppy({
debug: false,
locale: en_US,
onBeforeFileAdded: (currentFile, files) =>
{
const do_not_allow_arr = ['do_not_allow_me_1.txt', 'do_not_allow_me_2.txt', 'do_not_allow_me_3.txt'];
let allowed = true;
do_not_allow_arr.forEach((element) =>
{
if (currentFile.name === element)
{
allowed = false;
uppy.log(Translator.trans('upload.error.skipFilesFromBlockList'));
uppy.info((Translator.trans('upload.error.skipFilesFromBlockList')), 'error', 5000);
return allowed;
}
});
return allowed;
},
});
uppy.use(GoldenRetriever);
uppy.use(Dashboard, {
inline: true,
target: '#uppy-dashboard',
id: 'uppy',
width: '100%',
proudlyDisplayPoweredByUppy: false,
showProgressDetails: true,
});
uppy.use(XHR, {
endpoint: data_upload_endpoint
});
uppy.setOptions({
restrictions:
{
minNumberOfFiles: 1,
maxNumberOfFiles: 1,
minFileSize: data_allowed_file_size_min,
minTotalFileSize: data_allowed_file_size_min,
maxTotalFileSize: data_allowed_file_size_max,
allowedFileTypes: data_allowed_file_types
},
//autoProceed: true
});
uppy.on('file-added', (file) => {
console.log('Added file', file);
});
uppy.on('upload-success', (file, responseObject) => {
// (depending on the uploader plugin used, it might contain
// less info, the example is for @uppy/xhr-upload)
// responseObject = {
// status, // HTTP status code (0, 200, 300)
// body, // response body
// uploadURL // the file url, if it was returned
// }
console.log('after upload success');
});
uppy.on('upload-error', (file, responseObject) => {
// responseObject = {
// status, // HTTP status code (0, 200, 300)
// body // response body
// }
console.log('after upload error');
});
下面是验证器代码
<?php
namespace App\EventListener;
use App\Entity\FileType;
use App\UltraHelpers\UltraHelpers;
use Doctrine\Persistence\ManagerRegistry;
use Oneup\UploaderBundle\Event\ValidationEvent;
use Oneup\UploaderBundle\Uploader\Exception\ValidationException;
use Symfony\Component\Mime\MimeTypes;
class UploadValidationListener
{
/**
* @var ManagerRegistry
*/
private ManagerRegistry $doctrine;
/**
* @var UltraHelpers
*/
private UltraHelpers $ultraHelpers;
public function __construct(
ManagerRegistry $doctrine,
UltraHelpers $ultraHelpers
)
{
$this->doctrine = $doctrine;
$this->ultraHelpers = $ultraHelpers;
}
public function onValidate(ValidationEvent $event): void
{
$repo_file_Type = $this->doctrine->getRepository(FileType::class);
$file_extensions_allowed = $repo_file_Type->getActivatedFileTypeOnlyListArray();
$mimeTypes = new MimeTypes();
$errors = [];
$file_list_banned = [];
$file_list_banned[] = 'do_not_allow_me_1.txt';
$file_list_banned[] = 'do_not_allow_me_2.txt';
$file_list_banned[] = 'do_not_allow_me_3.txt';
$config = $event->getConfig();
$file = $event->getFile();
$filtered_file_info = $this->ultraHelpers->filterFileInfoFromFileName($file->getClientOriginalName());
$transliterated_file_name = $filtered_file_info['name'];
$full_file_name = $transliterated_file_name .'.'. $filtered_file_info['extension'];
$file_extension = $filtered_file_info['extension'];
$file_mime_type_from_file = $mimeTypes->guessMimeType($file);
$file_mime_types_from_extension = $mimeTypes->getMimeTypes($file_extension);
// process forbidden_files
if (in_array($full_file_name, $file_list_banned, true))
{
$errors[] = 'error.file_banned';
}
// If mime type of current file does not correspond to extensions mime type
// Damaged file or specially prepared for research / hacking
if (!in_array($file_mime_type_from_file, $file_mime_types_from_extension, true))
{
$errors[] = 'error.mime_type_mismatch';
}
if (!empty($errors))
{
throw new ValidationException(implode(', ', $errors));
}
}
}
1条答案
按热度按时间biswetbf1#
可以使用
ExceptionListener
,请在这里查看示例https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-listenerservices.yaml