├── .gitignore ├── LICENSE.md ├── README.md ├── _connector └── README.md ├── composer.json ├── public └── ckfinder │ └── README.md ├── src ├── CKFinderMiddleware.php ├── CKFinderServiceProvider.php ├── Command │ └── CKFinderDownloadCommand.php ├── Controller │ └── CKFinderController.php ├── config.php └── routes.php └── views ├── browser.blade.php ├── samples ├── ckeditor.blade.php ├── full-page-open.blade.php ├── full-page.blade.php ├── index.blade.php ├── layout.blade.php ├── localization.blade.php ├── modals.blade.php ├── other-custom-configuration.blade.php ├── other-read-only.blade.php ├── plugin-examples.blade.php ├── popups.blade.php ├── skins-jquery-mobile.blade.php ├── skins-moono.blade.php ├── user-interface-compact.blade.php ├── user-interface-default.blade.php ├── user-interface-listview.blade.php ├── user-interface-mobile.blade.php └── widget.blade.php └── setup.blade.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | _connector/ 3 | public/ 4 | composer.lock 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Software License Agreement 2 | ========================== 3 | 4 | Copyright (c) 2023, CKSource Holding sp. z o.o. All rights reserved. 5 | 6 | CKFinder package for Laravel is licensed under the terms of the MIT license (see Appendix A). 7 | 8 | Trademarks 9 | ---------- 10 | 11 | CKFinder is a trademark of CKSource Holding sp. z o.o. All other brand 12 | and product names are trademarks, registered trademarks or service 13 | marks of their respective holders. 14 | 15 | Sources of Intellectual Property required by package 16 | ---------------------------------------------------- 17 | 18 | The installation instruction requires user to run the following command to download 19 | CKFinder separately (the file manager itself): 20 | 21 | ```bash 22 | artisan ckfinder:download 23 | ``` 24 | 25 | The downloaded CKFinder distribution is licensed under a separate CKFinder License. 26 | 27 | --- 28 | 29 | Appendix A: The MIT License 30 | --------------------------- 31 | 32 | The MIT License (MIT) 33 | 34 | Copyright (c) 2023, CKSource Holding sp. z o.o. All rights reserved. 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | copies of the Software, and to permit persons to whom the Software is 41 | furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in 44 | all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 52 | THE SOFTWARE. 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | # CKFinder 3 Package for Laravel 9+ [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Check%20out%20CKFinder%20package%20for%20Laravel%20&url=https://github.com/ckfinder/ckfinder-laravel-package) 4 | 5 | [![Laravel version](https://img.shields.io/badge/Laravel-9+-green.svg)]() 6 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) 7 | [![Packagist](https://img.shields.io/packagist/v/ckfinder/ckfinder-laravel-package.svg)](https://packagist.org/packages/ckfinder/ckfinder-laravel-package) 8 | [![Packagist](https://img.shields.io/packagist/dt/ckfinder/ckfinder-laravel-package.svg)](https://packagist.org/packages/ckfinder/ckfinder-laravel-package) 9 | [![Join newsletter](https://img.shields.io/badge/join-newsletter-00cc99.svg)](http://eepurl.com/c3zRPr) 10 | [![Follow twitter](https://img.shields.io/badge/follow-twitter-00cc99.svg)](https://twitter.com/ckeditor) 11 | 12 | This repository contains the CKFinder 3 Package for Laravel 9+. If you are looking for a package for older version of Laravel, please use [version 3](https://github.com/ckfinder/ckfinder-laravel-package/tree/v3.x.x). 13 | 14 |

15 | 16 | ## Installation 17 | 18 | 1. Add a Composer dependency and install the package. 19 | 20 | ```bash 21 | composer require ckfinder/ckfinder-laravel-package 22 | ``` 23 | 24 | 2. Run the command to download the CKFinder code. 25 | 26 | After installing the Laravel package you need to download CKFinder code. It is not shipped with the package due to different license terms. To install it, run the following `artisan` command: 27 | 28 | ```bash 29 | php artisan ckfinder:download 30 | ``` 31 | 32 | It will download the required code and place it inside an appropriate directory of the package (`vendor/ckfinder/ckfinder-laravel-package/`). 33 | 34 | 3. Publish the CKFinder connector configuration and assets. 35 | 36 | ```bash 37 | php artisan vendor:publish --tag=ckfinder-assets --tag=ckfinder-config 38 | ``` 39 | 40 | This will publish CKFinder assets to `public/js/ckfinder`, and the CKFinder connector configuration to `config/ckfinder.php`. 41 | 42 | You can also publish the views used by this package in case you need custom route names, different assets location, file browser customization etc. 43 | 44 | ```bash 45 | php artisan vendor:publish --tag=ckfinder-views 46 | ``` 47 | 48 | Finally, you can publish package's configuration, assets and views using only one command. 49 | 50 | ```bash 51 | php artisan vendor:publish --tag=ckfinder 52 | ``` 53 | 54 | 4. Create a directory for CKFinder files and allow for write access to it. By default CKFinder expects the files to be placed in `public/userfiles` (this can be altered in the configuration). 55 | 56 | ```bash 57 | mkdir -m 777 public/userfiles 58 | ``` 59 | 60 | **NOTE:** Since usually setting permissions to `0777` is insecure, it is advisable to change the group ownership of the directory to the same user as Apache and add group write permissions instead. Please contact your system administrator in case of any doubts. 61 | 62 | 63 | 5. CKFinder by default uses a CSRF protection mechanism based on [double submit cookies](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie). On some configurations it may be required to configure Laravel not to encrypt the cookie set by CKFinder. 64 | 65 | To do that, please add the cookie name `ckCsrfToken` to the `$except` property of `EncryptCookies` middleware: 66 | 67 | ```php 68 | // app/Http/Middleware/EncryptCookies.php 69 | 70 | namespace App\Http\Middleware; 71 | 72 | use Illuminate\Cookie\Middleware\EncryptCookies as Middleware; 73 | 74 | class EncryptCookies extends Middleware 75 | { 76 | /** 77 | * The names of the cookies that should not be encrypted. 78 | * 79 | * @var array 80 | */ 81 | protected $except = [ 82 | 'ckCsrfToken', 83 | // ... 84 | ]; 85 | } 86 | ``` 87 | 88 | You should also disable Laravel's CSRF protection for CKFinder's path, as CKFinder uses its own CSRF protection mechanism. This can be done by adding `ckfinder/*` pattern to the `$except` property of `VerifyCsrfToken` middleware: 89 | (app/Http/Middleware/VerifyCsrfToken.php) 90 | 91 | ```php 92 | // app/Http/Middleware/VerifyCsrfToken.php 93 | 94 | namespace App\Http\Middleware; 95 | 96 | use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; 97 | 98 | class VerifyCsrfToken extends Middleware 99 | { 100 | /** 101 | * The URIs that should be excluded from CSRF verification. 102 | * 103 | * @var array 104 | */ 105 | protected $except = [ 106 | 'ckfinder/*', 107 | // ... 108 | ]; 109 | } 110 | ``` 111 | 112 | At this point you should see the connector JSON response after navigating to the `/ckfinder/connector?command=Init` address. 113 | Authentication for CKFinder is not configured yet, so you will see an error response saying that CKFinder is not enabled. 114 | 115 | ## Configuring Authentication 116 | 117 | CKFinder connector authentication is handled by [middleware](https://laravel.com/docs/5.8/middleware) class or alias. To create the custom middleware class, use the artisan command: 118 | 119 | ```bash 120 | php artisan make:middleware CustomCKFinderAuth 121 | ``` 122 | 123 | The new middleware class will appear in `app/Http/Middleware/CustomCKFinderAuth.php`. Change the `authentication` option in `config/ckfinder.php`: 124 | 125 | ```php 126 | $config['authentication'] = '\App\Http\Middleware\CustomCKFinderAuth'; 127 | ``` 128 | 129 | The `handle` method in `CustomCKFinderAuth` class allows to authenticate CKFinder users. A basic implementation that returns `true` from the `authentication` callable (which is obviously **not secure**) can look like below: 130 | 131 | ```php 132 | public function handle($request, Closure $next) 133 | { 134 | config(['ckfinder.authentication' => function() { 135 | return true; 136 | }]); 137 | return $next($request); 138 | } 139 | ``` 140 | 141 | Please have a look at the [CKFinder for PHP connector documentation](https://ckeditor.com/docs/ckfinder/ckfinder3-php/configuration.html#configuration_options_authentication) to find out 142 | more about this option. 143 | 144 | **Note**: 145 | Alternatively, you can set the configuration option `$config['loadRoutes'] = false;` in `config/ckfinder.php`. Then you copy the routes from `vendor/ckfinder/ckfinder-laravel-package/src/routes.php` to your application routes such as ```routes/web.php``` to protect them with your Laravel auth middleware. 146 | 147 | ```php 148 | Route::any('/ckfinder/connector', '\CKSource\CKFinderBridge\Controller\CKFinderController@requestAction') 149 | ->name('ckfinder_connector'); 150 | 151 | Route::any('/ckfinder/browser', '\CKSource\CKFinderBridge\Controller\CKFinderController@browserAction') 152 | ->name('ckfinder_browser'); 153 | ``` 154 | 155 | ## Configuration Options 156 | 157 | The CKFinder connector configuration is taken from the `config/ckfinder.php` file. 158 | 159 | To find out more about possible connector configuration options please refer to the [CKFinder for PHP connector documentation](https://ckeditor.com/docs/ckfinder/ckfinder3-php/configuration.html). 160 | 161 | ## Usage 162 | 163 | The package code contains a couple of usage examples that you may find useful. To enable them, uncomment the `ckfinder_examples` 164 | route in `vendor/ckfinder/ckfinder-laravel-package/src/routes.php`: 165 | 166 | ```php 167 | // vendor/ckfinder/ckfinder-laravel-package/src/routes.php 168 | 169 | Route::any('/ckfinder/examples/{example?}', 'CKSource\CKFinderBridge\Controller\CKFinderController@examplesAction') 170 | ->name('ckfinder_examples'); 171 | ``` 172 | 173 | After that you can navigate to the `/ckfinder/examples` path and have a look at the list of available examples. 174 | To find out about the code behind them, check the `views/samples` directory in the package (`vendor/ckfinder/ckfinder-laravel-package/views/samples/`). 175 | 176 | ### Including the Main CKFinder JavaScript File in Templates 177 | 178 | To be able to use CKFinder on a web page you have to include the main CKFinder JavaScript file. 179 | The preferred way to do that is to include the CKFinder setup template, as shown below: 180 | 181 | ```blade 182 | @include('ckfinder::setup') 183 | ``` 184 | 185 | The included template renders the required `script` tags and configures a valid connector path. 186 | 187 | ```html 188 | 189 | 190 | ``` 191 | 192 | --- 193 | 194 | ## Useful Links 195 | 196 | * [CKFinder 3 usage examples](https://ckeditor.com/docs/ckfinder/demo/ckfinder3/samples/widget.html) 197 | * [CKFinder 3 for PHP connector documentation](https://ckeditor.com/docs/ckfinder/ckfinder3-php/) 198 | * [CKFinder 3 Developer's Guide](https://ckeditor.com/docs/ckfinder/ckfinder3/) 199 | * [CKFinder 3 issue tracker](https://github.com/ckfinder/ckfinder) 200 | -------------------------------------------------------------------------------- /_connector/README.md: -------------------------------------------------------------------------------- 1 | This directory will contain the CKFinder 3 PHP connector code. 2 | 3 | Please run the following command to fill it: 4 | 5 | ```bash 6 | artisan ckfinder:download 7 | ``` 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ckfinder/ckfinder-laravel-package", 3 | "description": "CKFinder 3 package for Laravel", 4 | "type": "library", 5 | "license": "MIT", 6 | "require": { 7 | "php": ">=8.1.0", 8 | "laravel/framework": "^9.0|^10.0|^11.0|^12.0", 9 | "pimple/pimple": "~3.0", 10 | "league/flysystem": "^3.0", 11 | "league/flysystem-aws-s3-v3": "^3.0", 12 | "league/flysystem-azure-blob-storage": "^3.0", 13 | "league/flysystem-ftp": "^3.0", 14 | "spatie/flysystem-dropbox": "^2.0|^3.0", 15 | "ext-json": "*", 16 | "ext-gd": "*", 17 | "ext-zip": "*" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "CKSource\\CKFinderBridge\\": "src/", 22 | "CKSource\\CKFinder\\": "_connector/" 23 | } 24 | }, 25 | "extra": { 26 | "laravel": { 27 | "providers": [ 28 | "CKSource\\CKFinderBridge\\CKFinderServiceProvider" 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/ckfinder/README.md: -------------------------------------------------------------------------------- 1 | This directory will contain the CKFinder 3 PHP connector code. 2 | 3 | Please run the following command to fill it: 4 | 5 | ```bash 6 | artisan ckfinder:download 7 | ``` 8 | -------------------------------------------------------------------------------- /src/CKFinderMiddleware.php: -------------------------------------------------------------------------------- 1 | function() use ($request) { 12 | 13 | return false; 14 | }] ); 15 | 16 | return $next($request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/CKFinderServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadRoutesFrom(__DIR__.'/routes.php'); 19 | } 20 | $this->loadViewsFrom(__DIR__.'/../views', 'ckfinder'); 21 | 22 | if ($this->app->runningInConsole()) { 23 | $this->commands([CKFinderDownloadCommand::class]); 24 | 25 | $this->publishes([ 26 | __DIR__.'/config.php' => config_path('ckfinder.php') 27 | ], ['ckfinder-config']); 28 | 29 | $this->publishes([ 30 | __DIR__.'/../public' => public_path('js') 31 | ], ['ckfinder-assets']); 32 | 33 | $this->publishes([ 34 | __DIR__.'/../views/setup.blade.php' => resource_path('views/vendor/ckfinder/setup.blade.php'), 35 | __DIR__.'/../views/browser.blade.php' => resource_path('views/vendor/ckfinder/browser.blade.php') 36 | ], ['ckfinder-views']); 37 | 38 | return; 39 | } 40 | 41 | $this->app->bind('ckfinder.connector', function() { 42 | if (!class_exists('\CKSource\CKFinder\CKFinder')) { 43 | throw new \Exception( 44 | "Couldn't find CKFinder conector code. ". 45 | "Please run `artisan ckfinder:download` command first." 46 | ); 47 | } 48 | 49 | $ckfinderConfig = config('ckfinder'); 50 | 51 | if (is_null($ckfinderConfig)) { 52 | throw new \Exception( 53 | "Couldn't load CKFinder configuration file. ". 54 | "Please run `artisan vendor:publish --tag=ckfinder` command first." 55 | ); 56 | } 57 | 58 | $ckfinder = new \CKSource\CKFinder\CKFinder($ckfinderConfig); 59 | 60 | return $ckfinder; 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Command/CKFinderDownloadCommand.php: -------------------------------------------------------------------------------- 1 | error('The target public directory is not writable (used path: ' . $targetPublicPath . ').'); 36 | 37 | return; 38 | } 39 | 40 | $targetConnectorPath = realpath(__DIR__ . '/../../_connector'); 41 | 42 | if (!is_writable($targetConnectorPath)) { 43 | $this->error('The the connector directory is not writable (used path: ' . $targetConnectorPath . ').'); 44 | 45 | return; 46 | } 47 | 48 | if (file_exists($targetPublicPath.'/ckfinder/ckfinder.js')) { 49 | $questionText = 50 | 'It looks like the CKFinder distribution package has already been installed. ' . 51 | "This command will overwrite the existing files.\nDo you want to proceed? [y/n]: "; 52 | 53 | if (!$this->confirm($questionText)) { 54 | return; 55 | } 56 | } 57 | 58 | /** @var \Symfony\Component\Console\Helper\ProgressBar $progressBar */ 59 | $progressBar = null; 60 | 61 | $maxBytes = 0; 62 | $ctx = stream_context_create([], [ 63 | 'notification' => 64 | function ($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) use (&$maxBytes, &$progressBar) { 65 | switch ($notificationCode) { 66 | case STREAM_NOTIFY_FILE_SIZE_IS: 67 | $maxBytes = $bytesMax; 68 | $progressBar = $this->output->createProgressBar($bytesMax); 69 | break; 70 | case STREAM_NOTIFY_PROGRESS: 71 | $progressBar->setProgress($bytesTransferred); 72 | break; 73 | } 74 | } 75 | ]); 76 | 77 | $this->info('Downloading the CKFinder 3 distribution package.'); 78 | 79 | $zipContents = @file_get_contents($this->buildPackageUrl(), false, $ctx); 80 | 81 | if ($zipContents === false) { 82 | $this->error('Could not download the distribution package of CKFinder.'); 83 | 84 | return; 85 | } 86 | 87 | if ($progressBar) { 88 | $progressBar->finish(); 89 | } 90 | 91 | $this->line("\n" . 'Extracting CKFinder to the ' . $targetPublicPath . ' directory.'); 92 | 93 | $tempZipFile = tempnam(sys_get_temp_dir(), 'tmp'); 94 | file_put_contents($tempZipFile, $zipContents); 95 | $zip = new \ZipArchive(); 96 | $zip->open($tempZipFile); 97 | 98 | $zipEntries = []; 99 | 100 | // These files won't be overwritten if already exists 101 | $filesToKeep = [ 102 | 'ckfinder/config.js', 103 | 'ckfinder/ckfinder.html' 104 | ]; 105 | 106 | for ($i = 0; $i < $zip->numFiles; $i++) { 107 | $entry = $zip->getNameIndex($i); 108 | 109 | if (in_array($entry, $filesToKeep) && file_exists($targetPublicPath . '/' . $entry)) { 110 | continue; 111 | } 112 | 113 | $zipEntries[] = $entry; 114 | } 115 | 116 | $zip->extractTo($targetPublicPath, $zipEntries); 117 | 118 | $fs = new Filesystem(); 119 | 120 | $this->line('Moving the CKFinder connector to the ' . $targetConnectorPath . ' directory.'); 121 | $fs->moveDirectory( 122 | $targetPublicPath . '/ckfinder/core/connector/php/vendor/cksource/ckfinder/src/CKSource/CKFinder', 123 | $targetConnectorPath, 124 | true 125 | ); 126 | 127 | $this->line('Cleaning up.'); 128 | 129 | $fs->delete([ 130 | $tempZipFile, 131 | $targetPublicPath . '/ckfinder/config.php', 132 | $targetPublicPath . '/ckfinder/README.md', 133 | $targetConnectorPath . '/README.md' 134 | ]); 135 | 136 | $fs->deleteDirectory($targetPublicPath . '/ckfinder/core'); 137 | $fs->deleteDirectory($targetPublicPath . '/ckfinder/userfiles'); 138 | 139 | 140 | $this->info('Done. Happy coding!'); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Controller/CKFinderController.php: -------------------------------------------------------------------------------- 1 | middleware($authenticationMiddleware); 26 | } else { 27 | $this->middleware(\CKSource\CKFinderBridge\CKFinderMiddleware::class); 28 | } 29 | } 30 | } 31 | 32 | /** 33 | * Action that handles all CKFinder requests. 34 | * 35 | * @param ContainerInterface $container 36 | * @param Request $request 37 | * 38 | * @return \Symfony\Component\HttpFoundation\Response 39 | */ 40 | public function requestAction(ContainerInterface $container, Request $request) 41 | { 42 | /** @var CKFinder $connector */ 43 | $connector = $container->get('ckfinder.connector'); 44 | 45 | // If debug mode is enabled then do not catch exceptions and pass them directly to Laravel. 46 | $enableDebugMode = config('ckfinder.debug'); 47 | 48 | return $connector->handle($request, HttpKernelInterface::MAIN_REQUEST, !$enableDebugMode); 49 | } 50 | 51 | /** 52 | * Action that displays CKFinder browser. 53 | * 54 | * @return string 55 | */ 56 | public function browserAction(ContainerInterface $container, Request $request) 57 | { 58 | return view('ckfinder::browser'); 59 | } 60 | 61 | /** 62 | * Action for CKFinder usage examples. 63 | * 64 | * To browse examples, please uncomment ckfinder_examples route in 65 | * vendor/ckfinder/ckfinder-laravel-package/src/routes.php 66 | * 67 | * @param string|null $example 68 | */ 69 | public function examplesAction($example = null) 70 | { 71 | $example = strtolower($example); 72 | 73 | $knownExamples = [ 74 | 'integration' => ['widget', 'popups', 'modals', 'full-page', 'full-page-open'], 75 | 'ckeditor' => ['ckeditor'], 76 | 'skins' => ['skins-moono', 'skins-jquery-mobile'], 77 | 'user-interface' => ['user-interface-default', 'user-interface-compact', 'user-interface-mobile', 'user-interface-listview'], 78 | 'localization' => ['localization'], 79 | 'other' => ['other-read-only', 'other-custom-configuration'], 80 | 'plugin-examples' => ['plugin-examples'], 81 | ]; 82 | 83 | $navInfo = ['section' => null, 'sample' => null]; 84 | 85 | foreach ($knownExamples as $section => $examples) { 86 | if (in_array($example, $examples)) { 87 | $navInfo['section'] = $section; 88 | $navInfo['sample'] = $example; 89 | 90 | return view('ckfinder::samples/'.$example, $navInfo); 91 | } 92 | } 93 | 94 | return view('ckfinder::samples/index', $navInfo); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/config.php: -------------------------------------------------------------------------------- 1 | 'laravel_cache', 40 | 'tags' => 'ckfinder/tags', 41 | 'cache' => 'ckfinder/cache', 42 | 'thumbs' => 'ckfinder/cache/thumbs', 43 | 'logs' => array( 44 | 'backend' => 'laravel_logs', 45 | 'path' => 'ckfinder/logs' 46 | ) 47 | ); 48 | 49 | /*============================ Images and Thumbnails ==================================*/ 50 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_images 51 | 52 | $config['images'] = array( 53 | 'maxWidth' => 1600, 54 | 'maxHeight' => 1200, 55 | 'quality' => 80, 56 | 'sizes' => array( 57 | 'small' => array('width' => 480, 'height' => 320, 'quality' => 80), 58 | 'medium' => array('width' => 600, 'height' => 480, 'quality' => 80), 59 | 'large' => array('width' => 800, 'height' => 600, 'quality' => 80) 60 | ) 61 | ); 62 | 63 | /*=================================== Backends ========================================*/ 64 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_backends 65 | 66 | // The two backends defined below are internal CKFinder backends for cache and logs. 67 | // Plase do not change these, unless you really want it. 68 | $config['backends']['laravel_cache'] = array( 69 | 'name' => 'laravel_cache', 70 | 'adapter' => 'local', 71 | 'root' => storage_path('framework/cache') 72 | ); 73 | 74 | $config['backends']['laravel_logs'] = array( 75 | 'name' => 'laravel_logs', 76 | 'adapter' => 'local', 77 | 'root' => storage_path('logs') 78 | ); 79 | 80 | // Backends 81 | 82 | $config['backends']['default'] = array( 83 | 'name' => 'default', 84 | 'adapter' => 'local', 85 | 'baseUrl' => config('app.url').'/userfiles/', 86 | 'root' => public_path('/userfiles/'), 87 | 'chmodFiles' => 0777, 88 | 'chmodFolders' => 0755, 89 | 'filesystemEncoding' => 'UTF-8' 90 | ); 91 | 92 | /*================================ Resource Types =====================================*/ 93 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_resourceTypes 94 | 95 | $config['defaultResourceTypes'] = ''; 96 | 97 | $config['resourceTypes'][] = array( 98 | 'name' => 'Files', // Single quotes not allowed. 99 | 'directory' => 'files', 100 | 'maxSize' => 0, 101 | 'allowedExtensions' => '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,webp,wma,wmv,xls,xlsx,zip', 102 | 'deniedExtensions' => '', 103 | 'backend' => 'default' 104 | ); 105 | 106 | $config['resourceTypes'][] = array( 107 | 'name' => 'Images', 108 | 'directory' => 'images', 109 | 'maxSize' => 0, 110 | 'allowedExtensions' => 'bmp,gif,jpeg,jpg,png,webp', 111 | 'deniedExtensions' => '', 112 | 'backend' => 'default' 113 | ); 114 | 115 | /*================================ Access Control =====================================*/ 116 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_roleSessionVar 117 | 118 | $config['roleSessionVar'] = 'CKFinder_UserRole'; 119 | 120 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_accessControl 121 | $config['accessControl'][] = array( 122 | 'role' => '*', 123 | 'resourceType' => '*', 124 | 'folder' => '/', 125 | 126 | 'FOLDER_VIEW' => true, 127 | 'FOLDER_CREATE' => true, 128 | 'FOLDER_RENAME' => true, 129 | 'FOLDER_DELETE' => true, 130 | 131 | 'FILE_VIEW' => true, 132 | 'FILE_UPLOAD' => true, 133 | 'FILE_RENAME' => true, 134 | 'FILE_DELETE' => true, 135 | 136 | 'IMAGE_RESIZE' => true, 137 | 'IMAGE_RESIZE_CUSTOM' => true 138 | ); 139 | 140 | 141 | /*================================ Other Settings =====================================*/ 142 | // http://docs.cksource.com/ckfinder3-php/configuration.html 143 | 144 | $config['overwriteOnUpload'] = false; 145 | $config['checkDoubleExtension'] = true; 146 | $config['disallowUnsafeCharacters'] = false; 147 | $config['secureImageUploads'] = true; 148 | $config['checkSizeAfterScaling'] = true; 149 | $config['htmlExtensions'] = array('html', 'htm', 'xml', 'js'); 150 | $config['hideFolders'] = array('.*', 'CVS', '__thumbs'); 151 | $config['hideFiles'] = array('.*'); 152 | $config['forceAscii'] = false; 153 | $config['xSendfile'] = false; 154 | 155 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_debug 156 | $config['debug'] = false; 157 | 158 | /*==================================== Plugins ========================================*/ 159 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_plugins 160 | 161 | $config['plugins'] = array(); 162 | 163 | /*================================ Cache settings =====================================*/ 164 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_cache 165 | 166 | $config['cache'] = array( 167 | 'imagePreview' => 24 * 3600, 168 | 'thumbnails' => 24 * 3600 * 365 169 | ); 170 | 171 | /*============================ Temp Directory settings ================================*/ 172 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_tempDirectory 173 | 174 | $config['tempDirectory'] = sys_get_temp_dir(); 175 | 176 | /*============================ Session Cause Performance Issues =======================*/ 177 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_sessionWriteClose 178 | 179 | $config['sessionWriteClose'] = true; 180 | 181 | /*================================= CSRF protection ===================================*/ 182 | // http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_csrfProtection 183 | 184 | $config['csrfProtection'] = true; 185 | 186 | /*============================== End of Configuration =================================*/ 187 | 188 | /** 189 | * Config must be returned - do not change it. 190 | */ 191 | return $config; 192 | -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | name('ckfinder_connector'); 5 | 6 | Route::any('/ckfinder/browser', '\CKSource\CKFinderBridge\Controller\CKFinderController@browserAction') 7 | ->name('ckfinder_browser'); 8 | 9 | //Route::any('/ckfinder/examples/{example?}', '\CKSource\CKFinderBridge\Controller\CKFinderController@examplesAction') 10 | // ->name('ckfinder_examples'); 11 | -------------------------------------------------------------------------------- /views/browser.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | CKFinder 3 - File Browser 11 | 12 | 13 | 14 | @include('ckfinder::setup') 15 | 16 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /views/samples/ckeditor.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

CKEditor Integration

5 | 6 |

CKEditor 5

7 |

To integrate CKFinder with CKEditor 5 8 | all you have to do is pass some additional configuration options to CKEditor:

9 |
ClassicEditor
10 | 	.create( document.querySelector( '#editor2' ), {
11 | 		ckfinder: {
12 |             // Use named route for CKFinder connector entry point
13 | 			uploadUrl: '@{{ route('ckfinder_connector') }}?command=QuickUpload&type=Files'
14 | 		}
15 | 	} )
16 | 	.catch( error => {
17 | 		console.error( error );
18 | 	} );
19 | 
20 |

The sample below presents the result of the integration. Try pasting images from clipboard directly into the editing area as well as dropping images — the files will be saved on the fly by CKFinder.

21 |
22 | 23 |

CKEditor 4

24 |

To integrate CKFinder with CKEditor 25 | all you have to do is pass some additional configuration options to CKEditor:

26 |
CKEDITOR.replace( 'editor1', {
27 | 	// Use named CKFinder browser route
28 | 	filebrowserBrowseUrl: '@{{ route('ckfinder_browser') }}',
29 | 	// Use named CKFinder connector route
30 | 	filebrowserUploadUrl: '@{{ route('ckfinder_connector') }}?command=QuickUpload&type=Files'
31 | } );
32 |

It is also possible to use CKFinder.setupCKEditor() as shown below, to automatically setup integration between CKEditor and CKFinder:

33 |
var editor = CKEDITOR.replace( 'ckfinder' );
34 | CKFinder.setupCKEditor( editor );
35 |

The sample below presents the result of the integration. You can manage and select files from your server when creating links or embedding images in CKEditor 4 content. In modern browsers you may also try pasting images from clipboard directly into the editing area as well as dropping images — the files will be saved on the fly by CKFinder.

36 |
37 | @stop 38 | 39 | @section('scripts') 40 | 45 | 46 | 47 | 88 | 89 | @stop 90 | -------------------------------------------------------------------------------- /views/samples/full-page-open.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CKFinder 3 - Full Page Sample 8 | 9 | 10 | @include('ckfinder::setup') 11 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /views/samples/full-page.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Full Page Mode

5 | 6 |

The full page mode opens CKFinder using the entire page as the working area.

7 |
CKFinder.start();
8 |

Click the button below to open CKFinder in full page mode.

9 | 10 | Open CKFinder 11 | @stop 12 | 13 | @section('scripts') 14 | 15 | @stop 16 | -------------------------------------------------------------------------------- /views/samples/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

CKFinder Samples

5 |

This page presents a few samples of CKFinder 3 features. Use the navigation menu on the left side to browse all samples.

6 |

For more detailed information about CKFinder and its features please refer to documentation pages:

7 | 11 |

In case of any issues or suggestions please feel free to contact us.

12 | @stop 13 | -------------------------------------------------------------------------------- /views/samples/layout.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | CKFinder 3 Samples 10 | 11 | 14 | 15 | 16 |
17 |
18 |

19 | CKFinder Logo 20 |

21 | 26 |
27 |
28 |
29 | 59 |
60 | @yield('content') 61 |
62 |
63 | 74 | 83 | 84 | 85 | 86 | @include('ckfinder::setup') 87 | @yield('scripts') 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /views/samples/localization.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Localization

5 | 6 |

CKFinder interface is automatically displayed in the user's language (as set in the browser or operating system settings).

7 |

The language of the CKFinder UI can also be set manually by using the language configuration option.

8 | 9 |
10 |

Translations Needed!

11 |

At the moment many localizations are incomplete. Please feel free to provide translations for your native language. Your help will be much appreciated!

12 |
13 | 14 |

In the example below CKFinder is started in Brazilian Portuguese.

15 | 16 |
CKFinder.widget( 'ckfinder-widget', {
17 | 	language: 'pt-br',
18 | 	width: '100%',
19 | 	height: 500
20 | } );
21 | 22 |
23 | @stop 24 | 25 | @section('scripts') 26 | 33 | 34 | @stop 35 | -------------------------------------------------------------------------------- /views/samples/modals.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Modal Mode

5 | 6 |

The modal mode is similar to popup. The difference is that popups are opened using a separate browser window while in modal mode CKFinder is opened inside a modal container that is appended to current page document.

7 | 8 | 16 |
17 | 18 |

Multiple Modals

19 | 20 |

In some cases you may need more than one modal to handle multiple places that require selecting a file. 21 | Below you can find an example that fills each of the inputs with the URL of the selected file.

22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
var button1 = document.getElementById( 'ckfinder-popup-1' );
 32 | var button2 = document.getElementById( 'ckfinder-popup-2' );
 33 | 
 34 | button1.onclick = function() {
 35 | 	selectFileWithCKFinder( 'ckfinder-input-1' );
 36 | };
 37 | button2.onclick = function() {
 38 | 	selectFileWithCKFinder( 'ckfinder-input-2' );
 39 | };
 40 | 
 41 | function selectFileWithCKFinder( elementId ) {
 42 | 	CKFinder.modal( {
 43 | 		chooseFiles: true,
 44 | 		width: 800,
 45 | 		height: 600,
 46 | 		onInit: function( finder ) {
 47 | 			finder.on( 'files:choose', function( evt ) {
 48 | 				var file = evt.data.files.first();
 49 | 				var output = document.getElementById( elementId );
 50 | 				output.value = file.getUrl();
 51 | 			} );
 52 | 
 53 | 			finder.on( 'file:choose:resizedImage', function( evt ) {
 54 | 				var output = document.getElementById( elementId );
 55 | 				output.value = evt.data.resizedUrl;
 56 | 			} );
 57 | 		}
 58 | 	} );
 59 | }
 60 | 
61 | @stop 62 | 63 | @section('scripts') 64 | 121 | 122 | @stop 123 | -------------------------------------------------------------------------------- /views/samples/other-custom-configuration.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Custom Configuration

5 |

CKFinder provides many configuration options that can be changed to customize the application. 6 | For details please check the documentation.

7 |

In the example below the following options are set:

8 | 14 |
CKFinder.widget( 'ckfinder-widget', {
15 | 	id: 'custom-instance-id',
16 | 	thumbnailDefaultSize: 400,
17 | 	width: '100%',
18 | 	height: 500
19 | } );
20 |
21 | @stop 22 | 23 | @section('scripts') 24 | 32 | 33 | @stop 34 | -------------------------------------------------------------------------------- /views/samples/other-read-only.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Read-only Mode

5 |

Read-only mode can be enabled in CKFinder with the readOnly 6 | configuration option. The user will be able to browse the files but will not be able to introduce any changes. Thanks to this setting you will be able to use 7 | CKFinder as an online gallery.

8 |

Note: This will only disable certain UI elements. In order to successfully block file uploads and modifications, or to set read-only permissions for particular 9 | folders, you will need to adjust ACL settings 10 | accordingly in the server-side configuration file.

11 | 12 |
CKFinder.widget( 'ckfinder-widget', {
13 | 	readOnly: true,
14 | 	width: '100%',
15 | 	height: 500
16 | } );
17 | 18 |
19 |

Simple Gallery

20 |

With a little bit of imagination it is possible to turn CKFinder into a very simple gallery. Here CKFinder is configured to 21 | open a file on double click, run without a toolbar and without the folders panel.

22 |
23 |

The code behind this setup is quite simple:

24 |
CKFinder.widget( 'ckfinder-widget2', {
25 | 	displayFoldersPanel: false,
26 | 	height: 500,
27 | 	id: 'gallery',
28 | 	readOnly: true,
29 | 	readOnlyExclude: 'Toolbars',
30 | 	thumbnailDefaultSize: 143,
31 | 	width: '100%'
32 | } );
33 | 		
34 | @stop 35 | 36 | @section('scripts') 37 | 50 | 51 | @stop 52 | -------------------------------------------------------------------------------- /views/samples/plugin-examples.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Plugin Examples

5 |

The example below shows the StatusBarInfo plugin that displays basic information about the selected file in the application status bar. 6 | You can find more plugin examples in the CKFinder sample plugins repository. 7 | Please have a look at plugin documentation, too.

8 |
CKFinder.widget( 'ckfinder-widget', {
 9 | 	width: '100%',
10 | 	height: 500,
11 | 	plugins: [
12 | 		// The path must be relative to the location of the ckfinder.js file.
13 | 		'../samples/plugins/StatusBarInfo/StatusBarInfo'
14 | 	]
15 | } );
16 |
17 | @stop 18 | 19 | @section('scripts') 20 | 30 | 31 | @stop 32 | -------------------------------------------------------------------------------- /views/samples/popups.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Popup Mode

5 | 6 |

The popup mode is most suitable for selecting files that are stored on a server.
7 | Click the button below to open the popup and choose any file. After that you will see basic information 8 | about the file that was selected, including the URL.

9 | 10 | 18 |
19 | 20 |

Additionally, CKFinder supports a special file selection mode for images called Choose Resized. This feature 21 | allows you to resize the selected image to any size that is suitable for you. The CKFinder connector will automatically create 22 | a resized version of the image and return its URL.

23 | 24 |

Multiple Popups

25 |

In some cases you may need more than one popup to handle multiple places that require selecting a file. 26 | Below you can find an example that fills each of the inputs with the URL of the selected file.

27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | 36 |
var button1 = document.getElementById( 'ckfinder-popup-1' );
 37 | var button2 = document.getElementById( 'ckfinder-popup-2' );
 38 | 
 39 | button1.onclick = function() {
 40 | 	selectFileWithCKFinder( 'ckfinder-input-1' );
 41 | };
 42 | button2.onclick = function() {
 43 | 	selectFileWithCKFinder( 'ckfinder-input-2' );
 44 | };
 45 | 
 46 | function selectFileWithCKFinder( elementId ) {
 47 | 	CKFinder.popup( {
 48 | 		chooseFiles: true,
 49 | 		width: 800,
 50 | 		height: 600,
 51 | 		onInit: function( finder ) {
 52 | 			finder.on( 'files:choose', function( evt ) {
 53 | 				var file = evt.data.files.first();
 54 | 				var output = document.getElementById( elementId );
 55 | 				output.value = file.getUrl();
 56 | 			} );
 57 | 
 58 | 			finder.on( 'file:choose:resizedImage', function( evt ) {
 59 | 				var output = document.getElementById( elementId );
 60 | 				output.value = evt.data.resizedUrl;
 61 | 			} );
 62 | 		}
 63 | 	} );
 64 | }
 65 | 
66 | @stop 67 | 68 | @section('scripts') 69 | 126 | 127 | @stop 128 | -------------------------------------------------------------------------------- /views/samples/skins-jquery-mobile.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

jQuery Mobile Skin

5 | 6 |

CKFinder UI is based on jQuery Mobile so its look & feel can be changed using the jQuery Mobile Theme Roller. 7 | For more information about custom skins and Theme Roller please refer to CKFinder documentation.

8 | 9 |

jQuery Mobile Swatch "a" Skin

10 |
CKFinder.widget( 'ckfinder-widget', {
11 | 	width: '100%',
12 | 	height: 600,
13 | 	skin: 'jquery-mobile',
14 | 	swatch: 'a'
15 | } );
16 |
17 | 18 |

jQuery Mobile Swatch "b" Skin

19 |
CKFinder.widget( 'ckfinder-widget', {
20 | 	width: '100%',
21 | 	height: 600,
22 | 	skin: 'jquery-mobile',
23 | 	swatch: 'b'
24 | } );
25 |
26 | @stop 27 | 28 | @section('scripts') 29 | 44 | 45 | @stop 46 | -------------------------------------------------------------------------------- /views/samples/skins-moono.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Moono Skin

5 | 6 |

Moono is a default skin used in CKFinder that provides visual integration with CKEditor.

7 | 8 |
9 | @stop 10 | 11 | @section('scripts') 12 | 18 | 19 | @stop 20 | -------------------------------------------------------------------------------- /views/samples/user-interface-compact.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Compact User Interface

5 |

It is possible to disable the folders panel and have folders displayed as icons in the main area of the application. 6 | In the example below this mode is initialized inside a widget, but it also works in all standalone modes.

7 | 8 |
CKFinder.widget( 'ckfinder-widget', {
 9 | 	displayFoldersPanel: false,
10 | 	width: '100%',
11 | 	height: 700
12 | } );
13 | 14 |
15 | @stop 16 | 17 | @section('scripts') 18 | 25 | 26 | @stop 27 | -------------------------------------------------------------------------------- /views/samples/user-interface-default.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Default User Interface

5 |

By default folders are displayed in CKFinder in a folder tree panel, like in the example below.

6 | 7 |
8 | @stop 9 | 10 | @section('scripts') 11 | 17 | 18 | @stop 19 | -------------------------------------------------------------------------------- /views/samples/user-interface-listview.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

List View

5 |

By default files are displayed in CKFinder as thumbnails. With list view enabled all files will be displayed as a list, one bellow the other. No image previews are available in this mode.

6 |

The list view can be enabled regardless of the selected user interface (Default/Compact/Mobile).

7 | 8 |
CKFinder.widget( 'ckfinder-widget', {
 9 | 	defaultViewType: 'list',
10 | 	width: '100%',
11 | 	height: 700
12 | } );
13 | 14 |
15 | @stop 16 | 17 | @section('scripts') 18 | 28 | 29 | @stop 30 | -------------------------------------------------------------------------------- /views/samples/user-interface-mobile.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Mobile User Interface

5 |

Mobile user interface is enabled automatically when the width of the working area of the application gets below the value 6 | defined in the uiModeThreshold 7 | configuration option.

8 |

Note: This mode works best on mobile devices, as touch and swipe events are not enabled for desktop browsers.

9 | 10 |
11 | @stop 12 | 13 | @section('scripts') 14 | 21 | 22 | @stop 23 | -------------------------------------------------------------------------------- /views/samples/widget.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ckfinder::samples/layout') 2 | 3 | @section('content') 4 |

Widget Mode

5 | 6 |

Using the widget mode you can embed CKFinder directly on a page, as shown below.

7 |
CKFinder.widget( 'ckfinder-widget', {
 8 | 	width: '100%',
 9 | 	height: 700
10 | } );
11 | 12 |
13 | @stop 14 | 15 | @section('scripts') 16 | 22 | 23 | @stop 24 | -------------------------------------------------------------------------------- /views/setup.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | --------------------------------------------------------------------------------