ckfinder/ckfinder-symfony-bundle
Install the Bundle
composer require ckfinder/ckfinder-symfony-bundle
Download CKFinder
php bin/console ckfinder:download
php bin/console assets:install
Enable Routing
Create config/routes/ckfinder.yaml:
ckfinder_connector:
resource: "@CKSourceCKFinderBundle/Resources/config/routing.yml"
prefix: /
Configure Storage
Create a userfiles directory in your public/ folder (or customize via config):
mkdir -m 777 public/userfiles
First Use Case Integrate CKFinder with a Symfony form (e.g., TinyMCE):
{{ form_widget(form.content, {'attr': {'class': 'ckeditor'}}) }}
Add JS initialization:
ClassicEditor.create(document.querySelector('.ckeditor'), {
cloudServices: {
tokenUrl: '/ckfinder/connector?command=GetToken',
uploadUrl: '/ckfinder/connector?command=Upload'
}
});
/ckfinder/connector endpoint for file operations (upload, delete, etc.).fetch('/ckfinder/connector?command=Upload&type=Files', {
method: 'POST',
body: new FormData(document.querySelector('#file-upload'))
})
.then(response => response.json())
.then(data => console.log(data));
Extend CKSource\CKFinderBundle\Storage\StorageInterface for S3, database, etc.:
// src/Storage/CustomStorage.php
class CustomStorage implements StorageInterface {
public function save($path, $content) { /* ... */ }
public function read($path) { /* ... */ }
// ... other methods
}
Register in config/packages/ckfinder.yaml:
ckfinder:
storage:
adapter: custom
class: App\Storage\CustomStorage
Configure TinyMCE to use CKFinder:
tinymce.init({
selector: '#editor',
plugins: 'ckfinder',
toolbar: 'ckfinder',
ckfinder: {
uploadUrl: '/ckfinder/connector?command=Upload',
browser: '/ckfinder/connector?command=Browser'
}
});
Restrict file operations via Symfony security:
# config/packages/security.yaml
access_control:
- { path: ^/ckfinder/connector, roles: ROLE_USER }
Or use a custom AuthorizationChecker in your storage backend.
Override default settings (e.g., allowed file types) in config/packages/ckfinder.yaml:
ckfinder:
allowedFileTypes: ['jpg', 'png', 'pdf', 'docx']
maxFileSize: 10M
accessControl: {
'userfiles': {
'read': ['ROLE_USER'],
'write': ['ROLE_ADMIN']
}
}
Permissions Issues
public/userfiles is writable by the web server (e.g., chmod -R 777 public/userfiles).php bin/console ckfinder:debug-permissions.Routing Conflicts
ckfinder.yaml to avoid clashes (e.g., prefix: /media/).php bin/console cache:clear
CORS Errors
# config/packages/nelmio_cors.yaml
nelmio_cors:
defaults:
allow_origin: ['*']
allow_methods: ['GET', 'POST', 'PUT', 'DELETE']
Asset Installation
php bin/console assets:install
php bin/console ckfinder:download
Storage Backend Quirks
public/userfiles. For custom paths, set:
ckfinder:
storage:
basePath: '%kernel.project_dir%/public/custom-uploads'
/ckfinder/connector with curl:
curl -X POST -F "upload=@test.jpg" http://localhost/ckfinder/connector?command=Upload
php bin/console debug:config ckfinder to verify settings.Custom Commands
Extend the connector by adding new commands (e.g., GetFilesModifiedSince):
// src/Command/CustomCommand.php
class CustomCommand extends AbstractCommand {
protected function execute(InputInterface $input, OutputInterface $output) {
// Logic for custom command
}
}
Register in services.yaml:
services:
App\Command\CustomCommand:
tags: ['console.command']
Event Listeners Hook into file operations via events:
// src/EventListener/CKFinderListener.php
class CKFinderListener {
public function onUpload(UploadEvent $event) {
// Pre/post-upload logic
}
}
Bind in services.yaml:
services:
App\EventListener\CKFinderListener:
tags:
- { name: kernel.event_listener, event: ckfinder.upload, method: onUpload }
Twig Extensions Add CKFinder-specific Twig functions:
// src/Twig/CKFinderExtension.php
class CKFinderExtension extends \Twig\Extension\AbstractExtension {
public function getFunctions() {
return [
new \Twig\TwigFunction('ckfinder_url', [$this, 'getCKFinderUrl']),
];
}
}
debug: false in config/packages/ckfinder.yaml for production.framework:
http_cache:
cache_control:
rules:
- { path: ^/ckfinder/connector, max_age: 3600 }
How can I help you explore Laravel packages today?