CKFinder functionality can be extended with server side plugins. Althought the full source code of CKFinder server connector is available and it can be changed in any way, a much better way of enhancing CKFinder connector is to create a plugin.
The main advantages of plugins are:
- Upgrades are much easier.
- The plugin code is in a single place.
- Plugins can be easily turned off when are not needed anymore.
Common use cases:
- Adding new server side command (i.e. fileditor and imageresize plugin).
- Working with uploaded file (i.e. watermark plugin).
- Extending the information returned by the Init command (i.e. imageresize plugin).
Contents
[hide]Creating a plugin
Step1: Create plugin folder
Create a directory for your plugin inside of the "plugins" directory (by default CKFinder comes with three plugins: dummy, fileeditor, imagreresize). Let's use "myplugin" as the plugin name and use the same name for our new folder.
Step2: Create plugin file
Inside of your plugin's folder ("myplugin") create an empty file named plugin.php.
Step3: Add plugin definition
// Let's create an empty PHP file for now
Step4: Enable plugin
Add an include_once/require_once statement in the PHP configuration file (config.php):
include_once "plugins/myplugin/plugin.php";
Adding new server side command
Let's write a plugin that adds a new server side command to the connector.
For the sake of simplicity, we'll first create a simple plugin.php that just does exactly what we need:
<?php
// Include base XML command handler
require_once CKFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/XmlCommandHandlerBase.php";
// Since we will send a XML response, we'll extend the XmlCommandHandler
class CKFinder_Connector_CommandHandler_FileSize extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase
{
// The buildXml method is used to construct an XML response
function buildXml()
{
$fileName = $_GET["fileName"];
$filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $fileName);
// Adding a <FileSize> element to the XML response.
$oNode = new Ckfinder_Connector_Utils_XmlNode("FileSize");
$oNode->addAttribute("size", filesize($filePath));
$this->_connectorNode->addChild($oNode);
}
// Register the "FileSize" command
function onBeforeExecuteCommand( &$command )
{
if ( $command == 'FileSize' )
{
$this->sendResponse();
// false = stop further execution.
return false;
}
return true ;
}
}
$CommandHandler_FileSize = new CKFinder_Connector_CommandHandler_FileSize();
// Register the onBeforeExecuteCommand method to be called by the BeforeExecuteCommand hook.
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_FileSize, "onBeforeExecuteCommand");
The full source code of a plugin with all necessary security checks:
<?php
// A simple protection against calling this file directly.
if (!defined('IN_CKFINDER')) exit;
// Include base XML command handler
require_once CKFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/XmlCommandHandlerBase.php";
// Since we will send a XML response, we'll reuse the XmlCommandHandler
class CKFinder_Connector_CommandHandler_FileSize extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase
{
// The buildXml method is used to construct an XML response
function buildXml()
{
// A "must have", checking whether the connector is enabled and the basic parameters (like current folder) are safe.
$this->checkConnector();
$this->checkRequest();
// Checking ACL permissions, we're just getting an information about a file, so FILE_VIEW permission seems to be ok.
if (!$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_VIEW)) {
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED);
}
// Make sure we actually received a file name
if (!isset($_GET["fileName"])) {
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_NAME);
}
$fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_GET["fileName"]);
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig();
// Use the resource type configuration object to check whether the extension of a file to check is really allowed.
if (!$resourceTypeInfo->checkExtension($fileName)) {
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION);
}
// Make sure that the file name is really ok and has not been sent by a hacker
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($fileName) || $resourceTypeInfo->checkIsHiddenFile($fileName)) {
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST);
}
$filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $fileName);
if (!file_exists($filePath) || !is_file($filePath)) {
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND);
}
$size = filesize($filePath);
// *** The main part of this plugin ****
// Adding a <FileSize> element to the XML response.
$oNode = new Ckfinder_Connector_Utils_XmlNode("FileSize");
$oNode->addAttribute("size", $size);
$this->_connectorNode->addChild($oNode);
}
// Register the "FileSize" command
function onBeforeExecuteCommand( &$command )
{
if ( $command == 'FileSize' )
{
$this->sendResponse();
// false = stop further execution.
return false;
}
return true ;
}
}
$CommandHandler_FileSize = new CKFinder_Connector_CommandHandler_FileSize();
// Register the onBeforeExecuteCommand method to be called by the BeforeExecuteCommand hook.
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_FileSize, "onBeforeExecuteCommand");
// (Optional) Register a javascript plugin named "dummy"
$config['Plugins'][] = 'dummy';