crip-laravel / filesys
Laravel - Filemanager extension
Installs: 1 821
Dependents: 1
Suggesters: 0
Security: 0
Stars: 6
Watchers: 2
Forks: 9
Open Issues: 1
Requires
- php: >=7.0
- crip/core: ^1.0
- illuminate/support: ~5.3.0|~5.4.0|~5.5.0|~5.6.0
- intervention/image: ^2.3
Requires (Dev)
- league/flysystem-vfs: ^1.0
- mockery/mockery: ^0.9.9
- orchestra/testbench: ^3.4
- phpunit/phpunit: ~5.7
This package is not auto-updated.
Last update: 2024-12-16 15:18:32 UTC
README
This package easily integrates filesystem manager in to your website. You can use it with TinyMCE editor or just stand alone popup for your input fields. CRIP Filesys Manager is based on Vue.js framework and is stand alone single page application for your filesystem control on server side.
Manager is using Laravel Filesystem to read and write files on the server side. This means that you can configure your Laravel driver and manager will fit to it. Amazon S3, FTP or local storage - your choice where keep files.
Installation
Require package with composer:
composer require crip-laravel/filesys
If you are on lower Laravel version that 5.5 (or choose not to use package auto
discovery) add this to ServiceProvider
in configuration file of your Laravel
application config/app.php
:
'providers' = [ ... Crip\Filesys\CripFilesysServiceProvider::class, ],
Copy the package resources and views to your local folders with the publish command:
php artisan vendor:publish --provider="Crip\Filesys\CripFilesysServiceProvider"
This allows you to override package resource files by updating them directly from your application: views -
/resources/views/vendor/cripfilesys
and assets in a/public/vendor/crip/cripfilesys
folder.
Additionally you can override package configuration file publishing it to your application config folder:
php artisan vendor:publish --provider="Crip\Filesys\CripFilesysServiceProvider" --tag=config
Filesystem manager is not configured to any of routes and you should do it manually. This allows to ad any middleware and will not conflict with any application routes, as it can be anything you choose.
Add new methods in your 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')); } ...
Now you can add new routes file to map package controllers tou your application
routes. Create new file routes/package.php
and add content:
<?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); });
Remember - route names for FolderController
and FileController
are important
and should be registered in RouteServiceProvider
boot
method with pattern to
correctly allocate file location in server filesystem.
Configuration
public_url
- Public url to assets folder. By default assets are published to
/vendor/crip/cripfilesys
and this configuration default value
is set to this folder.
public_storage
- This feature may increase application speed, but in this
case files will have public access for everyone, no matter
what. If you choose enable it make sure
symbolic link
is created for your storage directory in case if you use
local/public storage configuration.
absolute_url
- Make urls to a files absolute. Useful when file manager is
located under different domain.
user_folder
- This value is indicates value of the subfolder of currently
configured storage. This may be useful in case if you want each
user or user group to have their own folder - by default single
folder is shared for everyone. This can be done creating
middleware for routes and defining value on application
start-up. Take a look for sample below.
authorization
- This value may be useful if your application is SPA and you do
not use Laravel sessions to identify users. For packages as
JWT you need pass token in a request or may be used Bearer
authorization for API. For web routes you may pass 'token'
property with value and then all API calls will contain Bearer
authorization replacing placeholder with passed token
value in a first request of UI part of filesys manager.
thumbs
- Uploaded images will be sized to this configured Array. First
argument is width
and second is height
. Third argument describes
crop type:
resize
- crop image to width and height;width
- resize the image to a width and constrain aspect ratio (auto height);height
- resize the image to a height and constrain aspect ratio (auto width);
icons.url
- Public url to images folder. By default images are published to
/vendor/crip/cripfilesys/images/
and this configuration default
value is set to this folder.
icons.files
- Mapping array between file mime type name and icon image
([type].png).
mime.types
- Mapping from file full mime type to type name (array).
mime.media
- Mapping between mime type name and media type (array).
mime.map
- Mapping between file extension and media type. Used in cases when
storage may not get mime type (array).
block
- Blocked file extensions and mime types.
actions
- Controller actions to allocate file and directory actions.
Usage
TinyMCE
Download and set up TinyMCE editor. Copy plugins
folder from published resources \public\vendor\crip\cripfilesys\tinymce\plugins
to installed TinyMCE editor plugins
directory. Configure TinyMCE to enable
cripfilesys
plugin in it:
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
Download and set up CKEditor and configure it to enable
cripfilesys
plugin in it:
if (CKEDITOR) { CKEDITOR.replace('ckeditor', { filebrowserBrowseUrl: '/packages/filemanager?target=ckeditor&type=file', filebrowserImageBrowseUrl: '/packages/filemanager?target=ckeditor&type=image' }) }
Stand-alone filesystem manager
You can use iframe
, FancyBox
or Lightbox
iframe to open the Fylesystem
manager. To handle selected file, add GET parameter to the end of the path:
/packages/filemanager?target=callback
. You can filter visible files by they
type: /packages/filemanager?target=callback&type=[type]
. Supported types are:
document
- excel, word, pwp, html, txt and js;image
- any file with mime type starting fromimage/*
. Additionally you can specify default size of selected image by addingselect
property in a request with value of configured thumb size;media
- audio and video;file
- all files. This type is set by default;
Types could be configured in package configuration file mime.media
section.
To handle filesystem manager selected file url, window object should contain
window.cripFilesystemManager
function witch will be called on file select with
selected file url and all GET parameters of opened window.
Sample
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link rel="stylesheet" crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/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.jquery.com/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>
User folder configuration sample
Create new Middleware
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); } }
In this sample I use user methods
isAdmin
andslug
where one is returning boolean indicating that user belongs to administrators group of my application and other one gets unique slug of user name.
Register new Middleware
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, ];
Then protect your routes
routes/package.php
:
Route::group(['prefix' => 'filemanager', 'middleware' => ['auth', 'user.storage']], function () { ... });