stechstudio / laravel-shuttle
这是我创建的包:laravel-shuttle
Requires
- php: ^8.0|^8.1
- illuminate/contracts: ^9.19.0
- league/flysystem-aws-s3-v3: ^3.0
- orchestra/testbench: ^7.6
- spatie/laravel-package-tools: ^1.9.2
Requires (Dev)
- laravel/pint: ^0.2.3
- nunomaduro/collision: ^6.2
- nunomaduro/larastan: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.1
- phpunit/phpunit: ^9.5
- spatie/laravel-ray: ^1.29
This package is auto-updated.
Last update: 2024-09-23 16:36:55 UTC
README
此包旨在提供一个简单而令人惊叹的方法,在TALL应用程序中实现大规模文件上传,直接上传到S3。
- 只需使用单个Blade组件集成到您的应用程序中,这就是全部。
- UI就绪。您不需要在UI中实现任何内容。用户可以在页面的任何位置拖放文件,并且会显示一个固定在底部的进度条。
- 当文件上传时,会触发事件,因此您的应用程序可以做出反应并相应地更新UI。
安装
1. 使用Composer安装此包
composer require stechstudio/laravel-shuttle
2. 迁移数据库
Shuttle会设置自己的uploads
表以存储每个文件的详细信息。然后您的应用程序可以使用这些上传记录,或者您可以在上传完成后将文件信息移动到不同的数据库表中。
php artisan migrate
3. 添加路由
Shuttle将为多部分上传创建所有必要的路由,您只需告诉Shuttle在哪里定义路由即可。这样,您可以包装任何中间件、路由前缀或其他要求。
Route::middleware(['auth'])->group(function() { Shuttle::routes(); });
4. 配置AWS
确保您已经在Laravel中正确配置了一个s3
磁盘。如果您想更改Shuttle使用的磁盘或S3客户端,请参阅下面的高级配置。
您决定使用的S3存储桶需要配置CORS。在AWS控制台中打开存储桶,点击权限选项卡,滚动到CORS框,并粘贴以下内容
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST",
"PUT",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3000
}
]
如果您希望,可以进一步限制来源。
免责声明
CORS Everywhere插件与此包不兼容。请确保在本地开发时将其禁用。
实现
在您的应用程序中实现Shuttle非常简单,让我们一步一步来。
1. 实现Blade组件
是时候将Shuttle应用到您的应用程序中了。您只需在视图中使用Blade组件,以便用户可以上传文件。这应该是一个Livewire视图文件。
<x-shuttle::uploader />
2. 添加上传上下文
您的Livewire组件需要公开一个$uploadContext
数组,其中包含有关上传文件的所有元数据,这些元数据将在以后用于确定所有权。
例如,假设您有一个简单的文件夹/文件应用程序。当用户上传文件到,您将需要将文件夹ID添加到每个文件上传中,以便可以在数据库中确定如何关联文件。您的Folder
Livewire组件类可能看起来像这样
class Folder extends Component { public $uploadContext = []; public $folder; public function mount(Folder $folder) { $this->folder = $folder; $this->uploadContext = ['folder_id' => $folder->id]; }
3. 告诉Shuttle如何关联文件
当文件上传时,Shuttle需要知道文件的所有者。我们不是指执行上传的用户,而是指文件应附加到的模型。这通常是文件夹或项目。
在您的AppServiceProvider
的boot()
方法中,您将需要定义一个回调函数,该函数接收文件元数据(包括前一步中提供的上下文信息)。这将返回一个数据库模型。
因此,对于上面的文件夹示例,我们可能定义一个回调函数如下
Shuttle::resolveOwnerWith(function(array $metadata) { return Folder::findOrFail($metadata['folder_id']); });
Shuttle现在将确保上传的文件具有设置为该文件夹的owner
关系。
您还需要在拥有者模型上添加HasUploads
特性。在我们的示例中,这将是Folder
模型。
警告
这是一个基本示例,用于使事物运行。您很可能会在回调函数中执行一些授权检查,以确保当前登录的用户有权将文件上传到指定的文件夹。
4. 将关系添加到您的拥有者模型,或者自己处理完成的上传
如果您想直接使用uploads
数据库记录,就没有什么需要做的了。您可以使用我们的上一个示例设置,通过$folder->uploads
访问,并检索所有已上传的文件。
或者,如果您希望自己处理上传文件的数据,可以设置一个回调,Shuttle在上传完成后执行。在您的AppServiceProvider
中这样做
Shuttle::whenComplete(function(Upload $upload) { // ...store the upload information somewhere else in your database });
在这种情况下,您可能希望将Upload
记录视为临时文件,并在处理完上述回调后执行$upload->delete()
。
上传文件
到目前为止,您应该能够访问到您实现Shuttle Blade组件的应用程序页面,并在Livewire组件中提供上传上下文。
将一些文件拖放到页面上,应该会看到一个半透明的覆盖层出现,告诉您可以放下您的文件。
一旦放下文件,您应该在页面底部看到一个条形图,显示上传的状态。您可以展开这个条形图,查看每个文件的上传状态。
当所有放下文件成功上传时,条形图会变成绿色。如果任何上传失败,它会变成红色并自动展开,显示错误消息。
事件
我们公开以下您可以监听的事件。
定制
您能够定制UI的颜色。您只需发布配置文件即可。
php artisan vendor:publish --tag=shuttle-config
<?php declare(strict_types=1); return [ /** * The URL endpoint used to trigger the * upload process. */ 'url_prefix' => '/uploader', /** * The disk you want to use for file uploads. This * must be a disk that uses the S3 driver. */ 'disk' => 's3', /** * The authentication guard used for authorization. */ 'guard' => 'web', /** * The background colors used for the file uploader UI. * You can customise the color for each state. You can * use any valid Tailwind background class. If you * need to specify a custom HEX value, create a * new color variable in your Tailwind config * file. Custom HEX values are not compiled * at run time. */ 'colors' => [ 'details-panel' => [ 'uploading' => env(key: 'DETAILS_PANEL_UPLOADING', default: 'bg-blue-500'), 'upload-success' => env(key: 'DETAILS_PANEL_UPLOAD_SUCCESS', default: 'bg-green-500'), 'upload-error' => env(key: 'DETAILS_PANEL_UPLOAD_ERROR', default: 'bg-red-500'), ], ], ];
CSRF令牌
您需要将以下内容添加到您的VerifyCsrfToken中间件中,以防止CSRF令牌不匹配错误。
protected $except = [ 'upload/sign/*', '*uploader/s3/multipart*' ];