eltharin / fileuploadmanager
fileuploadmanager 用于 symfony 的包
README
安装
- 使用 composer 安装包
composer require eltharin/fileuploadmanager
什么是 fileuploadmanager 包?
FileUploadManager 包使文件上传变得最简单,只需少量配置,即可实现自动上传。
它是如何工作的?
您可以通过两种不同的方式保存文件
- 内联:内容将保存在数据库中,以 base64 编码
- 文件系统:数据库将存储文件路径
您可以选择是否为文件创建一个实体。
案例
您有一个名为 Foo 的实体,它有一个表示文件的字段 bar。Bar 是文本类型,可空(如果不是文件),对于路径,您可以设置字符串。
#[ORM\Entity(repositoryClass: FooRepository::class)] class Foo { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $bar = null; ... public function getId(): ?int { return $this->id; } public function getBar(): ?string { return $this->bar; } public function setBar(?string $bar): static { $this->bar = $bar; return $this; } ... }
以下是一些不同的案例
1- 内容内联为 base64
在 FormType 中:您只需为 bar 属性添加一个项目,从 FileUploadType 中选择一些参数。
现在,如果您想将文件内容直接设置在字段中为 base64,可以设置以下选项
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('bar', FileUploadType::class, [ 'file_storage_inline' => true, 'file_storage_json' => false, ]); } }
字段内容将如下所示
iVBORw0KG`...`5ErkJggg==
2- 内容内联为 json
如果要让字段内容是一个包含名称、大小、内容和 mime-type 的 Json,选项将是
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('bar', FileUploadType::class, [ 'file_storage_inline' => true, 'file_storage_json' => true, //true is the default value, you can omit this line ]); } }
字段内容将如下所示
{"content":"iVBORw0KG`...`5ErkJggg==","name":"55c488f3e3888f054ca531dbd7252c34.png","size":81049,"mimeType":"image\/png"}
3- 内容在公共文件夹中的文件系统中为 json
如果要让字段内容是一个包含名称、大小、 mime-type 和文件路径的 Json,选项将是
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('bar', FileUploadType::class, [ 'file_storage_inline' => false, // false is the default value, you can omit this line 'file_storage_json' => true, // true is the default value, you can omit this line 'file_storage_path' => '/public/files',// "/public/files" is the default value, you can omit this line ]); } }
字段内容将如下所示
{"path":"\/public\/files\/55c488f3e3888f054ca531dbd7252c34_65de10fd784d8.png","name":"55c488f3e3888f054ca531dbd7252c34.png","size":81049,"mimeType":"image\/png"}
4- 内容在非公共文件夹中的文件系统中为 json
如果要让字段内容是一个包含名称、大小、内容和 mime-type 的 Json
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('bar', FileUploadType::class, [ 'file_storage_inline' => false, // false is the default value, you can omit this line 'file_storage_json' => true, // true is the default value, you can omit this line 'file_storage_path' => '/var/data/files', ]); } }
字段内容将如下所示
{"path":"\/var\/data\/files\/55c488f3e3888f054ca531dbd7252c34_65de10fd784d8.png","name":"55c488f3e3888f054ca531dbd7252c34.png","size":81049,"mimeType":"image\/png"}
如您所见,案例 3 和 4 类似,因为它们执行的是相同的操作,但是,由于文件不在公共文件夹中,系统不知道如何搜索它以使其可下载,因此在表单中链接消失。
为了解决这个问题,您可以将一个函数传递给参数:'file_downloadLink',如下所示
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; class FooType extends AbstractType { public function __construct(private UrlGeneratorInterface $router) { } public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('bar', FileUploadType::class, [ 'file_storage_inline' => false, // false is the default value, you can omit this line 'file_storage_json' => true, // true is the default value, you can omit this line 'file_storage_path' => '/var/data/files', 'file_downloadLink' => function (FormView $view) {return $this->router->generate('app_foo_showimg', ['id' => $view->parent->vars['value']->getId()]);}, ]); } }
在函数中,我们请求路由生成器获取名为 app_foo_showimg 的路由,该路由需要 Foo id 以显示关联的图片,Foo id 通过获取 $view->parent->vars['value']->getId() 获取。$view 是 UplodFormType,$view->parent 是前面的类型,因此是 FooType,获取值及其 id。
file_downloadLink 函数还用于图像类型文件的情况,在这种情况下,图像也显示在表单中,要设置此选项,必须将 'file_type' 选项设置为 'image'。
单独的实体中的文件
您可以选择将文件存储在单独的实体中,以简化数据库查询,或者为了有一个 ManyToX 关系,将许多文件关联到您的实体。
为此,您有两个 MappedSuperClass,Eltharin\FileUploadManagerBundle\Entity\FileInline 和 Eltharin\FileUploadManagerBundle\Entity\FilePath,您只需创建自己的实体,从其中一个扩展它,并创建自己的关系。
我们将将我们的 Foo 类更改为 File 实体
namespace App\Entity; #[ORM\Entity(repositoryClass: FooRepository::class)] class Foo { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\ManyToOne( cascade: ['persist'])] private ?File $fileInEntity = null; public function getId(): ?int { return $this->id; } public function getFileInEntity(): ?File { return $this->fileInEntity; } public function setFileInEntity(?File $fileInEntity): static { $this->fileInEntity = $fileInEntity; return $this; } }
以及 File 实体
namespace App\Entity; #[ORM\Entity(repositoryClass: FileRepository::class)] class File extends \Eltharin\FileUploadManagerBundle\Entity\FileInline { }
现在,您只需设置实体类为
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; use App\Entity\File; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('imageentityinline', FileUploadType::class, [ 'data_class' => File::class, ]); } }
当使用 Eltharin\FileUploadManagerBundle\Entity\FileInline 时,可以省略 file_storage_inline 选项,它将自动设置。
您也可以使用多对多关系,并关联其所属的集合
#[ORM\Entity(repositoryClass: FooRepository::class)] class Foo { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\ManyToMany(targetEntity: FilePath::class,cascade: ['persist'])] private Collection $manyimage; /** * @return Collection<int, FilePath> */ public function getManyimage(): Collection { return $this->manyimage; } public function addManyimage(FilePath $manyimage): static { if (!$this->manyimage->contains($manyimage)) { $this->manyimage->add($manyimage); } return $this; } public function removeManyimage(FilePath $manyimage): static { $this->manyimage->removeElement($manyimage); return $this; } }
表单类型
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; use App\Entity\File; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class FooType extends AbstractType { public function __construct(private UrlGeneratorInterface $router) { } public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('manyimage', CollectionType::class,[ 'allow_add' => true, 'allow_delete' => true, 'required' => false, 'entry_type' => FileUploadType::class, 'entry_options' => [ 'data_class' => File::class, 'file_type' => 'image', 'file_storage_path' => '/var/data/files', 'file_downloadLink' => function (FormView $view) {return $this->router->generate('app_foo_showimg2', ['foo' => $view->parent->parent->vars['value']->getId(), 'file' => $view->vars['value']->getId()]);}, 'delete_on_remove' => false, ], ]); } }
在多对多关系的情况下,请考虑将 delete_on_remove 选项设置为 false,此选项可以被对文件实体上的 onDelete 事件的 eventlistener 替换。
其他选项
-
allow_update : 允许用户通过设置 input[type=file] 来替换文件(如果已存在文件)。默认值:true;
-
allow_delete : 允许用户在不替换其他文件的情况下删除文件,在表单中会显示一个复选框。
-
upload_options : 传递给输入字段的选项
-
delete_options : 传递给删除复选框字段的选项
-
file_manager : 如果缺少某些选项,您可以创建自己的文件管理器服务
- 您必须创建一个带有 autoConfigure 属性且标签为 app.fileManager 的类
- 类必须实现 Eltharin\FileUploadManagerBundle\Form\FileManager\FileManagerInterface
- 完成您自己的函数
#[Autoconfigure(tags: ['app.fileManager'])] class FileManagerService implements FileManagerInterface { public function populate(&$fileData, UploadedFile $file, $options) { ... } public function remove(&$fileData, array $options) { $fileData = null; } public function getFileViewData(FormView $view, array $options) : array { ... return [ 'thumbnail' => $thumbnail, 'download_link' => $link, 'download_name' => $name, ]; } }
并将其传递给类型选项
use Eltharin\FileUploadManagerBundle\Form\FileUploadType; use App\Entity\File; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('file', FileUploadType::class, [ 'file_manager' => FileManagerService::class, ]); } }
您不喜欢我的默认值吗?
您可以在 /conf/packages/ 目录下创建一个名为 eltharin_file_upload_manager.yaml 的 Yaml(或 XML 或 PHP,根据您的配置)
并设置您自己的默认值
eltharin_file_upload_manager: default: allow_update: false allow_delete: true data_class: null delete_on_remove: false file_storage_inline: true file_manager: 'App\Service\FileManager' file_storage_json: false file_storage_path: '/public/documents'