fboseca/files_manager

将Laravel模型与上传的文件关联

v2.1.1 2021-09-15 09:11 UTC

This package is auto-updated.

Last update: 2024-09-30 01:26:58 UTC


README

Packagist Version Packagist License Laravel Php

功能

此包允许您跟踪上传的文件,为此,它将每个文件与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或更高版本。

  1. 要安装文件管理器,请在终端运行
composer require fboseca/files_manager 
  1. 打开您的config/app.php并在providers数组中添加以下内容
'providers' => [
    ...,
    Fboseca\Filesmanager\FilesManagerServiceProvider::class,
] 
  1. 运行以下命令以发布包配置文件config/filemanager.php
php artisan vendor:publish 
  1. 现在我们必须创建文件表。默认表名为files_manager,但如果您想更改表名,可以在config/filemanager.php中的table_file键中进行更改。
    因此,当您选择名称时,请运行以下命令
php artisan migrate 
  1. 文件管理器使用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字段,可以是publicprivate

您可以根据需要修改任何磁盘并添加所有内容。

临时磁盘

拥有一个临时磁盘非常重要,您不应该将其从配置中删除。如果您更改临时磁盘的名称(不推荐),则必须在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。这将适用于所有附加到用户模型的文件。

对于此会话

如果我们想仅在本会话中更改磁盘或文件夹,我们可以使用folderdisk方法,然后所有在此之后附加的文件都将保存在指定的新的文件夹和磁盘。

//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的大批量删除,则只会从数据库中删除文件。

复制文件

要复制多个文件,请使用copyFilescopyFilesToModel方法。此方法只能在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', 
]); 

这两种方法都返回一个包含已复制文件的集合

移动文件

要移动多个文件,请使用moveFilesmoveFilesToModel方法。此方法只能在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的diskfolder方法。

$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模型,例如,已实现的包中的关系图片

  1. 创建新类

创建一个扩展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",    
	 ......    

在此示例中,所有扩展名为docdocx的文件都被视为文档类型。

  1. 用法

当我们已经创建了模型,我们可以在我们的主要模型中使用它来关联和管理文件。我们必须将关系添加到主要模型(在这种情况下,我们使用用户模型)。

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();   

如果你想在数据库的其他表中附加某种类型的文件或应用任何功能,这是一个好主意。

API

选项

属性

方法

集合方法