clevis / files-upload-control
Nette Forms 的文件上传控制。
Requires
- php: >= 5.3.7
Requires (Dev)
- mockery/mockery: @dev
- nette/nette: @dev
- petrp/access: @dev
This package is not auto-updated.
Last update: 2024-09-23 15:27:33 UTC
README
表单组件用于文件上传。请下载并创建一个模板,默认模板可能不适合您。
允许以两种方式发送文件
- 正常表单方式。
- Ajax方式。
在处理表单时,您将获得作为字段元素的实体值,这些实体代表文件。请参阅与模型的连接。
Ajax信号的API是根据jQuery File Upload Plugin定制的,但应与其他上传库兼容。请参阅与前端连接。
兼容性
测试通过Nette @dev
(目前为 nette/nette@ae11ca1) 和 2.0.12
。
在PHP 5.3上测试不会通过 - 我在闭包中多次使用了 $this
,并且可能还有一些缩写的数组... 但是组件应该在PHP 5.3上工作。
与模板工厂的连接
组件要求在服务容器中有一个名为 "templateFactory" 的服务,它有一个公共方法 createTemplate($file, Nette\Application\UI\Control $control)
。
这有点复杂,但在这里不会详细说明正确的解决方案(正确的解决方案应该有一个接口,该接口在另一个包中定义,该包要求这个包;最好的情况是,这个接口已经在Nette中定义了)。
与模型的连接
这个组件的构造函数传递一个 IFilesRepository
对象,该对象负责 CRUD IFileEntity
类型实体。它可以部署在 PetrP/Orm
和 Tharos/LeanMapper
上。仓库还负责将文件移动到临时目录之外。
请注意,仅在通过信号上传时调用 saveFile
。对于通过表单上传的文件,您必须在表单处理程序中处理实体的存储。
与前端连接
Nette中每个表单元素的属性是 htmlName
,POST变量的名称由此派生。
htmlName[]
- 上传的文件。htmlName-autoUploaded[]
- 通过Ajax上传的文件的ID。仅在此处处理表单发送。
因此,通过HTML上传由 <input type="file" name="{$control->htmlName}[]">
处理,任何Ajax上传器也使用相同的名称(只是不同的URL,下面会详细说明)。
Ajax上传器在Ajax上传成功后应将 <input type="hidden" name="{$control->htmlName}-autoUploaded[]" value="...">
插入到表单中,其中 value
将是上传文件的ID(从上传信号的payload中获取)。这样表单就会记住通过它上传了哪些文件,并在提交后从仓库中提取它们的实体。
这个组件不仅限于上传新文件,还可以成功用于更改现有文件的顺序。只需列出它们,并为每个添加一个 hidden
与 htmlName-autoUploaded[]
。添加jQuery sortable,任务完成。在处理时,您将获得所有文件的正确顺序数组。
Ajax上传信号
{$control->getUploadLink()}
接受 htmlName[]
中的文件,返回以下格式的JSON payload
{
"files": [
{
"id": 1,
"name": "nazev-souboru.txt",
"size": 123,
"type": "text/plain",
"delete_type": "DELETE",
"delete_url": "URL delete signálu",
"thumbnail_url": "URL náhledu",
"url": "URL plné velikosti"
},
{
"id": 1,
"name": "jini-soubor.gif",
"size": 666,
"type": "image/gif",
"delete_type": "DELETE",
"delete_url": "URL delete signálu",
"thumbnail_url": "...",
"url": "..."
},
{
"name": "prilis-velky-soubor.txt",
"error": "Maximální povolená velikost souboru je 123."
},
{
"name": "vice-problemu.gif",
"error": [
"Je vyžadována přípona TXT.",
"Maximální povolená velikost souboru je 123."
]
}
]
}
仅在组件定义了 IUrlProvider 时,thumbnail_url
和 url
的值才在响应中。如果格式不符合要求,您可以重定义 createFilePayload()
和 createErrorPayload()
方法。
仅根据以下规则进行上传验证
FilesUploadControl::MAX_FILE_SIZE
FilesUploadControl::MIME_TYPE
FilesUploadControl::IMAGE
FilesUploadControl::RULE_EXTENSION
如果控件上部署了其他验证器,那么这些验证器将在表单提交后才会被调用。
Ajax 删除信号
{$control->getDeleteLink(IFileEntity $file)}
如果组件设置了会话部分(参见 setAutoUploadsSessionSection()
),则可以通过此信号删除(或调用 IFilesRepositor::deleteFile()
)通过上传信号上传的文件,但这些文件在表单提交时还没有被处理。
即使没有设置会话,或者会话中不存在该文件,也会调用 onBeforeDelete
和 onDelete
事件,因此您可以扩展此行为。
无论操作结果如何,都会返回此响应
{
"success": true
}
组件设置
可选依赖
setUrlProvider(IFileUrlProvider $urlProvider)
- 如果上传信号需要返回 URL 和预览 URL,则需要知道如何操作。setAutoUploadsSessionSection(SessionSection $autoUploadsSession)
- 如果要使用删除信号。
事件
onAutoUpload(IFileEntity $file, \ArrayObject $filePayload)
- 在文件上传信号保存文件后。可以修改 payload(这是一个 ArrayObject,因为我在传递数组引用时遇到了一些问题,现在不知道是什么问题)。onBeforeDelete(IFileEntity $file)
- 在删除前。onDelete(IFileEntity $file)
- 删除后,即使没有成功,也会调用。这可能需要更改。
防止 CSRF 攻击
如果表单通过 Form::addProtection()
受保护,则此组件的 Ajax 信号也将受保护。方法 getUploadLink()
和 getDeleteLink()
会将令牌添加到信号 URL,并在处理信号时进行检查。