fboseca / files_manager
将Laravel模型与上传的文件关联
Requires
- php: >=7.1.3
- laravel/framework: >=6
Requires (Dev)
- orchestra/canvas: 5.x-dev
- orchestra/testbench: 5.x-dev
- phpunit/phpunit: 8.5.x-dev
This package is auto-updated.
Last update: 2024-09-30 01:26:58 UTC
README
功能
此包允许您跟踪上传的文件,为此,它将每个文件与Laravel模型关联,从而实现快速便捷的管理。
安装后,您可以执行以下操作
$user = User::find(1);
//attach a file with a User model
//thats will be save the file on bbdd and the storage app/public/files by default
$user->addFile($request->file('file'));
//for download all images into a zip file
$user1->images->toZipFile()->download('allMyImages');
//for delete all images with date less now
$user1->images()->where('created_at', '<', Carbon:now())->removeFiles();
并在视图中显示图像文件
//return all images attached to User
@foreach ($user->images as $file )
<img src="{{$file->src}}" width="100"/>
@endforeach
//return all images from gallery
@foreach ($user->images()->withGroup('gallery')->get() as $file )
<img src="{{$file->src}}" width="100"/>
@endforeach
内容
安装
此包需要Laravel 6或更高版本以及Php 7.1.3或更高版本。
- 要安装文件管理器,请在终端运行
composer require fboseca/files_manager
- 打开您的
config/app.php
并在providers
数组中添加以下内容
'providers' => [
...,
Fboseca\Filesmanager\FilesManagerServiceProvider::class,
]
- 运行以下命令以发布包配置文件
config/filemanager.php
php artisan vendor:publish
- 现在我们必须创建文件表。默认表名为files_manager,但如果您想更改表名,可以在
config/filemanager.php
中的table_file键中进行更改。
因此,当您选择名称时,请运行以下命令
php artisan migrate
- 文件管理器使用Laravel存储链接,为您自己的主机保存公共文件,因此请运行以下命令
php php artisan storage:link
配置
将以下属性值复制到config/filesystems.php
。文件管理器使用Laravel的磁盘来保存文件,并将使用这些值来获取保存信息。
'temp' => [
'driver' => 'local',
'root' => storage_path('app/temp'),
'visibility' => 'private'
],
'private' => [
'driver' => 'local',
'root' => storage_path('app/private'),
'url' => env('APP_URL') . config('filemanager.url_link_private_files'),
'visibility' => 'private'
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public'
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'visibility' => 'public'
],
所有磁盘都必须有一个visibility字段,可以是public或private。
您可以根据需要修改任何磁盘并添加所有内容。
临时磁盘
拥有一个临时磁盘非常重要,您不应该将其从配置中删除。如果您更改临时磁盘的名称(不推荐),则必须在config/filemanager.php
中的disk_temp键中更改名称。
"disk_temp" => "{yourNameDisk}",
公共磁盘
默认情况下,本地公共磁盘不应修改。如果您想添加其他公共磁盘,您可以通过添加其他磁盘来实现。
请注意,所有公共文件都将保存在storage_path('app/public/{your-custom-folder}')下。
//disk by default
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
//new disk created
'uploads' => [
'driver' => 'local',
'root' => storage_path('app/public/uploads'),
'url' => env('APP_URL') . '/storage/uploads',
'visibility' => 'public',
]
请记住,当文件在公共磁盘上托管时,文件管理器使用Laravel的符号链接来返回路径,因此指示磁盘配置中的URL非常重要。
'root' => storage_path('app/public/{yourRoutePath}'),
'url' => env('APP_URL') . '/storage/{yourRoutePath}',
私有本地磁盘
对于私有磁盘,您必须确保根路径不在app/public下。
'private' => [
.....
'root' => storage_path('app/private'),
],
要获取私有文件路径,此包默认提供了一条路由,您必须使用此路由为所有创建的本地私有磁盘。
'private' => [
.....
'url' => env('APP_URL') . config('filemanager.url_link_private_files'),
],
'otherDiskPrivate' => [
.....
'url' => env('APP_URL') . config('filemanager.url_link_private_files'),
],
如果您想更改默认URL,您必须将其添加到Laravel的文件路由中。
Route::get('custom/files/{has}', function ($has) {
return \Redirect::route('file.manager.private', $has);
});
然后更改默认配置。
"url_link_private_files" => "/custom/files/",
请注意,在新路由中,has参数非常重要,因为私有文件的ID将被加密。
外部磁盘
对于外部驱动器,您必须提供文件所在的路径。
's3' => [
....
'url' => env('AWS_URL'),
'visibility' => 'private'
],
其他配置
配置此包的选项包括
文件扩展名
当我们保存文件时,它将以配置中扩展键中指定的类型保存。此文件配置为 config/filemanager.php
。默认情况下,所有图像扩展名的文件都被视为 img 类型,如下例所示,但您可以将其修改为所需的类型。
"extensions" => [
"bmp" => "img",
"gif" => "img",
"jpeg" => "img",
"jpg" => "img",
"png" => "img",
"tiff" => "img",
"*" => "file",
]
如果文件扩展名未出现在列表中,文件管理器将使用默认键 *
。
"extensions" => [ "*" => "file"]
在这种情况下,具有 txt 扩展名的文件将被视为 file 类型。
请勿从扩展名的配置中删除
*
值。
如果原始文件没有扩展名,文件管理器将应用默认文件扩展名,这可以在 extension_default 键中进行配置,默认为 txt。
"extension_default" => "txt"
按类型编制文件目录对于查找特定类型的文件非常重要,如以下所述。
用法
我们必须做的第一件事是在我们想要您拥有的文件日志模型中附加 HasFiles 特性。您可以选择任何模型来附加文件,您唯一需要做的是将特性放入模型中。
class User extends Authenticatable {
use Notifiable, HasFiles;
.....
}
现在 User 模型可以附加文件到自身。
添加文件
要将文件保存到模型中,请使用 addFile 方法传递您想要保存的文件。此方法接受文件作为第一个参数,选项数组的第二个参数,并返回一个 FileManager 类。
$user = User::find(1);
$newFile = $user->addFile($request->file('file'));
您添加的任何文件,永远不会被覆盖,这是一个安全系统,以防止文件被替换。文件管理器会自动创建一个唯一的随机名称,并将文件保存到配置中指示的数据库和磁盘文件夹。它将采用文件 config/filemanager.php
的默认配置。
"folder_default" => "files",
"disk_default" => "public",
更改名称
如果在磁盘和文件夹中存在相同名称,文件管理器会自动将名称更改为 name_(1).extension
,以确保文件不会被覆盖。
$newFile = $user->addFile($request->file('file'),[
"group" => "gallery",
"name" => "myNameFile",
"description" => "A description for a file",
"disk" => "s3",
"folder" => "otherFolder"
]);
请注意,没有必要指定文件扩展名,因为文件管理器会自动应用正确的扩展名到文件,并且它将根据配置检查文件类型。
扩展名将自动应用,请参阅 文件扩展名 文档。
出于安全原因,如果文件名包含空格或点,则文件名将被修改。例如,如果名称是 my Name File.d.doc,则将更改为 my_name_file.doc
。
只有第一个点之前的文本才是有效的,空格将被更改为
'_'
。
从路径添加文件
我们可以从路径资源添加文件。此方法接收文件路径作为第一个参数,作为可选参数具有与 addFile
方法相同的参数:group, name 和 description
$newFile = $user->addFileFromPath($pathOfFile);
$newFile = $user->addFileFromPath($pathOfFile,[
"group" => "gallery",
"name" => "myNameFile",
"description" => "A description for a file",
"disk" => "s3",
"folder" => "otherFolder"
]);
带有内容添加文件
我们可以使用内容添加文件。此方法接收文件路径作为第一个参数,文件扩展名作为第二个参数。同样,作为可选参数具有与 addFile
方法相同的参数:group, name 和 description
$newFile = $user->addFileWithContent('hello world', 'txt');
$newFile = $user->addFileWithContent('hello world', 'txt', [
"group" => "gallery",
"name" => "myNameFile",
"description" => "A description for a file",
"disk" => "s3",
"folder" => "otherFolder"
]);
获取文件
我们可以以多种方式访问模型的文件。简单的方法是调用关系 files。文件返回 FileManager 类的集合。
$user->files
如果您只想获取图像文件,可以调用关系 images。
@foreach ($user->images as $file )
<img src="{{$file->src}}" width="100"/>
@endforeach
@foreach ($user->files as $file )
<a href="{{$file->src}}" target="_blank">{{$file->name}}</a>
@endforeach
默认情况下,只为图像配置了获取模型类型文件的关系,但如果您想添加更多类型的关系,请参阅 为文件类型创建关系。
方法append和prepend
要向文件添加新内容,请使用方法 append(在文档末尾)和 prepend(在文档开头)。
$file1 = $user1->addFile($request->file('file'));
$file1->append('End of document');
$file1->prepend('Start of document');
删除
要删除文件,只需使用模型的方法 delete。此方法从数据库和主机中删除文件。
$file = $user->files()->find(1);
$file->delete();
因此,如果您想删除所有用户图像,请参阅 删除文件。
下载
要下载文件,请使用 download 方法。此方法接受一个参数来选择下载文件的名称,默认为当前名称。文件名不需要提供扩展名。
//in your controller
return $file->download();
return $file->download('name-of-file');
获取下载路由
对于在 HTML 中下载文件,FileManager 提供了下载文件的属性和路由。
对于公共文件,我们使用属性 downloadSrc,但如果我们想下载公共和私有文件,我们将使用 forceDownloadSrc
//in your view
<a href="{{$file->downloadSrc}}">download</a> //only for public files
<a href="{{$file->forceDownloadSrc}}">download</a> //for all public and privates files
默认路由是 download/file/{has}
,并且 FileManager 会自动将其放入配置中。 如果我们想更改默认下载路径,我们必须在 Laravel 路由文件中添加此代码
Route::get('you/route/{has}', function ($has) {
return \Redirect::route('download.file', $has);
})->name('{yourNameOfRoute}');
之后,我们必须更改配置。在 config/filemanager.php
文件中的 symbolic_link_download_files 将默认值更改为您路由的名称。
"symbolic_link_download_files" => "youNameOfRoute"
示例
//in route.php
Route::get('myNameOfPathDownloadFiles/{has}', function ($has) {
return \Redirect::route('download.file', $has);
})->name('download.route');
//in config/filemanager.php
"symbolic_link_download_files" => "download.route"
复制
方法 copy 将创建与原始文件同名的新文件副本。它将保存到与原始文件相同的文件夹和磁盘上。此方法接受选项数组作为参数。
$file = $user->files()->find(1);
$file2 = $file->copy(); //copy exactly the flie
//copy a file in distinct folder, disk, with distinct name, group and description
$file2 = $file->copy([
"folder" => 'fileCopied', //change folder
"disk" => 'private', //change disk
"name" => 'avatar', //change name
"group" => 'gallery', //change group
"description" => 'A description of file', //change description
]);
如果文件已存在于指定的文件夹和磁盘上,FileManager 将将其名称更改为 nameOfFile_(1).extension
以防止覆盖。
复制到模型
我们可以将文件复制到实现 HasFile 特性的其他模型中。为此,使用方法 copyToModel,将复制文件的模型作为第一个参数传递,并将数组选项作为第二个参数。
$file = $user->files()->find(1);
$file2 = $file->copyToModel($user2); //copy exactly the flie attaching to $user2
$file2 = $file->copyToModel($user2,[
"folder" => 'fileCopied', //change folder
"disk" => 'private', //change disk
"name" => 'avatar', //change name
"group" => 'gallery', //change group
"description" => 'A description of file', //change description
]);
此方法返回复制的文件。
移动
方法 move 将将此文件移动到其他文件夹。此方法需要文件夹作为第一个参数,并接受选项数组作为第二个参数。
$file = $user->files()->find(1);
$file2 = $file->move("other_folder"); //move the file to **other_folder folder**
$file2 = $file->move('other_folder',[
"disk" => 'private', //change disk
"name" => 'avatar', //change name
"group" => 'gallery', //change group
"description" => 'A description of file', //change description
]);
如果文件已存在于指定的文件夹和磁盘上,FileManager 将将其名称更改为 nameOfFile_(1).extension
以防止覆盖。
移动到模型
我们可以将文件移动到实现 HasFile 特性的其他模型中。为此,使用方法 moveToModel,将你想要移动文件的模型作为第一个参数传递,并将选项数组作为第二个参数。
$file = $user->files()->find(1);
$file2 = $file->moveToModel($user2); //move the flie attaching to $user2
$file2 = $file->moveToModel($user2,[
"folder" => 'fileCopied', //change folder
"disk" => 'private', //change disk
"name" => 'avatar', //change name
"group" => 'gallery', //change group
"description" => 'A description of file', //change description
]);
此方法返回移动的文件。
保存和获取头像
FileManager 提供了一个保存每个模型头像的方法。这是一个特殊的方法,只能接受一个图像,因此如果我们传递一个图像作为头像保存,最后一张图像将被删除。
为此,使用方法 setAvatar 并接受选项数组作为第二个参数。
$user->setAvatar($request->file('file'));
$fileSaved = $user->setAvatar($file, [
"name" => "logo2",
"folder" => "avatars",
"disk" => "s3",
"description" => "A description for a file"
]);
要获取头像实例,请使用属性 avatar,它返回一个 FileManager 模型。
<img src="{{$user->avatar->src}}" width="100"/>
请注意,头像不应保存到具有私有可见性的磁盘上
从图片获取源
对于图像文件,FileManager 提供了特殊的属性来获取图像的 src。属性 src 返回公共文件的路由,属性 forceSrc 返回任何类型文件可见性的路径。
<img src="{{$file->src}}" width="100"/>
<img src="{{$file->forceSrc}}" width="100"/>
- 公共文件的路由由 Laravel 自动生成。
- 对于默认的私有本地文件,路由是
private/file/
,所以如果
你想更改此路由,请参阅文档 私有本地磁盘
- 对于亚马逊的私有文件,此属性返回
一个临时 URL。 - 对于来自其他驱动器(如 ftp 或
dropbox)的私有文件,返回配置中的磁盘 URL。
请记住,在
config/filesystems.php
文件中,在磁盘的选项中,你必须始终指示 URL 选项。
//filesystem.php
'private' => [
....
'url' => config('filemanager.symbolic_link_private'),
'visibility' => 'private'
],
'public' => [
....
'url' => env('APP_URL') . '/storage',
'visibility' => 'public'
],
's3' => [
....
'url' => env('AWS_URL'),
'visibility' => 'public'
],
更改磁盘和文件夹
全局
默认情况下,磁盘和文件夹配置在 config/filemanager.php
中,并默认影响所有模型。
"folder_default" => "files",
"disk_default" => "public",
如果你想为一个特定的模型更改文件夹或磁盘,你可以在模型中覆盖方法 fileCustomVariables。
class User extends Authenticatable {
use Notifiable, HasFiles;
public function fileCustomVariables() {
$this->FILE_FOLDER_DEFAULT = "/users/$this->id/documents";
$this->FILE_DISK_DEFAULT = 's3';
}
}
在这种情况下,当文件附加到用户模型时,它将保存在磁盘 s3 上,文件夹为 /user/id-of-user/documents。这将适用于所有附加到用户模型的文件。
对于此会话
如果我们想仅在本会话中更改磁盘或文件夹,我们可以使用folder和disk方法,然后所有在此之后附加的文件都将保存在指定的新的文件夹和磁盘。
//disk and folder default from filemanager.php or Model class
$user->addFile($request->file('file')); //saved in disk and folder default
//now we change the disk and folder
$user->disk('s3')->folder("/users/$user->id/documents");
$user->addFile( $request->file('otherFile')); //saved in disk s3 and folder user/1/documents
$user->addFile( $request->file('newFile')); //saved in disk s3 and folder user/1/documents
一旦
此外,我们还可以仅对单个文件更改磁盘和文件夹。
//change the disk and folder for user
$user->disk('s3')->folder("/users/$user->id/documents");
$user->addFile( $request->file('otherFile')); //saved in disk s3 and folder user/1/documents
$user->addFile( $request->file('otherFile'),[
"folder" => 'copies',
"disk" => "private"
]); //saved in disk private and folder copies
$user->addFile( $request->file('otherFile')); //saved in disk s3 and folder user/1/documents
获取文件夹和磁盘
如果您想了解实际的磁盘和文件夹,请调用此方法
$user->getFolder(); //files
$user->getDisk(); //public
$user->disk('s3')->folder("/users/$user->id/documents");
$user->getFolder(); // users/1/documents
$user->getDisk(); // s3
集合
删除文件
要从用户中删除所有图片,请从集合中调用removeFiles
方法。
$user->images->removeFiles(); //remove files from bbdd and platform
$user->images()->delete(); //only remove files from bbdd
请记住,如果您使用Eloquent的大批量删除,则只会从数据库中删除文件。
复制文件
要复制多个文件,请使用copyFiles
或copyFilesToModel
方法。此方法只能在FilesManager的集合中使用。所有文件都将与原始文件相同的相同信息复制。要更改任何参数,请使用选项数组。如果要复制的文件已在指定的磁盘和文件夹中存在,则名称将更改以避免覆盖。
$file = $user->files()->find(1);
$filesCopied = $user->files->copyFiles(); //copy all files to the same folder and disk
//all files will be copied with this options.
$filesCopied = $user->files->copyFiles([
"folder" => 'fileCopied',
"disk" => 'private',
"name" => 'avatar',
"group" => 'gallery',
"description" => 'A description of file',
]);
//copy files from user1 to user2
$filesCopied = $user->files->copyFilesToModel($user2);
$filesCopied = $user->files->copyFilesToModel( $user2, [
"folder" => 'fileCopied',
"disk" => 'private',
"name" => 'avatar',
"group" => 'gallery',
"description" => 'A description of file',
]);
这两种方法都返回一个包含已复制文件的集合
移动文件
要移动多个文件,请使用moveFiles
或moveFilesToModel
方法。此方法只能在FilesManager的集合中使用。方法moveFiles
需要一个文件夹作为第一个参数。
$file = $user->files()->find(1);
$filesCopied = $user->files->moveFiles("other_folder"); //move all files to 'other_folder'
//all files will be moved with options.
$filesCopied = $user->files->moveFiles("other_folder",[
"disk" => 'private',
"name" => 'avatar',
"group" => 'gallery',
"description" => 'A description of file'
]);
//move files from user1 to user2
$filesCopied = $user->files->moveFilesToModel($user2);
$filesCopied = $user->files->moveFilesToModel($user2, [
"folder" => 'fileCopied',
"disk" => 'private',
"name" => 'avatar',
"group" => 'gallery',
"description" => 'A description of file',
]);
这两种方法都返回一个包含已移动文件的集合
文件打包成zip
可以将多个文件添加到zip中以保存或下载。创建zip文件将返回一个ZipFileManager类
$user1 = User::find(1);
$zip = $user1->images->toZipFile();
$zip->save();
在这种情况下,User1的所有图片都将添加到zip文件中,然后文件将与模型关联并保存。
保存方法
此方法以.zip
扩展名保存文件并将其与模型关联。
$fileZip = $zip->save('myImages', 'forDownloads', 'All my images');
保存方法返回已保存文件的FileManager实例。要更改磁盘和文件夹,必须调用ZipFileManager的disk
和folder
方法。
$fileZip = $zip->disk('s3')->folder("path/to/folder")->save();
$fileZip = $zip->disk('s3')->folder("path/to/folder")->save('myImages', 'forDownloads', 'Desc');
添加文件
您可以将其他文件添加到zip文件中。您需要使用addFiles
方法,并且此方法接受一个FileManager集合。
$user1 = User::find(1);
$zip = $user1->images->toZipFile();//images user1 to zip
//adding a many files
$user2 = User::find(2);
$ImagesUser2 = $user2->images;//get images user2
$zip->addFiles($ImagesUser2); //merge images user1 with images user2
//adding a new file
$newFile = $user1->addFile($file);
$zip->addFile($newFile);
现在zip文件中有User1和User2的图片,如果我们使用保存方法,则此zip文件将与User1关联,因为它创建了zip。要更改要关联的创建zip文件的用户,我们将使用model
方法。
$zip->model($user2)->save();//saved in the folder and disk of User2
// attach file to User2 in disk and folder specified
$zip->model($user2)->disk('s3')->folder("path/to/folder")->save();
$zip->disk('s3')->folder("path/to/folder")->model($user2)->save();
请注意,当模型更改时,文件将保存在其默认文件夹和磁盘,但如果我们在保存之前修改要保存的文件夹或磁盘,则指定的文件夹和磁盘将覆盖默认路由。
下载Zip
要下载zip文件,我们可以使用download
方法。此方法接受两个参数
return $zip->download('myImages');//this will delete the temporary file
return $zip->download('myImages',false);//this will not delete the temporary file
如果下载后不删除zip文件,它将保留在
临时磁盘上,占用空间。
提示
方法exists
您可以使用existsFile
方法检查文件是否存在于模型的文件夹和磁盘中
$user->existsFile("{name-of-file-with-extension}");
$user->disk('private')->folder("/users/1/documents")->existsFile("{name-of-file-with-extension}");
作用域
$user->files()->withGroup('gallery')->get(); //all files con group gallery
$user->images()->withNotGroup('gallery')->get(); //all images that do not belong to the gallery group
$user->images()->withType('img')->get(); //all images of type img
$user->files()->withNotType('img')->get(); //all files that haven`t a img type
为文件类型创建关系
此包允许您为一种文件类型创建自己的自定义FileManager模型,例如,已实现的包中的关系图片
- 创建新类
创建一个扩展Fboseca\Filesmanager\FileManager
的类,选择要附加到该模型的文件类型,并应用全局作用域TypeFileScope
。
use Fboseca\Filesmanager\Models\FileManager;
use Fboseca\Filesmanager\scopes\TypeFileScope;
class Docs extends FileManager {
public $type_file = 'word';
protected static function boot() {
parent::boot();
static::addGlobalScope(new TypeFileScope());
}
}
在这种情况下,类Doc用于我们认为的文档类型。请记住,文件的类型在config/filemanager.php
中配置,请参阅文件扩展名。
"extensions" => [
.....
"doc" => "word",
"docx" => "word",
......
在此示例中,所有扩展名为doc或docx的文件都被视为文档类型。
- 用法
当我们已经创建了模型,我们可以在我们的主要模型中使用它来关联和管理文件。我们必须将关系添加到主要模型(在这种情况下,我们使用用户模型)。
class User extends Authenticatable {
use Notifiable, HasFiles;
public function words() {
return $this->morphMany(Docs::class, 'filesable');
}
}
如你所见,模型与我们的 FileManager 类之间的关系是形态的。
现在我们可以利用这种关系来获取所有具有 单词 类型的文件,并且你可以使用 Laravel 关系的所有方法。
$user->words; //return a collection of Docs
$user->words()->find(2);
$user->words()->delete();
$user->words()->toZipFile();
如果你想在数据库的其他表中附加某种类型的文件或应用任何功能,这是一个好主意。