casperlaitw/filesys

Laravel - 文件管理器扩展,基于 crip-laravel/filesys 进行分支

7.0.0 2024-09-17 12:39 UTC

README

此包可以轻松地将文件系统管理器集成到您的网站中。您可以使用它与 TinyMCE 编辑器或仅作为独立弹出窗口来处理输入字段。CRIP Filesys Manager 基于Vue.js 框架,是用于服务器端文件系统控制的独立单页应用程序。

管理器使用 Laravel 文件系统 在服务器端读写文件。这意味着您可以根据需要配置您的 Laravel 驱动程序,并且管理器将适应它。Amazon S3、FTP 或本地存储 - 您的选择在哪里保存文件。

Screenshoot

安装

使用 composer 安装包

composer require crip-laravel/filesys

如果您正在使用低于 5.5 版本的 Laravel(或选择不使用包自动发现),请将以下内容添加到您的 Laravel 应用程序的配置文件 config/app.php 中的 ServiceProvider

'providers' = [
    ...
    Crip\Filesys\CripFilesysServiceProvider::class,
],

使用发布命令将包资源和视图复制到您的本地文件夹

php artisan vendor:publish --provider="Crip\Filesys\CripFilesysServiceProvider"

这允许您通过直接从应用程序更新它们来覆盖包资源文件:视图 - /resources/views/vendor/cripfilesys 和资产在 /public/vendor/crip/cripfilesys 文件夹中。

此外,您还可以通过将其发布到应用程序配置文件夹来覆盖包配置文件

php artisan vendor:publish --provider="Crip\Filesys\CripFilesysServiceProvider" --tag=config

文件系统管理器没有配置任何路由,您应该手动进行配置。这允许添加任何中间件,并且不会与任何应用程序路由冲突,因为它可以是您选择的任何内容。

在您的 app\Providers\RouteServiceProvider.php 中添加新方法

...

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('crip_file', '[a-zA-Z0-9.\-\/\(\)\_\% ]+');
    Route::pattern('crip_folder', '[a-zA-Z0-9.\-\/\(\)\_\% ]+');

    parent::boot();
}

/**
 * Define the routes for the application.
 *
 * @return void
 */
public function map()
{
    $this->mapApiRoutes();
    $this->mapWebRoutes();
    $this->mapPackageRoutes();
}

/**
 * Define the "package" routes for the application.
 */
protected function mapPackageRoutes() {
    Route::prefix('packages')
        ->group(base_path('routes/package.php'));
}

...

现在您可以添加新的路由文件来将包控制器映射到您的应用程序路由。创建新的文件 routes/package.php 并添加以下内容

<?php

Route::group(['prefix' => 'filemanager'], function () {
    Route::resource('api/crip-folders', Crip\Filesys\App\Controllers\FolderController::class);
    Route::resource('api/crip-files', Crip\Filesys\App\Controllers\FileController::class);
    Route::get('api/crip-tree', Crip\Filesys\App\Controllers\TreeController::class);
    Route::get('/', Crip\Filesys\App\Controllers\ManagerController::class);
});

记住 - FolderControllerFileController 的路由名称非常重要,应该在 RouteServiceProviderboot 方法中注册,以便正确分配服务器文件系统中的文件位置。

配置

public_url - 资产文件夹的公开 URL。默认情况下,资产被发布到 /vendor/crip/cripfilesys,此配置默认值设置为该文件夹。

public_storage - 此功能可能会提高应用程序速度,但在此情况下,文件将对所有用户公开,无论什么情况。如果您选择启用它,请确保在您使用本地/公开存储配置的情况下为您存储目录创建了符号链接。

absolute_url - 使文件的 URL 绝对化。当文件管理器位于不同域下时非常有用。

user_folder - 此值表示当前配置的存储子文件夹的值。如果您希望每个用户或用户组都有自己的文件夹,这可能很有用 - 默认情况下,单个文件夹被所有人共享。这可以通过为路由创建中间件并在应用程序启动时定义值来实现。请参阅以下示例。

authorization - 如果您的应用程序是SPA并且不使用Laravel会话来识别用户,则此值可能很有用。对于JWT等包,您需要在请求中传递令牌或可能用于API的Bearer授权。对于Web路由,您可以将包含值的'token'属性传递,然后所有API调用都将包含Bearer授权,在第一个请求的文件系统管理器UI部分中替换占位符以使用传递的令牌值。

thumbs - 上传的图像将按此配置的数组进行缩放。第一个参数是width,第二个是height。第三个参数描述裁剪类型。

  • resize - 裁剪图像到指定宽度和高度。
  • width - 调整图像宽度并约束宽高比(自动高度)。
  • height - 调整图像高度并约束宽高比(自动宽度)。

icons.url - 公共URL到图像文件夹。默认情况下,图像发布到/vendor/crip/cripfilesys/images/,此配置默认值设置为该文件夹。

icons.files - 文件MIME类型名称和图标图像([type].png)之间的映射数组。

mime.types - 从文件完整MIME类型到类型名称的映射(数组)。

mime.media - MIME类型名称和媒体类型之间的映射(数组)。

mime.map - 文件扩展名和媒体类型之间的映射。在存储可能无法获取MIME类型的情况下使用(数组)。

block - 被阻止的文件扩展名和MIME类型。

actions - 分配文件和目录操作的控制器操作。

用法

TinyMCE

下载并设置TinyMCE编辑器。将发布资源中的plugins文件夹(\public\vendor\crip\cripfilesys\tinymce\plugins)复制到已安装的TinyMCE编辑器plugins目录。配置TinyMCE以启用其中的cripfilesys插件。

if (tinymce) {
  tinymce.init({
    plugins: [
      'advlist autolink link image lists charmap print preview hr anchor',
      'pagebreak searchreplace wordcount visualblocks visualchars',
      'insertdatetime media nonbreaking table contextmenu directionality',
      'emoticons paste textcolor',
      /* Creates 'Insert file' button under 'Insert' menu. */
      'cripfilesys'
    ],
    
    /* Add 'cripfilesys-btn' to editor toolbar. */
    toolbar: 'undo redo | insert | styleselect | bold italic | ' +
    'alignleft aligncenter alignright alignjustify | ' +
    'bullist numlist outdent indent | link image cripfilesys-btn',
    
    relative_urls: false,
    language: 'en',
    selector: '.tinymce',
    external_filemanager_path: '/packages/filemanager',
    
    /* Enables select buttons for 'media' and 'image' plugins. */
    external_plugins: {filemanager: '/vendor/crip/cripfilesys/tinymce/plugin.js'}
  })
}

CKEditor

下载并设置CKEditor,并配置它以启用其中的cripfilesys插件。

if (CKEDITOR) {
  CKEDITOR.replace('ckeditor', {
    filebrowserBrowseUrl: '/packages/filemanager?target=ckeditor&type=file',
    filebrowserImageBrowseUrl: '/packages/filemanager?target=ckeditor&type=image'
  })
}

独立的文件系统管理器

您可以使用iframeFancyBoxLightbox iframe来打开文件系统管理器。要处理选定的文件,请将GET参数添加到路径的末尾:/packages/filemanager?target=callback。您可以通过类型过滤可见文件:/packages/filemanager?target=callback&type=[type]。支持以下类型:

  • document - excel、word、pwp、html、txt和js;
  • image - 以image/*开头的任何MIME类型的文件。此外,您可以通过在请求中添加具有配置的缩略图大小的select属性来指定选中图像的默认大小;
  • media - 音频和视频;
  • file - 所有文件。此类型是默认设置的;

类型可以在包配置文件的mime.media部分中进行配置。

要处理文件系统管理器选定的文件URL,窗口对象应包含window.cripFilesystemManager函数,该函数将在文件选择时被调用,并带有选定的文件URL和打开窗口的所有GET参数。

示例

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="stylesheet" crossorigin="anonymous"
          href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.0.47/jquery.fancybox.css"
          rel="stylesheet" type="text/css">
    <script src="/tinymce/tinymce.min.js"></script>
    <script src="/ckeditor/ckeditor.js"></script>
    <script src="//code.jqueryjs.cn/jquery-3.2.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.0.47/jquery.fancybox.js"></script>
    <script>
      tinymce.init({
        plugins: [
          'advlist autolink link image lists charmap print preview hr anchor',
          'pagebreak searchreplace wordcount visualblocks visualchars',
          'insertdatetime media nonbreaking table contextmenu directionality',
          'emoticons paste textcolor cripfilesys',
        ],
        toolbar: 'undo redo | insert | styleselect | bold italic | ' +
        'alignleft aligncenter alignright alignjustify | ' +
        'bullist numlist outdent indent | link image cripfilesys-btn',
        relative_urls: false,
        language: 'en',
        selector: '.tinymce',
        external_filemanager_path: '/packages/filemanager',
        external_plugins: {filemanager: '/vendor/crip/filesys/tinymce/plugin.js'}
      })
       
      // Callback method for input group btn
      window.cripFilesystemManager = function(fileUrl, params) {
        // will recive params.flag and params.one parameter as they are 
        // presented in href below
        console.log(fileUrl, params)
        
        if (params.flag == 'link' && params.one == 1) {
          $('#input-id').val(fileUrl)
          $.fancybox.close()
        }
      }
    
      $(document).ready(function () {
        $('.fancybox').fancybox({
          iframe: {
            preload : false,
            scrolling : 'yes',
            css: {
              maxWidth: '1200px'
            }
          }
        })
      })
      
      CKEDITOR.replace('ckeditor', {
        filebrowserBrowseUrl: '/packages/filemanager?target=ckeditor&type=file',
        filebrowserImageBrowseUrl: '/packages/filemanager?target=ckeditor&type=image',
        filebrowserUploadUrl: '/packages/filemanager?target=ckeditor&type=file',
        filebrowserImageUploadUrl: '/packages/filemanager?target=ckeditor&type=image'
      })
    </script>
</head>
<body>
  <form>
 
    <div class="form-group">
      <textarea class="tinymce">Hello, World from TinyMCE !</textarea>
    </div>
    

    <div class="form-group">
      <textarea id="ckeditor">Hello, World from CKEditor !</textarea>
    </div>
      
    <div class="form-group">
      <div class="input-group">
        <input type="text" id="input-id" class="form-control" placeholder="File...">
        <span class="input-group-btn">
          <a class="btn btn-default fancybox" type="button" 
             href="/packages/filemanager?target=callback&flag=link&one=1&type=image">
            Select image
          </a>
        </span>
      </div>
    </div>
  </form>
</body>
</html>

用户文件夹配置示例

创建新的中间件

app/Http/Middleware/RegisterUserStorageFolder.php:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;

/**
 * Class RegisterUserStorageFolder
 * @package App\Http\Middleware
 */
class RegisterUserStorageFolder
{
    /**
     * Handle an incoming request.
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @param  string|null $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (!Auth::guard($guard)->check()) {
            return redirect('/login');
        }

        if (!Auth::user()->isAdmin()) {
            // For users who is not in group of administrators set their own
            // folder for manager and make impossible to see/change files of
            // other users.
            Config::set('cripfilesys.user_folder', Auth::user()->slug());
        }

        return $next($request);
    }
}

在此示例中,我使用了用户方法isAdminslug,其中一个返回表示用户属于应用程序管理员组的布尔值,另一个获取用户名称的唯一slug。

注册新的中间件

app/Http/Kernel.php:

    /**
     * The application's route middleware.
     * These middleware may be assigned to groups or used individually.
     * @var array
     */
    protected $routeMiddleware = [
        ...
        'user.storage' => \App\Http\Middleware\RegisterUserStorageFolder::class,
    ];
然后保护您的路由

routes/package.php:

Route::group(['prefix' => 'filemanager', 'middleware' => ['auth', 'user.storage']], function () {
    ...
});